Exemple #1
0
void wxMySQLRecordset::SetHandle(MYSQL_STMT * stmt)
{
	m_Stmt = stmt;
	m_HasResult = false;	
	if(m_Stmt)
	{	
		printf("MYSQL_STMT_RESULT_METADATA\r\n");
		MYSQL_RES * metadata_result = mysql_stmt_result_metadata(m_Stmt);
		if(metadata_result)
		{				
			m_HasResult = true;
			SetFieldCount(mysql_num_fields(metadata_result));
			mysql_free_result(metadata_result);
		} else SetFieldCount(mysql_stmt_param_count(m_Stmt));
	}
}
Exemple #2
0
 MySQLPreparedStatement(MySQLConnection *_conn, MySQLStatement *_stmt)
 : conn(_conn), stmt(_stmt)
 {
     // Create bindings for input parameters
     inputBindings.init(mysql_stmt_param_count(*stmt));
     // And for results
     res.setown(new MySQLResult(mysql_stmt_result_metadata(*stmt)));
     if (*res)
     {
         resultBindings.bindResults(*res);
         /* Bind the result buffers */
         if (mysql_stmt_bind_result(*stmt, resultBindings.queryBindings()))
             fail(mysql_stmt_error(*stmt));
     }
     else if (mysql_stmt_errno(*stmt))  // SQL actions don't return results...
         fail(mysql_stmt_error(*stmt));
 }
Exemple #3
0
/// Reports debug information about a truncated column.
///
/// @private
static void SqlStmt_P_ShowDebugTruncatedColumn(SqlStmt* self, size_t i)
{
	MYSQL_RES* meta;
	MYSQL_FIELD* field;
	MYSQL_BIND* column;

	meta = mysql_stmt_result_metadata(self->stmt);
	field = mysql_fetch_field_direct(meta, (unsigned int)i);
	ShowSQL("DB error - data of field '%s' was truncated.\n", field->name);
	ShowDebug("column - %lu\n", (unsigned long)i);
	Sql_P_ShowDebugMysqlFieldInfo("data   - ", field->type, field->flags&UNSIGNED_FLAG, self->column_lengths[i].length, "");
	column = &self->columns[i];
	if( column->buffer_type == MYSQL_TYPE_STRING )
		Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "+1(nul-terminator)");
	else
		Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "");
	mysql_free_result(meta);
}
MyStatement::MyStatement(MyDatabase *db, MYSQL_STMT *stmt)
: m_mysql(db->m_mysql), m_pParent(db), m_stmt(stmt), m_rs(NULL), m_Results(false)
{
	m_Params = (unsigned int)mysql_stmt_param_count(m_stmt);

	if (m_Params)
	{
		m_pushinfo = (ParamBind *)malloc(sizeof(ParamBind) * m_Params);
		memset(m_pushinfo, 0, sizeof(ParamBind) * m_Params);
		m_bind = (MYSQL_BIND *)malloc(sizeof(MYSQL_BIND) * m_Params);
		memset(m_bind, 0, sizeof(MYSQL_BIND) * m_Params);
	} else {
		m_pushinfo = NULL;
		m_bind = NULL;
	}

	m_pRes = mysql_stmt_result_metadata(stmt);
	m_Results = false;
}
Exemple #5
0
/* call-seq: stmt.fields # => array
 *
 * Returns a list of fields that will be returned by this statement.
 */
static VALUE fields(VALUE self) {
  MYSQL_FIELD *fields;
  MYSQL_RES *metadata;
  unsigned int field_count;
  unsigned int i;
  VALUE field_list;
  MYSQL_STMT* stmt;
#ifdef HAVE_RUBY_ENCODING_H
  rb_encoding *default_internal_enc, *conn_enc;
#endif
  GET_STATEMENT(self);
  stmt = stmt_wrapper->stmt;

#ifdef HAVE_RUBY_ENCODING_H
  default_internal_enc = rb_default_internal_encoding();
  {
    GET_CLIENT(stmt_wrapper->client);
    conn_enc = rb_to_encoding(wrapper->encoding);
  }
#endif

  metadata    = mysql_stmt_result_metadata(stmt);
  fields      = mysql_fetch_fields(metadata);
  field_count = mysql_stmt_field_count(stmt);
  field_list  = rb_ary_new2((long)field_count);

  for(i = 0; i < field_count; i++) {
    VALUE rb_field;

    rb_field = rb_str_new(fields[i].name, fields[i].name_length);
#ifdef HAVE_RUBY_ENCODING_H
    rb_enc_associate(rb_field, conn_enc);
    if (default_internal_enc) {
     rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
   }
#endif

    rb_ary_store(field_list, (long)i, rb_field);
  }

  mysql_free_result(metadata);
  return field_list;
}
		void GetBindings( MYSQL_STMT * stmt, DatabaseConnectionMySqlSPtr connection, DatabaseValuedObjectInfosPtrArray const & columns, std::vector< std::unique_ptr< SInMySqlBindBase > > & inbinds, std::vector< MYSQL_BIND > & binds )
		{
			MYSQL_RES * data = mysql_stmt_result_metadata( stmt );

			if ( !data )
			{
				DB_EXCEPT( EDatabaseExceptionCodes_ConnectionError, ERROR_MYSQL_STMT_METADATA );
			}

			binds.resize( columns.size() );
			auto bindIt = binds.begin();

			for ( auto & column : columns )
			{
				MYSQL_FIELD * field = mysql_fetch_field( data );
				inbinds.emplace_back( GetInBind( column->GetType(), field->type, *bindIt++, field->length, field->decimals, std::max( field->length, field->max_length ) ) );
			}

			mysql_free_result( data );
		}
bool SqlPreparedStatement::Prepare()
{
	auto sql = Sql();
	mSTMT = mysql_stmt_init(Sql());
	if (mSTMT == nullptr)
	{
		throw SqlException(sql, "Error in SqlPreparedStatement::mysql_stmt_init");
	}

	if (mysql_stmt_prepare(mSTMT, mStatement.c_str(), (ulong)mStatement.Length()) != 0)
	{
		SqlException e(mSTMT, "Error in SqlPreparedStatement::mysql_stmt_prepare");
		mysql_stmt_free_result(mSTMT);
		mysql_stmt_close(mSTMT);
		throw e;
	}

	mParamterCount = mysql_stmt_param_count(mSTMT);
	mResultCount = mysql_stmt_field_count(mSTMT);
	if (mResultCount!=0)
	{
		if ((mResultMetadata = mysql_stmt_result_metadata(mSTMT)) == NULL)
		{
			throw SqlException(mSTMT, "Error in SqlPreparedStatement::mysql_stmt_result_metadata");
		}

		MYSQL_FIELD* field = nullptr;
		while ((field = mysql_fetch_field(mResultMetadata)) != nullptr)
		{
			mResultFields.Add(field);
		}
	}

	
	
	return true;
}
Exemple #8
0
bool MySQLStmtVariables::bind_result(MYSQL_STMT *stmt) {
  assert(m_arr.size() == mysql_stmt_field_count(stmt));

  MYSQL_RES *res = mysql_stmt_result_metadata(stmt);
  MYSQL_FIELD *fields = mysql_fetch_fields(res);
  for(int i = 0; i < m_arr.size(); i++) {
    MYSQL_BIND *b = &m_vars[i];
    b->is_unsigned = (fields[i].flags & UNSIGNED_FLAG) ? 1 : 0;

    switch (fields[i].type) {
      case MYSQL_TYPE_NULL:
        b->buffer_type = MYSQL_TYPE_NULL;
      case MYSQL_TYPE_DOUBLE:
      case MYSQL_TYPE_FLOAT:
        b->buffer_type = MYSQL_TYPE_DOUBLE;
        b->buffer_length = sizeof(double);
        break;
      case MYSQL_TYPE_LONGLONG:
#if MYSQL_VERSION_ID > 50002
      case MYSQL_TYPE_BIT:
#endif
      case MYSQL_TYPE_LONG:
      case MYSQL_TYPE_INT24:
      case MYSQL_TYPE_SHORT:
      case MYSQL_TYPE_YEAR:
      case MYSQL_TYPE_TINY:
        b->buffer_type = MYSQL_TYPE_LONGLONG;
        b->buffer_length = sizeof(int64_t);
        break;
      case MYSQL_TYPE_DATE:
      case MYSQL_TYPE_NEWDATE:
      case MYSQL_TYPE_DATETIME:
      case MYSQL_TYPE_TIMESTAMP:
      case MYSQL_TYPE_TIME:
      case MYSQL_TYPE_STRING:
      case MYSQL_TYPE_VARCHAR:
      case MYSQL_TYPE_VAR_STRING:
      case MYSQL_TYPE_ENUM:
      case MYSQL_TYPE_SET:
      case MYSQL_TYPE_LONG_BLOB:
      case MYSQL_TYPE_MEDIUM_BLOB:
      case MYSQL_TYPE_BLOB:
      case MYSQL_TYPE_TINY_BLOB:
      case MYSQL_TYPE_GEOMETRY:
      case MYSQL_TYPE_DECIMAL:
      case MYSQL_TYPE_NEWDECIMAL:
        b->buffer_type = MYSQL_TYPE_STRING;
        b->buffer_length = fields[i].max_length ?
                             fields[i].max_length :
                             fields[i].length;
        break;
      default:
        // There exists some more types in this enum like MYSQL_TYPE_TIMESTAMP2
        // MYSQL_TYPE_DATETIME2, MYSQL_TYPE_TIME2 but they are just used on the
        // server
        assert(false);
    }

    if (b->buffer_length > 0) {
      b->buffer = calloc(1, b->buffer_length);
    }
  }
  mysql_free_result(res);

  return !mysql_stmt_bind_result(stmt, m_vars);
}
Exemple #9
0
void fun()
{
    const uint32_t STRING_SIZE = 50;
    const std::string SELECT_SAMPLE = "SELECT fid, fipbegin, fipend, flocation FROM tiptable";

    MYSQL_BIND bind[4];
    MYSQL_RES *prepare_meta_result;

    MYSQL_TIME ts;
    (void)ts;
    int param_count;

    MYSQL* mysql = init();
    if (!mysql) {
        printf("error\n");
        return;
    }

    /* Prepare a SELECT query to fetch data from test_table */
    MYSQL_STMT* stmt = mysql_stmt_init(mysql);
    if (!stmt) {
        fprintf(stderr, " mysql_stmt_init(), out of memory\n");
        exit(0);
    }
    if (mysql_stmt_prepare(stmt, SELECT_SAMPLE.c_str(), SELECT_SAMPLE.size())) {
        fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }

    fprintf(stdout, " prepare, SELECT successful\n");

    /* Get the parameter count from the statement */
    param_count = (int)mysql_stmt_param_count(stmt);

    fprintf(stdout, " total parameters in SELECT: %d\n", param_count);
    if (param_count != 0) {
        fprintf(stderr, " invalid parameter count returned by MySQL\n");
        exit(0);
    }

    /* Fetch result set meta information */
    prepare_meta_result = mysql_stmt_result_metadata(stmt);
    if (!prepare_meta_result) {
        fprintf(stderr, " mysql_stmt_result_metadata(),  returned no meta information\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }

    /* Get total columns in the query */
    int column_count = mysql_num_fields(prepare_meta_result);
    fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);
    if (column_count != 4) {
        fprintf(stderr, " invalid column count returned by MySQL\n");
        exit(0);
    }

    /* Execute the SELECT query */
    if (mysql_stmt_execute(stmt)) {
        fprintf(stderr, " mysql_stmt_execute(), failed\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }
    /* Bind the result buffers for all 4 columns before fetching them */

    unsigned long length[4];
    my_bool is_null[4];
    my_bool error[4];
    short small_data;
    (void)small_data;
    int int_data[4];
    char str_data[4][STRING_SIZE];

    std::memset(bind, 0, sizeof(bind));
    /* INTEGER COLUMN */
    bind[0].buffer_type = MYSQL_TYPE_LONG;
    bind[0].buffer = (char *)&int_data[0];
    bind[0].is_null = &is_null[0];
    bind[0].length = &length[0];
    bind[0].error = &error[0];

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

    bind[2].buffer_type = MYSQL_TYPE_LONG;
    bind[2].buffer = (char *)&int_data[2];
    bind[2].is_null = &is_null[2];
    bind[2].length = &length[2];
    bind[2].error = &error[2];

    bind[3].buffer_type = MYSQL_TYPE_STRING;
    bind[3].buffer = (char *)&str_data[3];
    bind[3].buffer_length = STRING_SIZE;
    bind[3].is_null = &is_null[3];
    bind[3].length = &length[3];
    bind[3].error = &error[3];


    /* TIMESTAMP COLUMN */
    /*
    bind[3].buffer_type = MYSQL_TYPE_TIMESTAMP;
    bind[3].buffer = (char *)&ts;
    bind[3].is_null = &is_null[3];
    bind[3].length = &length[3];
    bind[3].error = &error[3];
    */

    /* Bind the result buffers */
    if (mysql_stmt_bind_result(stmt, bind)) {
        fprintf(stderr, " mysql_stmt_bind_result() failed\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }

    /* Now buffer all results to client (optional step) */

    auto tbegin = std::chrono::system_clock::now();
    if (mysql_stmt_store_result(stmt)) {
        fprintf(stderr, " mysql_stmt_store_result() failed\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }
    auto tend = std::chrono::system_clock::now();
    fprintf(stderr, "mysql_stmt_store_result use %d\n", (int)std::chrono::duration_cast<std::chrono::seconds>(tend-tbegin).count());

    fprintf(stderr, "total rows:%d\n",(int)::mysql_stmt_num_rows(stmt));

    /* Fetch all rows */
    int row_count = 0;
    fprintf(stdout, "Fetching results ...\n");
    while (!mysql_stmt_fetch(stmt)) {
        row_count++;
        fprintf(stdout, " row %d\n", row_count);

        /* column 1 */
        fprintf(stdout, " column1: ");
        if (is_null[0])
            fprintf(stdout, " NULL\t");
        else
            fprintf(stdout, " %d(%ld)\t", int_data[0], length[0]);

        /* column 2 */
        fprintf(stdout, " column2: ");
        if (is_null[1])
            fprintf(stdout, " NULL\t");
        else
            fprintf(stdout, " %d(%ld)\t", int_data[1], length[1]);

        /* column 3 */
        fprintf(stdout, " column3: ");
        if (is_null[2])
            fprintf(stdout, " NULL\t");
        else
            fprintf(stdout, " %d(%ld)\t", int_data[2], length[2]);

        fprintf(stdout, " column4: ");
        if (is_null[3])
            fprintf(stdout, " NULL\t");
        else
            fprintf(stdout, " %s(%ld)\t", str_data[3], length[3]);

        /* column 4 */
        /*
        fprintf(stdout, " column4 (timestamp): ");
        if (is_null[3])
            fprintf(stdout, " NULL\n");
        else
            fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
                ts.year, ts.month, ts.day,
                ts.hour, ts.minute, ts.second,
                length[3]);
                */
        fprintf(stdout, "\n");
        if (row_count > 10)
            break;
    }

    /* Validate rows fetched */
    fprintf(stdout, " total rows fetched: %d\n", row_count);

    /* Free the prepared result metadata */
    mysql_free_result(prepare_meta_result);

    /* Close the statement */
    if (mysql_stmt_close(stmt)) {
        fprintf(stderr, " failed while closing the statement\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(0);
    }
}
Exemple #10
0
long MyRecordset::LoadStmt(MYSQL_STMT* stmt, long indcol)
{
    MYSQL_FIELD    *fields;
    MYSQL_BIND* binds = NULL;  /* for output buffers */
    MYSQL_RES *result = NULL;
    result = mysql_stmt_result_metadata(stmt);
    test_stmt_error(stmt, result == NULL);
    
    char* buffer = NULL;
    
    nbcol = mysql_stmt_field_count(stmt);
        
    fields = mysql_fetch_fields(result);
    
    binds = new MYSQL_BIND[nbcol*sizeof(MYSQL_BIND)];
    
    memset(binds, 0, sizeof (MYSQL_BIND) * nbcol);
    
    int size=0;
    for(int i = 0; i < nbcol; i++)
        size+=fields[i].length;
    
    buffer = new char[size*8];
    
    memset(buffer, 0, sizeof (char) * size*8);
    int pos = 0;
    
    for(int i = 0; i < nbcol; i++)
    {
        colname.push_back(fields[i].name);
        coltype.push_back(fields[i].type);
        binds[i].buffer_type = fields[i].type;
        binds[i].is_null = 0;
        binds[i].buffer = &buffer[pos];
        binds[i].buffer_length = fields[i].length;
        pos+=fields[i].length;
    }

    int status = mysql_stmt_bind_result(stmt, binds);
    test_stmt_error(stmt, status);
    
    int linenum = 0;
    
    char tmp[8000];
    
    while(true)
    {
        status = mysql_stmt_fetch(stmt);
        if (status == 1 || status == MYSQL_NO_DATA)
            break;
        data.push_back(vector<string>());
        MYSQL_TIME ts;
        string stmp;
        for(int i = 0; i < nbcol; i++)
        {
            switch (binds[i].buffer_type) {
                case MYSQL_TYPE_TINY:
                    snprintf(tmp, 8000, "%d", *((signed char*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_SHORT:
                    snprintf(tmp, 8000, "%d", *((short int*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_LONG:
                    snprintf(tmp, 8000, "%d", *((int*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_LONGLONG:
                    snprintf(tmp, 8000, "%lld", *((long long int*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_DECIMAL:
                    snprintf(tmp, 8000, "%s", ((char*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_NEWDECIMAL:
                    snprintf(tmp, 8000, "%s", (char*)(binds[i].buffer));
                    stmp = string(tmp);
                    data.back().push_back(stmp); break;
                case MYSQL_TYPE_FLOAT:
                    snprintf(tmp, 8000, "%f", *((float*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_DOUBLE:
                    snprintf(tmp, 8000, "%f", *((double*)(binds[i].buffer)));
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_TIME:
                    ts = *((MYSQL_TIME*)(binds[i].buffer));
                    snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_DATE:
                    ts = *((MYSQL_TIME*)(binds[i].buffer));
                    snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_DATETIME:
                    ts = *((MYSQL_TIME*)(binds[i].buffer));
                    snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_TIMESTAMP:
                    ts = *((MYSQL_TIME*)(binds[i].buffer));
                    snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_STRING:
                    snprintf(tmp, 8000, "%s", (char*)binds[i].buffer);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_VAR_STRING:
                    snprintf(tmp, 8000, "%s", (char*)binds[i].buffer);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_BLOB:
                    snprintf(tmp, 8000, "%s", (char*)binds[i].buffer);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_BIT:
                    snprintf(tmp, 8000, "%s", (char*)binds[i].buffer);
                    data.back().push_back(string(tmp)); break;
                case MYSQL_TYPE_NULL:
                    data.back().push_back(""); break;
                default:
                    printf("UNKNOWN TYPE %s %d\n", fields[i].name, binds[i].buffer_type);
                    exit(1);
                    break;
            }
            
            if(indcol != -1 && i == indcol)
            {
                int cval = *((int*)(binds[i].buffer));
                index[cval] = linenum;
            }
        }
        linenum++;
    }
    nbrow = linenum;
    
    
    while(mysql_stmt_next_result(stmt) == 0)
    {
        linenum+=0;
    }
    
    mysql_free_result(result);
    delete[] binds;
    delete[] buffer;
    
    return 0;
}
Exemple #11
0
static DWORD GroupSyncIncrChanges(DB_CONTEXT *db, SYNC_CONTEXT *sync)
{
    CHAR        *query;
    BYTE        syncEvent;
    CHAR        syncInfo[255];
    CHAR        groupName[_MAX_NAME + 1];
    DWORD       error;
    GROUPFILE   groupFile;
    INT         result;
    MYSQL_BIND  bindInput[2];
    MYSQL_BIND  bindOutput[3];
    MYSQL_RES   *metadata;
    MYSQL_STMT  *stmt;

    ASSERT(db != NULL);
    ASSERT(sync != NULL);

    //
    // Prepare statement and bind parameters
    //

    stmt = db->stmt[7];

    query = "SELECT name, type, info FROM io_group_changes"
            "  WHERE time BETWEEN ? AND ?"
            "  ORDER BY id ASC";

    result = mysql_stmt_prepare(stmt, query, strlen(query));
    if (result != 0) {
        TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    DB_CHECK_PARAMS(bindInput, stmt);
    ZeroMemory(&bindInput, sizeof(bindInput));

    bindInput[0].buffer_type = MYSQL_TYPE_LONG;
    bindInput[0].buffer      = &sync->prevUpdate;
    bindInput[0].is_unsigned = TRUE;

    bindInput[1].buffer_type = MYSQL_TYPE_LONG;
    bindInput[1].buffer      = &sync->currUpdate;
    bindInput[1].is_unsigned = TRUE;

    result = mysql_stmt_bind_param(stmt, bindInput);
    if (result != 0) {
        TRACE("Unable to bind parameters: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    metadata = mysql_stmt_result_metadata(stmt);
    if (metadata == NULL) {
        TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Execute prepared statement
    //

    result = mysql_stmt_execute(stmt);
    if (result != 0) {
        LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Bind and fetch results
    //

    DB_CHECK_RESULTS(bindOutput, metadata);
    ZeroMemory(&bindOutput, sizeof(bindOutput));

    bindOutput[0].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[0].buffer        = groupName;
    bindOutput[0].buffer_length = sizeof(groupName);

    bindOutput[1].buffer_type   = MYSQL_TYPE_TINY;
    bindOutput[1].buffer        = &syncEvent;
    bindOutput[1].is_unsigned   = TRUE;

    bindOutput[2].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[2].buffer        = syncInfo;
    bindOutput[2].buffer_length = sizeof(syncInfo);

    result = mysql_stmt_bind_result(stmt, bindOutput);
    if (result != 0) {
        TRACE("Unable to bind results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_store_result(stmt);
    if (result != 0) {
        TRACE("Unable to buffer results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Process result set
    //

    for (;;) {
        if (mysql_stmt_fetch(stmt) != 0) {
            break;
        }

        switch ((SYNC_EVENT)syncEvent) {
            case SYNC_EVENT_CREATE:
                TRACE("GroupSyncIncr: Create(%s)", groupName);

                // Read group file from database
                ZeroMemory(&groupFile, sizeof(GROUPFILE));
                error = DbGroupRead(db, groupName, &groupFile);
                if (error != ERROR_SUCCESS) {
                    LOG_WARN("Unable to read group \"%s\" (error %lu).", groupName, error);
                } else {

                    // Create local user
                    error = GroupEventCreate(groupName, &groupFile);
                    if (error != ERROR_SUCCESS) {
                        LOG_WARN("Unable to create group \"%s\" (error %lu).", groupName, error);
                    }
                }
                break;

            case SYNC_EVENT_RENAME:
                TRACE("GroupSyncIncr: Rename(%s,%s)", groupName, syncInfo);

                error = GroupEventRename(groupName, syncInfo);
                if (error != ERROR_SUCCESS) {
                    LOG_WARN("Unable to rename group \"%s\" to \"%s\" (error %lu).", groupName, syncInfo, error);
                }
                break;

            case SYNC_EVENT_DELETE:
                TRACE("GroupSyncIncr: Delete(%s)", groupName);

                error = GroupEventDelete(groupName);
                if (error != ERROR_SUCCESS) {
                    LOG_WARN("Unable to delete group \"%s\" (error %lu).", groupName, error);
                }
                break;

            default:
                LOG_ERROR("Unknown sync event %d.", syncEvent);
                break;
        }
    }

    mysql_free_result(metadata);

    return ERROR_SUCCESS;
}
Exemple #12
0
static int dbd_mysql_pselect_internal(apr_pool_t *pool, apr_dbd_t *sql,
                                      apr_dbd_results_t **res,
                                      apr_dbd_prepared_t *statement,
                                      int random, MYSQL_BIND *bind)
{
    int nfields, i;
    my_bool *is_nullr;
#if MYSQL_VERSION_ID >= 50000
    my_bool *error;
#endif
    int ret;
    unsigned long *length, maxlen;

    ret = mysql_stmt_bind_param(statement->stmt, bind);
    if (ret == 0) {
        ret = mysql_stmt_execute(statement->stmt);
        if (!ret) {
            if (!*res) {
                *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
            }
            (*res)->random = random;
            (*res)->statement = statement->stmt;
            (*res)->res = mysql_stmt_result_metadata(statement->stmt);
            (*res)->pool = pool;
            apr_pool_cleanup_register(pool, (*res)->res,
                                      free_result, apr_pool_cleanup_null);
            nfields = mysql_num_fields((*res)->res);
            if (!(*res)->bind) {
                (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND));
                length = apr_pcalloc(pool, nfields*sizeof(unsigned long));
#if MYSQL_VERSION_ID >= 50000
                error = apr_palloc(pool, nfields*sizeof(my_bool));
#endif
                is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool));
                for ( i = 0; i < nfields; ++i ) {
                    maxlen = ((*res)->res->fields[i].length < sql->fldsz ?
                              (*res)->res->fields[i].length : sql->fldsz) + 1;
                    if ((*res)->res->fields[i].type == MYSQL_TYPE_BLOB) {
                        (*res)->bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB;
                    }
                    else {
                        (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
                    }
                    (*res)->bind[i].buffer_length = maxlen;
                    (*res)->bind[i].length = &length[i];
                    (*res)->bind[i].buffer = apr_palloc(pool, maxlen);
                    (*res)->bind[i].is_null = is_nullr+i;
#if MYSQL_VERSION_ID >= 50000
                    (*res)->bind[i].error = error+i;
#endif
                }
            }
            ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind);
            if (!ret) {
                ret = mysql_stmt_store_result(statement->stmt);
            }
        }
    }
    if (ret != 0) {
        ret = mysql_stmt_errno(statement->stmt);
    }

    return ret;
}
Exemple #13
0
static int dbd_mysql_pvselect(apr_pool_t *pool, apr_dbd_t *sql,
                              apr_dbd_results_t **res,
                              apr_dbd_prepared_t *statement, int random,
                              va_list args)
{
    int i;
    int nfields;
    char *arg;
    my_bool is_null = FALSE;
    my_bool *is_nullr;
#if MYSQL_VERSION_ID >= 50000
    my_bool *error;
#endif
    int ret;
    unsigned long *length, maxlen;
    int nargs;
    MYSQL_BIND *bind;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    nargs = mysql_stmt_param_count(statement->stmt);
    bind = apr_palloc(pool, nargs*sizeof(MYSQL_BIND));

    for (i=0; i < nargs; ++i) {
        arg = va_arg(args, char*);
        bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
        bind[i].buffer = arg;
        bind[i].buffer_length = strlen(arg);
        bind[i].length = &bind[i].buffer_length;
        bind[i].is_null = &is_null;
        bind[i].is_unsigned = 0;
    }

    ret = mysql_stmt_bind_param(statement->stmt, bind);
    if (ret == 0) {
        ret = mysql_stmt_execute(statement->stmt);
        if (!ret) {
            if (!*res) {
                *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
            }
            (*res)->random = random;
            (*res)->statement = statement->stmt;
            (*res)->res = mysql_stmt_result_metadata(statement->stmt);
            apr_pool_cleanup_register(pool, (*res)->res,
                                      free_result, apr_pool_cleanup_null);
            nfields = mysql_num_fields((*res)->res);
            if (!(*res)->bind) {
                (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND));
                length = apr_pcalloc(pool, nfields*sizeof(unsigned long));
#if MYSQL_VERSION_ID >= 50000
                error = apr_palloc(pool, nfields*sizeof(my_bool));
#endif
                is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool));
                for ( i = 0; i < nfields; ++i ) {
                    maxlen = ((*res)->res->fields[i].length < sql->fldsz ?
                              (*res)->res->fields[i].length : sql->fldsz) + 1;
                    (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
                    (*res)->bind[i].buffer_length = maxlen;
                    (*res)->bind[i].length = &length[i];
                    (*res)->bind[i].buffer = apr_palloc(pool, maxlen);
                    (*res)->bind[i].is_null = is_nullr+i;
#if MYSQL_VERSION_ID >= 50000
                    (*res)->bind[i].error = error+i;
#endif
                }
            }
            ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind);
            if (!ret) {
                ret = mysql_stmt_store_result(statement->stmt);
            }
        }
    }
    if (ret != 0) {
        ret = mysql_stmt_errno(statement->stmt);
    }
    if (sql->trans) {
        sql->trans->errnum = ret;
    }
    return ret;
}
int sqlite3_prepare(sqlite3* db,              /* Database handle */
                    const char* zSql,         /* SQL statement, UTF-8 encoded */
                    int nBytes,               /* Maximum length of zSql in bytes. */
                    mysqlite3_stmt** ppStmt,  /* OUT: Statement handle */
                    const char** pzTail       /* OUT: Pointer to unused portion of zSql */
)
{
    int rc = SQLITE_OK;
    
    mysqlite3_stmt* stmt = (mysqlite3_stmt*)malloc(sizeof(mysqlite3_stmt));
    
    stmt->mydb   = db;
    stmt->mystmt = mysql_stmt_init(db);
    stmt->myres  = NULL;
    stmt->myparams = NULL;
    stmt->results  = NULL;
    stmt->nresults = 0;
    stmt->executed = 0;
    stmt->nrow     = 0;
    stmt->lengths  = NULL;
    
    int stmt_len = statement_length(zSql, nBytes);
    
    if (nBytes > 0 && nBytes < stmt_len)
    {
        stmt_len = nBytes;
    }
    
    // "Strip" trailing semicolon, if present
    if (zSql[stmt_len-1] == ';')
    {
        stmt_len -= 1;
    }
    
    // Make a copy of the SQL and save it
    stmt->sql = strndup(zSql, stmt_len);
    
    mysql_stmt_prepare(stmt->mystmt, stmt->sql, stmt_len);
    
    stmt->nparams = mysql_stmt_param_count(stmt->mystmt);
    if (stmt->nparams > 0)
    {
        stmt->myparams = (MYSQL_BIND*)malloc(sizeof(MYSQL_BIND)*stmt->nparams);
    }
    
    /* Result set information */
    stmt->myres = mysql_stmt_result_metadata(stmt->mystmt);

    stmt->ncolumns = 0;
    if (stmt->myres)
    {
        /* Get total columns in the query */
        stmt->ncolumns = mysql_num_fields(stmt->myres);
        
        // Set STMT_ATTR_UPDATE_MAX_LENGTH attribute
        my_bool aBool = 1;
        mysql_stmt_attr_set(stmt->mystmt, STMT_ATTR_UPDATE_MAX_LENGTH, &aBool);
        
        if (stmt->ncolumns > 0)
        {
            stmt->results = malloc(sizeof(MYSQL_BIND)* stmt->ncolumns);
            stmt->lengths = malloc(sizeof(unsigned long)* stmt->ncolumns);
            memset(stmt->results, 0, sizeof(MYSQL_BIND)* stmt->ncolumns);
            
            int i;
            for (i=0; i < stmt->ncolumns; i++)
            {
                //stmt->results[i].buffer          = malloc(stmt->myres->fields[i].max_length);
                //stmt->results[i].buffer_type     = stmt->myres->fields[i].type;
                //stmt->results[i].buffer_length   = stmt->myres->fields[i].max_length;
                
                stmt->results[i].buffer          = 0;
                stmt->results[i].is_null         = 0;
                stmt->results[i].buffer_length   = 0;
                stmt->results[i].length          = &stmt->lengths[i];
            }
        }
    }
    
    *ppStmt = (mysqlite3_stmt*)stmt;
    
    if (pzTail)
    {
        (*pzTail) = NULL;
        if (stmt_len < strlen(zSql))
        {
            (*pzTail) = zSql+stmt_len;
            if (*pzTail[0] == ';') {
                (*pzTail)++;
            }
            if (*pzTail[0] == '\0') {
                *pzTail = NULL;
            }
        }
    }
    
    return rc;
};
Exemple #15
0
static DWORD UserSyncFull(DB_CONTEXT *db)
{
    BOOL        removed;
    CHAR        *query;
    CHAR        userName[_MAX_NAME + 1];
    DWORD       error;
    DWORD       i;
    USERFILE    userFile;
    INT         result;
    NAME_ENTRY  *entry;
    NAME_LIST   list;
    MYSQL_BIND  bind[17];
    MYSQL_RES   *metadata;
    MYSQL_STMT  *stmt;

    ASSERT(db != NULL);
    TRACE("db=%p", db);

    //
    // Build list of user IDs
    //

    error = NameListCreateUsers(&list);
    if (error != ERROR_SUCCESS) {
        LOG_ERROR("Unable to create user ID list (error %lu).", error);
        return error;
    }

    //
    // Prepare and execute statement
    //

    stmt = db->stmt[7];

    query = "SELECT name,description,flags,home,limits,password,vfsfile,credits,"
            "       ratio,alldn,allup,daydn,dayup,monthdn,monthup,wkdn,wkup"
            "  FROM io_user";

    result = mysql_stmt_prepare(stmt, query, strlen(query));
    if (result != 0) {
        LOG_WARN("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    metadata = mysql_stmt_result_metadata(stmt);
    if (metadata == NULL) {
        LOG_WARN("Unable to retrieve result metadata: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_execute(stmt);
    if (result != 0) {
        LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Bind and fetch results
    //

    DB_CHECK_RESULTS(bind, metadata);
    ZeroMemory(&bind, sizeof(bind));

    bind[0].buffer_type   = MYSQL_TYPE_STRING;
    bind[0].buffer        = userName;
    bind[0].buffer_length = sizeof(userName);

    bind[1].buffer_type   = MYSQL_TYPE_STRING;
    bind[1].buffer        = userFile.Tagline;
    bind[1].buffer_length = sizeof(userFile.Tagline);

    bind[2].buffer_type   = MYSQL_TYPE_STRING;
    bind[2].buffer        = userFile.Flags;
    bind[2].buffer_length = sizeof(userFile.Flags);

    bind[3].buffer_type   = MYSQL_TYPE_STRING;
    bind[3].buffer        = userFile.Home;
    bind[3].buffer_length = sizeof(userFile.Home);

    bind[4].buffer_type   = MYSQL_TYPE_BLOB;
    bind[4].buffer        = &userFile.Limits;
    bind[4].buffer_length = sizeof(userFile.Limits);

    bind[5].buffer_type   = MYSQL_TYPE_BLOB;
    bind[5].buffer        = &userFile.Password;
    bind[5].buffer_length = sizeof(userFile.Password);

    bind[6].buffer_type   = MYSQL_TYPE_STRING;
    bind[6].buffer        = userFile.MountFile;
    bind[6].buffer_length = sizeof(userFile.MountFile);

    bind[7].buffer_type   = MYSQL_TYPE_BLOB;
    bind[7].buffer        = &userFile.Ratio;
    bind[7].buffer_length = sizeof(userFile.Ratio);

    bind[8].buffer_type   = MYSQL_TYPE_BLOB;
    bind[8].buffer        = &userFile.Credits;
    bind[8].buffer_length = sizeof(userFile.Credits);

    bind[9].buffer_type   = MYSQL_TYPE_BLOB;
    bind[9].buffer        = &userFile.DayUp;
    bind[9].buffer_length = sizeof(userFile.DayUp);

    bind[10].buffer_type   = MYSQL_TYPE_BLOB;
    bind[10].buffer        = &userFile.DayDn;
    bind[10].buffer_length = sizeof(userFile.DayDn);

    bind[11].buffer_type   = MYSQL_TYPE_BLOB;
    bind[11].buffer        = &userFile.WkUp;
    bind[11].buffer_length = sizeof(userFile.WkUp);

    bind[12].buffer_type   = MYSQL_TYPE_BLOB;
    bind[12].buffer        = &userFile.WkDn;
    bind[12].buffer_length = sizeof(userFile.WkDn);

    bind[13].buffer_type   = MYSQL_TYPE_BLOB;
    bind[13].buffer        = &userFile.MonthUp;
    bind[13].buffer_length = sizeof(userFile.MonthUp);

    bind[14].buffer_type   = MYSQL_TYPE_BLOB;
    bind[14].buffer        = &userFile.MonthDn;
    bind[14].buffer_length = sizeof(userFile.MonthDn);

    bind[15].buffer_type   = MYSQL_TYPE_BLOB;
    bind[15].buffer        = &userFile.AllUp;
    bind[15].buffer_length = sizeof(userFile.AllUp);

    bind[16].buffer_type   = MYSQL_TYPE_BLOB;
    bind[16].buffer        = &userFile.AllDn;
    bind[16].buffer_length = sizeof(userFile.AllDn);

    result = mysql_stmt_bind_result(stmt, bind);
    if (result != 0) {
        LOG_WARN("Unable to bind results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_store_result(stmt);
    if (result != 0) {
        LOG_WARN("Unable to buffer results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Process result set
    //

    for (;;) {
        ZeroMemory(&userFile, sizeof(USERFILE));
        if (mysql_stmt_fetch(stmt) != 0) {
            break;
        }

        // Remove user from the list beforehand in case DbUserReadExtra() fails
        removed = NameListRemove(&list, userName);

        // Read the user's admin-groups, groups, and hosts
        error = DbUserReadExtra(db, userName, &userFile);
        if (error != ERROR_SUCCESS) {
            LOG_WARN("Unable to read user \"%s\" (error %lu).", userName, error);
            continue;
        }

        //
        // If ioFTPD fails to open a user at start-up, the user will still
        // have an entry in the UserIdTable file but ioFTPD considers them
        // gone. The call to UserExists() is done to check for this.
        //
        if (!removed || !UserExists(userName)) {
            TRACE("UserSyncFull: Create(%s)", userName);

            // User does not exist locally, create it.
            error = UserEventCreate(userName, &userFile);
            if (error != ERROR_SUCCESS) {
                LOG_WARN("Unable to create user \"%s\" (error %lu).", userName, error);
            }
        } else {
            TRACE("UserSyncFull: Update(%s)", userName);

            // User already exists locally, update it.
            error = UserEventUpdate(userName, &userFile);
            if (error != ERROR_SUCCESS) {
                LOG_WARN("Unable to update user \"%s\" (error %lu).", userName, error);
            }
        }
    }

    mysql_free_result(metadata);

    //
    // Delete remaining users
    //

    for (i = 0; i < list.count; i++) {
        entry = list.array[i];
        TRACE("UserSyncFull: Delete(%s,%d)", entry->name, entry->id);

        // User does not exist on database, delete it.
        error = UserEventDeleteEx(entry->name, entry->id);
        if (error != ERROR_SUCCESS) {
            LOG_WARN("Unable to delete user \"%s\" (error %lu).", entry->name, error);
        }
    }

    NameListDestroy(&list);

    return ERROR_SUCCESS;
}
Exemple #16
0
static VALUE each(VALUE self) {
  VALUE block;
  MYSQL_STMT *stmt;
  MYSQL_RES *result;

  Data_Get_Struct(self, MYSQL_STMT, stmt);

  result = mysql_stmt_result_metadata(stmt);
  if (result) {
    MYSQL_BIND *result_buffers;
    my_bool *is_null;
    my_bool *error;
    unsigned long *length;
    MYSQL_FIELD *fields;
    unsigned long field_count;
    unsigned long i;

    if (mysql_stmt_store_result(stmt)) {
      rb_raise(cMysql2Error, "%s", mysql_stmt_error(stmt));
    }

    fields = mysql_fetch_fields(result);
    field_count = mysql_num_fields(result);

    result_buffers = xcalloc(field_count, sizeof(MYSQL_BIND));
    is_null = xcalloc(field_count, sizeof(my_bool));
    error   = xcalloc(field_count, sizeof(my_bool));
    length  = xcalloc(field_count, sizeof(unsigned long));

    for (i = 0; i < field_count; i++) {
      result_buffers[i].buffer_type = fields[i].type;

      //      mysql type    |            C type
      switch(fields[i].type) {
        case MYSQL_TYPE_NULL:         // NULL
          break;
        case MYSQL_TYPE_TINY:         // signed char
          result_buffers[i].buffer = xcalloc(1, sizeof(signed char));
          result_buffers[i].buffer_length = sizeof(signed char);
          break;
        case MYSQL_TYPE_SHORT:        // short int
          result_buffers[i].buffer = xcalloc(1, sizeof(short int));
          result_buffers[i].buffer_length = sizeof(short int);
          break;
        case MYSQL_TYPE_INT24:        // int
        case MYSQL_TYPE_LONG:         // int
        case MYSQL_TYPE_YEAR:         // int
          result_buffers[i].buffer = xcalloc(1, sizeof(int));
          result_buffers[i].buffer_length = sizeof(int);
          break;
        case MYSQL_TYPE_LONGLONG:     // long long int
          result_buffers[i].buffer = xcalloc(1, sizeof(long long int));
          result_buffers[i].buffer_length = sizeof(long long int);
          break;
        case MYSQL_TYPE_FLOAT:        // float
        case MYSQL_TYPE_DOUBLE:       // double
          result_buffers[i].buffer = xcalloc(1, sizeof(double));
          result_buffers[i].buffer_length = sizeof(double);
          break;
        case MYSQL_TYPE_TIME:         // MYSQL_TIME
        case MYSQL_TYPE_DATE:         // MYSQL_TIME
        case MYSQL_TYPE_NEWDATE:      // MYSQL_TIME
        case MYSQL_TYPE_DATETIME:     // MYSQL_TIME
        case MYSQL_TYPE_TIMESTAMP:    // MYSQL_TIME
          result_buffers[i].buffer = xcalloc(1, sizeof(MYSQL_TIME));
          result_buffers[i].buffer_length = sizeof(MYSQL_TIME);
          break;
        case MYSQL_TYPE_DECIMAL:      // char[]
        case MYSQL_TYPE_NEWDECIMAL:   // char[]
        case MYSQL_TYPE_STRING:       // char[]
        case MYSQL_TYPE_VAR_STRING:   // char[]
        case MYSQL_TYPE_VARCHAR:      // char[]
        case MYSQL_TYPE_TINY_BLOB:    // char[]
        case MYSQL_TYPE_BLOB:         // char[]
        case MYSQL_TYPE_MEDIUM_BLOB:  // char[]
        case MYSQL_TYPE_LONG_BLOB:    // char[]
        case MYSQL_TYPE_BIT:          // char[]
        case MYSQL_TYPE_SET:          // char[]
        case MYSQL_TYPE_ENUM:         // char[]
        case MYSQL_TYPE_GEOMETRY:     // char[]
          result_buffers[i].buffer = malloc(fields[i].max_length);
          result_buffers[i].buffer_length = fields[i].max_length;
          break;
        default:
          rb_raise(cMysql2Error, "unhandled mysql type: %d", fields[i].type);
      }

      result_buffers[i].is_null = &is_null[i];
      result_buffers[i].length  = &length[i];
      result_buffers[i].error   = &error[i];
      result_buffers[i].is_unsigned = ((fields[i].flags & UNSIGNED_FLAG) != 0);
    }

    if(mysql_stmt_bind_result(stmt, result_buffers)) {
      for(i = 0; i < field_count; i++) {
        if (result_buffers[i].buffer) {
          free(result_buffers[i].buffer);
        }
      }
      free(result_buffers);
      free(is_null);
      free(error);
      free(length);
      rb_raise(cMysql2Error, "%s", mysql_stmt_error(stmt));
    }

    block = rb_block_proc();

    while(!mysql_stmt_fetch(stmt)) {
      VALUE row = rb_ary_new2((long)field_count);

      for(i = 0; i < field_count; i++) {
        VALUE column = Qnil;
        MYSQL_TIME *ts;

        if (is_null[i]) {
          column = Qnil;
        } else {
          switch(result_buffers[i].buffer_type) {
            case MYSQL_TYPE_TINY:         // signed char
              if (result_buffers[i].is_unsigned) {
                column = UINT2NUM(*((unsigned char*)result_buffers[i].buffer));
              } else {
                column = INT2NUM(*((signed char*)result_buffers[i].buffer));
              }
              break;
            case MYSQL_TYPE_SHORT:        // short int
              if (result_buffers[i].is_unsigned) {
                column = UINT2NUM(*((unsigned short int*)result_buffers[i].buffer));
              } else  {
                column = INT2NUM(*((short int*)result_buffers[i].buffer));
              }
              break;
            case MYSQL_TYPE_INT24:        // int
            case MYSQL_TYPE_LONG:         // int
            case MYSQL_TYPE_YEAR:         // int
              if (result_buffers[i].is_unsigned) {
                column = UINT2NUM(*((unsigned int*)result_buffers[i].buffer));
              } else {
                column = INT2NUM(*((int*)result_buffers[i].buffer));
              }
              break;
            case MYSQL_TYPE_LONGLONG:     // long long int
              if (result_buffers[i].is_unsigned) {
                column = ULL2NUM(*((unsigned long long int*)result_buffers[i].buffer));
              } else {
                column = LL2NUM(*((long long int*)result_buffers[i].buffer));
              }
              break;
            case MYSQL_TYPE_FLOAT:        // float
              column = rb_float_new((double)(*((float*)result_buffers[i].buffer)));
              break;
            case MYSQL_TYPE_DOUBLE:       // double
              column = rb_float_new((double)(*((double*)result_buffers[i].buffer)));
              break;
            case MYSQL_TYPE_DATE:         // MYSQL_TIME
              ts = (MYSQL_TIME*)result_buffers[i].buffer;
              column = rb_funcall(cDate, rb_intern("new"), 3, INT2NUM(ts->year), INT2NUM(ts->month), INT2NUM(ts->day));
              break;
            case MYSQL_TYPE_TIME:         // MYSQL_TIME
              ts = (MYSQL_TIME*)result_buffers[i].buffer;
              column = rb_funcall(rb_cTime,
                  rb_intern("mktime"), 6,
                  UINT2NUM(Qnil),
                  UINT2NUM(Qnil),
                  UINT2NUM(Qnil),
                  UINT2NUM(ts->hour),
                  UINT2NUM(ts->minute),
                  UINT2NUM(ts->second));
              break;
            case MYSQL_TYPE_NEWDATE:      // MYSQL_TIME
            case MYSQL_TYPE_DATETIME:     // MYSQL_TIME
            case MYSQL_TYPE_TIMESTAMP:    // MYSQL_TIME
              ts = (MYSQL_TIME*)result_buffers[i].buffer;
              column = rb_funcall(rb_cTime,
                  rb_intern("mktime"), 6,
                  UINT2NUM(ts->year),
                  UINT2NUM(ts->month),
                  UINT2NUM(ts->day),
                  UINT2NUM(ts->hour),
                  UINT2NUM(ts->minute),
                  UINT2NUM(ts->second));
              break;
            case MYSQL_TYPE_DECIMAL:      // char[]
            case MYSQL_TYPE_NEWDECIMAL:   // char[]
              column = rb_funcall(cBigDecimal, rb_intern("new"), 1, rb_str_new(result_buffers[i].buffer, *(result_buffers[i].length)));
              break;
            case MYSQL_TYPE_STRING:       // char[]
            case MYSQL_TYPE_VAR_STRING:   // char[]
            case MYSQL_TYPE_VARCHAR:      // char[]
            case MYSQL_TYPE_TINY_BLOB:    // char[]
            case MYSQL_TYPE_BLOB:         // char[]
            case MYSQL_TYPE_MEDIUM_BLOB:  // char[]
            case MYSQL_TYPE_LONG_BLOB:    // char[]
            case MYSQL_TYPE_BIT:          // char[]
            case MYSQL_TYPE_SET:          // char[]
            case MYSQL_TYPE_ENUM:         // char[]
            case MYSQL_TYPE_GEOMETRY:     // char[]
              column = rb_str_new(result_buffers[i].buffer, *(result_buffers[i].length));
              break;
            default:
              rb_raise(cMysql2Error, "unhandled buffer type: %d",
                  result_buffers[i].buffer_type);
              break;
          }
        }

        rb_ary_store(row, (long)i, column);
      }

      rb_yield(row);
    }

    free(result_buffers);
    free(is_null);
    free(error);
    free(length);
  }

  return self;
}
Exemple #17
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;
}
Exemple #18
0
const RecordSet &MySqlDataProvider::processSql()
{
    if (!mIsConnected)
        throw std::runtime_error("not connected to database");

    // Since we'll have to return something in all cases,
    // we clear the result member first.
    mRecordSet.clear();

    if (!mBind)
    {
        LOG_ERROR("MySqlDataProvider::processSql: "
                  "No bind done before processing.");
        return mRecordSet;
    }

    if (mysql_stmt_bind_param(mStmt, mBind))
    {
        LOG_ERROR("MySqlDataProvider::processSql Bind params failed: "
                  << mysql_stmt_error(mStmt));
        return mRecordSet;
    }

    if (mysql_stmt_field_count(mStmt) > 0)
    {
        MYSQL_BIND* resultBind;
        MYSQL_RES* res;

        if (mysql_stmt_execute(mStmt))
        {
            LOG_ERROR("MySqlDataProvider::processSql Execute failed: "
                      << mysql_stmt_error(mStmt));
        }

        res = mysql_stmt_result_metadata(mStmt);

        // set the field names.
        unsigned nFields = mysql_num_fields(res);
        MYSQL_FIELD* fields = mysql_fetch_fields(res);
        Row fieldNames;

        resultBind = new MYSQL_BIND[mysql_num_fields(res)];

        unsigned i = 0;
        for (i = 0; i < mysql_num_fields(res); ++i)
        {
            resultBind[i].buffer_type = MYSQL_TYPE_STRING;
            resultBind[i].buffer = (void*) new char[255];
            resultBind[i].buffer_length = 255;
            resultBind[i].is_null = new my_bool;
            resultBind[i].length = new unsigned long;
            resultBind[i].error = new my_bool;
        }

        if (mysql_stmt_bind_result(mStmt, resultBind))
        {
            LOG_ERROR("MySqlDataProvider::processSql Bind result failed: "
                      << mysql_stmt_error(mStmt));
        }

        for (i = 0; i < nFields; ++i)
            fieldNames.push_back(fields[i].name);

        mRecordSet.setColumnHeaders(fieldNames);

        // store the result of the query.
        if (mysql_stmt_store_result(mStmt))
            throw DbSqlQueryExecFailure(mysql_stmt_error(mStmt));

        // populate the RecordSet.
        while (!mysql_stmt_fetch(mStmt))
        {
            Row r;

            for (i = 0; i < nFields; ++i)
                r.push_back(static_cast<char *>(resultBind[i].buffer));

            mRecordSet.add(r);
        }

        delete[] resultBind;
    }
    else
    {
        if (mysql_stmt_execute(mStmt))
        {
            LOG_ERROR("MySqlDataProvider::processSql Execute failed: "
                      << mysql_stmt_error(mStmt));
        }
    }

    // Free memory
    mysql_stmt_free_result(mStmt);

    return mRecordSet;
}
Exemple #19
0
static int my_process_stmt_result(MYSQL_STMT *stmt)
{
 int         field_count;
 int         row_count= 0;
 MYSQL_BIND  buffer[MAX_RES_FIELDS];
 MYSQL_FIELD *field;
 MYSQL_RES   *result;
 char        data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE];
 ulong       length[MAX_RES_FIELDS];
 my_bool     is_null[MAX_RES_FIELDS];
 int         rc, i;

 if (!(result= mysql_stmt_result_metadata(stmt))) /* No meta info */
 {
   while (!mysql_stmt_fetch(stmt))
   row_count++;
   return row_count;
 }

 field_count= MY_MIN(mysql_num_fields(result), MAX_RES_FIELDS);

 memset(buffer, 0, sizeof(buffer));
 memset(length, 0, sizeof(length));
 memset(is_null, 0, sizeof(is_null));

 for(i= 0; i < field_count; i++)
 {
   buffer[i].buffer_type= MYSQL_TYPE_STRING;
   buffer[i].buffer_length= MAX_FIELD_DATA_SIZE;
   buffer[i].length= &length[i];
   buffer[i].buffer= (void *) data[i];
   buffer[i].is_null= &is_null[i];
 }

 rc= mysql_stmt_bind_result(stmt, buffer);
 check_execute(stmt, rc);

 rc= 1;
 mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc);
 rc= mysql_stmt_store_result(stmt);
 check_execute(stmt, rc);
 my_print_result_metadata(result);

 mysql_field_seek(result, 0);
 while ((rc= mysql_stmt_fetch(stmt)) == 0)
 {
   if (!opt_silent)
   {
     fputc('\t', stdout);
     fputc('|', stdout);
   }
   mysql_field_seek(result, 0);
   for (i= 0; i < field_count; i++)
   {
     field= mysql_fetch_field(result);
     if (!opt_silent)
     {
       if (is_null[i])
       fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
       else if (length[i] == 0)
       {
	 data[i][0]= '\0';  /* unmodified buffer */
	 fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
       }
       else if (IS_NUM(field->type))
       fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
       else
       fprintf(stdout, " %-*s |", (int) field->max_length, data[i]);
     }
   }
   if (!opt_silent)
   {
     fputc('\t', stdout);
     fputc('\n', stdout);
   }
   row_count++;
 }
 DIE_UNLESS(rc == MYSQL_NO_DATA);
 if (!opt_silent)
 {
   if (row_count)
   my_print_dashes(result);
   fprintf(stdout, "\n\t%d %s returned\n", row_count,
   row_count == 1 ? "row" : "rows");
 }
 mysql_free_result(result);
 return row_count;
}
Exemple #20
0
/*
 * the @ps struct is modified and transferred to the new data model created in
 * this function
 *
 * See MySQL's documentation "C API Prepared Statement Type Codes":
 *     http://docs.oracle.com/cd/E17952_01/refman-5.5-en/c-api-prepared-statement-type-codes.html
 */
GdaDataModel *
gda_mysql_recordset_new (GdaConnection            *cnc,
			 GdaMysqlPStmt            *ps,
			 GdaSet                   *exec_params,
			 GdaDataModelAccessFlags   flags,
			 GType                    *col_types)
{
	GdaMysqlRecordset *model;
        MysqlConnectionData *cdata;
        gint i;
	GdaDataModelAccessFlags rflags;

        g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
        g_return_val_if_fail (ps != NULL, NULL);

	cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
	if (!cdata)
		return NULL;

	g_assert (ps->mysql_stmt);

	/* make sure @ps reports the correct number of columns using the API*/
        if (_GDA_PSTMT (ps)->ncols < 0)
		_GDA_PSTMT(ps)->ncols = mysql_stmt_field_count (ps->mysql_stmt);

        /* completing @ps if not yet done */
	g_assert (! ps->stmt_used);
        ps->stmt_used = TRUE;
        if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
		/* create prepared statement's columns */
		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
			_GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, 
									 gda_column_new ());
		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);

		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;

		if (col_types) {
			for (i = 0; ; i++) {
				if (col_types [i] > 0) {
					if (col_types [i] == G_TYPE_NONE)
						break;
					if (i >= _GDA_PSTMT (ps)->ncols) {
						g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i,
							   _GDA_PSTMT (ps)->ncols - 1);
						break;
					}
					else
						_GDA_PSTMT (ps)->types [i] = col_types [i];
				}
			}
		}
	}

	/* get rid of old bound result if any */
	if (ps->mysql_bind_result) {
		gint i;
		for (i = 0; i < ((GdaPStmt *) ps)->ncols; ++i) {
			g_free (ps->mysql_bind_result[i].buffer);
			g_free (ps->mysql_bind_result[i].is_null);
			g_free (ps->mysql_bind_result[i].length);
		}
		g_free (ps->mysql_bind_result);
		ps->mysql_bind_result = NULL;
	}

	/* fill bind result */
	MYSQL_RES *mysql_res = mysql_stmt_result_metadata (ps->mysql_stmt);
	MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res);
	
	MYSQL_BIND *mysql_bind_result = g_new0 (MYSQL_BIND, GDA_PSTMT (ps)->ncols);
	GSList *list;

	for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
	     i < GDA_PSTMT (ps)->ncols; 
	     i++, list = list->next) {
		GdaColumn *column = GDA_COLUMN (list->data);
		
		/* use C API to set columns' information using gda_column_set_*() */
		MYSQL_FIELD *field = &mysql_fields[i];
		
		GType gtype = _GDA_PSTMT(ps)->types[i];
		if (gtype == GDA_TYPE_NULL) {
			gtype = _gda_mysql_type_to_gda (cdata, field->type, field->charsetnr);
			_GDA_PSTMT(ps)->types[i] = gtype;
		}
		gda_column_set_g_type (column, gtype);
		gda_column_set_name (column, field->name);
		gda_column_set_description (column, field->name);
		
		/* binding results with types */
		mysql_bind_result[i].buffer_type = field->type;
		mysql_bind_result[i].is_unsigned = field->flags & UNSIGNED_FLAG ? TRUE : FALSE;
		mysql_bind_result[i].is_null = g_malloc0 (sizeof (my_bool));
		
		switch (mysql_bind_result[i].buffer_type) {
		case MYSQL_TYPE_TINY:
			mysql_bind_result[i].buffer = g_malloc0 (sizeof (signed char));
			break;
		case MYSQL_TYPE_SHORT:
			mysql_bind_result[i].buffer = g_malloc0 (sizeof (short int));
			break;
		case MYSQL_TYPE_INT24:
		case MYSQL_TYPE_LONG:
		case MYSQL_TYPE_YEAR:
			mysql_bind_result[i].buffer = g_malloc0 (sizeof (int));
			break;
		case MYSQL_TYPE_LONGLONG:
			mysql_bind_result[i].buffer = g_malloc0 (sizeof (long long));
			break;
		case MYSQL_TYPE_NULL:
			break;
		case MYSQL_TYPE_TIME:
		case MYSQL_TYPE_DATE:
		case MYSQL_TYPE_DATETIME:
		case MYSQL_TYPE_TIMESTAMP:
			mysql_bind_result[i].buffer = g_malloc0 (sizeof (MYSQL_TIME));
			break;
		case MYSQL_TYPE_FLOAT:
		case MYSQL_TYPE_DOUBLE:
			mysql_bind_result[i].buffer = g_malloc0 (sizeof (double));
			break;
		case MYSQL_TYPE_STRING:
		case MYSQL_TYPE_VAR_STRING:
		case MYSQL_TYPE_BLOB:
		case MYSQL_TYPE_TINY_BLOB:
		case MYSQL_TYPE_MEDIUM_BLOB:
		case MYSQL_TYPE_LONG_BLOB:
		case MYSQL_TYPE_DECIMAL:
		case MYSQL_TYPE_NEWDECIMAL:
		case MYSQL_TYPE_BIT:
			mysql_bind_result[i].buffer = g_malloc0 (field->max_length + 1);
			mysql_bind_result[i].buffer_length = field->max_length + 1;
			mysql_bind_result[i].length = g_malloc0 (sizeof (unsigned long));
			break;
		default:
			g_warning (_("Invalid column bind data type. %d\n"),
				   mysql_bind_result[i].buffer_type);
		}
		/*g_print ("%s(): NAME=%s, TYPE=%d, GTYPE=%s, unsigned: %d\n",
			 __FUNCTION__, field->name, field->type, g_type_name (gtype),
			 field->flags & UNSIGNED_FLAG);*/
	}
	
	if (mysql_stmt_bind_result (ps->mysql_stmt, mysql_bind_result)) {
		g_warning ("mysql_stmt_bind_result failed: %s\n",
			   mysql_stmt_error (ps->mysql_stmt));
	}
	
	mysql_free_result (mysql_res);
	ps->mysql_bind_result = mysql_bind_result;

	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported */
	if (flags & GDA_DATA_MODEL_ACCESS_RANDOM)
		rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
	else
		rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD;

	/* create data model */
        model = g_object_new (GDA_TYPE_MYSQL_RECORDSET,
			      "connection", cnc,
			      "prepared-stmt", ps,
			      "model-usage", rflags,
			      "exec-params", exec_params, 
			      NULL);
        model->priv->cnc = cnc;
	g_object_ref (G_OBJECT(cnc));

	model->priv->mysql_stmt = ps->mysql_stmt;

	((GdaDataSelect *) model)->advertized_nrows = mysql_stmt_affected_rows (ps->mysql_stmt);

        return GDA_DATA_MODEL (model);
}
Exemple #21
0
void stmt_fetch_init(Stmt_fetch *fetch, unsigned stmt_no_arg,
const char *query_arg)
{
 unsigned long type= CURSOR_TYPE_READ_ONLY;
 int rc;
 unsigned i;
 MYSQL_RES *metadata;
 DBUG_ENTER("stmt_fetch_init");

 /* Save query and statement number for error messages */
 fetch->stmt_no= stmt_no_arg;
 fetch->query= query_arg;

 fetch->handle= mysql_stmt_init(mysql);

 rc= mysql_stmt_prepare(fetch->handle, fetch->query, (ulong)strlen(fetch->query));
 check_execute(fetch->handle, rc);

 /*
 The attribute is sent to server on execute and asks to open read-only
 for result set
 */
 mysql_stmt_attr_set(fetch->handle, STMT_ATTR_CURSOR_TYPE,
 (const void*) &type);

 rc= mysql_stmt_execute(fetch->handle);
 check_execute(fetch->handle, rc);

 /* Find out total number of columns in result set */
 metadata= mysql_stmt_result_metadata(fetch->handle);
 fetch->column_count= mysql_num_fields(metadata);
 mysql_free_result(metadata);

 /*
 Now allocate bind handles and buffers for output data:
 calloc memory to reduce number of MYSQL_BIND members we need to
 set up.
 */

 fetch->bind_array= (MYSQL_BIND *) calloc(1, sizeof(MYSQL_BIND) *
 fetch->column_count);
 fetch->out_data= (char**) calloc(1, sizeof(char*) * fetch->column_count);
 fetch->out_data_length= (ulong*) calloc(1, sizeof(ulong) *
                                         fetch->column_count);
 for (i= 0; i < fetch->column_count; ++i)
 {
   fetch->out_data[i]= (char*) calloc(1, MAX_COLUMN_LENGTH);
   fetch->bind_array[i].buffer_type= MYSQL_TYPE_STRING;
   fetch->bind_array[i].buffer= fetch->out_data[i];
   fetch->bind_array[i].buffer_length= MAX_COLUMN_LENGTH;
   fetch->bind_array[i].length= fetch->out_data_length + i;
 }

 mysql_stmt_bind_result(fetch->handle, fetch->bind_array);

 fetch->row_count= 0;
 fetch->is_open= TRUE;

 /* Ready for reading rows */
 DBUG_VOID_RETURN;
}
Exemple #22
0
int mysql_dumper_dump(struct mysql_login_info *mysql_login_info, const char *outputdir, const char *dbname, const char *tablename, const char *query, size_t query_len, struct mysql_dumper_type *types) {
    MYSQL mysql;
    MYSQL_STMT *stmt = NULL;
    mysql_init(&mysql);
    my_bool b_flag = 1;
    if (0 != mysql_options(&mysql, MYSQL_OPT_RECONNECT, (const char *)&b_flag))
        return report_error(&mysql);

    if (NULL == mysql_real_connect(&mysql, mysql_login_info->host, mysql_login_info->user, mysql_login_info->pass, mysql_login_info->db, mysql_login_info->port, NULL, CLIENT_COMPRESS))
        return report_error(&mysql);

    b_flag = 0;
    if (0 != mysql_options(&mysql, MYSQL_REPORT_DATA_TRUNCATION, (const char *)&b_flag))
        return report_error(&mysql);

    stmt = mysql_stmt_init(&mysql);
    if (!stmt)
        return report_error(&mysql);

    if (0 != mysql_stmt_prepare(stmt, query, query_len))
        return report_stmt_error(&mysql, stmt);

    MYSQL_RES *rs = mysql_stmt_result_metadata(stmt);
    if (!rs)
        return report_stmt_error(&mysql, stmt);

    unsigned int n = mysql_num_fields(rs);
    MYSQL_FIELD *fields = mysql_fetch_fields(rs);
    int field_types[n];
    MYSQL_BIND bind[n];
    my_bool is_null[n];
    unsigned long length[n];
    my_bool error[n];
    memset(bind, 0, sizeof(MYSQL_BIND) * n);
    int null_terminate_str[n];
    memset(null_terminate_str, 0, sizeof(int) * n);

    struct file_writer ffields[n];
    struct file_writer vfields[2][n];

    struct vmbuf buf = VMBUF_INITIALIZER;
    vmbuf_init(&buf, 4096);
    vmbuf_sprintf(&buf, "%s/%s/%s/schema.txt", outputdir, dbname, tablename);
    mkdir_for_file_recursive(vmbuf_data(&buf));
    int fdschema = creat(vmbuf_data(&buf), 0644);
    struct vmfile ds_txt = VMFILE_INITIALIZER;
    vmbuf_reset(&buf);
    vmbuf_sprintf(&buf, "%s/%s/%s/ds.txt", outputdir, dbname, tablename);
    if (0 > vmfile_init(&ds_txt, vmbuf_data(&buf), 4096))
        return LOGGER_ERROR("failed to create: %s", vmbuf_data(&buf)), vmbuf_free(&buf), -1;
    vmfile_sprintf(&ds_txt, "DS_LOADER_BEGIN()\n");
    vmfile_sprintf(&ds_txt, "/*\n * DB: %s\n */\n", dbname);
    vmfile_sprintf(&ds_txt, "#undef DB_NAME\n#define DB_NAME %s\n", dbname);
    ssize_t len = 80 - strlen(tablename);
    if (len < 0) len = 4;
    char header[len];
    memset(header, '=', len);
    vmfile_sprintf(&ds_txt, "/* %.*s[ %s ]%.*s */\n", (int)len / 2, header, tablename, (int)(len - (len / 2)), header);
    vmfile_sprintf(&ds_txt, "#   undef TABLE_NAME\n#   define TABLE_NAME %s\n", tablename);
    /*
     * initialize output files
     */
    unsigned int i;
    for (i = 0; i < n; ++i) {
        file_writer_make(&ffields[i]);
        file_writer_make(&vfields[0][i]);
        file_writer_make(&vfields[1][i]);
    }

    struct hashtable ht_types = HASHTABLE_INITIALIZER;
    hashtable_init(&ht_types, 32);
    if (NULL != types) {
        struct mysql_dumper_type *t = types;
        for (; t->name; ++t) {
            /* storing ptr here which points to static str */
            hashtable_insert(&ht_types, t->name, strlen(t->name), t, sizeof(struct mysql_dumper_type));
        }
    }
    /*
     * parse meta data and construct bind array
     */
    int err = 0;
    for (i = 0; i < n; ++i) {
        field_types[i] = fields[i].type;
        bind[i].is_unsigned = IS_UNSIGNED(fields[i].flags);

        int64_t ds_type = -1;
        const char *ds_type_str = "VAR";
        /*
         * handle overrides
         */
        while (NULL != types) {
            uint32_t ofs = hashtable_lookup(&ht_types, fields[i].name, strlen(fields[i].name));
            if (!ofs) break;
            struct mysql_dumper_type *type = (struct mysql_dumper_type *)hashtable_get_val(&ht_types, ofs);
            null_terminate_str[i] = MYSQL_DUMPER_CSTR & type->flags;
            if (type->mysql_type)
                field_types[i] = type->mysql_type;
            bind[i].is_unsigned = (type->flags & MYSQL_DUMPER_UNSIGNED) > 0 ? 1 : 0;
            break;
        }
        vmbuf_reset(&buf);
        vmbuf_sprintf(&buf, "%s/%s/%s/%s", outputdir, dbname, tablename, fields[i].name);

        mkdir_for_file_recursive(vmbuf_data(&buf));
        if (is_var_length_field(field_types[i])) {
            size_t ofs = vmbuf_wlocpos(&buf);
            vmbuf_sprintf(&buf, ".ofs");
            if (0 > (err = file_writer_init(&vfields[0][i], vmbuf_data(&buf))))
                break;
            vmbuf_wlocset(&buf, ofs);
            vmbuf_sprintf(&buf, ".dat");
            if (0 > (err = file_writer_init(&vfields[1][i], vmbuf_data(&buf))))
                break;
        } else {
            ds_type = get_ds_type(field_types[i], bind[i].is_unsigned);
            const char *s = get_ds_type_str(ds_type);
            if (*s) ds_type_str = s;
            if (0 > (err = file_writer_init(&ffields[i], vmbuf_data(&buf))) ||
                0 > (err = file_writer_write(&ffields[i], &ds_type, sizeof(ds_type))))
                break;;
        }
        len = ribs_mysql_get_storage_size(field_types[i], fields[i].length);
        if (fdschema > 0)
            dprintf(fdschema, "%03d  name = %s, size=%zu, length=%lu, type=%s (%s), is_prikey=%d, ds_type=%s\n", i, fields[i].name, len, fields[i].length, ribs_mysql_get_type_name(field_types[i]), bind[i].is_unsigned ? "unsigned" : "signed", IS_PRI_KEY(fields[i].flags), ds_type_str);
        if (is_var_length_field(field_types[i])) {
            vmfile_sprintf(&ds_txt, "        DS_VAR_FIELD_LOADER(%s)\n", fields[i].name);
        } else {
            vmfile_sprintf(&ds_txt, "        DS_FIELD_LOADER(%s, %s)\n", ds_type_str, fields[i].name);
        }
        bind[i].buffer_type = field_types[i];
        bind[i].buffer_length = len;
        bind[i].buffer = malloc(len);
        bind[i].is_null = &is_null[i];
        bind[i].length = &length[i];
        bind[i].error = &error[i];
    }
    hashtable_free(&ht_types);
    mysql_free_result(rs);
    close(fdschema);
    //vmfile_sprintf(&ds_txt, "/*\n * TABLE END: %s\n */\n", tablename);
    vmfile_sprintf(&ds_txt, "DS_LOADER_END()\n");
    vmfile_close(&ds_txt);
    /*
     * execute & bind
     */
    if (0 != err ||
        0 != mysql_stmt_execute(stmt) ||
        0 != mysql_stmt_bind_result(stmt, bind)) {
        err = -1;
        report_stmt_error(&mysql, stmt);
        goto dumper_close_writer;
    }
    char zeros[4096];
    memset(zeros, 0, sizeof(zeros));
    int mysql_err = 0;
    size_t count = 0, num_rows_errors = 0;
    /*
     * write all rows to output files
     */
    while (0 == (mysql_err = mysql_stmt_fetch(stmt))) {
        int b = 0;
        for (i = 0; i < n && !b; ++i)
            b = b || error[i];
        if (b) {
            ++num_rows_errors;
            continue;
        }
        for (i = 0; i < n; ++i) {
            if (is_var_length_field(field_types[i])) {
                size_t ofs = file_writer_wlocpos(&vfields[1][i]);
                if (0 > (err = file_writer_write(&vfields[0][i], &ofs, sizeof(ofs))) ||
                    0 > (err = file_writer_write(&vfields[1][i], is_null[i] ? NULL : bind[i].buffer, is_null[i] ? 0 : length[i])))
                    goto dumper_error;
                if (null_terminate_str[i]) {
                    const char c = '\0';
                    if (0 > (err = file_writer_write(&vfields[1][i], &c, sizeof(c))))
                        goto dumper_error;
                }
            } else {
                if (0 > (err = file_writer_write(&ffields[i], is_null[i] ? zeros : bind[i].buffer, bind[i].buffer_length)))
                    goto dumper_error;
            }
        }
        ++count;
    }
    /* no dumper errors */
    goto dumper_ok;
 dumper_error:
    LOGGER_ERROR("failed to write data, aborting");
 dumper_ok:
    /* we are done with mysql, close it */
    mysql_stmt_close(stmt);
    mysql_close(&mysql);
    LOGGER_INFO("%s: %zu records, %zu skipped", tablename, count, num_rows_errors);
    /* check for mysql errors */
    if (mysql_err != MYSQL_NO_DATA) {
        LOGGER_ERROR("mysql_stmt_fetch returned an error (code=%d)\n", mysql_err);
        err = -1;
    }
 dumper_close_writer:
    /*
     * finalize & free memory
     */
    for (i = 0; i < n; ++i) {
        if (is_var_length_field(field_types[i])) {
            size_t ofs = file_writer_wlocpos(&vfields[1][i]);
            if (0 > (err = file_writer_write(&vfields[0][i], &ofs, sizeof(ofs))))
                LOGGER_ERROR("failed to write offset");
            file_writer_close(&vfields[0][i]);
            file_writer_close(&vfields[1][i]);
        } else {
            file_writer_close(&ffields[i]);
        }
        free(bind[i].buffer);
    }
    vmbuf_free(&buf);
    return err;
}
Exemple #23
0
static DWORD UserSyncIncrUpdates(DB_CONTEXT *db, SYNC_CONTEXT *sync)
{
    CHAR        *query;
    CHAR        userName[_MAX_NAME + 1];
    DWORD       error;
    INT         result;
    USERFILE    userFile;
    MYSQL_BIND  bindInput[2];
    MYSQL_BIND  bindOutput[17];
    MYSQL_RES   *metadata;
    MYSQL_STMT  *stmt;

    ASSERT(db != NULL);
    ASSERT(sync != NULL);

    //
    // Prepare statement and bind parameters
    //

    stmt = db->stmt[7];

    query = "SELECT name,description,flags,home,limits,password,vfsfile,credits,"
            "       ratio,alldn,allup,daydn,dayup,monthdn,monthup,wkdn,wkup"
            "  FROM io_user"
            "  WHERE updated BETWEEN ? AND ?";

    result = mysql_stmt_prepare(stmt, query, strlen(query));
    if (result != 0) {
        LOG_WARN("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    DB_CHECK_PARAMS(bindInput, stmt);
    ZeroMemory(&bindInput, sizeof(bindInput));

    bindInput[0].buffer_type = MYSQL_TYPE_LONG;
    bindInput[0].buffer      = &sync->prevUpdate;
    bindInput[0].is_unsigned = TRUE;

    bindInput[1].buffer_type = MYSQL_TYPE_LONG;
    bindInput[1].buffer      = &sync->currUpdate;
    bindInput[1].is_unsigned = TRUE;

    result = mysql_stmt_bind_param(stmt, bindInput);
    if (result != 0) {
        LOG_WARN("Unable to bind parameters: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    metadata = mysql_stmt_result_metadata(stmt);
    if (metadata == NULL) {
        LOG_WARN("Unable to retrieve result metadata: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Execute prepared statement
    //

    result = mysql_stmt_execute(stmt);
    if (result != 0) {
        LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Bind and fetch results
    //

    DB_CHECK_RESULTS(bindOutput, metadata);
    ZeroMemory(&bindOutput, sizeof(bindOutput));

    bindOutput[0].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[0].buffer        = userName;
    bindOutput[0].buffer_length = sizeof(userName);

    bindOutput[1].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[1].buffer        = userFile.Tagline;
    bindOutput[1].buffer_length = sizeof(userFile.Tagline);

    bindOutput[2].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[2].buffer        = userFile.Flags;
    bindOutput[2].buffer_length = sizeof(userFile.Flags);

    bindOutput[3].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[3].buffer        = userFile.Home;
    bindOutput[3].buffer_length = sizeof(userFile.Home);

    bindOutput[4].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[4].buffer        = &userFile.Limits;
    bindOutput[4].buffer_length = sizeof(userFile.Limits);

    bindOutput[5].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[5].buffer        = &userFile.Password;
    bindOutput[5].buffer_length = sizeof(userFile.Password);

    bindOutput[6].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[6].buffer        = userFile.MountFile;
    bindOutput[6].buffer_length = sizeof(userFile.MountFile);

    bindOutput[7].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[7].buffer        = &userFile.Ratio;
    bindOutput[7].buffer_length = sizeof(userFile.Ratio);

    bindOutput[8].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[8].buffer        = &userFile.Credits;
    bindOutput[8].buffer_length = sizeof(userFile.Credits);

    bindOutput[9].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[9].buffer        = &userFile.DayUp;
    bindOutput[9].buffer_length = sizeof(userFile.DayUp);

    bindOutput[10].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[10].buffer        = &userFile.DayDn;
    bindOutput[10].buffer_length = sizeof(userFile.DayDn);

    bindOutput[11].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[11].buffer        = &userFile.WkUp;
    bindOutput[11].buffer_length = sizeof(userFile.WkUp);

    bindOutput[12].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[12].buffer        = &userFile.WkDn;
    bindOutput[12].buffer_length = sizeof(userFile.WkDn);

    bindOutput[13].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[13].buffer        = &userFile.MonthUp;
    bindOutput[13].buffer_length = sizeof(userFile.MonthUp);

    bindOutput[14].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[14].buffer        = &userFile.MonthDn;
    bindOutput[14].buffer_length = sizeof(userFile.MonthDn);

    bindOutput[15].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[15].buffer        = &userFile.AllUp;
    bindOutput[15].buffer_length = sizeof(userFile.AllUp);

    bindOutput[16].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[16].buffer        = &userFile.AllDn;
    bindOutput[16].buffer_length = sizeof(userFile.AllDn);

    result = mysql_stmt_bind_result(stmt, bindOutput);
    if (result != 0) {
        LOG_WARN("Unable to bind results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_store_result(stmt);
    if (result != 0) {
        LOG_WARN("Unable to buffer results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Process result set
    //

    for (;;) {
        ZeroMemory(&userFile, sizeof(USERFILE));
        if (mysql_stmt_fetch(stmt) != 0) {
            break;
        }
        TRACE("UserSyncIncr: Update(%s)", userName);

        // Read the user's admin-groups, groups, and hosts
        error = DbUserReadExtra(db, userName, &userFile);
        if (error != ERROR_SUCCESS) {
            LOG_WARN("Unable to read user \"%s\" (error %lu).", userName, error);
        } else {

            // Update user file
            error = UserEventUpdate(userName, &userFile);
            if (error != ERROR_SUCCESS) {
                LOG_WARN("Unable to update user \"%s\" (error %lu).", userName, error);
            }
        }
    }

    mysql_free_result(metadata);

    return ERROR_SUCCESS;
}
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, 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;
}
Exemple #25
0
static SLVAL
sl_mysql_stmt_execute(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    mysql_stmt_t* stmt = get_mysql_stmt(vm, self);
    size_t req = mysql_stmt_param_count(stmt->stmt);
    if(argc < req) {
        char buff[100];
        sprintf(buff, "Prepared statement has %lu parameter markers, but only %lu parameters were given", req, argc);
        sl_throw_message2(vm, vm->lib.ArgumentError, buff);
    }

    if(!stmt->bind) {
        stmt->bind = sl_alloc(vm->arena, sizeof(MYSQL_BIND) * req);
    }

    for(size_t i = 0; i < req; i++) {
        stmt->bind[i].buffer_type = MYSQL_TYPE_STRING;
        sl_string_t* str = sl_get_string(vm, sl_to_s(vm, argv[i]));
        stmt->bind[i].buffer = str->buff;
        stmt->bind[i].buffer_length = str->buff_len;
        stmt->bind[i].length = NULL;
        stmt->bind[i].is_null = NULL;
        stmt->bind[i].is_unsigned = 1;
        stmt->bind[i].error = NULL;
    }

    if(mysql_stmt_bind_param(stmt->stmt, stmt->bind)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    if(mysql_stmt_execute(stmt->stmt)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    MYSQL_RES* res = mysql_stmt_result_metadata(stmt->stmt);
    if(!res) {
        /* query did not produce a result set */
        return sl_make_int(vm, mysql_stmt_affected_rows(stmt->stmt));
    }

    int field_count = mysql_stmt_field_count(stmt->stmt);
    MYSQL_FIELD* field;
    SLVAL field_names[field_count];
    enum enum_field_types field_types[field_count];
    size_t field_i = 0;
    while((field = mysql_fetch_field(res))) {
        field_names[field_i] = sl_make_cstring(vm, field->name);
        if(field->type == MYSQL_TYPE_LONG || field->type == MYSQL_TYPE_SHORT || field->type == MYSQL_TYPE_TINY) {
            field_types[field_i] = MYSQL_TYPE_LONG;
        } else {
            field_types[field_i] = MYSQL_TYPE_STRING;
        }
        field_i++;
    }

    MYSQL_BIND output_binds[field_count];
    my_bool output_errors[field_count];
    my_bool output_is_nulls[field_count];
    unsigned long output_lengths[field_count];
    for(int i = 0; i < field_count; i++) {
        output_binds[i].buffer_type = MYSQL_TYPE_STRING;
        output_binds[i].buffer = NULL;
        output_binds[i].buffer_length = 0;
        output_binds[i].length = &output_lengths[i];
        output_binds[i].is_null = &output_is_nulls[i];
        output_binds[i].error = &output_errors[i];
    }
    if(mysql_stmt_bind_result(stmt->stmt, output_binds)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    SLVAL result_rows = sl_make_array(vm, 0, NULL);
    while(1) {
        int code = mysql_stmt_fetch(stmt->stmt);
        if(code == MYSQL_NO_DATA) {
            break;
        }
        if(code == 1) {
            sl_mysql_stmt_check_error(vm, stmt->stmt);
        }
        SLVAL row = sl_make_dict(vm, 0, NULL);
        for(int i = 0; i < field_count; i++) {
            MYSQL_BIND cell;
            cell.length = &output_lengths[i];
            cell.is_null = &output_is_nulls[i];
            cell.error = &output_errors[i];
            cell.buffer_type = field_types[i];
            int buffer_long;
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    cell.buffer = &buffer_long;
                    cell.buffer_length = sizeof(buffer_long);
                    break;
                default: /* MYSQL_TYPE_STRING */
                    cell.buffer = sl_alloc_buffer(vm->arena, output_lengths[i] + 1);
                    cell.buffer_length = output_lengths[i];
                    break;
            }
            if(mysql_stmt_fetch_column(stmt->stmt, &cell, i, 0)) {
                sl_mysql_stmt_check_error(vm, stmt->stmt);
            }
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    sl_dict_set(vm, row, field_names[i], sl_make_int(vm, buffer_long));
                    break;
                default: /* MYSQL_TYPE_STRING */
                    sl_dict_set(vm, row, field_names[i], sl_make_string(vm, cell.buffer, output_lengths[i]));
                    break;
            }
        }
        sl_array_push(vm, result_rows, 1, &row);
    }

    return result_rows;
}
Exemple #26
0
        void mysql_stmt_resultset::get_results()
        {
            if (stmt_ == NULL || bindings_ != NULL || status_ != -1)
                return;

            if ((status_ = mysql_stmt_execute(stmt_)))
            {
                throw database_exception(last_stmt_error(stmt_));
            }

            metadata_ = mysql_stmt_result_metadata(stmt_);

            if (metadata_ == NULL)
                throw database_exception("No result data found.");

            columnCount_ = mysql_num_fields(metadata_);

            bindings_ = (MYSQL_BIND *) calloc(columnCount_, sizeof(MYSQL_BIND));

            auto fields = mysql_fetch_fields(metadata_);

            for (auto i = 0; i < columnCount_; i++)
            {
                switch (fields[i].type)
                {
                case MYSQL_TYPE_INT24:
                    bindings_[i].buffer_type = MYSQL_TYPE_LONGLONG;
                    break;
                case MYSQL_TYPE_DECIMAL:
                case MYSQL_TYPE_NEWDECIMAL:
                    bindings_[i].buffer_type = MYSQL_TYPE_DOUBLE;
                    break;
                case MYSQL_TYPE_BIT:
                    bindings_[i].buffer_type = MYSQL_TYPE_TINY;
                    break;
                case MYSQL_TYPE_YEAR:
                    break;
                case MYSQL_TYPE_VAR_STRING:
                    bindings_[i].buffer_type = MYSQL_TYPE_STRING;
                    break;
                case MYSQL_TYPE_SET:
                case MYSQL_TYPE_ENUM:
                case MYSQL_TYPE_GEOMETRY:
                    break;
                default:
                    bindings_[i].buffer_type = fields[i].type;
                    break;
                }
                bindings_[i].is_null = (my_bool *) calloc(1, sizeof(my_bool));
                bindings_[i].is_unsigned = 0;
                bindings_[i].error = 0;
                bindings_[i].buffer_length = fields[i].length;
                bindings_[i].length = (size_t *) calloc(1, sizeof(size_t));
                bindings_[i].buffer = calloc(1, fields[i].length);
            }

            if (mysql_stmt_bind_result(stmt_, bindings_) != 0)
            {
                throw database_exception(last_stmt_error(stmt_));
            }
        }
Exemple #27
0
static DWORD GroupSyncFull(DB_CONTEXT *db)
{
    CHAR        *query;
    CHAR        groupName[_MAX_NAME + 1];
    DWORD       error;
    DWORD       i;
    GROUPFILE   groupFile;
    INT         result;
    NAME_ENTRY  *entry;
    NAME_LIST   list;
    MYSQL_BIND  bind[5];
    MYSQL_RES   *metadata;
    MYSQL_STMT  *stmt;

    ASSERT(db != NULL);
    TRACE("db=%p", db);

    //
    // Build list of group IDs
    //

    error = NameListCreateGroups(&list);
    if (error != ERROR_SUCCESS) {
        LOG_ERROR("Unable to create group ID list (error %lu).", error);
        return error;
    }

    //
    // Prepare and execute statement
    //

    stmt = db->stmt[7];

    query = "SELECT name, description, slots, users, vfsfile"
            "  FROM io_group";

    result = mysql_stmt_prepare(stmt, query, strlen(query));
    if (result != 0) {
        TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    metadata = mysql_stmt_result_metadata(stmt);
    if (metadata == NULL) {
        TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_execute(stmt);
    if (result != 0) {
        LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Bind and fetch results
    //

    DB_CHECK_RESULTS(bind, metadata);
    ZeroMemory(&bind, sizeof(bind));

    bind[0].buffer_type   = MYSQL_TYPE_STRING;
    bind[0].buffer        = groupName;
    bind[0].buffer_length = sizeof(groupName);

    bind[1].buffer_type   = MYSQL_TYPE_STRING;
    bind[1].buffer        = groupFile.szDescription;
    bind[1].buffer_length = sizeof(groupFile.szDescription);

    bind[2].buffer_type   = MYSQL_TYPE_BLOB;
    bind[2].buffer        = groupFile.Slots;
    bind[2].buffer_length = sizeof(groupFile.Slots);

    bind[3].buffer_type   = MYSQL_TYPE_LONG;
    bind[3].buffer        = &groupFile.Users;

    bind[4].buffer_type   = MYSQL_TYPE_STRING;
    bind[4].buffer        = groupFile.szVfsFile;
    bind[4].buffer_length = sizeof(groupFile.szVfsFile);

    result = mysql_stmt_bind_result(stmt, bind);
    if (result != 0) {
        TRACE("Unable to bind results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_store_result(stmt);
    if (result != 0) {
        TRACE("Unable to buffer results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Process result set
    //

    for (;;) {
        ZeroMemory(&groupFile, sizeof(GROUPFILE));
        if (mysql_stmt_fetch(stmt) != 0) {
            break;
        }

        //
        // If ioFTPD fails to open a group at start-up, the group will still
        // have an entry in the GroupIdTable file but ioFTPD considers them
        // gone. The call to GroupExists() is done to check for this.
        //
        if (!NameListRemove(&list, groupName) || !GroupExists(groupName)) {
            TRACE("GroupSyncFull: Create(%s)", groupName);

            // Group does not exist locally, create it.
            error = GroupEventCreate(groupName, &groupFile);
            if (error != ERROR_SUCCESS) {
                LOG_WARN("Unable to create group \"%s\" (error %lu).", groupName, error);
            }
        } else {
            TRACE("GroupSyncFull: Update(%s)", groupName);

            // Group already exists locally, update it.
            error = GroupEventUpdate(groupName, &groupFile);
            if (error != ERROR_SUCCESS) {
                LOG_WARN("Unable to update group \"%s\" (error %lu).", groupName, error);
            }
        }
    }

    mysql_free_result(metadata);

    //
    // Delete remaining groups
    //

    for (i = 0; i < list.count; i++) {
        entry = list.array[i];
        TRACE("GroupSyncFull: Delete(%s,%d)", entry->name, entry->id);

        // Group does not exist on database, delete it.
        error = GroupEventDeleteEx(entry->name, entry->id);
        if (error != ERROR_SUCCESS) {
            LOG_WARN("Unable to delete group \"%s\" (error %lu).", entry->name, error);
        }
    }

    NameListDestroy(&list);

    return ERROR_SUCCESS;
}
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("[ERROR]: PreparedStatement (id: %u, database: `%s`) error binding params:  [%u] %s",
                index, m_connectionInfo.database.c_str(), 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("[ERROR]: PreparedStatement (id: %u, database: `%s`) error executing:  [%u] %s",
                index, m_connectionInfo.database.c_str(), 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] Prepared SQL: %u on database `%s`",
                getMSTimeDiff(_s, getMSTime()), index, m_connectionInfo.database.c_str());

        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;

    }
}
Exemple #29
0
static DWORD GroupSyncIncrUpdates(DB_CONTEXT *db, SYNC_CONTEXT *sync)
{
    CHAR        *query;
    CHAR        groupName[_MAX_NAME + 1];
    DWORD       error;
    GROUPFILE   groupFile;
    INT         result;
    MYSQL_BIND  bindInput[2];
    MYSQL_BIND  bindOutput[5];
    MYSQL_RES   *metadata;
    MYSQL_STMT  *stmt;

    ASSERT(db != NULL);
    ASSERT(sync != NULL);

    //
    // Prepare statement and bind parameters
    //

    stmt = db->stmt[7];

    query = "SELECT name, description, slots, users, vfsfile"
            "  FROM io_group"
            "  WHERE updated BETWEEN ? AND ?";

    result = mysql_stmt_prepare(stmt, query, strlen(query));
    if (result != 0) {
        TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    DB_CHECK_PARAMS(bindInput, stmt);
    ZeroMemory(&bindInput, sizeof(bindInput));

    bindInput[0].buffer_type = MYSQL_TYPE_LONG;
    bindInput[0].buffer      = &sync->prevUpdate;
    bindInput[0].is_unsigned = TRUE;

    bindInput[1].buffer_type = MYSQL_TYPE_LONG;
    bindInput[1].buffer      = &sync->currUpdate;
    bindInput[1].is_unsigned = TRUE;

    result = mysql_stmt_bind_param(stmt, bindInput);
    if (result != 0) {
        TRACE("Unable to bind parameters: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    metadata = mysql_stmt_result_metadata(stmt);
    if (metadata == NULL) {
        TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Execute prepared statement
    //

    result = mysql_stmt_execute(stmt);
    if (result != 0) {
        LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Bind and fetch results
    //

    DB_CHECK_RESULTS(bindOutput, metadata);
    ZeroMemory(&bindOutput, sizeof(bindOutput));

    bindOutput[0].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[0].buffer        = groupName;
    bindOutput[0].buffer_length = sizeof(groupName);

    bindOutput[1].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[1].buffer        = groupFile.szDescription;
    bindOutput[1].buffer_length = sizeof(groupFile.szDescription);

    bindOutput[2].buffer_type   = MYSQL_TYPE_BLOB;
    bindOutput[2].buffer        = groupFile.Slots;
    bindOutput[2].buffer_length = sizeof(groupFile.Slots);

    bindOutput[3].buffer_type   = MYSQL_TYPE_LONG;
    bindOutput[3].buffer        = &groupFile.Users;

    bindOutput[4].buffer_type   = MYSQL_TYPE_STRING;
    bindOutput[4].buffer        = groupFile.szVfsFile;
    bindOutput[4].buffer_length = sizeof(groupFile.szVfsFile);

    result = mysql_stmt_bind_result(stmt, bindOutput);
    if (result != 0) {
        TRACE("Unable to bind results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    result = mysql_stmt_store_result(stmt);
    if (result != 0) {
        TRACE("Unable to buffer results: %s", mysql_stmt_error(stmt));
        return DbMapErrorFromStmt(stmt);
    }

    //
    // Process result set
    //

    for (;;) {
        ZeroMemory(&groupFile, sizeof(GROUPFILE));
        if (mysql_stmt_fetch(stmt) != 0) {
            break;
        }
        TRACE("GroupSyncIncr: Update(%s)", groupName);

        error = GroupEventUpdate(groupName, &groupFile);
        if (error != ERROR_SUCCESS) {
            LOG_WARN("Unable to update group \"%s\" (error %lu).", groupName, error);
        }
    }

    mysql_free_result(metadata);

    return ERROR_SUCCESS;
}
Exemple #30
0
void Statement::Prepare() {
	if (! _db.IsConnected()) {
		throw DatabaseException("Error in Statement::Prepare", 0, "----", "Database is not connected");
	}

	_numberAffectedRows = 0;

	if ((_stmt = mysql_stmt_init(_db._db)) == NULL) {
		throw DatabaseException(_db._db, "Error in Statement::Prepare during initialize");
	}

	if (mysql_stmt_prepare(_stmt, _sqlStatement.c_str(), _sqlStatement.length()) != 0) {
		mysql_stmt_close(_stmt);
		throw DatabaseException(_stmt, "Error in Statement::Prepare during prepare");
	}

	_bind = NULL;
	unsigned long parameterCount = ParameterCount();
	if (parameterCount > 0) {
		_bind = (MYSQL_BIND *) malloc(sizeof(MYSQL_BIND) * parameterCount);
		memset(_bind, 0, sizeof(MYSQL_BIND) * parameterCount);
	}

	_numberResultColumns = 0;
	_hasBlobField = false;

	MYSQL_RES *metaData;
	if ((metaData = mysql_stmt_result_metadata(_stmt)) == NULL) {
		return;
	}

	_resultBind = NULL;
	_numberResultColumns = mysql_num_fields(metaData);
	if (_numberResultColumns > 0) {
		_resultBind = (MYSQL_BIND *) malloc(sizeof(MYSQL_BIND) * _numberResultColumns);
		memset(_resultBind, 0, sizeof(MYSQL_BIND) * _numberResultColumns);
	}

	int fieldPos = 0;
	MYSQL_FIELD *field;
	while ((field = mysql_fetch_field(metaData)) != NULL) {
		ParamBuffer *buffer = NULL;

		if ((field->type == MYSQL_TYPE_VAR_STRING) || 
		    (field->type == MYSQL_TYPE_STRING) ||
		    (field->type == MYSQL_TYPE_DECIMAL) ||
		    (field->type == MYSQL_TYPE_BIT) ||
		    (field->type == MYSQL_TYPE_VARCHAR)) {
			std::string str;
			buffer = new ParamBuffer(str, field->length);
			_resultBind[fieldPos].buffer_type = field->type;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
		}
		else if (field->type == MYSQL_TYPE_TINY) {
			if ((field->flags & UNSIGNED_FLAG) != 0) {
				buffer = new ParamBuffer((const unsigned char) 0);
			} else {
				buffer = new ParamBuffer((const char) 0);
			}
			_resultBind[fieldPos].buffer_type = MYSQL_TYPE_TINY;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
			_resultBind[fieldPos].is_unsigned = buffer->IsUnsigned();
		}
		else if ((field->type == MYSQL_TYPE_SHORT) ||
			 (field->type == MYSQL_TYPE_YEAR)) {
			if ((field->flags & UNSIGNED_FLAG) != 0) {
				buffer = new ParamBuffer((const unsigned short int) 0);
			} else {
				buffer = new ParamBuffer((const short int) 0);
			}
			_resultBind[fieldPos].buffer_type = MYSQL_TYPE_SHORT;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
			_resultBind[fieldPos].is_unsigned = buffer->IsUnsigned();
		}
		else if ((field->type == MYSQL_TYPE_LONG) ||
			 (field->type == MYSQL_TYPE_INT24)) {
			if ((field->flags & UNSIGNED_FLAG) != 0) {
				buffer = new ParamBuffer((const unsigned int) 0);
			} else {
				buffer = new ParamBuffer((const int) 0);
			}
			_resultBind[fieldPos].buffer_type = field->type;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
			_resultBind[fieldPos].is_unsigned = buffer->IsUnsigned();
		}
		else if (field->type == MYSQL_TYPE_FLOAT) {
			_resultBind[fieldPos].buffer_type = field->type;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
			_resultBind[fieldPos].is_unsigned = buffer->IsUnsigned();
		}
		else if (field->type == MYSQL_TYPE_DOUBLE) {
			_resultBind[fieldPos].buffer_type = field->type;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
			_resultBind[fieldPos].is_unsigned = buffer->IsUnsigned();
		}
		else if ((field->type == MYSQL_TYPE_TIMESTAMP) ||
			 (field->type == MYSQL_TYPE_DATE) ||
			 (field->type == MYSQL_TYPE_TIME) ||
			 (field->type == MYSQL_TYPE_DATETIME)) {
			Julian time;
			buffer = new ParamBuffer(time);
			_resultBind[fieldPos].buffer_type = field->type;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
		}
		else if ((field->type == MYSQL_TYPE_BLOB) ||
			 (field->type == MYSQL_TYPE_TINY_BLOB) ||
			 (field->type == MYSQL_TYPE_MEDIUM_BLOB) ||
			 (field->type == MYSQL_TYPE_LONG_BLOB)) {
			_hasBlobField = true;
			Binary data(field->length);
			buffer = new ParamBuffer(data);
			_resultBind[fieldPos].buffer_type = field->type;
			_resultBind[fieldPos].buffer = buffer->Buffer();
			_resultBind[fieldPos].buffer_length = buffer->BufferSize();
			_resultBind[fieldPos].length = buffer->BufferLength();
			_resultBind[fieldPos].is_null = buffer->IsNull();
			_resultBind[fieldPos].error = buffer->Error();
		}

		if (buffer != NULL) {
			_resultParams.push_back(buffer);	
		}
		fieldPos++;
	}

	if (_resultParams.size() != _numberResultColumns) {
		mysql_free_result(metaData);
		mysql_stmt_close(_stmt);
		throw DatabaseException("Error in Statement::Prepare", 0, "----", "was not able to bind all parameters");
	}

	if (_hasBlobField) {
		my_bool setMax = 1;
		mysql_stmt_attr_set(_stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &setMax);
	}

	if (_numberResultColumns > 0) {
		if (mysql_stmt_bind_result(_stmt, _resultBind) != 0) {
			mysql_free_result(metaData);
			mysql_stmt_close(_stmt);
			throw DatabaseException(_stmt, "Error in Statement::Prepare while binding results");
		}
	}

	mysql_free_result(metaData);
}