/* Now it's more like installing result */
void MADB_InstallStmt(MADB_Stmt *Stmt, MYSQL_STMT *stmt)
{
  Stmt->stmt= stmt;

  if (mysql_stmt_field_count(Stmt->stmt) == 0)
  {
    Stmt->AffectedRows= mysql_stmt_affected_rows(Stmt->stmt);
  }
  else
  {
    Stmt->AffectedRows= 0;
    MADB_StmtResetResultStructures(Stmt);
    MADB_DescSetIrdMetadata(Stmt, mysql_fetch_fields(FetchMetadata(Stmt)), mysql_stmt_field_count(Stmt->stmt));
  }
}
Beispiel #2
0
T MysqlResultSet_new(void *stmt, int maxRows, int keep) {
	T R;
	assert(stmt);
	NEW(R);
	R->stmt = stmt;
        R->keep = keep;
        R->maxRows = maxRows;
        R->columnCount = mysql_stmt_field_count(R->stmt);
        if ((R->columnCount <= 0) || ! (R->meta = mysql_stmt_result_metadata(R->stmt))) {
                DEBUG("Warning: column error - %s\n", mysql_stmt_error(stmt));
                R->stop = true;
        } else {
                R->bind = CALLOC(R->columnCount, sizeof (MYSQL_BIND));
                R->columns = CALLOC(R->columnCount, sizeof (struct column_t));
                for (int i = 0; i < R->columnCount; i++) {
                        R->columns[i].buffer = ALLOC(STRLEN + 1);
                        R->bind[i].buffer_type = MYSQL_TYPE_STRING;
                        R->bind[i].buffer = R->columns[i].buffer;
                        R->bind[i].buffer_length = STRLEN;
                        R->bind[i].is_null = &R->columns[i].is_null;
                        R->bind[i].length = &R->columns[i].real_length;
                        R->columns[i].field = mysql_fetch_field_direct(R->meta, i);
                }
                if ((R->lastError = mysql_stmt_bind_result(R->stmt, R->bind))) {
                        DEBUG("Warning: bind error - %s\n", mysql_stmt_error(stmt));
                        R->stop = true;
                }
        }
	return R;
}
int MADB_KeyTypeCount(MADB_Dbc *Connection, char *TableName, int KeyFlag)
{
  int          Count= 0;
  unsigned int i;
  char         StmtStr[1024];
  char         *p= StmtStr;
  char         Database[65];
  MADB_Stmt    *Stmt= NULL;
  MADB_Stmt    *KeyStmt;
  
  Connection->Methods->GetAttr(Connection, SQL_ATTR_CURRENT_CATALOG, Database, 65, NULL, FALSE);
  p+= _snprintf(p, 1024, "SELECT * FROM ");
  if (Database)
  {
    p+= _snprintf(p, 1024 - strlen(p), "`%s`.", Database);
  }
  p+= _snprintf(p, 1024 - strlen(p), "%s LIMIT 0", TableName);
  if (MA_SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE)Connection, (SQLHANDLE*)&Stmt) == SQL_ERROR ||
    Stmt->Methods->ExecDirect(Stmt, (SQLCHAR *)StmtStr, SQL_NTS) == SQL_ERROR ||
    Stmt->Methods->Fetch(Stmt) == SQL_ERROR)
  {
    goto end;
  }
  KeyStmt= (MADB_Stmt *)Stmt;
  for (i=0; i < mysql_stmt_field_count(KeyStmt->stmt); i++)
    if (KeyStmt->stmt->fields[i].flags & KeyFlag)
      Count++;
end:
  if (Stmt)
    Stmt->Methods->StmtFree(Stmt, SQL_DROP);
  return Count;
}
int MADB_KeyTypeCount(MADB_Dbc *Connection, char *TableName, int KeyFlag)
{
  int Count= 0;
  unsigned int i;
  char StmtStr[1024];
  char *p= StmtStr;
  char Database[65];
  SQLHSTMT Stmt= NULL;
  MADB_Stmt *KeyStmt;
  
  SQLGetConnectAttr((SQLHDBC)Connection, SQL_ATTR_CURRENT_CATALOG, Database, 65, NULL);
  p+= my_snprintf(p, 1024, "SELECT * FROM ");
  if (Database)
    p+= my_snprintf(p, 1024 - strlen(p), "`%s`.", Database);
  p+= my_snprintf(p, 1024 - strlen(p), "%s LIMIT 0", TableName);
  if (SQLAllocStmt((SQLHDBC)Connection, &Stmt) == SQL_ERROR ||
      SQLPrepare(Stmt, (SQLCHAR *)StmtStr, SQL_NTS) == SQL_ERROR ||
      SQLExecute(Stmt) == SQL_ERROR ||
      SQLFetch(Stmt) == SQL_ERROR)
      goto end;
  KeyStmt= (MADB_Stmt *)Stmt;
  for (i=0; i < mysql_stmt_field_count(KeyStmt->stmt); i++)
    if (KeyStmt->stmt->fields[i].flags & KeyFlag)
      Count++;
end:
  if (Stmt)
    SQLFreeHandle(SQL_HANDLE_STMT, Stmt);
  return Count;
}
Beispiel #5
0
/// Returns the number of columns in each row of the result.
size_t SqlStmt_NumColumns(SqlStmt* self)
{
	if( self )
		return (size_t)mysql_stmt_field_count(self->stmt);
	else
		return 0;
}
Beispiel #6
0
/* call-seq: stmt.fields # => array
 *
 * Returns a list of fields that will be returned by this statement.
 */
static VALUE fields(VALUE self) {
  MYSQL_STMT *stmt;
  MYSQL_FIELD *fields;
  MYSQL_RES *metadata;
  unsigned int field_count;
  unsigned int i;
  VALUE field_list;
  VALUE cMysql2Field;

  Data_Get_Struct(self, MYSQL_STMT, stmt);
  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);

  cMysql2Field = rb_const_get(mMysql2, rb_intern("Field"));

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

    /* FIXME: encoding.  Also, can this return null? */
    field = rb_str_new(fields[i].name, fields[i].name_length);

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

  return field_list;
}
Beispiel #7
0
/* #@ _PROCESS_CALL_RESULT_ */
static void process_call_result (MYSQL *conn, MYSQL_STMT *stmt)
{
int status;
int num_cols;

  /*
   * For each result, check number of columns.  If none, the result is
   * the final status packet and there is nothing to do. Otherwise,
   * fetch the result set.
   */
  do {
    if ((num_cols = mysql_stmt_field_count (stmt)) > 0)
    {
      /* announce whether result set contains parameters or data set */
      if (conn->server_status & SERVER_PS_OUT_PARAMS)
        printf ("OUT/INOUT parameter values:\n");
      else
        printf ("Statement result set values:\n");

      if (process_result_set (stmt, num_cols))
        break; /* some error occurred */
    }

    /* status is -1 = done, 0 = more results, >0 = error */
    status = mysql_stmt_next_result (stmt);
    if (status > 0)
      print_stmt_error (stmt, "Error checking for next result");
  } while (status == 0);
}
MYSQL_RES *MADB_GetDefaultColumnValues(MADB_Stmt *Stmt, MYSQL_FIELD *fields)
{
  DYNAMIC_STRING DynStr;
  unsigned int i;
  MYSQL_RES *result= NULL;
  
  init_dynamic_string(&DynStr, "SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='", 512, 512);
  if (dynstr_append(&DynStr, fields[0].db) ||
      dynstr_append(&DynStr, "' AND TABLE_NAME='") ||
      dynstr_append(&DynStr, fields[0].org_table) ||
      dynstr_append(&DynStr, "' AND COLUMN_NAME IN ("))
    goto error;

  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
  {
    if (dynstr_append(&DynStr, i > 0 ? ",'" : "'") ||
        dynstr_append(&DynStr, fields[i].org_name) ||
        dynstr_append(&DynStr, "'"))
      goto error;
  }
  if (dynstr_append(&DynStr, ") AND COLUMN_DEFAULT IS NOT NULL"))
    goto error;

  LOCK_MARIADB(Stmt->Connection);
  if (mysql_query(Stmt->Connection->mariadb, DynStr.str))
    goto error;
  result= mysql_store_result(Stmt->Connection->mariadb);
  
error:
    UNLOCK_MARIADB(Stmt->Connection);
    dynstr_free(&DynStr);
    return result;
}
Beispiel #9
0
bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount)
{
    if (!m_Mysql)
        return false;

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

        stmt->BindParameters();

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

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

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

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

            m_mStmt->ClearParameters();
            return false;
        }

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

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

            m_mStmt->ClearParameters();
            return false;
        }

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

    }
}
bool MySQLPreparedStatement::execute()
{
    doQuery();
    my_bool    bool_tmp=1;
    mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
    //mysql_stmt_store_result(stmt);
    return (mysql_stmt_field_count(stmt) > 0);
}
Beispiel #11
0
static int dbd_mysql_num_cols(apr_dbd_results_t *res)
{
    if (res->statement) {
        return mysql_stmt_field_count(res->statement);
    }
    else {
        return mysql_num_fields(res->res);
    }
}
Beispiel #12
0
std::vector<int> DBManager::check_jobs() {
	std::vector<int> job_ids;

	char *stmt_str = "SELECT id FROM wkdd_ldp_jobs WHERE status = 'pending' ORDER BY start_time ASC";
	MYSQL_BIND result[1];
	int my_job_id;

	if (mysql_stmt_prepare(m_stmt, stmt_str, strlen(stmt_str)) != 0) {
		print_stmt_error("could not prepare select statement");
		return job_ids;
	}
	
	if (mysql_stmt_field_count(m_stmt) != 1) {
		print_stmt_error("unexpected column count from select");
		return job_ids;
	}
	
	// initialize result column structures
	memset((void *)result, 0, sizeof(result)); // zero the structures
	
	// set up my_id parameter
	result[0].buffer_type = MYSQL_TYPE_LONG;
	result[0].buffer = (void *) &my_job_id;
	result[0].is_unsigned = 0;
	result[0].is_null = 0;
	
	if (mysql_stmt_bind_result(m_stmt, result) != 0) {
		print_stmt_error("could not bind parameters for select");
		return job_ids;
	}
	
	if (mysql_stmt_execute(m_stmt) != 0) {
		print_stmt_error("could not execute select");
		return job_ids;
	}
	
	// fetch result set into client memory; this is optional, but it allows mysql_stmt_num_rows() to be called to determine the number of rows in the result set
	if (mysql_stmt_store_result(m_stmt) != 0) {
		print_stmt_error("could not buffer result set");
		return job_ids;
	}
	
	while (mysql_stmt_fetch(m_stmt) == 0) {  // fetch each row
		// store into vector
		job_ids.push_back(my_job_id);
	}
	
	// deallocate result set
	mysql_stmt_free_result(m_stmt);
	
	return job_ids;
}
bool MySqlConnection::_Query(PreparedStmt* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount)
{
	if (!m_Mysql)
		return false;

	uint32 index = stmt->m_stmtIndex;
	{
		MySqlPreparedStmt* pStmt = GetPreparedStatement(index);
		pStmt->m_pPrepareStmt = stmt;     // Cross reference them for debug output
		stmt->m_pStmt = pStmt;     /// @todo Cleaner way

		stmt->bindParameters();

		MYSQL_STMT* msql_STMT = pStmt->GetMySqlStmt();
		MYSQL_BIND* msql_BIND = pStmt->GetBind();

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

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

			pStmt->clearParameters();
			return false;
		}

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

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

			pStmt->clearParameters();
			return false;
		}
		
		pStmt->clearParameters();

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

		return true;
	}
}
Beispiel #14
0
int wb_dbms_query::prepare(const char *query, int nResult, int nParam)
{
    int rc = 0;
    static const char *method = "prepare";

    if (!m_prepared) {

        m_query = query;

        m_stmt = mysql_stmt_init(m_db->con());
        if (m_stmt == 0) error(method, "mysql_stmt_init");

        rc = mysql_stmt_prepare(m_stmt, query, strlen(query));
        if (rc) error(rc, method, "mysql_stmt_prepare");

        m_nParam  = mysql_stmt_param_count(m_stmt);
        m_nResult = mysql_stmt_field_count(m_stmt);

        assert((m_nParam == nParam) && (m_nResult == nResult));

        if (m_nParam > 0) {
            m_param.bind    = (MYSQL_BIND *)calloc(m_nParam,  sizeof(MYSQL_BIND));
            m_param.length  = (size_t *)calloc(m_nParam,  sizeof(size_t));
            m_param.is_null = (my_bool *)calloc(m_nParam,  sizeof(my_bool));

            for (int i = m_nParam - 1; i >= 0; i--) {
                m_param.bind[i].is_null = &m_param.is_null[i];
                m_param.bind[i].length  = (long unsigned int *)&m_param.length[i];
            }
        }

        if (m_nResult > 0) {
            m_result.bind    = (MYSQL_BIND *)calloc(m_nResult, sizeof(MYSQL_BIND));
            m_result.length  = (size_t *)calloc(m_nParam,  sizeof(size_t));
            m_result.is_null = (my_bool *)calloc(m_nResult, sizeof(my_bool));

            for (int i = m_nResult - 1; i >= 0; i--) {
                m_result.bind[i].is_null = &m_result.is_null[i];
                m_result.bind[i].length  = (long unsigned int *)&m_result.length[i];
            }
        }

        m_prepared = true;
    }

    return rc;
}
Beispiel #15
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;
}
MYSQL_RES *MADB_GetDefaultColumnValues(MADB_Stmt *Stmt, MYSQL_FIELD *fields)
{
  MADB_DynString DynStr;
  unsigned int i;
  MYSQL_RES *result= NULL;
  
  MADB_InitDynamicString(&DynStr, "SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='", 512, 512);
  if (MADB_DynstrAppend(&DynStr, fields[0].db) ||
      MADB_DynstrAppend(&DynStr, "' AND TABLE_NAME='") ||
      MADB_DynstrAppend(&DynStr, fields[0].org_table) ||
      MADB_DynstrAppend(&DynStr, "' AND COLUMN_NAME IN ("))
    goto error;

  for (i=0; i < mysql_stmt_field_count(Stmt->stmt); i++)
  {
    MADB_DescRecord *Rec= MADB_DescGetInternalRecord(Stmt->Ard, i, MADB_DESC_READ);

    if (!Rec->inUse || MADB_ColumnIgnoredInAllRows(Stmt->Ard, Rec) == TRUE)
    {
      continue;
    }
    if (MADB_DynstrAppend(&DynStr, i > 0 ? ",'" : "'") ||
      MADB_DynstrAppend(&DynStr, fields[i].org_name) ||
      MADB_DynstrAppend(&DynStr, "'"))
    {
      goto error;
    }
  }
  if (MADB_DynstrAppend(&DynStr, ") AND COLUMN_DEFAULT IS NOT NULL"))
    goto error;

  LOCK_MARIADB(Stmt->Connection);
  if (mysql_query(Stmt->Connection->mariadb, DynStr.str))
    goto error;
  result= mysql_store_result(Stmt->Connection->mariadb);
  
error:
    UNLOCK_MARIADB(Stmt->Connection);
    MADB_DynstrFree(&DynStr);
    return result;
}
Beispiel #17
0
void
handle_query(ETERM *cmd)
{
  ETERM *query, *resp;
  MYSQL_STMT *handle;
  char *q;

  query = erl_element(2, cmd);
  q = erl_iolist_to_string(query);
  erl_free_term(query);

  logmsg("INFO: got query: %s", q);

  handle = mysql_stmt_init(&dbh);
  if (mysql_stmt_prepare(handle, q, strlen(q))) {
    resp = erl_format("{error, {mysql_error, ~i, ~s}}",
                      mysql_stmt_errno(handle), mysql_stmt_error(handle));
  } else if (mysql_stmt_execute(handle)) {
    resp = erl_format("{error, {mysql_error, ~i, ~s}}",
                      mysql_stmt_errno(handle), mysql_stmt_error(handle));
  } else {
    set_mysql_results(handle);
    if (results) {
      resp = handle_mysql_result();
    } else {
      if (mysql_stmt_field_count(handle) == 0) {
        resp = erl_format("{updated, ~i}", numrows);
      } else {
        resp = erl_format("{error, {mysql_error, ~i, ~s}}",
                          mysql_stmt_errno(handle), mysql_stmt_error(handle));
      }
    }
  }

  erl_free(q);
  mysql_stmt_close(handle);

  write_msg(resp);
  erl_free_term(resp);
}
Beispiel #18
0
static MYSQL_STMT *
table_mysql_prepare_stmt(MYSQL *_db, const char *query, unsigned long nparams,
    unsigned int nfields)
{
	MYSQL_STMT	*stmt;

	if ((stmt = mysql_stmt_init(_db)) == NULL) {
		log_warnx("warn: table-mysql: mysql_stmt_init: %s",
		    mysql_error(_db));
		goto end;
	}
	if (mysql_stmt_prepare(stmt, query, strlen(query))) {
		log_warnx("warn: table-mysql: mysql_stmt_prepare: %s",
		    mysql_stmt_error(stmt));
		goto end;
	}
	if (mysql_stmt_param_count(stmt) != nparams) {
		log_warnx("warn: table-mysql: wrong number of params for %s", query);
		goto end;
	}
	if (mysql_stmt_field_count(stmt) != nfields) {
		log_warnx("warn: table-mysql: wrong number of columns in resultset");
		goto end;
	}
	if (mysql_stmt_bind_result(stmt, results)) {
		log_warnx("warn: table-mysql: mysql_stmt_bind_results: %s",
		    mysql_stmt_error(stmt));
		goto end;
	}

	return (stmt);

    end:
	if (stmt)
		mysql_stmt_close(stmt);

	return (NULL);
}
Beispiel #19
0
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;
}
Beispiel #20
0
void
handle_select_count(ETERM *msg)
{
  ETERM *query, *resp;
  MYSQL_STMT *handle;
  char *q;

  query = erl_element(2, msg);
  q = erl_iolist_to_string(query);
  erl_free_term(query);

  logmsg("INFO: Got select count for: %s", q);

  handle = mysql_stmt_init(&dbh);
  if (mysql_stmt_prepare(handle, q, strlen(q))) {
    resp = erl_format("{error, {mysql_error, ~i, ~s}}",
                      mysql_stmt_errno(handle), mysql_stmt_error(handle));
  } else if (mysql_stmt_execute(handle)) {
    resp = erl_format("{error, {mysql_error, ~i, ~s}}",
                      mysql_stmt_errno(handle), mysql_stmt_error(handle));
  } else {
    set_mysql_results(handle);
    if (results) {
      resp = erl_format("{ok, ~i}", mysql_stmt_affected_rows(handle));
    } else if (mysql_stmt_field_count(handle) == 0) {
      resp = erl_format("{ok, ~i}", mysql_stmt_affected_rows(handle));
    } else {
      resp = erl_format("{error, {mysql_error, ~i, ~s}}",
                        mysql_stmt_errno(handle), mysql_stmt_error(handle));
    }
  }
  erl_free(q);

  write_msg(resp);
  erl_free_term(resp);
}
Beispiel #21
0
int test_sp_params(MYSQL *mysql)
{
  int i, rc;
  MYSQL_STMT *stmt;
  int a[] = {10,20,30};
  MYSQL_BIND bind[3];
  char *stmtstr= "CALL P1(?,?,?)";
  char res[3][20];

  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
  check_mysql_rc(rc, mysql);

  rc= mysql_query(mysql, "CREATE PROCEDURE p1(OUT p_out VARCHAR(19), IN p_in INT, INOUT p_inout INT)" 
                         "BEGIN "
                          "  SET p_in = 300, p_out := 'This is OUT param', p_inout = 200; "
                          "  SELECT p_inout, p_in, substring(p_out, 9);"
                         "END");
  check_mysql_rc(rc, mysql);

  stmt= mysql_stmt_init(mysql);
  check_mysql_rc(rc, mysql);

  rc= mysql_stmt_prepare(stmt, stmtstr, strlen(stmtstr));
  check_stmt_rc(rc, stmt);

  FAIL_IF(mysql_stmt_param_count(stmt) != 3, "expected param_count=3");

  memset(bind, 0, sizeof(MYSQL_BIND) * 3);
  for (i=0; i < 3; i++)
  {
    bind[i].buffer= &a[i];
    bind[i].buffer_type= MYSQL_TYPE_LONG;
  }
  bind[0].buffer_type= MYSQL_TYPE_NULL;
  rc= mysql_stmt_bind_param(stmt, bind);
  check_stmt_rc(rc, stmt);

  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);

  memset(res, 0, 60);

  memset(bind, 0, sizeof(MYSQL_BIND) * 3);
  for (i=0; i < 3; i++)
  {
    bind[i].buffer_type= MYSQL_TYPE_STRING;
    bind[i].buffer_length= 20;
    bind[i].buffer= res[i];
  }

  do {
    if (mysql->server_status & SERVER_PS_OUT_PARAMS)
    {
      diag("out param result set");
      FAIL_IF(mysql_stmt_field_count(stmt) != 2, "expected 2 columns");
      FAIL_IF(strcmp(stmt->fields[0].org_name, "p_out") != 0, "wrong field name");
      FAIL_IF(strcmp(stmt->fields[1].org_name, "p_inout") != 0, "wrong field name");
      rc= mysql_stmt_bind_result(stmt, bind);
      check_stmt_rc(rc, stmt);
      rc= mysql_stmt_fetch(stmt);
      check_stmt_rc(rc, stmt);
      FAIL_IF(strcmp(res[0],"This is OUT param") != 0, "comparison failed");
      FAIL_IF(strcmp(res[1],"200") != 0, "comparison failed");
    }
    else
    if (mysql_stmt_field_count(stmt))
    {
      diag("sp result set");
      FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 columns");
      rc= mysql_stmt_bind_result(stmt, bind);
      check_stmt_rc(rc, stmt);
      rc= mysql_stmt_fetch(stmt);
      check_stmt_rc(rc, stmt);
      FAIL_IF(strcmp(res[0],"200") != 0, "comparison failed");
      FAIL_IF(strcmp(res[1],"300") != 0, "comparison failed");
      FAIL_IF(strcmp(res[2],"OUT param") != 0, "comparison failed");

    }
  } while (mysql_stmt_next_result(stmt) == 0);

  rc= mysql_stmt_close(stmt);
  return OK;
}
Beispiel #22
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;
}
Beispiel #23
0
/* call-seq: stmt.field_count # => 2
 *
 * Returns the number of fields the prepared statement returns.
 */
static VALUE field_count(VALUE self) {
  MYSQL_STMT *stmt;
  Data_Get_Struct(self, MYSQL_STMT, stmt);

  return UINT2NUM(mysql_stmt_field_count(stmt));
}
Beispiel #24
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);
}
Beispiel #25
0
/*==========================================
 * ステートメント結果の列数を返す
 *------------------------------------------
 */
int sqldbs_stmt_field_count(struct sqldbs_stmt *st)
{
	nullpo_retr(-1, st);

	return (int)mysql_stmt_field_count(st->stmt);
}
Beispiel #26
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;
}
Beispiel #27
0
 size_t mysql_stmt_resultset::column_count() const
 {
     return mysql_stmt_field_count(stmt_);
 }
Beispiel #28
0
DBJob DBManager::get_job(const int& id) {
	DBJob data;

	char *stmt_str = "SELECT term, type FROM wkdd_ldp_jobs WHERE id = ?";
	MYSQL_BIND param[1];
	MYSQL_BIND result[2];
	int my_job_id;
	int my_type;
	char my_term[2000];
	unsigned long my_term_length;

	if (mysql_stmt_prepare(m_stmt, stmt_str, strlen(stmt_str)) != 0) {
		print_stmt_error("could not prepare select statement");
		return data;
	}
	
	if (mysql_stmt_field_count(m_stmt) != 2) {
		print_stmt_error("unexpected column count from select");
		return data;
	}
	
	// initialize result column structures
	memset((void *)param, 0, sizeof(param));
	memset((void *)result, 0, sizeof(result)); // zero the structures
	
	// set up my_id parameter
	param[0].buffer_type = MYSQL_TYPE_LONG;
	param[0].buffer = (void *) &my_job_id;
	param[0].is_unsigned = 0;
	param[0].is_null = 0;
	
	// set up my_term parameter
	result[0].buffer_type = MYSQL_TYPE_STRING;
	result[0].buffer = (void *) &my_term;
	result[0].buffer_length = sizeof(my_term);
	result[0].length = &my_term_length;
	result[0].is_null = 0;
	
	// set up my_type parameter
	result[1].buffer_type = MYSQL_TYPE_LONG;
	result[1].buffer = (void *) &my_type;
	result[1].is_unsigned = 0;
	result[1].is_null = 0;
	
	if (mysql_stmt_bind_param(m_stmt, param) != 0) {
		print_stmt_error("could not bind parameters for select");
		return data;
	}
	
	if (mysql_stmt_bind_result(m_stmt, result) != 0) {
		print_stmt_error("could not bind parameters for select");
		return data;
	}
	
	// set variable
	my_job_id = id;
	
	if (mysql_stmt_execute(m_stmt) != 0) {
		print_stmt_error("could not execute select");
		return data;
	}
	
	// fetch result set into client memory; this is optional, but it allows mysql_stmt_num_rows() to be called to determine the number of rows in the result set
	if (mysql_stmt_store_result(m_stmt) != 0) {
		print_stmt_error("could not buffer result set");
		return data;
	}
	
	mysql_stmt_fetch(m_stmt);  // fetch the single result
	data = DBJob(my_term, my_type);
	
	// deallocate result set
	mysql_stmt_free_result(m_stmt);
	
	return data;
}
Beispiel #29
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);
}
Beispiel #30
0
static int test_multi_result(MYSQL *mysql)
{
  MYSQL_STMT *stmt;
  MYSQL_BIND ps_params[3];  /* input parameter buffers */
  MYSQL_BIND rs_bind[3];
  int        int_data[3];   /* input/output values */
  my_bool    is_null[3];    /* output value nullability */
  int        rc, i;

  /* set up stored procedure */
  rc = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
  check_mysql_rc(rc, mysql);

  rc = mysql_query(mysql,
      "CREATE PROCEDURE p1("
      "  IN p_in INT, "
      "  OUT p_out INT, "
      "  INOUT p_inout INT) "
      "BEGIN "
      "  SELECT p_in, p_out, p_inout; "
      "  SET p_in = 100, p_out = 200, p_inout = 300; "
      "  SELECT p_in, p_out, p_inout; "
      "END");
  check_mysql_rc(rc, mysql);

  /* initialize and prepare CALL statement with parameter placeholders */
  stmt = mysql_stmt_init(mysql);
  if (!stmt)
  {
    diag("Could not initialize statement");
    exit(1);
  }
  rc = mysql_stmt_prepare(stmt, "CALL p1(?, ?, ?)", 16);
  check_stmt_rc(rc, stmt);

  /* initialize parameters: p_in, p_out, p_inout (all INT) */
  memset(ps_params, 0, sizeof (ps_params));

  ps_params[0].buffer_type = MYSQL_TYPE_LONG;
  ps_params[0].buffer = (char *) &int_data[0];
  ps_params[0].length = 0;
  ps_params[0].is_null = 0;

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

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

  /* bind parameters */
  rc = mysql_stmt_bind_param(stmt, ps_params);
  check_stmt_rc(rc, stmt);

  /* assign values to parameters and execute statement */
  int_data[0]= 10;  /* p_in */
  int_data[1]= 20;  /* p_out */
  int_data[2]= 30;  /* p_inout */

  rc = mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);

  FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 fields");

  memset(rs_bind, 0, sizeof (MYSQL_BIND) * 3);
  for (i=0; i < 3; i++)
  {
    rs_bind[i].buffer = (char *) &(int_data[i]);
    rs_bind[i].buffer_length = sizeof (int_data);
    rs_bind[i].buffer_type = MYSQL_TYPE_LONG;
    rs_bind[i].is_null = &is_null[i];
  }
  rc= mysql_stmt_bind_result(stmt, rs_bind);
  check_stmt_rc(rc, stmt);

  rc= mysql_stmt_fetch(stmt);
  check_stmt_rc(rc, stmt);
 
  FAIL_IF(int_data[0] != 10 || int_data[1] != 20 || int_data[2] != 30,
          "expected 10 20 30"); 
  rc= mysql_stmt_next_result(stmt);
  check_stmt_rc(rc, stmt);
  rc= mysql_stmt_bind_result(stmt, rs_bind);

  rc= mysql_stmt_fetch(stmt);
  FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 fields");
  FAIL_IF(int_data[0] != 100 || int_data[1] != 200 || int_data[2] != 300,
          "expected 100 200 300"); 

  FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results");
  rc= mysql_stmt_bind_result(stmt, rs_bind);

  rc= mysql_stmt_fetch(stmt);
  FAIL_IF(mysql_stmt_field_count(stmt) != 2, "expected 2 fields");
  FAIL_IF(int_data[0] != 200 || int_data[1] != 300,
          "expected 100 200 300"); 
  
  FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results");
  FAIL_IF(mysql_stmt_field_count(stmt) != 0, "expected 0 fields");

  rc= mysql_stmt_close(stmt);
  return OK;
}