예제 #1
0
void output_mysql_init()
{
#if HAVE_LIBMYSQLCLIENT
	int rc;
	char    create_query[sizeof(mysql_create_template) +64];
	char    insert_query[sizeof(mysql_insert_template) +64];

	if (!cfg.mysql_flag)
		return;

	snprintf(create_query, sizeof(create_query), mysql_create_template, cfg.mysql_table);
	snprintf(insert_query, sizeof(insert_query), mysql_insert_template, cfg.mysql_table);

	rc = mysql_library_init(0, NULL, NULL);
	if (rc)
		log_msg(LOG_ERR, "Error initializing MySQL library (%d)", rc);

	cfg.mysql_conn = mysql_init(cfg.mysql_conn);
	if (!cfg.mysql_conn)
		log_msg(LOG_ERR, "Error allocating MySQL object");
	
	mysql_options(cfg.mysql_conn, MYSQL_READ_DEFAULT_GROUP, PACKAGE);
	if (!mysql_real_connect(cfg.mysql_conn, NULL, NULL, NULL, cfg.mysql_db, 0, NULL, 0))
		log_msg(LOG_ERR, "Failed to connect to database: Error: %s", 
	    			mysql_error(cfg.mysql_conn));

	log_msg(LOG_DEBUG, "Using MySQL create query: %s",
	                create_query);
	if(mysql_query(cfg.mysql_conn, create_query))
		log_msg(LOG_ERR, "Error creating table `addrwatch` in MySQL database: %s",
				mysql_error(cfg.mysql_conn));

	cfg.mysql_stmt = mysql_stmt_init(cfg.mysql_conn);
	if (!cfg.mysql_stmt)
		log_msg(LOG_ERR, "Error allocating MySQL statement object");
	
	log_msg(LOG_DEBUG, "Using MySQL insert query: %s [%d]",
	                insert_query, sizeof(insert_query));
	rc = mysql_stmt_prepare(cfg.mysql_stmt, insert_query, strnlen(insert_query, sizeof(insert_query)));
	if (rc)
		log_msg(LOG_ERR, "Error preparing MySQL statement object: %s",
				mysql_stmt_error(cfg.mysql_stmt));
	
	bzero(cfg.mysql_bind, sizeof(cfg.mysql_bind));

	cfg.mysql_bind[0].buffer_type = MYSQL_TYPE_LONGLONG;
	cfg.mysql_bind[0].buffer = &cfg.mysql_vars.timestamp;
	cfg.mysql_bind[0].is_null = 0;
	cfg.mysql_bind[0].length = 0;

	cfg.mysql_bind[1].buffer_type = MYSQL_TYPE_VAR_STRING;
	cfg.mysql_bind[1].buffer = cfg.mysql_vars.hostname;
	cfg.mysql_bind[1].is_null = 0;
	cfg.mysql_bind[1].length = &cfg.mysql_vars.hostname_len;

	cfg.mysql_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
	cfg.mysql_bind[2].buffer = cfg.mysql_vars.iface;
	cfg.mysql_bind[2].is_null = 0;
	cfg.mysql_bind[2].length = &cfg.mysql_vars.iface_len;

	cfg.mysql_bind[3].buffer_type = MYSQL_TYPE_LONG;
	cfg.mysql_bind[3].buffer = &cfg.mysql_vars.vlan;
	cfg.mysql_bind[3].is_null = 0;
	cfg.mysql_bind[3].length = 0;

	//cfg.mysql_vars.mac_len = ETHER_ADDR_LEN;
	//cfg.mysql_bind[3].buffer_type = MYSQL_TYPE_STRING;
	cfg.mysql_bind[4].buffer_type = MYSQL_TYPE_VAR_STRING;
	cfg.mysql_bind[4].buffer = cfg.mysql_vars.mac;
	cfg.mysql_bind[4].is_null = 0;
	cfg.mysql_bind[4].length = &cfg.mysql_vars.mac_len;

	cfg.mysql_bind[5].buffer_type = MYSQL_TYPE_VAR_STRING;
	cfg.mysql_bind[5].buffer = cfg.mysql_vars.ip;
	cfg.mysql_bind[5].is_null = 0;
	cfg.mysql_bind[5].length = &cfg.mysql_vars.ip_len;

	cfg.mysql_bind[6].buffer_type = MYSQL_TYPE_VAR_STRING;
	cfg.mysql_bind[6].buffer = cfg.mysql_vars.origin;
	cfg.mysql_bind[6].is_null = 0;
	cfg.mysql_bind[6].length = &cfg.mysql_vars.origin_len;

	if (mysql_stmt_bind_param(cfg.mysql_stmt, cfg.mysql_bind))
		log_msg(LOG_ERR, "Error binding MySQL statement object: %s",
				mysql_stmt_error(cfg.mysql_stmt));
#endif
}
예제 #2
0
nsresult jxMySQL50Statement::BindOutput()
{
	PRInt32		ndx;
	PRInt32		col_type;

	// Allocate the BIND array and supporting structures.
	nsresult rv = mOut.Allocate();
    if (NS_FAILED(rv))
    {
        SET_ERROR_RETURN(rv);
    }

	// Set up the BIND structure based on the column types specified by the database metadata.
	for (ndx=0; ndx < mOut.mCount ; ndx++) {
		col_type = (mSTMT->fields) ? mSTMT->fields[ndx].type : MYSQL_TYPE_STRING;
		switch (col_type) {
			case MYSQL_TYPE_LONGLONG:
			case MYSQL_TYPE_DOUBLE:
			case MYSQL_TYPE_NEWDECIMAL:
			case MYSQL_TYPE_FLOAT:
			case MYSQL_TYPE_SHORT:
			case MYSQL_TYPE_TINY:
			case MYSQL_TYPE_LONG:
			case MYSQL_TYPE_INT24:
			case MYSQL_TYPE_YEAR:
				mOut.mBindArrayType[ndx] = MYSQL_TYPE_DOUBLE;
				
				/* allocate buffer for double */
				mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_DOUBLE;
				mOut.mBIND[ndx].buffer = &(mOut.mBindArrayBufferTYPE_DOUBLE[ndx]);
				mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]);
				break;

			case MYSQL_TYPE_NULL:
				mOut.mBindArrayType[ndx] = MYSQL_TYPE_NULL;
				/*
				  don't initialize to 0 :
				  1. stmt->result.buf[ofs].buflen
				  2. bind[ofs].buffer
				  3. bind[ofs].buffer_length
				  because memory was allocated with ecalloc
				*/
				mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_NULL;
				mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]);
				break;

			case MYSQL_TYPE_STRING:
			case MYSQL_TYPE_VAR_STRING:
			case MYSQL_TYPE_BIT:
				{
					unsigned long	tmp = 0;
					if (mSTMT->fields[ndx].max_length == 0 && !mysql_stmt_attr_get(mSTMT, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
					{
						mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = (mSTMT->fields) ? (mSTMT->fields[ndx].length) ? mSTMT->fields[ndx].length + 1: 256: 256;
					} else {
						/*
							the user has called store_result(). if he does not there is no way to determine the
							libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
						*/
						if (!(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = mSTMT->fields[ndx].max_length))
							++mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx];
					}
					mOut.mBindArrayType[ndx] = MYSQL_TYPE_STRING;
					mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_STRING;
		    		mOut.mBindArrayBufferTYPE_STRING[ndx] = static_cast<char*>(nsMemory::Alloc(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx])) ;
					if (!mOut.mBindArrayBufferTYPE_STRING[ndx])
                    {
                        SET_ERROR_RETURN (JX_MYSQL50_ERROR_OUT_OF_MEMORY);
                    }
                    mOut.mBIND[ndx].buffer = mOut.mBindArrayBufferTYPE_STRING[ndx];
					mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]);
					mOut.mBIND[ndx].buffer_length = mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx];
					mOut.mBIND[ndx].length = &(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]);
				}
				break;

			case MYSQL_TYPE_BLOB:
			case MYSQL_TYPE_TINY_BLOB:
			case MYSQL_TYPE_MEDIUM_BLOB:
			case MYSQL_TYPE_LONG_BLOB:
				{
#if 0
					PRUint32	tmp = 0;
					if (mSTMT->fields[ndx].max_length == 0 && !mysql_stmt_attr_get(mSTMT, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
					{
						if (mSTMT->fields && mSTMT->fields[ndx].length)
							tmp = mSTMT->fields[ndx].length + 1;

						// tmp will be zero if a length isn't available or if it was the maximum possible of 4GB-1.  In
						// this case, supply a suitable length.

                        // NB. tmp may not always be 4GB-1, so if we do not want support larger than 16MB, we should try
                        // to prevent it.
						if (tmp == 0 || tmp > 16*1024*1024) {
							switch (col_type) {
							case MYSQL_TYPE_BLOB:			tmp =      64*1024;		break;
							case MYSQL_TYPE_TINY_BLOB:		tmp =          256;		break;
							case MYSQL_TYPE_MEDIUM_BLOB:    tmp = 16*1024*1024;		break;
							case MYSQL_TYPE_LONG_BLOB:		tmp = 16*1024*1024;		break;
							}
						}
						mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = tmp;
					} else {
						/*
							the user has called store_result(). if he does not there is no way to determine the
							libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
						*/
						if (!(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = mSTMT->fields[ndx].max_length))
							++mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx];
					}
					mOut.mBindArrayType[ndx] = MYSQL_TYPE_BLOB;
					mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_BLOB;
		    		mOut.mBindArrayBufferTYPE_STRING[ndx] = static_cast<char*>(nsMemory::Alloc(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx])) ;
                    if (!mOut.mBindArrayBufferTYPE_STRING[ndx])
                    {
                        SET_ERROR_RETURN (JX_MYSQL50_ERROR_OUT_OF_MEMORY);
                    }
					mOut.mBIND[ndx].buffer = mOut.mBindArrayBufferTYPE_STRING[ndx];
					mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]);
					mOut.mBIND[ndx].buffer_length = mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx];
					mOut.mBIND[ndx].length = (unsigned long*)&(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]);
#endif
                    mOut.mBindArrayType[ndx] = MYSQL_TYPE_BLOB;
					mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_BLOB;
		    		mOut.mBindArrayBufferTYPE_STRING[ndx] = 0;
					mOut.mBIND[ndx].buffer = mOut.mBindArrayBufferTYPE_STRING[ndx];
					mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]);
					mOut.mBIND[ndx].buffer_length = 0;
                    mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx] = 0;
					mOut.mBIND[ndx].length = &(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]);

				}
				break;

			case MYSQL_TYPE_DATETIME:
			case MYSQL_TYPE_TIME:
			case MYSQL_TYPE_DATE:
			case MYSQL_TYPE_TIMESTAMP:
                if (col_type == MYSQL_TYPE_TIMESTAMP )
				    mOut.mBindArrayType[ndx] = MYSQL_TYPE_DATETIME;
                else
                    mOut.mBindArrayType[ndx] = col_type;

			    mOut.mBindArrayBufferTYPE_DATE[ndx] = static_cast<MYSQL_TIME*>(nsMemory::Alloc(sizeof(MYSQL_TIME)));
                if (!mOut.mBindArrayBufferTYPE_DATE[ndx])
                {
                    SET_ERROR_RETURN (JX_MYSQL50_ERROR_OUT_OF_MEMORY);
                }

				
				/* allocate buffer for DATE */
				mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_DATETIME;
				mOut.mBIND[ndx].buffer = (void*)mOut.mBindArrayBufferTYPE_DATE[ndx];
				mOut.mBIND[ndx].buffer_length = sizeof(MYSQL_TIME);
				mOut.mBIND[ndx].length = (unsigned long*)&(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]);
				mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]);
				break;


			default:
				SET_ERROR_RETURN (JX_MYSQL50_ERROR_INVALID_TYPE);
				break;
		}
	}

	PRUint32 rc = mysql_stmt_bind_result(mSTMT, mOut.mBIND);

	if (rc)
    {
        SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR);
	} else
    {
        if (mRES)
        {
            mysql_free_result(mRES);
            mRES = nsnull;
        }
         
		mRES = mysql_stmt_result_metadata(mSTMT);
        if (mRES)
        {
            if (mysql_stmt_store_result(mSTMT))
            {
#if 0
                int i=0;
                unsigned int en = mysql_stmt_errno(mSTMT);
                const char* es = mysql_stmt_error(mSTMT);
                // Not sure why this would fail.  Will need to be investigated
                // Per DOC, this needs to be called earlier.
                // SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR);
#endif
            }
        }
		return NS_OK;
	}
}
예제 #3
0
fsal_posixdb_status_t fsal_posixdb_initPreparedQueries(fsal_posixdb_conn * p_conn)
{
    int rc;
    unsigned int retry = 1;

    static const char *buildonepath_query =
        "SELECT CONCAT('/',name), handleidparent, handletsparent FROM Parent WHERE handleid=? AND handlets=?";

    /* @TODO  retry = lmgr_config.connect_retry_min; */

    /* create prepared statements */

    do
    {
        /* First create the prepared statement */
        p_conn->stmt_tab[BUILDONEPATH] = mysql_stmt_init(&p_conn->db_conn);

        /* retry if connection to server failed */
        if((p_conn->stmt_tab[BUILDONEPATH] == NULL)
                && db_is_retryable(mysql_errno(&p_conn->db_conn)))
        {
            LogCrit(COMPONENT_FSAL, "Connection to database lost in %s()... Retrying in %u sec.",
                    __FUNCTION__, retry);
            sleep(retry);
            retry *= 2;
            /*if ( retry > lmgr_config.connect_retry_max )
               retry = lmgr_config.connect_retry_max; */
        }
        else
            break;

    }
    while(1);

    if(!p_conn->stmt_tab[BUILDONEPATH])
        ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, mysql_errno(&p_conn->db_conn));

    /* another retry loop */
    /* @TODO retry = lmgr_config.connect_retry_min; */
    retry = 1;

    do
    {
        /* prepare the request */
        rc = mysql_stmt_prepare(p_conn->stmt_tab[BUILDONEPATH], buildonepath_query,
                                strlen(buildonepath_query));

        if(rc && db_is_retryable(mysql_stmt_errno(p_conn->stmt_tab[BUILDONEPATH])))
        {
            LogCrit(COMPONENT_FSAL, "Connection to database lost in %s()... Retrying in %u sec.",
                    __FUNCTION__, retry);
            sleep(retry);
            retry *= 2;
            /*if ( retry > lmgr_config.connect_retry_max )
               retry = lmgr_config.connect_retry_max; */

        }
        else
            break;

    }
    while(1);

    if(rc)
    {
        LogCrit(COMPONENT_FSAL, "Failed to create prepared statement: Error: %s (query='%s')",
                mysql_stmt_error(p_conn->stmt_tab[BUILDONEPATH]), buildonepath_query);
        mysql_stmt_close(p_conn->stmt_tab[BUILDONEPATH]);
        ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, rc);
    }

    ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
예제 #4
0
/* FIXME: Add support for DB_NONE, in this case the function should determine
 * the type of the column in the database and set the field type appropriately.
 * This function must be called after check_result.
 */
static int bind_result(MYSQL_STMT* st, db_fld_t* fld)
{
	int i, n, err = 0;
	struct my_fld* f;
	MYSQL_BIND* result;

	/* Calculate the number of fields in the result */
	for(n = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[n]); n++);
	/* Return immediately if there are no fields in the result set */
	if (n == 0) return 0;

	result = (MYSQL_BIND*)pkg_malloc(sizeof(MYSQL_BIND) * n);
	if (result == NULL) {
		ERR("mysql: No memory left\n");
		return 1;
	}
	memset(result, '\0', sizeof(MYSQL_BIND) * n);
	
	for(i = 0; i < n; i++) {
		f = DB_GET_PAYLOAD(fld + i);
		result[i].is_null = &f->is_null;
		/* We can do it for all the types here, mysql will ignore it
		 * for fixed-size types such as MYSQL_TYPE_LONG
		 */
		result[i].length = &f->length;
		switch(fld[i].type) {
		case DB_INT:
		case DB_BITMAP:
			result[i].buffer_type = MYSQL_TYPE_LONG;
			result[i].buffer = &fld[i].v.int4;
			break;

		case DB_FLOAT:
			result[i].buffer_type = MYSQL_TYPE_FLOAT;
			result[i].buffer = &fld[i].v.flt;
			break;
			
		case DB_DOUBLE:
			result[i].buffer_type = MYSQL_TYPE_DOUBLE;
			result[i].buffer = &fld[i].v.dbl;
			break;

		case DB_DATETIME:
			result[i].buffer_type = MYSQL_TYPE_DATETIME;
			result[i].buffer = &f->time;
			break;

		case DB_STR:
			result[i].buffer_type = MYSQL_TYPE_VAR_STRING;
			if (!f->buf.s) f->buf.s = pkg_malloc(STR_BUF_SIZE);
			if (f->buf.s == NULL) {
				ERR("mysql: No memory left\n");
				err = 1;
				goto error;
			}
			result[i].buffer = f->buf.s;
			fld[i].v.lstr.s = f->buf.s;
			result[i].buffer_length = STR_BUF_SIZE - 1;
			break;

		case DB_CSTR:
			result[i].buffer_type = MYSQL_TYPE_VAR_STRING;
			if (!f->buf.s) f->buf.s = pkg_malloc(STR_BUF_SIZE);
			if (f->buf.s == NULL) {
				ERR("mysql: No memory left\n");
				err = 1;
				goto error;
			}
			result[i].buffer = f->buf.s;
			fld[i].v.cstr = f->buf.s;
			result[i].buffer_length = STR_BUF_SIZE - 1;
			break;

		case DB_BLOB:
			result[i].buffer_type = MYSQL_TYPE_BLOB;
			if (!f->buf.s) f->buf.s = pkg_malloc(STR_BUF_SIZE);
			if (f->buf.s == NULL) {
				ERR("mysql: No memory left\n");
				err = 1;
				goto error;
			}
			result[i].buffer = f->buf.s;
			fld[i].v.blob.s = f->buf.s;
			result[i].buffer_length = STR_BUF_SIZE - 1;
			break;

		case DB_NONE:
			/* Eliminates gcc warning */
			break;

		}
	}

	err = mysql_stmt_bind_result(st, result);
	if (err) {
		ERR("mysql: Error while binding result: %s\n", mysql_stmt_error(st));
		goto error;
	}

	/* We do not need the array of MYSQL_BIND anymore, mysql_stmt_bind_param
	 * creates a copy in the statement and we will update it there
	 */
	if (result) pkg_free(result);
	return 0;
   
 error:
	if (result) pkg_free(result);
	return err;
}
예제 #5
0
	StatementException::StatementException(MYSQL_STMT* stmt) throw()
	{
		m_error = mysql_stmt_errno(stmt);
		m_msg = mysql_stmt_error(stmt);
	}
예제 #6
0
파일: time.c 프로젝트: stucky68/data
int main()
{
    int ret = 0, status = 0;
    MYSQL *mysql;
    MYSQL_RES *result;

    mysql = mysql_init(NULL);
    mysql = mysql_real_connect(mysql, "localhost", "root", "jiangxin", "mydb61", 0, NULL, 0);
    if (mysql == NULL)
    {
        ret = mysql_errno(mysql);
        printf("%s", mysql_error(mysql));
        printf("func mysql_real_connect() err:%d\n", ret);
        return ret;
    }
    else
    {
        printf("conncet ok \n");
    }

    MYSQL_TIME ts;
    MYSQL_BIND bind[3];
    MYSQL_STMT *stmt;
    char query[1024] = "INSERT INTO test_table(date_field, time_field, timestamp_field) values(?,?,?)";

    stmt = mysql_stmt_init(mysql);
    if (!stmt)
    {
        fprintf(stderr, "mysql_stmt_init(), out of memory\n");
        exit(0);
    }
    if (mysql_stmt_prepare(stmt, query, strlen(query)))
    {
        fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
        fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
        exit(0);
    }

    bind[0].buffer_type = MYSQL_TYPE_DATE;
    bind[0].buffer = (char *)&ts;
    bind[0].is_null = 0;
    bind[0].length = 0;

    bind[1] = bind[2] = bind[0];

    mysql_stmt_bind_param(stmt, bind);

    ts.year = 2002;
    ts.month = 02;
    ts.day = 03;

    ts.hour = 10;
    ts.minute = 45;
    ts.second = 20;

    mysql_stmt_execute(stmt);
    if (mysql_stmt_close(stmt))
    {
        fprintf(stderr, " failed while closing the statement\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }
    mysql_close(mysql);
}
예제 #7
0
/**
 * This is the main command execution function. The function contains
 * all the necessary logic to detect reset or disconnected database
 * connections and uploads commands to the server if necessary.
 * @param cmd Command to be executed
 * @return    0 if OK, <0 on MySQL failure, >0 on DB API failure
 */
static int exec_cmd_safe(db_cmd_t* cmd)
{
    int i, err;
    db_con_t* con;
    struct my_cmd* mcmd;
    struct my_con* mcon;
	
    /* First things first: retrieve connection info
     * from the currently active connection and also
     * mysql payload from the database command
     */
    mcmd = DB_GET_PAYLOAD(cmd);
    con = cmd->ctx->con[db_payload_idx];
    mcon = DB_GET_PAYLOAD(con);
    
    for(i = 0; i <= my_retries; i++) {
	if ((mcon->flags & MY_CONNECTED) == 0) {
	    /* The connection is disconnected, try to reconnect */
	    if (my_con_connect(con)) {
		INFO("mysql: exec_cmd_safe failed to re-connect\n");
		continue;
	    }
	}	
	
	/* Next check the number of resets in the database connection, if this
	 * number is higher than the number we keep in my_cmd structure in
	 * last_reset variable then the connection was reset and we need to
	 * upload the command again to the server before executing it, because
	 * the server recycles all server side information upon disconnect.
	 */
	if (mcon->resets > mcmd->last_reset) {
	    INFO("mysql: Connection reset detected, uploading command to server\n");
	    err = upload_cmd(cmd);
	    if (err < 0) {
		INFO("mysql: Error while uploading command\n");
		continue;
	    } else if (err > 0) {
		/* DB API error, this is a serious problem such as memory
		 * allocation failure, bail out
		 */
		return 1;
	    }
	}
	
	set_mysql_params(cmd);
	err = mysql_stmt_execute(mcmd->st);
	if (err == 0) {
	    /* The command was executed successfully, now fetch all data to
	     * the client if it was requested by the user */
	    if (mcmd->flags & MY_FETCH_ALL) {
		err = mysql_stmt_store_result(mcmd->st);
		if (err) {
		    INFO("mysql: Error while fetching data to client.\n");
		    goto error;
		}
	    }
	    return 0;
	}
	
    error:
	/* Command execution failed, log a message and try to reconnect */
	INFO("mysql: libmysql: %d, %s\n", mysql_stmt_errno(mcmd->st),
	     mysql_stmt_error(mcmd->st));
	INFO("mysql: Error while executing command on server, trying to reconnect\n");

	my_con_disconnect(con);
	if (my_con_connect(con)) {
	    INFO("mysql: Failed to reconnect server\n");
	} else {
	    INFO("mysql: Successfully reconnected server\n");
	}
    }
    
    INFO("mysql: Failed to execute command, giving up\n");
    return -1;
}
예제 #8
0
static int
statement_fetch_impl_cont (lua_State * L, statement_t * statement, /* {{{ */
			   int event, int named_columns)
{
  int column_count;
  unsigned long *real_length = NULL;
  int values = 0;

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;

      real_length = calloc (column_count, sizeof (unsigned long));

      statement->event =
	mysql_stmt_fetch_cont (&(statement->ret), statement->stmt, event);

      if (statement->event & MYSQL_WAIT_EXCEPT)
	{
	  lua_pushnil (L);
	  lua_pushfstring (L, mysql_stmt_error (statement->stmt));
	  values = 2;
	}

      if (statement->event & MYSQL_WAIT_TIMEOUT)
	{
	  statement->timeout =
	    1000 * mysql_get_timeout_value_ms (statement->mysql);
	}
      /* Pretty sure statement->ret should be the return value, but it seems to return 1 */
      /* using mysql_stmt_errno instead */
      if (mysql_stmt_errno (statement->stmt) != 0)
	{
	  lua_pushnil (L);
	  lua_pushstring (L, mysql_stmt_error (statement->stmt));
	  values = 2;
	}
      if (statement->event > 0)
	{
	  lua_pushboolean (L, 0);
	  lua_pushnumber (L, convert_mysql_to_ev (statement->event));
	  values = 2;
	}

      if (mysql_stmt_errno (statement->stmt) == 0
	  || statement->ret == MYSQL_DATA_TRUNCATED)
	{
	  int d = 1;

	  lua_pushboolean (L, 1);
	  lua_newtable (L);
	  values = 2;
	  for (i = 0; i < column_count; i++)
	    {
	      lua_push_type_t lua_push =
		mysql_to_lua_push (statement->fields[i].type);
	      const char *name = statement->fields[i].name;

	      if (statement->bind[i].buffer == NULL)
		{
		  char *buffer =
		    (char *) calloc (real_length[i] + 1, sizeof (char));
		  statement->bind[i].buffer = buffer;
		  statement->bind[i].buffer_length = real_length[i];
		  mysql_stmt_fetch_column (statement->stmt,
					   &(statement->bind[i]), i, 0);
		}

	      if (lua_push == LUA_PUSH_NIL)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_NIL (name);
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_NIL (d);
		    }
		}
	      else if (lua_push == LUA_PUSH_INTEGER)
		{
		  if (statement->fields[i].type == MYSQL_TYPE_YEAR
		      || statement->fields[i].type == MYSQL_TYPE_SHORT)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(short
						 *) (statement->
						     bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      *(short
						*) (statement->
						    bind[i].buffer));
			}
		    }
		  else if (statement->fields[i].type == MYSQL_TYPE_TINY)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       (int) *(char
						       *) (statement->bind
							   [i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      (int) *(char
						      *) (statement->bind
							  [i].buffer));
			}
		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(int
						 *) (statement->
						     bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      *(int
						*) (statement->
						    bind[i].buffer));
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_NUMBER)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_FLOAT (name,
					     *(double
					       *) (statement->
						   bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_FLOAT (d,
					    *(double
					      *) (statement->bind[i].buffer));
		    }
		}
	      else if (lua_push == LUA_PUSH_STRING)
		{

		  if (statement->fields[i].type == MYSQL_TYPE_TIMESTAMP
		      || statement->fields[i].type == MYSQL_TYPE_DATETIME)
		    {
		      char str[20];
		      struct st_mysql_time *t = statement->bind[i].buffer;

		      snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d",
				t->year, t->month, t->day, t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (statement->fields[i].type == MYSQL_TYPE_TIME)
		    {
		      char str[9];
		      struct st_mysql_time *t = statement->bind[i].buffer;

		      snprintf (str, 9, "%02d:%02d:%02d", t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (statement->fields[i].type == MYSQL_TYPE_DATE)
		    {
		      char str[20];
		      struct st_mysql_time *t = statement->bind[i].buffer;

		      snprintf (str, 11, "%d-%02d-%02d", t->year,
				t->month, t->day);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}

		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name,
						  statement->bind[i].buffer);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d,
						 statement->bind[i].buffer);
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_BOOLEAN)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_BOOL (name,
					    *(int *) (statement->
						      bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_BOOL (d,
					   *(int *) (statement->
						     bind[i].buffer));
		    }
		}
	      else
		{
		  luaL_error (L, DBI_ERR_UNKNOWN_PUSH);
		  values = 1;
		}
	    }
	}
      else
	{
	  lua_pushnil (L);
	  values = 1;
	}
    }

  if (statement->bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (statement->bind[i].buffer);
	}

      free (statement->bind);
    }
  return values;

} /* }}} */
예제 #9
0
static int
statement_fetch_impl (lua_State * L, statement_t * statement, /* {{{ */
		      int named_columns)
{
  int column_count, fetch_result_ok;
  MYSQL_BIND *bind = NULL;
  unsigned long *real_length = NULL;
  const char *error_message = NULL;

  if (!statement->stmt)
    {
      luaL_error (L, DBI_ERR_FETCH_INVALID);
      return 0;
    }

  if (!statement->metadata)
    {
      luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE);
      return 0;
    }

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;
      MYSQL_FIELD *fields;

      real_length = calloc (column_count, sizeof (unsigned long));

      bind = malloc (sizeof (MYSQL_BIND) * column_count);
      memset (bind, 0, sizeof (MYSQL_BIND) * column_count);

      fields = mysql_fetch_fields (statement->metadata);

      for (i = 0; i < column_count; i++)
	{
	  unsigned int length = mysql_buffer_size (&fields[i]);
	  if (length > sizeof (MYSQL_TIME))
	    {
	      bind[i].buffer = NULL;
	      bind[i].buffer_length = 0;
	    }
	  else
	    {
	      char *buffer = (char *) malloc (length);
	      memset (buffer, 0, length);

	      bind[i].buffer = buffer;
	      bind[i].buffer_length = length;
	    }

	  bind[i].buffer_type = fields[i].type;
	  bind[i].length = &real_length[i];
	}

      if (mysql_stmt_bind_result (statement->stmt, bind))
	{
	  error_message = DBI_ERR_BINDING_RESULTS;
	  goto cleanup;
	}

      fetch_result_ok = mysql_stmt_fetch (statement->stmt);
      if (fetch_result_ok == 0 || fetch_result_ok == MYSQL_DATA_TRUNCATED)
	{
	  int d = 1;

	  lua_newtable (L);
	  for (i = 0; i < column_count; i++)
	    {
	      lua_push_type_t lua_push = mysql_to_lua_push (fields[i].type);
	      const char *name = fields[i].name;

	      if (bind[i].buffer == NULL)
		{
		  char *buffer =
		    (char *) calloc (real_length[i] + 1, sizeof (char));
		  bind[i].buffer = buffer;
		  bind[i].buffer_length = real_length[i];
		  mysql_stmt_fetch_column (statement->stmt, &bind[i], i, 0);
		}

	      if (lua_push == LUA_PUSH_NIL)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_NIL (name);
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_NIL (d);
		    }
		}
	      else if (lua_push == LUA_PUSH_INTEGER)
		{
		  if (fields[i].type == MYSQL_TYPE_YEAR
		      || fields[i].type == MYSQL_TYPE_SHORT)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(short *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d, *(short *) (bind[i].buffer));
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_TINY)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       (int) *(char
						       *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      (int) *(char
						      *) (bind[i].buffer));
			}
		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(int *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d, *(int *) (bind[i].buffer));
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_NUMBER)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_FLOAT (name,
					     *(double *) (bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_FLOAT (d, *(double *) (bind[i].buffer));
		    }
		}
	      else if (lua_push == LUA_PUSH_STRING)
		{

		  if (fields[i].type == MYSQL_TYPE_TIMESTAMP
		      || fields[i].type == MYSQL_TYPE_DATETIME)
		    {
		      char str[20];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d",
				t->year, t->month, t->day, t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_TIME)
		    {
		      char str[9];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 9, "%02d:%02d:%02d", t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_DATE)
		    {
		      char str[20];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 11, "%d-%02d-%02d", t->year,
				t->month, t->day);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}

		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, bind[i].buffer);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, bind[i].buffer);
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_BOOLEAN)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_BOOL (name, *(int *) (bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_BOOL (d, *(int *) (bind[i].buffer));
		    }
		}
	      else
		{
		  luaL_error (L, DBI_ERR_UNKNOWN_PUSH);
		}
	    }
	}
      else
	{
	  lua_pushnil (L);
	}
    }

cleanup:
  free (real_length);

  if (bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (bind[i].buffer);
	}

      free (bind);
    }

  if (error_message)
    {
      luaL_error (L, error_message, mysql_stmt_error (statement->stmt));
      return 0;
    }

  return 1;
} /* }}} */
예제 #10
0
/*
 * success,err = statement:execute(...)
 */
static int
statement_execute (lua_State * L) /* {{{ */
{
  int n = lua_gettop (L);
  statement_t *statement =
    (statement_t *) luaL_checkudata (L, 1, DBD_MYSQL_STATEMENT);
  int num_bind_params = n - 1;
  int expected_params;

  unsigned char *buffer = NULL;
  int offset = 0;

  MYSQL_BIND *bind = NULL;
  MYSQL_RES *metadata = NULL;

  char *error_message = NULL;
  char *errstr = NULL;

  int p;

  if (statement->metadata)
    {
      /*
       * free existing metadata from any previous executions
       */
      mysql_free_result (statement->metadata);
      statement->metadata = NULL;
    }

  if (!statement->stmt)
    {
      lua_pushboolean (L, 0);
      lua_pushstring (L, DBI_ERR_EXECUTE_INVALID);
      return 2;
    }

  expected_params = mysql_stmt_param_count (statement->stmt);

  if (expected_params != num_bind_params)
    {
      /*
       * mysql_stmt_bind_param does not handle this condition,
       * and the client library will segfault if these do no match
       */
      lua_pushboolean (L, 0);
      lua_pushfstring (L, DBI_ERR_PARAM_MISCOUNT, expected_params,
		       num_bind_params);
      return 2;
    }

  if (num_bind_params > 0)
    {
      bind = malloc (sizeof (MYSQL_BIND) * num_bind_params);
      if (bind == NULL)
	{
	  luaL_error (L, "Could not alloc bind params\n");
	}

      buffer = (unsigned char *) malloc (num_bind_params * sizeof (double));
      memset (bind, 0, sizeof (MYSQL_BIND) * num_bind_params);
    }

  for (p = 2; p <= n; p++)
    {
      int type = lua_type (L, p);
      int i = p - 2;

      const char *str = NULL;
      size_t *str_len = NULL;
      double *num = NULL;
      int *boolean = NULL;
      char err[64];

      switch (type)
	{
	case LUA_TNIL:
	  bind[i].buffer_type = MYSQL_TYPE_NULL;
	  bind[i].is_null = (my_bool *) 1;
	  break;

	case LUA_TBOOLEAN:
	  boolean = (int *) (buffer + offset);
	  offset += sizeof (int);
	  *boolean = lua_toboolean (L, p);

	  bind[i].buffer_type = MYSQL_TYPE_LONG;
	  bind[i].is_null = (my_bool *) 0;
	  bind[i].buffer = (char *) boolean;
	  bind[i].length = 0;
	  break;

	case LUA_TNUMBER:
	  /*
	   * num needs to be it's own 
	   * memory here
	   */
	  num = (double *) (buffer + offset);
	  offset += sizeof (double);
	  *num = lua_tonumber (L, p);

	  bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
	  bind[i].is_null = (my_bool *) 0;
	  bind[i].buffer = (char *) num;
	  bind[i].length = 0;
	  break;

	case LUA_TSTRING:
	  str_len = (size_t *) (buffer + offset);
	  offset += sizeof (size_t);
	  str = lua_tolstring (L, p, str_len);

	  bind[i].buffer_type = MYSQL_TYPE_STRING;
	  bind[i].is_null = (my_bool *) 0;
	  bind[i].buffer = (char *) str;
	  bind[i].length = str_len;
	  break;

	default:
	  snprintf (err, sizeof (err) - 1, DBI_ERR_BINDING_TYPE_ERR,
		    lua_typename (L, type));
	  errstr = err;
	  error_message = DBI_ERR_BINDING_PARAMS;
	  goto cleanup;
	}
    }

  if (mysql_stmt_bind_param (statement->stmt, bind))
    {
      error_message = DBI_ERR_BINDING_PARAMS;
      goto cleanup;
    }

  if (mysql_stmt_execute (statement->stmt))
    {
      error_message = DBI_ERR_BINDING_EXEC;
      goto cleanup;
    }

  metadata = mysql_stmt_result_metadata (statement->stmt);

  if (metadata)
    {
      mysql_stmt_store_result (statement->stmt);
    }

cleanup:
  if (bind)
    {
      free (bind);
    }

  if (buffer)
    {
      free (buffer);
    }

  if (error_message)
    {
      lua_pushboolean (L, 0);
      lua_pushfstring (L, error_message,
		       errstr ? errstr : mysql_stmt_error (statement->stmt));
      return 2;
    }

  statement->metadata = metadata;

  lua_pushboolean (L, 1);
  return 1;
} /* }}} */
예제 #11
0
static int
statement_fetch_impl_start (lua_State * L, statement_t * statement) /* {{{ */
{
  int column_count;
  unsigned long *real_length = NULL;
  const char *error_message = NULL;

  if (!statement->stmt)
    {
      luaL_error (L, DBI_ERR_FETCH_INVALID);
      return 0;
    }

  if (!statement->metadata)
    {
      luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE);
      return 0;
    }

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;

      real_length = calloc (column_count, sizeof (unsigned long));

      statement->bind = malloc (sizeof (MYSQL_BIND) * column_count);
      memset (statement->bind, 0, sizeof (MYSQL_BIND) * column_count);

      statement->fields = mysql_fetch_fields (statement->metadata);

      for (i = 0; i < column_count; i++)
	{
	  unsigned int length = mysql_buffer_size (&statement->fields[i]);
	  if (length > sizeof (MYSQL_TIME))
	    {
	      statement->bind[i].buffer = NULL;
	      statement->bind[i].buffer_length = 0;
	    }
	  else
	    {
	      char *buffer = (char *) malloc (length);
	      memset (buffer, 0, length);

	      statement->bind[i].buffer = buffer;
	      statement->bind[i].buffer_length = length;
	    }

	  statement->bind[i].buffer_type = statement->fields[i].type;
	  statement->bind[i].length = &real_length[i];
	}

      if (mysql_stmt_bind_result (statement->stmt, statement->bind))
	{
	  error_message = DBI_ERR_BINDING_RESULTS;
	  goto cleanup;
	}

      statement->event =
	mysql_stmt_fetch_start (&(statement->ret), statement->stmt);

      if (statement->event & MYSQL_WAIT_EXCEPT)
	{
	  lua_pushnil (L);
	  return 1;
	}
      if (statement->event & MYSQL_WAIT_TIMEOUT)
	{
	  statement->timeout =
	    1000 * mysql_get_timeout_value_ms (statement->mysql);
	}

      lua_pushboolean (L, 1);
      lua_pushnumber (L, statement->event);
      return 2;
    }
  else
    {
      lua_pushnil (L);
      return 1;
    }


cleanup:
  free (real_length);

  if (statement->bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (statement->bind[i].buffer);
	}

      free (statement->bind);
    }


  if (error_message)
    {
      luaL_error (L, error_message, mysql_stmt_error (statement->stmt));
      return 0;
    }

  return 1;
} /* }}} */
/**
 * Get all of the keys in the datastore.
 *
 * @param cls closure
 * @param proc function to call on each key
 * @param proc_cls closure for proc
 */
static void
mysql_plugin_get_keys (void *cls,
			PluginKeyProcessor proc,
			void *proc_cls)
{
  struct Plugin *plugin = cls;
  const char *query = "SELECT hash FROM gn090";
  int ret;
  MYSQL_STMT *statement;
  struct GNUNET_HashCode key;
  MYSQL_BIND cbind[1];
  unsigned long length;

  statement = GNUNET_MYSQL_statement_get_stmt (plugin->mc,
					       plugin->get_all_keys);
  if (statement == NULL)
  {
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  if (mysql_stmt_prepare (statement, query, strlen (query)))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
                     _("Failed to prepare statement `%s'\n"), query);
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  GNUNET_assert (proc != NULL);
  if (mysql_stmt_execute (statement))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("`%s' for `%s' failed at %s:%d with error: %s\n"),
                "mysql_stmt_execute", query, __FILE__, __LINE__,
                mysql_stmt_error (statement));
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  memset (cbind, 0, sizeof (cbind));
  cbind[0].buffer_type = MYSQL_TYPE_BLOB;
  cbind[0].buffer = &key;
  cbind[0].buffer_length = sizeof (key);
  cbind[0].length = &length;
  cbind[0].is_unsigned = GNUNET_NO;
  if (mysql_stmt_bind_result (statement, cbind))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("`%s' failed at %s:%d with error: %s\n"),
                "mysql_stmt_bind_result", __FILE__, __LINE__,
                mysql_stmt_error (statement));
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  while (0 == (ret = mysql_stmt_fetch (statement)))
  {
    if (sizeof (struct GNUNET_HashCode) == length)
      proc (proc_cls, &key, 1);
  }
  if (ret != MYSQL_NO_DATA)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("`%s' failed at %s:%d with error: %s\n"),
		     "mysql_stmt_fetch", __FILE__, __LINE__,
		     mysql_stmt_error (statement));
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  mysql_stmt_reset (statement);
}
bool MySQLConnection::Execute(PreparedStatement* stmt)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        ASSERT(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     // TODO: Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

        uint32 _s = 0;
        if (sLog->GetSQLDriverQueryLogging())
            _s = getMSTime();

        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (sLog->GetSQLDriverQueryLogging())
            sLog->outSQLDriver("[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString(m_queries[index].first).c_str());

        m_mStmt->ClearParameters();
        return true;
    }
}
예제 #14
0
int sqlrow(DB db,SQL sql,const char *format,...)
{
	int i;
	my_bool w;
	int *ii;
	char **t;
	MYSQL_FIELD *f;
	va_list ap;

	if(!db||!sql)
	{
		printf("sqlrow: bad database/query handle\n");
		return -1;
	}

	if(!sql->result)
	{
		w=1;
		if(mysql_stmt_attr_set(sql->sql,STMT_ATTR_UPDATE_MAX_LENGTH,&w))
		{
			printf("sqlsetattr: %s\n",mysql_stmt_error(sql->sql));
			goto out0;
		}
		if(mysql_stmt_execute(sql->sql))
		{
			printf("sqlexecute: %s\n",mysql_stmt_error(sql->sql));
			goto out0;
		}
		if(!(sql->restotal=mysql_stmt_field_count(sql->sql)))return 1;
		if(mysql_stmt_store_result(sql->sql))
		{
			printf("sqlstore: %s\n",mysql_stmt_error(sql->sql));
			goto out0;
		}
		if(!(sql->result=mysql_stmt_result_metadata(sql->sql)))return 1;
		if(!(f=mysql_fetch_fields(sql->result)))
		{
			printf("sqlfields: %s\n",mysql_stmt_error(sql->sql));
			goto out0;
		}
		if(!(sql->reslbuf=malloc(sql->restotal*sizeof(unsigned long))))
		{
			printf("sqlrow: out of memory\n");
			goto out0;
		}
		if(!(sql->resibuf=malloc(sql->restotal*sizeof(int))))
		{
			printf("sqlrow: out of memory\n");
			goto out0;
		}
		if(!(sql->resparam=malloc(sql->restotal*sizeof(MYSQL_BIND))))
		{
			printf("sqlrow: out of memory\n");
			goto out0;
		}
		memset(sql->resparam,0,sql->restotal*sizeof(MYSQL_BIND));
		for(i=0;i<sql->restotal;i++)switch(f[i].type)
		{
		case FIELD_TYPE_TINY:
		case FIELD_TYPE_SHORT:
		case FIELD_TYPE_LONG:
		case FIELD_TYPE_LONGLONG:
		case FIELD_TYPE_INT24:
			sql->resparam[i].buffer_type=MYSQL_TYPE_LONG;
			sql->resparam[i].buffer=&sql->resibuf[i];
			break;

		case FIELD_TYPE_STRING:
		case FIELD_TYPE_VAR_STRING:
		case FIELD_TYPE_BLOB:
			sql->resparam[i].buffer_type=MYSQL_TYPE_BLOB;
			sql->resparam[i].buffer_length=f[i].max_length+1;
			sql->resparam[i].length=&sql->reslbuf[i];
			if(!(sql->resparam[i].buffer=malloc(f[i].max_length+1)))
			{
				while(i--)if(sql->resparam[i].buffer_type==
					MYSQL_TYPE_BLOB)
					free(sql->resparam[i].buffer);
				free(sql->resparam);
				sql->resparam=NULL;
				printf("sqlrow: out of memory\n");
				goto out0;
			}
			break;

		default:
			printf("sqlrow: unknown field type %d\n",f[i].type);
			return -1;
		}
		if(mysql_stmt_bind_result(sql->sql,sql->resparam))
		{
			printf("sqlresbind: %s\n",mysql_stmt_error(sql->sql));
			goto out0;
		}
	}

	if(mysql_stmt_fetch(sql->sql))return 1;

	va_start(ap,format);
	for(i=0;*format;i++)if(i==sql->restotal)
	{
		va_end(ap);
		goto out1;
	}
	else switch(*format++)
	{
	case 'i':
		if(sql->resparam[i].buffer_type!=MYSQL_TYPE_LONG)
		{
			va_end(ap);
			goto out1;
		}
		ii=va_arg(ap,int *);
		*ii=sql->resibuf[i];
		break;
		break;
	case 't':
		if(sql->resparam[i].buffer_type!=MYSQL_TYPE_BLOB)
		{
			va_end(ap);
			goto out1;
		}
		t=va_arg(ap,char **);
		*t=sql->resparam[i].buffer;
		(*t)[sql->reslbuf[i]]=0;
		break;
	default:printf("unknown format %c\n",format[-1]);
		va_end(ap);
		goto out0;
	}
	va_end(ap);

	return 0;

out1:	printf("sqlrow format mismatch\n");
out0:	return -1;
}
예제 #15
0
파일: sql.c 프로젝트: itaka/hurricane
/// Fetches the next row.
int SqlStmt_NextRow(SqlStmt* self)
{
	int err;
	size_t i;
	size_t cols;
	MYSQL_BIND* column;
	unsigned long length;

	if( self == NULL )
		return SQL_ERROR;

	// bind columns
	if( self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns) )
		err = 1;// error binding columns
	else
		err = mysql_stmt_fetch(self->stmt);// fetch row

	// check for errors
	if( err == MYSQL_NO_DATA )
		return SQL_NO_DATA;
#if defined(MYSQL_DATA_TRUNCATED)
	// MySQL 5.0/5.1 defines and returns MYSQL_DATA_TRUNCATED [FlavioJS]
	if( err == MYSQL_DATA_TRUNCATED )
	{
		my_bool truncated;

		if( !self->bind_columns )
		{
			ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n");
			return SQL_ERROR;
		}

		// find truncated column
		cols = SqlStmt_NumColumns(self);
		for( i = 0; i < cols; ++i )
		{
			column = &self->columns[i];
			column->error = &truncated;
			mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0);
			column->error = NULL;
			if( truncated )
			{// report truncated column
				SqlStmt_P_ShowDebugTruncatedColumn(self, i);
				return SQL_ERROR;
			}
		}
		ShowSQL("DB error - data truncated (unknown source)\n");
		return SQL_ERROR;
	}
#endif
	if( err )
	{
		ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
		return SQL_ERROR;
	}

	// propagate column lengths and clear unused parts of string/enum/blob buffers
	cols = SqlStmt_NumColumns(self);
	for( i = 0; i < cols; ++i )
	{
		length = self->column_lengths[i].length;
		column = &self->columns[i];
#if !defined(MYSQL_DATA_TRUNCATED)
		// MySQL 4.1/(below?) returns success even if data is truncated, so we test truncation manually [FlavioJS]
		if( column->buffer_length < length )
		{// report truncated column
			if( column->buffer_type == MYSQL_TYPE_STRING || column->buffer_type == MYSQL_TYPE_BLOB )
			{// string/enum/blob column
				SqlStmt_P_ShowDebugTruncatedColumn(self, i);
				return SQL_ERROR;
			}
			// FIXME numeric types and null [FlavioJS]
		}
#endif
		if( self->column_lengths[i].out_length )
			*self->column_lengths[i].out_length = (uint32)length;
		if( column->buffer_type == MYSQL_TYPE_STRING )
		{// clear unused part of the string/enum buffer (and nul-terminate)
			memset((char*)column->buffer + length, 0, column->buffer_length - length + 1);
		}
		else if( column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length )
		{// clear unused part of the blob buffer
			memset((char*)column->buffer + length, 0, column->buffer_length - length);
		}
	}

	return SQL_SUCCESS;
}
예제 #16
0
static int
st_init_dbconnection(storage_mysql_t *st, db_connection_t *dbc)
{
    MYSQL *mysql = mysql_init(&dbc->dbh);
    if (!mysql) {
        fprintf(stderr, "Can't initialize the mysql handler\n");
        return -1;
    }
#ifndef __MACH__
    pthread_spin_init(&dbc->lock, 0);
#endif
    dbc->initialized = 1;

    my_bool b = 1;

    if (!mysql_real_connect(&dbc->dbh,
                            st->dbhost,
                            st->dbuser,
                            st->dbpasswd,
                            st->dbname,
                            st->dbport,
                            st->unix_socket,
                            0))
    {
        fprintf(stderr, "Can't connect to mysql database: %s\n",
                mysql_error(&dbc->dbh));
        return -1;
    }

    if (!st->table_checked) {
        char create_table_sql[2048];
        snprintf(create_table_sql, sizeof(create_table_sql),
                "CREATE TABLE IF NOT EXISTS `%s` (`%s` char(255) primary key, `%s` blob, `%s` int, `%s` longblob)",
                st->table, st->keyfield, st->keybytesfield, st->valuesizefield, st->valuefield);
        mysql_query(&dbc->dbh, create_table_sql);
        st->table_checked = 1;
    }

    char sql[2048];
    snprintf(sql, sizeof(sql), "SELECT `%s` FROM `%s` WHERE `%s` = ?", st->valuefield, st->table, st->keyfield);
    dbc->select_stmt = mysql_stmt_init(mysql);
    int rc = mysql_stmt_prepare(dbc->select_stmt, sql, strlen(sql));
    if (rc != 0) {
        fprintf(stderr, "Can't prepare the select_stmt '%s' : %s\n",
                sql, mysql_stmt_error(dbc->select_stmt));
        return -1;
    }
  
    snprintf(sql, sizeof(sql), "REPLACE INTO `%s` VALUES(?, ?, ?, ?)", st->table);
    dbc->insert_stmt = mysql_stmt_init(mysql);
    rc = mysql_stmt_prepare(dbc->insert_stmt, sql, strlen(sql));
    if (rc != 0) {
        fprintf(stderr, "Can't prepare the insert_stmt '%s' : %s\n",
                sql, mysql_stmt_error(dbc->insert_stmt));
        return -1;
    }

    snprintf(sql, sizeof(sql), "DELETE FROM `%s` WHERE `%s` = ?", st->table, st->keyfield);
    dbc->delete_stmt = mysql_stmt_init(mysql);
    rc = mysql_stmt_prepare(dbc->delete_stmt, sql, strlen(sql));
    if (rc != 0) {
        fprintf(stderr, "Can't prepare the delete_stmt '%s' : %s\n",
                sql, mysql_stmt_error(dbc->delete_stmt));
        return -1;
    }

    snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM `%s` WHERE `%s` = ?", st->table, st->keyfield);
    dbc->exist_stmt = mysql_stmt_init(mysql);
    rc = mysql_stmt_prepare(dbc->exist_stmt, sql, strlen(sql));
    if (rc != 0) {
        fprintf(stderr, "Can't prepare the exist_stmt '%s' : %s\n",
                sql, mysql_stmt_error(dbc->exist_stmt));
        return -1;
    }

    snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM `%s`", st->table);
    dbc->count_stmt = mysql_stmt_init(mysql);
    rc = mysql_stmt_prepare(dbc->count_stmt, sql, strlen(sql));
    if (rc != 0) {
        fprintf(stderr, "Can't prepare the count_stmt '%s' : %s\n",
                sql, mysql_stmt_error(dbc->count_stmt));
        return -1;
    }

    snprintf(sql, sizeof(sql), "SELECT `%s`, `%s`  FROM `%s`",
            st->keybytesfield, st->valuesizefield, st->table);
    dbc->index_stmt = mysql_stmt_init(mysql);
    rc = mysql_stmt_prepare(dbc->index_stmt, sql, strlen(sql)); 
    if (rc != 0) {
        fprintf(stderr, "Can't prepare the index_stmt '%s' : %s\n",
                sql, mysql_stmt_error(dbc->index_stmt));
        return -1;
    }

    return 0;
}
예제 #17
0
bool MySQLConnection::Execute(PreparedStatement* stmt)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        // guarded block for thread-safe mySQL request
        ACE_Guard<ACE_Thread_Mutex> query_connection_guard(m_Mutex);

        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        ASSERT(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     // TODO: Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

        #ifdef SQLQUERY_LOG
        uint32 _s = getMSTime();
        #endif
        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            sLog.outSQLDriver("[ERROR]: PreparedStatement (id: %u) error binding params:  %s", index, mysql_stmt_error(msql_STMT));
            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            sLog.outSQLDriver("[ERROR]: PreparedStatement (id: %u) error executing:  %s", index, mysql_stmt_error(msql_STMT));
            m_mStmt->ClearParameters();
            return false;
        }
        else
        {
            #ifdef SQLQUERY_LOG
            sLog.outSQLDriver("[%u ms] Prepared SQL: %u", getMSTimeDiff(_s, getMSTime()), index);
            #endif
            m_mStmt->ClearParameters();
            return true;
        }
    }
}
예제 #18
0
static int st_fetch(void *key, size_t klen, void **value, size_t *vlen, void *priv)
{
    storage_mysql_t *st = (storage_mysql_t *)priv;

    char *keystr = malloc((klen*2)+ 1);
    char *p = (char *)key;
    char *o = (char *)keystr;
    int i;
    for (i = 0; i < klen; i++) {
        snprintf(o, 3, "%02x", p[i]);
        o += 2;
    }
    *o = 0;


    db_connection_t *dbc = st_get_dbconnection(st);
    if (!dbc) {
        free(keystr);
        return -1;
    }

    MYSQL_BIND bnd = {
        .buffer_type = MYSQL_TYPE_STRING,
        .buffer = keystr,
        .buffer_length = strlen(keystr)
    };

    if (mysql_stmt_bind_param(dbc->select_stmt, &bnd) != 0) {
        // TODO - error messages
        SPIN_UNLOCK(&dbc->lock);
        free(keystr);
        return -1;
    }

    if (mysql_stmt_execute(dbc->select_stmt) != 0) {
        // TODO - error messages
        fprintf(stderr, "Can't execute fetch statement : %s\n", mysql_stmt_error(dbc->select_stmt));
        SPIN_UNLOCK(&dbc->lock);
        free(keystr);
        return -1;
    }

    size_t size = 256;
    void *data = malloc(size);
    my_bool error = 0;

    MYSQL_BIND obnd = {
        .buffer_type = MYSQL_TYPE_LONG_BLOB,
        .buffer = data,
        .buffer_length = size,
        .length = &size,
        .error = &error
    };

    mysql_stmt_bind_result(dbc->select_stmt, &obnd);

    int rc = mysql_stmt_fetch(dbc->select_stmt);

    if (error == 1) {
        data = realloc(data, size);
        obnd.buffer = data;
        obnd.buffer_length = size;
        error = 0;
        mysql_stmt_bind_result(dbc->select_stmt, &obnd);
        mysql_stmt_fetch(dbc->select_stmt);
    }

    if (rc != 0 || obnd.is_null) {
        free(data);
        data = NULL;
    } else {

        if (value) {
            *value = data;
        } else {
            free(data);
        }

        if (vlen) {
            *vlen = size;
        }
    }

    mysql_stmt_free_result(dbc->select_stmt);
    mysql_stmt_reset(dbc->select_stmt);

    SPIN_UNLOCK(&dbc->lock);

    free(keystr);
    return 0;
}
예제 #19
0
/**
 * Upload database command to the server
 * @param cmd  Command to be uploaded
 * @return     0 if OK, >0 on DB API errors, <0 on MySQL errors
 */
static int upload_cmd(db_cmd_t* cmd)
{
    struct my_cmd* res;
    struct my_con* mcon;
    int err = 0;
    
    res = DB_GET_PAYLOAD(cmd);
    
    /* FIXME: The function should take the connection as one of parameters */
    mcon = DB_GET_PAYLOAD(cmd->ctx->con[db_payload_idx]);
    /* Do not upload the command if the connection is not connected */
    if ((mcon->flags & MY_CONNECTED) == 0) {
	err = 1;
	goto error;
    }

    /* If there is a previous pre-compiled statement, close it first */
    if (res->st) mysql_stmt_close(res->st);
    res->st = NULL;
    
    /* Create a new pre-compiled statement data structure */
    res->st = mysql_stmt_init(mcon->con);
    if (res->st == NULL) {
	ERR("mysql: Error while creating new MySQL_STMT data structure (no memory left)\n");
	err = 1;
	goto error;
    }
    
    /* Try to upload the command to the server */
    if (mysql_stmt_prepare(res->st, res->sql_cmd.s, res->sql_cmd.len)) {
	err = mysql_stmt_errno(res->st);    
	ERR("mysql: libmysql: %d, %s\n", err, mysql_stmt_error(res->st));
	ERR("mysql: An error occurred while uploading command to server\n");
    }
    if (err == CR_SERVER_LOST ||
	err == CR_SERVER_GONE_ERROR) {
	/* Connection to the server was lost, mark the connection as
	 * disconnected. In this case mysql_stmt_prepare invalidates the
	 * connection internally and calling another mysql function on that
	 * connection would crash. To make sure that no other mysql function
	 * gets called unless the connection is reconnected we disconnect it
	 * explicitly here. This is a workaround for mysql bug #33384. */
	my_con_disconnect(cmd->ctx->con[db_payload_idx]);
    }
    if (err) {
	/* Report mysql error to the caller */
	err = -1;
	goto error;
    }
    
    err = bind_mysql_params(res->st, cmd->vals, cmd->match);
    if (err) goto error;
    
    if (cmd->type == DB_GET || cmd->type == DB_SQL) {
	err = check_result(cmd, res);
	if (err) goto error;
	err = bind_result(res->st, cmd->result);
	if (err) goto error;
    }
    
    res->last_reset = mcon->resets;
    return 0;
    
error:
    if (res->st) {
	mysql_stmt_close(res->st);
	res->st = NULL;
    }
    return err;
}
예제 #20
0
int driverMySQL_prepareStatement(struct xsb_queryHandle* handle)
{
  struct driverMySQL_preparedresultset* rs;
  MYSQL* mysql;
  MYSQL_STMT* stmt;
  MYSQL_RES* res;
  int i;
  char* sqlQuery;
  int numResultCols;
  MYSQL_FIELD* field;

  sqlQuery = (char *)malloc((strlen(handle->query) + 1) * sizeof(char));
  strcpy(sqlQuery, handle->query);
	
  mysql = NULL;	

  for (i = 0 ; i < numHandles ; i++)
    {
      if (!strcmp(mysqlHandles[i]->handle, handle->connHandle->handle))
	{
	  mysql = mysqlHandles[i]->mysql;
	  break;
	}
    }

  if ((stmt = mysql_stmt_init(mysql)) == NULL)
    {
      errorMesg = "mysql_stmt_init() failed\n";
      //errorMesg = mysql_stmt_error(stmt);
      free(sqlQuery);
      sqlQuery = NULL;
      return FAILURE;		
    }
  if ( mysql_stmt_prepare(stmt, sqlQuery, (unsigned long)strlen(sqlQuery))) {
    errorMesg = mysql_stmt_error(stmt);
    free(sqlQuery);
    sqlQuery = NULL;
    return FAILURE;		
  }

  rs = (struct driverMySQL_preparedresultset *)malloc(sizeof(struct driverMySQL_preparedresultset));
  rs->statement = stmt;

  res = mysql_stmt_result_metadata(stmt);

  numResultCols = 0;
  if (res == NULL)
    {
      if (mysql_errno(mysql))
	{
	  errorMesg = mysql_stmt_error(stmt);
	  free(sqlQuery);
	  sqlQuery = NULL;
	  free(rs);
	  rs = NULL;
	  return FAILURE;
	}
    }
  else numResultCols = mysql_num_fields(res);

  rs->returnFields = numResultCols;

  handle->numParams = mysql_stmt_param_count(stmt);
  handle->numResultCols = rs->returnFields;
  handle->state = QUERY_BEGIN;
	
  rs->handle = handle;
  rs->bindResult = NULL;
	
  rs->metaInfo = (struct xsb_data **)malloc(rs->returnFields * sizeof(struct xsb_data *));
  for (i = 0 ; i < rs->returnFields ; i++)
    {
      rs->metaInfo[i] = (struct xsb_data *)malloc(sizeof(struct xsb_data));
      field = mysql_fetch_field_direct(res, i);
      rs->metaInfo[i]->type = driverMySQL_getXSBType(field);
      rs->metaInfo[i]->length = field->length;
    }
  prepQueries[numPrepQueries++] = rs;

  free(sqlQuery);
  sqlQuery = NULL;

  return rs->handle->numParams;
}
예제 #21
0
/*
 * FIXME: This function will only work if we have one db connection
 * in every context, otherwise it would initialize the result set
 * from the first connection in the context.
 */
static int check_result(db_cmd_t* cmd, struct my_cmd* payload)
{
	int i, n;
	MYSQL_FIELD *fld;
	MYSQL_RES *meta = NULL;

	meta = mysql_stmt_result_metadata(payload->st);
	if (meta == NULL) {
		/* No error means no result set to be checked */
		if (mysql_stmt_errno(payload->st) == 0) return 0;
		ERR("mysql: Error while getting metadata of SQL command: %d, %s\n",
			mysql_stmt_errno(payload->st), mysql_stmt_error(payload->st));
		return -1;
	}
	n = mysql_num_fields(meta);
	if (cmd->result == NULL) {
		/* The result set parameter of db_cmd function was empty, that
		 * means the command is select * and we have to create the array
		 * of result fields in the cmd structure manually.
		 */
		cmd->result = db_fld(n + 1);
		cmd->result_count = n;
		for(i = 0; i < cmd->result_count; i++) {
			struct my_fld *f;
			if (my_fld(cmd->result + i, cmd->table.s) < 0) goto error;
			f = DB_GET_PAYLOAD(cmd->result + i);
			fld = mysql_fetch_field_direct(meta, i);
			f->name = pkg_malloc(strlen(fld->name)+1);
			if (f->name == NULL) {
				ERR("mysql: Out of private memory\n");
				goto error;
			}
			strcpy(f->name, fld->name);
			cmd->result[i].name = f->name;
		}
	} else {
		if (cmd->result_count != n) {
			BUG("mysql: Number of fields in MySQL result does not match number of parameters in DB API\n");
			goto error;
		}
	}

	/* Now iterate through all the columns in the result set and replace
	 * any occurrence of DB_UNKNOWN type with the type of the column
	 * retrieved from the database and if no column name was provided then
	 * update it from the database as well. 
	 */
	for(i = 0; i < cmd->result_count; i++) {
		fld = mysql_fetch_field_direct(meta, i);
		if (cmd->result[i].type != DB_NONE) continue;
		switch(fld->type) {
		case MYSQL_TYPE_TINY:
		case MYSQL_TYPE_SHORT:
		case MYSQL_TYPE_INT24:
		case MYSQL_TYPE_LONG:
			cmd->result[i].type = DB_INT;
			break;

		case MYSQL_TYPE_FLOAT:
			cmd->result[i].type = DB_FLOAT;
			break;

		case MYSQL_TYPE_DOUBLE:
			cmd->result[i].type = DB_DOUBLE;
			break;

		case MYSQL_TYPE_TIMESTAMP:
		case MYSQL_TYPE_DATETIME:
			cmd->result[i].type = DB_DATETIME;
			break;

		case MYSQL_TYPE_STRING:
		case MYSQL_TYPE_VAR_STRING:
			cmd->result[i].type = DB_STR;
			break;

		default:
			ERR("mysql: Unsupported MySQL column type: %d, table: %s, column: %s\n",
				fld->type, cmd->table.s, fld->name);
			goto error;
		}
	}
	
	if (meta) mysql_free_result(meta);
	return 0;

error:
	if (meta) mysql_free_result(meta);
	return 1;
}
예제 #22
0
파일: mysql.c 프로젝트: nicboul/xia
int_vector *mysql_exec(struct stmt_singleton *stmt)
{
	journal_strace("mysql_exec");

	int ret, num_row, itr;
	int_vector *data_vtr;

	static int buf = 0;	/* XXX being static fixes a bad bug */

	printf("Running MySQL query\n\n\t%s\n\n", stmt->stmt);

	if (stmt->out_buf_count > 1) {
		journal_notice("%s :: %s:%i\n",
			"mysql_exec() does not support multicolumn vector",
			__FILE__, __LINE__);
		return NULL;
	}

	ret = mysql_stmt_prepare(mysql_stmt, stmt->stmt, stmt->stmt_length);
	printf("mysql_stmt_prepare (%i)\n", ret);

	ret = mysql_stmt_bind_param(mysql_stmt, stmt->in_buf);
	printf("mysql_stmt_bind_param (%i)\n", ret);

	ret = mysql_stmt_param_count(mysql_stmt);
	printf("mysql_stmt_param_count (%i)\n", ret);

	if (ret != stmt->in_buf_count) {
		journal_notice("%s :: %s:%i\n",
			"corrupted dbal method", __FILE__, __LINE__);
		return NULL;
	}

	if (stmt->out_buf) {
		stmt->out_buf->buffer = (char *)&buf;
		ret = mysql_stmt_bind_result(mysql_stmt, stmt->out_buf);
		printf("mysql_stmt_bind_result (%i)\n", ret);
	}

	ret = mysql_stmt_execute(mysql_stmt);
	printf("mysql_stmt_execute (%i)\n", ret);

	if (ret == 1) { // I dont know why...
		printf("err: %s\n", mysql_stmt_error(mysql_stmt));
		return NULL;
	}

	ret = mysql_stmt_store_result(mysql_stmt);
	printf("mysql_stmt_store_result (%i)\n", ret);

	num_row = mysql_stmt_num_rows(mysql_stmt);
	printf("mysql_stmt_num_rows (%i)\n", num_row);

	data_vtr = calloc(VECTOR_SET_MAX(num_row), sizeof(int_vector));
	data_vtr[VECTOR_IDX_MAX] = num_row;

	for (itr = VECTOR_IDX_BEGIN; !mysql_stmt_fetch(mysql_stmt); itr++) {
		data_vtr[itr] = buf;
		printf("MySQL returned value %i\n", buf);
	}
	
	data_vtr[VECTOR_IDX_SIZE] = VECTOR_SET_SIZE(itr);
	
	return data_vtr;	
}
예제 #23
0
PreparedResultSet::PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES *result, uint64 rowCount, uint32 fieldCount) :
m_rowCount(rowCount),
m_rowPosition(0),
m_fieldCount(fieldCount),
m_rBind(NULL),
m_stmt(stmt),
m_res(result),
m_isNull(NULL),
m_length(NULL)
{
    if (!m_res)
        return;

    if (m_stmt->bind_result_done)
    {
        delete[] m_stmt->bind->length;
        delete[] m_stmt->bind->is_null;
    }

    m_rBind = new MYSQL_BIND[m_fieldCount];
    m_isNull = new my_bool[m_fieldCount];
    m_length = new unsigned long[m_fieldCount];

    memset(m_isNull, 0, sizeof(my_bool) * m_fieldCount);
    memset(m_rBind, 0, sizeof(MYSQL_BIND) * m_fieldCount);
    memset(m_length, 0, sizeof(unsigned long) * m_fieldCount);

    //- This is where we store the (entire) resultset
    if (mysql_stmt_store_result(m_stmt))
    {
        sLog->outSQLDriver("%s:mysql_stmt_store_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt));
        return;
    }

    //- This is where we prepare the buffer based on metadata
    uint32 i = 0;
    MYSQL_FIELD* field = mysql_fetch_field(m_res);
    while (field)
    {
        size_t size = Field::SizeForType(field);

        m_rBind[i].buffer_type = field->type;
        m_rBind[i].buffer = malloc(size);
        memset(m_rBind[i].buffer, 0, size);
        m_rBind[i].buffer_length = size;
        m_rBind[i].length = &m_length[i];
        m_rBind[i].is_null = &m_isNull[i];
        m_rBind[i].error = NULL;
        m_rBind[i].is_unsigned = field->flags & UNSIGNED_FLAG;

        ++i;
        field = mysql_fetch_field(m_res);
    }

    //- This is where we bind the bind the buffer to the statement
    if (mysql_stmt_bind_result(m_stmt, m_rBind))
    {
        sLog->outSQLDriver("%s:mysql_stmt_bind_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt));
        delete[] m_rBind;
        delete[] m_isNull;
        delete[] m_length;
        return;
    }

    m_rowCount = mysql_stmt_num_rows(m_stmt);

    m_rows.resize(uint32(m_rowCount));
    while (_NextRow())
    {
        m_rows[uint32(m_rowPosition)] = new Field[m_fieldCount];
        for (uint64 fIndex = 0; fIndex < m_fieldCount; ++fIndex)
        {
            if (!*m_rBind[fIndex].is_null)
                m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( m_rBind[fIndex].buffer,
                                                            m_rBind[fIndex].buffer_length,
                                                            m_rBind[fIndex].buffer_type,
                                                           *m_rBind[fIndex].length );
            else
                switch (m_rBind[fIndex].buffer_type)
                {
                    case MYSQL_TYPE_TINY_BLOB:
                    case MYSQL_TYPE_MEDIUM_BLOB:
                    case MYSQL_TYPE_LONG_BLOB:
                    case MYSQL_TYPE_BLOB:
                    case MYSQL_TYPE_STRING:
                    case MYSQL_TYPE_VAR_STRING:
                    m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( "",
                                                            m_rBind[fIndex].buffer_length,
                                                            m_rBind[fIndex].buffer_type,
                                                           *m_rBind[fIndex].length );
                    break;
                    default:
                    m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( 0,
                                                            m_rBind[fIndex].buffer_length,
                                                            m_rBind[fIndex].buffer_type,
                                                           *m_rBind[fIndex].length );
                }
        }
        m_rowPosition++;
    }
    m_rowPosition = 0;

    /// All data is buffered, let go of mysql c api structures
    CleanUp();
}
예제 #24
0
void Event::updateNotes( const StringSetMap &newNoteSetMap ) {
  bool update = false;

  //Info( "Checking notes, %d <> %d", noteSetMap.size(), newNoteSetMap.size() );
  if ( newNoteSetMap.size() > 0 ) {
    if ( noteSetMap.size() == 0 ) {
      noteSetMap = newNoteSetMap;
      update = true;
    } else {
      for ( StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); newNoteSetMapIter != newNoteSetMap.end(); ++newNoteSetMapIter ) {
        const std::string &newNoteGroup = newNoteSetMapIter->first;
        const StringSet &newNoteSet = newNoteSetMapIter->second;
        //Info( "Got %d new strings", newNoteSet.size() );
        if ( newNoteSet.size() > 0 ) {
          StringSetMap::iterator noteSetMapIter = noteSetMap.find( newNoteGroup );
          if ( noteSetMapIter == noteSetMap.end() ) {
            //Info( "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size() );
            noteSetMap.insert( StringSetMap::value_type( newNoteGroup, newNoteSet ) );
            update = true;
          } else {
            StringSet &noteSet = noteSetMapIter->second;
            //Info( "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size() );
            for ( StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); newNoteSetIter != newNoteSet.end(); ++newNoteSetIter ) {
              const std::string &newNote = *newNoteSetIter;
              StringSet::iterator noteSetIter = noteSet.find( newNote );
              if ( noteSetIter == noteSet.end() ) {
                noteSet.insert( newNote );
                update = true;
              }
            } // end for
          } // end if ( noteSetMap.size() == 0
        } // end if newNoteSetupMap.size() > 0
      } // end foreach newNoteSetMap
    } // end if have old notes
  } // end if have new notes

  if ( update ) {
    std::string notes;
    createNotes( notes );

    Debug( 2, "Updating notes for event %d, '%s'", id, notes.c_str() );
    static char sql[ZM_SQL_MED_BUFSIZ];
#if USE_PREPARED_SQL
    static MYSQL_STMT *stmt = 0;

    char notesStr[ZM_SQL_MED_BUFSIZ] = "";
    unsigned long notesLen = 0;

    if ( !stmt ) {
      const char *sql = "update Events set Notes = ? where Id = ?";

      stmt = mysql_stmt_init( &dbconn );
      if ( mysql_stmt_prepare( stmt, sql, strlen(sql) ) ) {
        Fatal( "Unable to prepare sql '%s': %s", sql, mysql_stmt_error(stmt) );
      }

      /* Get the parameter count from the statement */
      if ( mysql_stmt_param_count( stmt ) != 2 ) {
        Fatal( "Unexpected parameter count %ld in sql '%s'", mysql_stmt_param_count( stmt ), sql );
      }

      MYSQL_BIND  bind[2];
      memset(bind, 0, sizeof(bind));

      /* STRING PARAM */
      bind[0].buffer_type = MYSQL_TYPE_STRING;
      bind[0].buffer = (char *)notesStr;
      bind[0].buffer_length = sizeof(notesStr);
      bind[0].is_null = 0;
      bind[0].length = &notesLen;

      bind[1].buffer_type= MYSQL_TYPE_LONG;
      bind[1].buffer= (char *)&id;
      bind[1].is_null= 0;
      bind[1].length= 0;

      /* Bind the buffers */
      if ( mysql_stmt_bind_param( stmt, bind ) ) {
        Fatal( "Unable to bind sql '%s': %s", sql, mysql_stmt_error(stmt) );
      }
    }

    strncpy( notesStr, notes.c_str(), sizeof(notesStr) );

    if ( mysql_stmt_execute( stmt ) ) {
      Fatal( "Unable to execute sql '%s': %s", sql, mysql_stmt_error(stmt) );
    }
#else
    static char escapedNotes[ZM_SQL_MED_BUFSIZ];

    mysql_real_escape_string(&dbconn, escapedNotes, notes.c_str(), notes.length());

    snprintf(sql, sizeof(sql), "UPDATE Events SET Notes = '%s' WHERE Id = %" PRIu64, escapedNotes, id);
    db_mutex.lock();
    if ( mysql_query(&dbconn, sql) ) {
      Error("Can't insert event: %s", mysql_error(&dbconn));
    }
    db_mutex.unlock();
#endif
  } // end if update
}
예제 #25
0
/* [noscript] long init (in AString query); */
NS_IMETHODIMP jxMySQL50Statement::Init(const nsAString & query, PRInt32 *_retval)
{
    nsresult rv = NS_OK;

	if (mConnection == nsnull)
    {
        SET_ERROR_RETURN (JX_MYSQL50_ERROR_NOT_CONNECTED);
    }

    if (mSTMT != nsnull)
    {
        SET_ERROR_RETURN (JX_MYSQL50_ERROR_STMT_ALREADY_INITIALIZED);
    }

	MYSQL * mysql;
	mConnection->GetMysql(&mysql);

	// Create a new statement handle
	if ((mSTMT = mysql_stmt_init(mysql))) 
	{
		// Get the query string
		char * stmt = ToNewUTF8String(query);

		// Prepare the statement
        int ret = mysql_stmt_prepare(mSTMT, stmt, query.Length());
        nsMemory::Free(stmt);
			
		if (ret) 
		{
			// Statement prep failed
#if 0
            char err[512];
            sprintf(err, " %s", mysql_stmt_error(mSTMT));
#endif
            *_retval = ret;
            SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR);
		}
		else 
		{
			mIn.mCount = mysql_stmt_param_count(mSTMT);
			mOut.mCount = mysql_stmt_field_count(mSTMT);

			// Statement prep succeeded
            *_retval = 0;

            // Allocated the BIND array and supporting structures
	        if (mIn.mBIND == nsnull && mIn.mCount > 0) { 
		        rv = mIn.Allocate();
		        if (rv != NS_OK)
                {
                    *_retval = -1;
                    SET_ERROR_RETURN (rv);
                }
            }	    
		}
	}
	else {
		// Statement prep failed
		*_retval = -1;
        SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR);
	}

    return NS_OK;
}
예제 #26
0
bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        ASSERT(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     // TODO: Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

        uint32 _s = 0;
        if (sLog->GetSQLDriverQueryLogging())
            _s = getMSTime();

        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s",
                m_statementTable[index].query, lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled succesfuly (ie reconnection)
                return _Query(stmt, pResult, pRowCount, pFieldCount);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s",
                m_statementTable[index].query, lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled succesfuly (ie reconnection)
                return _Query(stmt, pResult, pRowCount, pFieldCount);      // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (sLog->GetSQLDriverQueryLogging())
            sLog->outSQLDriver("[%u ms] SQL(p): %s",
                getMSTimeDiff(_s, getMSTime()), m_statementTable[index].query);

        m_mStmt->ClearParameters();

        *pResult = mysql_stmt_result_metadata(msql_STMT);
        *pRowCount = mysql_stmt_num_rows(msql_STMT);
        *pFieldCount = mysql_stmt_field_count(msql_STMT);

        return true;

    }
}
예제 #27
0
my_bool fetch_n(const char **query_list, unsigned query_count,
                enum fetch_type fetch_type)
{
    unsigned open_statements= query_count;
    int rc, error_count= 0;
    Stmt_fetch *fetch_array= (Stmt_fetch*) calloc(1, sizeof(Stmt_fetch) *
                             query_count);
    Stmt_fetch *fetch;
    DBUG_ENTER("fetch_n");

    for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
    {
        /* Init will exit(1) in case of error */
        stmt_fetch_init(fetch, fetch - fetch_array,
                        query_list[fetch - fetch_array]);
    }

    if (fetch_type == USE_STORE_RESULT)
    {
        for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
        {
            rc= mysql_stmt_store_result(fetch->handle);
            check_execute(fetch->handle, rc);
        }
    }

    while (open_statements)
    {
        for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
        {
            if (fetch->is_open && (rc= stmt_fetch_fetch_row(fetch)))
            {
                open_statements--;
                /*
                We try to fetch from the rest of the statements in case of
                error
                */
                if (rc != MYSQL_NO_DATA)
                {
                    fprintf(stderr,
                            "Got error reading rows from statement %d,\n"
                            "query is: %s,\n"
                            "error message: %s", (int) (fetch - fetch_array),
                            fetch->query,
                            mysql_stmt_error(fetch->handle));
                    error_count++;
                }
            }
        }
    }
    if (error_count)
        fprintf(stderr, "Fetch FAILED");
    else
    {
        unsigned total_row_count= 0;
        for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
            total_row_count+= fetch->row_count;
        if (!opt_silent)
            printf("Success, total rows fetched: %d\n", total_row_count);
    }
    for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
        stmt_fetch_close(fetch);
    free(fetch_array);
    DBUG_RETURN(error_count != 0);
}
예제 #28
0
DatabaseException::DatabaseException(MYSQL_STMT *stmt, const std::string &initialMessage) {
	_errno = mysql_stmt_errno(stmt);
	_errorMessage = mysql_stmt_error(stmt);
	_sqlState = mysql_stmt_sqlstate(stmt);
	_initialMessage = initialMessage;
}
예제 #29
0
if_status_t IF_db_log_wind_record ( time_t iStartDTM,
									time_t iEndDTM,
									int iNumMeasurements,
									float fSpeedMin,
									float fSpeedMax,
									float fSpeedAve,
									float fAngleAve)
{
	/* static function variables */
	static MYSQL_BIND    bind[7];
	static MYSQL_TIME bStartDTM;
	static MYSQL_TIME bEndDTM;
	static int ibNumMeasurements;
	static float fbSpeedMin;
	static float fbSpeedMax;
	static float fbSpeedAve;
	static float fbAngleAve;

	/* function variables */
	if_status_t retval = IF_OK;

	/* Do one-off setup if insert statement has not been prepared */
	if ( stmtInsertRecord == NULL )
	{
		stmtInsertRecord = mysql_stmt_init(&mysql);
		
		if (mysql_stmt_prepare(stmtInsertRecord, WIND_REC_INSERT_STMT, strlen(WIND_REC_INSERT_STMT)))
		{
			IF_log_event ( 0,
		                   IF_SEV_ERROR,
		                   "Failed to prepare statement for wind data record insert: '%s' [%d]",
		                   mysql_stmt_error(stmtInsertRecord), mysql_stmt_errno(stmtInsertRecord) );
			mysql_stmt_close(stmtInsertRecord);
			stmtInsertRecord = NULL;
	        retval = IF_ERR;
		}
		memset ( bind, 0, sizeof(bind) );
		
		/* start datetime */
		bind[0].buffer_type = MYSQL_TYPE_DATETIME; 
		bind[0].buffer = &bStartDTM;
		bind[0].buffer_length = sizeof(bStartDTM);
		bind[0].length = 0; /* ignored for numeric & temporal types */
		bind[0].is_null = (my_bool*) 0;    /* Never null */
		bind[0].is_unsigned = (my_bool) 0; /* signed */

		/* end datetime */
		bind[1].buffer_type = MYSQL_TYPE_DATETIME; 
		bind[1].buffer = &bEndDTM;
		bind[1].buffer_length = sizeof(bEndDTM);
		bind[1].length = 0; /* ignored for numeric & temporal types */
		bind[1].is_null = (my_bool*) 0;    /* Never null */
		bind[1].is_unsigned = (my_bool) 0; /* signed */

		/* number of measurements */
		bind[2].buffer_type = MYSQL_TYPE_LONG; 
		bind[2].buffer = &ibNumMeasurements;
		bind[2].buffer_length = sizeof(ibNumMeasurements);
		bind[2].length = 0; /* ignored for numeric & temporal types */
		bind[2].is_null = (my_bool*) 0;    /* Never null */
		bind[2].is_unsigned = (my_bool) 0; /* signed */

		/* minimum speed */
		bind[3].buffer_type = MYSQL_TYPE_FLOAT; 
		bind[3].buffer = &fbSpeedMin;
		bind[3].buffer_length = sizeof(fbSpeedMin);
		bind[3].length = 0; /* ignored for numeric & temporal types */
		bind[3].is_null = (my_bool*) 0;    /* Never null */
		bind[3].is_unsigned = (my_bool) 0; /* signed */

		/* maximum speed */
		bind[4].buffer_type = MYSQL_TYPE_FLOAT; 
		bind[4].buffer = &fbSpeedMax;
		bind[4].buffer_length = sizeof(fbSpeedMax);
		bind[4].length = 0; /* ignored for numeric & temporal types */
		bind[4].is_null = (my_bool*) 0;    /* Never null */
		bind[4].is_unsigned = (my_bool) 0; /* signed */

		/* average speed */
		bind[5].buffer_type = MYSQL_TYPE_FLOAT; 
		bind[5].buffer = &fbSpeedAve;
		bind[5].buffer_length = sizeof(fbSpeedAve);
		bind[5].length = 0; /* ignored for numeric & temporal types */
		bind[5].is_null = (my_bool*) 0;    /* Never null */
		bind[5].is_unsigned = (my_bool) 0; /* signed */
		 
		/* average angle */
		bind[6].buffer_type = MYSQL_TYPE_FLOAT; 
		bind[6].buffer = &fbAngleAve;
		bind[6].buffer_length = sizeof(fbAngleAve);
		bind[6].length = 0; /* ignored for numeric & temporal types */
		bind[6].is_null = (my_bool*) 0;    /* Never null */
		bind[6].is_unsigned = (my_bool) 0; /* signed */
		
		if ( mysql_stmt_bind_param ( stmtInsertRecord, bind ) != 0 )
		{
			IF_log_event ( 0,
		                   IF_SEV_ERROR,
		                   "Failed to bind wind data record input parameters: '%s' [%d]",
		                   mysql_stmt_error(stmtInsertRecord), mysql_stmt_errno(stmtInsertRecord) );
			mysql_stmt_close(stmtInsertRecord);
			stmtInsertRecord = NULL;
	        retval = IF_ERR;
		}
	}		

	convert_time ( iStartDTM, &bStartDTM );
	convert_time ( iEndDTM,   &bEndDTM   );
	ibNumMeasurements = iNumMeasurements; 
	fbSpeedMin = fSpeedMin;
	fbSpeedMax = fSpeedMax;
	fbSpeedAve = fSpeedAve;
	fbAngleAve = fAngleAve;	
	
	/* Execute the INSERT statement */
	if (mysql_stmt_execute(stmtInsertRecord) != 0 )
	{
		IF_log_event ( 0,
	                   IF_SEV_ERROR,
	                   "Failed to insert wind data record : '%s' [%d]",
	                   mysql_error(&mysql), mysql_errno(&mysql) );
	    retval = IF_ERR;
	}
		
	return retval;
}
예제 #30
0
bool SqlStatement::fetch()
{
	for (unsigned i = 0, e = data_.size(); i != e; ++i) {
		MYSQL_BIND *d = &data_[i];

		if (!fixedLengths_[i]) {
			// var-size field
			if (d->buffer)
				free(d->buffer);

			d->buffer = NULL;
			d->buffer_length = 0;
		}

		nulls_[i] = 0;
	}

	if (mysql_stmt_bind_result(stmt_, &data_.front()) != 0) {
		error_ = mysql_stmt_error(stmt_);
		fprintf(stderr, "mysql_stmt_bind_result step 1 failed: %s\n", error_);
		return false;
	}

	int rc = mysql_stmt_fetch(stmt_);
	switch (rc) {
		case 1:
			error_ = mysql_stmt_error(stmt_);
			fprintf(stderr, "mysql_stmt_fetch failed (%d): %s\n", rc, error_);
			return false;
		case MYSQL_NO_DATA:
			//DEBUG("end of result set.");
			return false;
		case 0:
		case MYSQL_DATA_TRUNCATED:
		default:
			break;
	}

	for (unsigned i = 0, e = data_.size(); i != e; ++i) {
		MYSQL_BIND *d = &data_[i];

		/*TRACE("[%2u] length: result(%lu) given(%lu) %s",
				i, *d->length, d->buffer_length,
				mysql_type_str(d->buffer_type));*/

		if (fixedLengths_[i]) {
			//TRACE("fixed-length value[%d]: %s", i, this->valueAt<std::string>(i).c_str());
			continue;
		}

		d->buffer_length = *d->length;
		d->buffer = malloc(d->buffer_length + 1);
		((char *)d->buffer)[d->buffer_length] = '\0';

		if (mysql_stmt_fetch_column(stmt_, d, i, 0) != 0) {
			error_ = mysql_stmt_error(stmt_);
			fprintf(stderr, "mysql_stmt_fetch step 1 failed: %s\n", error_);
			return false;
		}
	}

	return true;
}