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

  statement = GNUNET_MYSQL_statement_get_stmt (plugin->mc,
					       plugin->get_all_keys);
  if (statement == NULL)
  {
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  if (mysql_stmt_prepare (statement, query, strlen (query)))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
                     _("Failed to prepare statement `%s'\n"), query);
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  GNUNET_assert (proc != NULL);
  if (mysql_stmt_execute (statement))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("`%s' for `%s' failed at %s:%d with error: %s\n"),
                "mysql_stmt_execute", query, __FILE__, __LINE__,
                mysql_stmt_error (statement));
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  memset (cbind, 0, sizeof (cbind));
  cbind[0].buffer_type = MYSQL_TYPE_BLOB;
  cbind[0].buffer = &key;
  cbind[0].buffer_length = sizeof (key);
  cbind[0].length = &length;
  cbind[0].is_unsigned = GNUNET_NO;
  if (mysql_stmt_bind_result (statement, cbind))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("`%s' failed at %s:%d with error: %s\n"),
                "mysql_stmt_bind_result", __FILE__, __LINE__,
                mysql_stmt_error (statement));
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  while (0 == (ret = mysql_stmt_fetch (statement)))
  {
    if (sizeof (struct GNUNET_HashCode) == length)
      proc (proc_cls, &key, 1);
  }
  if (ret != MYSQL_NO_DATA)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("`%s' failed at %s:%d with error: %s\n"),
		     "mysql_stmt_fetch", __FILE__, __LINE__,
		     mysql_stmt_error (statement));
    GNUNET_MYSQL_statements_invalidate (plugin->mc);
    return;
  }
  mysql_stmt_reset (statement);
}
예제 #2
0
void readConfigData() {
	int i, k, flag;
	char sql[1024];
	
	sprintf(sql, "select configID, Session_sessionID as sessionID, nonPropID, moduleName, paramIndex, paramName, paramValue, comment from Config where Session_sessionID=%d;", sessionID);

	MYSQL_STMT *stmt;
	MYSQL_BIND bind[8];
	my_bool error[8];
	
	struct config cbuffer;

	//fprintf(stderr , "forming query..");
	if( (stmt = mysql_stmt_init(&mysql))== (MYSQL_STMT *) NULL) {
		fprintf(stderr,"error in mysql_stmt_init: %s\n", mysql_stmt_error(stmt));
		exit(1);
	}

	flag = mysql_stmt_prepare(stmt, sql, strlen(sql));
	if(flag!=0) {
		fprintf(stderr,"error in mysql_stmt_prepare: %s\n", mysql_stmt_error(stmt));
		exit(1);
	}

	memset(bind, 0, sizeof(bind));

	i = 0;
	bind[i].buffer_type = FIELD_TYPE_LONG;
	bind[i].buffer = &(cbuffer.configID);
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_LONG;
	bind[i].buffer = &(cbuffer.sessionID);
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_LONG;
	bind[i].buffer = &(cbuffer.propID);
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_STRING;
	bind[i].buffer = &(cbuffer.moduleName);
	bind[i].buffer_length = 256;
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_LONG;
	bind[i].buffer = &(cbuffer.paramIndex);
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_STRING;
	bind[i].buffer = &(cbuffer.paramName);
	bind[i].buffer_length = 256;
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_STRING;
	bind[i].buffer = &(cbuffer.paramValue);
	bind[i].buffer_length = 256;
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_STRING;
	bind[i].buffer = &(cbuffer.comment);
	bind[i].buffer_length = 256;
	bind[i].error = &error[i];
	
	flag = mysql_stmt_bind_result(stmt, bind);
	if(flag!=0) {
		fprintf(stderr, "error in mysql_stmt_bind_result: %s", mysql_stmt_error(stmt));
		exit(1);
	}

	//fprintf(stderr,"executing query..");
	flag = mysql_stmt_execute(stmt);
	if(flag!=0) {
		fprintf(stderr, "error in mysql_stmt_execute: %s", mysql_stmt_error(stmt));
		exit(1);
	}

	//fprintf(stderr,"executed query..");
	
	flag = mysql_stmt_store_result(stmt);
	if(flag!=0) {
		fprintf(stderr, "error in mysql_stmt_store_result: %s", mysql_stmt_error(stmt));
		exit(1);
	}
	
	//fprintf(stderr,"stored result..");
	config_data_length = mysql_stmt_num_rows(stmt);
	//fprintf(stderr,"reading %d config_data..", config_data_length);

	i = 0;
	flag = 0;
	while(flag==0) {
		flag = mysql_stmt_fetch(stmt);
		if(flag!=0) {
			if(flag == MYSQL_NO_DATA) {
				//fprintf(stderr,"done fetching data..");
				flag = 1;
			}
			else if(flag == MYSQL_DATA_TRUNCATED) {
				flag = 1;
				for(k=0; k<10; k++) {
					if(error[k]!=0) printf("fetching data truncated in parameter %d\n",k);
				}
			}
			else {
				fprintf(stderr, "error in mysql_stmt_fetch: %s\n", mysql_stmt_error(stmt));
				exit(1);
			}
		}
	
		if(flag==0) {
			memcpy(&(config_data[i]), &(cbuffer), sizeof(struct config));
			i++;
		}
	}
	
	mysql_stmt_close(stmt);
	//fprintf(stderr,"done\n");

	/*for(i=0; i < config_data_length; i++) {
		printf("%d %d %d %s %d %s %s %s\n",
			config_data[i].configID,
			config_data[i].sessionID,
			config_data[i].propID,
			config_data[i].moduleName,
			config_data[i].paramIndex,
			config_data[i].paramName,
			config_data[i].paramValue,
			config_data[i].comment);
	}*/
}
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;
}
예제 #4
0
bool database::get_device_firmware_update_url(
    int DeviceID, TDS_FirmwareUpdateParams *params,
    TSD_FirmwareUpdate_UrlResult *url) {
  MYSQL_STMT *stmt;
  MYSQL_BIND pbind[6];
  memset(pbind, 0, sizeof(pbind));
  memset(url, 0, sizeof(TSD_FirmwareUpdate_UrlResult));

  bool result = false;

  pbind[0].buffer_type = MYSQL_TYPE_LONG;
  pbind[0].buffer = (char *)&DeviceID;

  pbind[1].buffer_type = MYSQL_TYPE_TINY;
  pbind[1].buffer = (char *)&params->Platform;

  pbind[2].buffer_type = MYSQL_TYPE_LONG;
  pbind[2].buffer = (char *)&params->Param1;

  pbind[3].buffer_type = MYSQL_TYPE_LONG;
  pbind[3].buffer = (char *)&params->Param2;

  pbind[4].buffer_type = MYSQL_TYPE_LONG;
  pbind[4].buffer = (char *)&params->Param3;

  pbind[5].buffer_type = MYSQL_TYPE_LONG;
  pbind[5].buffer = (char *)&params->Param4;

  const char sql1[] = "SET @p0=?, @p1=?, @p2=?, @p3=?, @p4=?, @p5=?";
  const char sql2[] =
      "CALL `supla_get_device_firmware_url`(@p0, @p1, @p2, @p3, @p4, @p5, @p6, "
      "@p7, @p8, @p9)";
  const char sql3[] =
      "SELECT @p6 AS `protocols`, @p7 AS `host`, @p8 AS `port`, @p9 AS `path`";

  char q_executed = 0;

  if (stmt_execute((void **)&stmt, sql1, pbind, 6, true)) {
    mysql_stmt_close((MYSQL_STMT *)stmt);
    q_executed++;
  }

  if (stmt_execute((void **)&stmt, sql2, NULL, 0, true)) {
    mysql_stmt_close((MYSQL_STMT *)stmt);
    q_executed++;
  }

  if (q_executed == 2 && stmt_execute((void **)&stmt, sql3, NULL, 0, true)) {
    mysql_stmt_store_result(stmt);

    if (mysql_stmt_num_rows(stmt) > 0) {
      MYSQL_BIND rbind[4];
      memset(rbind, 0, sizeof(rbind));

      unsigned long host_size;
      my_bool host_is_null;

      unsigned long path_size;
      my_bool path_is_null;

      rbind[0].buffer_type = MYSQL_TYPE_TINY;
      rbind[0].buffer = (char *)&url->url.available_protocols;

      rbind[1].buffer_type = MYSQL_TYPE_STRING;
      rbind[1].buffer = url->url.host;
      rbind[1].is_null = &host_is_null;
      rbind[1].buffer_length = SUPLA_URL_HOST_MAXSIZE;
      rbind[1].length = &host_size;

      rbind[2].buffer_type = MYSQL_TYPE_LONG;
      rbind[2].buffer = (char *)&url->url.port;

      rbind[3].buffer_type = MYSQL_TYPE_STRING;
      rbind[3].buffer = url->url.path;
      rbind[3].is_null = &path_is_null;
      rbind[3].buffer_length = SUPLA_URL_PATH_MAXSIZE;
      rbind[3].length = &path_size;

      if (mysql_stmt_bind_result(stmt, rbind)) {
        supla_log(LOG_ERR, "MySQL - stmt bind error - %s",
                  mysql_stmt_error(stmt));

      } else if (mysql_stmt_fetch(stmt) == 0) {
        if (host_is_null || host_size == 0 ||
            host_size >= SUPLA_URL_HOST_MAXSIZE)
          url->url.host[0] = 0;

        if (path_is_null || path_size == 0 ||
            path_size >= SUPLA_URL_PATH_MAXSIZE)
          url->url.path[0] = 0;

        if (url->url.available_protocols > 0 &&
            strnlen(url->url.host, SUPLA_URL_HOST_MAXSIZE) > 0 &&
            strnlen(url->url.path, SUPLA_URL_PATH_MAXSIZE) > 0)
          url->exists = 1;

        result = true;
      }
    }

    mysql_stmt_free_result(stmt);
    mysql_stmt_close(stmt);
  }

  return result;
}
예제 #5
0
void database::get_device_channels(int DeviceID,
                                   supla_device_channels *channels) {
  MYSQL_STMT *stmt;
  const char sql[] =
      "SELECT `type`, `func`, `param1`, `param2`, `param3`, `channel_number`, "
      "`id`, `hidden` FROM `supla_dev_channel` WHERE `iodevice_id` = ? ORDER "
      "BY `channel_number`";

  MYSQL_BIND pbind[1];
  memset(pbind, 0, sizeof(pbind));

  pbind[0].buffer_type = MYSQL_TYPE_LONG;
  pbind[0].buffer = (char *)&DeviceID;

  if (stmt_execute((void **)&stmt, sql, pbind, 1, true)) {
    my_bool is_null[5];

    MYSQL_BIND rbind[8];
    memset(rbind, 0, sizeof(rbind));

    int type, func, param1, param2, param3, number, id, hidden;

    rbind[0].buffer_type = MYSQL_TYPE_LONG;
    rbind[0].buffer = (char *)&type;
    rbind[0].is_null = &is_null[0];

    rbind[1].buffer_type = MYSQL_TYPE_LONG;
    rbind[1].buffer = (char *)&func;
    rbind[1].is_null = &is_null[1];

    rbind[2].buffer_type = MYSQL_TYPE_LONG;
    rbind[2].buffer = (char *)&param1;
    rbind[2].is_null = &is_null[2];

    rbind[3].buffer_type = MYSQL_TYPE_LONG;
    rbind[3].buffer = (char *)&param2;
    rbind[3].is_null = &is_null[3];

    rbind[4].buffer_type = MYSQL_TYPE_LONG;
    rbind[4].buffer = (char *)&param3;
    rbind[4].is_null = &is_null[4];

    rbind[5].buffer_type = MYSQL_TYPE_LONG;
    rbind[5].buffer = (char *)&number;

    rbind[6].buffer_type = MYSQL_TYPE_LONG;
    rbind[6].buffer = (char *)&id;

    rbind[7].buffer_type = MYSQL_TYPE_LONG;
    rbind[7].buffer = (char *)&hidden;

    if (mysql_stmt_bind_result(stmt, rbind)) {
      supla_log(LOG_ERR, "MySQL - stmt bind error - %s",
                mysql_stmt_error(stmt));
    } else {
      mysql_stmt_store_result(stmt);

      if (mysql_stmt_num_rows(stmt) > 0) {
        while (!mysql_stmt_fetch(stmt)) {
          if (is_null[0] == true) type = 0;
          if (is_null[1] == true) func = 0;
          if (is_null[2] == true) param1 = 0;
          if (is_null[3] == true) param2 = 0;
          if (is_null[4] == true) param3 = 0;

          channels->add_channel(id, number, type, func, param1, param2, param3,
                                hidden > 0);
        }
      }
    }

    mysql_stmt_close(stmt);
  }
}
예제 #6
0
파일: mysql_dumper.c 프로젝트: seung/ribs2
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;
}
예제 #7
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 = req::calloc(b->buffer_length, 1);
    }
  }
  mysql_free_result(res);

  return !mysql_stmt_bind_result(stmt, m_vars);
}
예제 #8
0
/* #@ _PROCESS_RESULT_SET_ */
static int process_result_set (MYSQL_STMT *stmt, int num_cols)
{
MYSQL_FIELD *fields;     /* pointer to result set metadata */
MYSQL_BIND  *params;     /* pointer to output buffers */
int         int_data[3];  /* output parameter values */
my_bool     is_null[3];  /* output parameter nullability */
int         i;

  MYSQL_RES *metadata = mysql_stmt_result_metadata (stmt);
  if (metadata == NULL)
  {
    print_stmt_error (stmt, "Cannot get statement result metadata");
    return (1);
  }

  fields = mysql_fetch_fields (metadata);

  params = (MYSQL_BIND *) malloc (sizeof (MYSQL_BIND) * num_cols);
  if (!params)
  {
    print_stmt_error (NULL, "Cannot allocate output parameters");
    return (1);
  }

  /* initialize parameter structures and bind to statement */
  memset (params, 0, sizeof (MYSQL_BIND) * num_cols);

  for (i = 0; i < num_cols; ++i)
  {
    params[i].buffer_type = fields[i].type;
    params[i].is_null = &is_null[i];

    if (fields[i].type != MYSQL_TYPE_LONG)
    {
      fprintf (stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
      return (1);
    }
    params[i].buffer = (char *) &(int_data[i]);
    params[i].buffer_length = sizeof (int_data);
  }
  mysql_free_result (metadata); /* done with metadata, free it */

  if (mysql_stmt_bind_result (stmt, params))
  {
    print_stmt_error (stmt, "Cannot bind result to output buffers");
    return (1);
  }

  /* retrieve result set rows, display contents */
  while (1)
  {
    int status = mysql_stmt_fetch (stmt);
    if (status == 1 || status == MYSQL_NO_DATA)
      break;  /* no more rows */

    for (i = 0; i < num_cols; ++i)
    {
      printf (" val[%d] = ", i+1);
      if (params[i].buffer_type != MYSQL_TYPE_LONG)
        printf ("  unexpected type (%d)\n", params[i].buffer_type);
      else
      {
        if (*params[i].is_null)
          printf ("NULL;");
        else
          printf ("%ld;", (long) *((int *) params[i].buffer));
      }
    }
    printf ("\n");
  }

  free (params); /* done with output buffers, free them */
  return (0);
}
예제 #9
0
파일: mysql.c 프로젝트: nicboul/xia
int_vector *mysql_exec(struct stmt_singleton *stmt)
{
	journal_strace("mysql_exec");

	int ret, num_row, itr;
	int_vector *data_vtr;

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

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

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

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

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

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

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

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

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

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

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

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

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

	for (itr = VECTOR_IDX_BEGIN; !mysql_stmt_fetch(mysql_stmt); itr++) {
		data_vtr[itr] = buf;
		printf("MySQL returned value %i\n", buf);
	}
	
	data_vtr[VECTOR_IDX_SIZE] = VECTOR_SET_SIZE(itr);
	
	return data_vtr;	
}
예제 #10
0
static int
statement_fetch_impl (lua_State * L, statement_t * statement, /* {{{ */
		      int named_columns)
{
  int column_count, fetch_result_ok;
  MYSQL_BIND *bind = NULL;
  unsigned long *real_length = NULL;
  const char *error_message = NULL;

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

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

  column_count = mysql_num_fields (statement->metadata);

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

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

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

      fields = mysql_fetch_fields (statement->metadata);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

cleanup:
  free (real_length);

  if (bind)
    {
      int i;

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

      free (bind);
    }

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

  return 1;
} /* }}} */
예제 #11
0
static int st_fetch(void *key, size_t klen, void **value, size_t *vlen, void *priv)
{
    storage_mysql_t *st = (storage_mysql_t *)priv;

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


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

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

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

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

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

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

    mysql_stmt_bind_result(dbc->select_stmt, &obnd);

    int rc = mysql_stmt_fetch(dbc->select_stmt);

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

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

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

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

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

    SPIN_UNLOCK(&dbc->lock);

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

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

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

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;

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

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

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

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

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

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

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

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

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

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


cleanup:
  free (real_length);

  if (statement->bind)
    {
      int i;

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

      free (statement->bind);
    }


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

  return 1;
} /* }}} */
예제 #13
0
static int test_simple_prepare(MYSQL *my)
{
  MYSQL *mysql= mysql_init(NULL);
  MYSQL_STMT *stmt;
  MYSQL_BIND bind[2];
  int val1= 17;
  char *val2= "MariaDB";
  char buffer[100];
  char *stmt_create= "CREATE TABLE t2 (a int, b varchar(200), c int)";
  char *stmt_insert= "INSERT INTO t2 VALUES (1, ?, ?)";
  int rc;

  FAIL_IF(!mysql, "mysql_init() failed");

  mysql_options(mysql, MYSQL_DATABASE_DRIVER, "sqlite");

  FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, (schema) ? schema : "test",
                         port, socketname, 0), mysql_error(my));

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
  check_mysql_rc(rc, mysql);

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, stmt_create, strlen(stmt_create));
  FAIL_IF(stmt->stmt_id != 1, "expected stmt_id=1");
  check_stmt_rc(rc, stmt);

  FAIL_IF(mysql_stmt_param_count(stmt), "Expected param_count= 0");

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

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, stmt_insert, strlen(stmt_insert));
  FAIL_IF(stmt->stmt_id != 2, "expected stmt_id=2");
  check_stmt_rc(rc, stmt);

  FAIL_IF(mysql_stmt_param_count(stmt) != 2, "Expected 2 parameters");

  mysql_stmt_close(stmt);

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, "CREATE xxxx (a int)", 50);
  FAIL_IF(rc == 0, "error expected");
  mysql_stmt_close(stmt);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
  check_mysql_rc(rc, mysql);
  rc= mysql_query(mysql, "CREATE TABLE t2 (a int, b varchar(20))");
  check_mysql_rc(rc, mysql);

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, "INSERT INTO t2 VALUES(?,?)", 50);
  check_stmt_rc(rc, stmt);

  memset(bind, 0, sizeof(MYSQL_BIND) * 2);
  bind[0].buffer_type= MYSQL_TYPE_LONG;
  bind[0].buffer= &val1;

  bind[1].buffer_type= MYSQL_TYPE_STRING;
  bind[1].buffer= val2;
  bind[1].buffer_length= strlen(val2);

  rc= mysql_stmt_bind_param(stmt, bind);
  check_stmt_rc(rc, stmt);

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

  val1++;

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

  bind[1].buffer= buffer;

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, "SELECT a,b FROM t2", 50);
  check_stmt_rc(rc, stmt);

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


  mysql_stmt_fetch(stmt);
  FAIL_IF(val1 != 17, "expected value=17");

  mysql_stmt_fetch(stmt);
  FAIL_IF(val1 != 18, "expected value=18");

  rc= mysql_stmt_fetch(stmt);
  FAIL_IF(rc != MYSQL_NO_DATA, "Expected eof");
  mysql_stmt_close(stmt);
  mysql_close(mysql);

  return OK;
}
예제 #14
0
bool
DbUtil::runQuery(const char* sql,
                 const Properties& args,
                 SqlResultSet& rows){

  clear_error();
  rows.clear();
  if (!isConnected())
    return false;
  assert(m_mysql);

  g_debug << "runQuery: " << endl
          << " sql: '" << sql << "'" << endl;


  MYSQL_STMT *stmt= mysql_stmt_init(m_mysql);
  if (mysql_stmt_prepare(stmt, sql, (unsigned long)strlen(sql)))
  {
    report_error("Failed to prepare: ", m_mysql);
    return false;
  }

  uint params= mysql_stmt_param_count(stmt);
  MYSQL_BIND *bind_param = new MYSQL_BIND[params];
  NdbAutoObjArrayPtr<MYSQL_BIND> _guard(bind_param);

  memset(bind_param, 0, params * sizeof(MYSQL_BIND));

  for(uint i= 0; i < mysql_stmt_param_count(stmt); i++)
  {
    BaseString name;
    name.assfmt("%d", i);
    // Parameters are named 0, 1, 2...
    if (!args.contains(name.c_str()))
    {
      g_err << "param " << i << " missing" << endl;
      assert(false);
    }
    PropertiesType t;
    Uint32 val_i;
    const char* val_s;
    args.getTypeOf(name.c_str(), &t);
    switch(t) {
    case PropertiesType_Uint32:
      args.get(name.c_str(), &val_i);
      bind_param[i].buffer_type= MYSQL_TYPE_LONG;
      bind_param[i].buffer= (char*)&val_i;
      g_debug << " param" << name.c_str() << ": " << val_i << endl;
      break;
    case PropertiesType_char:
      args.get(name.c_str(), &val_s);
      bind_param[i].buffer_type= MYSQL_TYPE_STRING;
      bind_param[i].buffer= (char*)val_s;
      bind_param[i].buffer_length= (unsigned long)strlen(val_s);
      g_debug << " param" << name.c_str() << ": " << val_s << endl;
      break;
    default:
      assert(false);
      break;
    }
  }
  if (mysql_stmt_bind_param(stmt, bind_param))
  {
    report_error("Failed to bind param: ", m_mysql);
    mysql_stmt_close(stmt);
    return false;
  }

  if (mysql_stmt_execute(stmt))
  {
    report_error("Failed to execute: ", m_mysql);
    mysql_stmt_close(stmt);
    return false;
  }

  /*
    Update max_length, making it possible to know how big
    buffers to allocate
  */
  my_bool one= 1;
  mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one);

  if (mysql_stmt_store_result(stmt))
  {
    report_error("Failed to store result: ", m_mysql);
    mysql_stmt_close(stmt);
    return false;
  }

  uint row= 0;
  MYSQL_RES* res= mysql_stmt_result_metadata(stmt);
  if (res != NULL)
  {
    MYSQL_FIELD *fields= mysql_fetch_fields(res);
    uint num_fields= mysql_num_fields(res);
    MYSQL_BIND *bind_result = new MYSQL_BIND[num_fields];
    NdbAutoObjArrayPtr<MYSQL_BIND> _guard1(bind_result);
    memset(bind_result, 0, num_fields * sizeof(MYSQL_BIND));

    for (uint i= 0; i < num_fields; i++)
    {
      unsigned long buf_len= sizeof(int);

      switch(fields[i].type){
      case MYSQL_TYPE_STRING:
        buf_len = fields[i].length + 1;
        break;
      case MYSQL_TYPE_VARCHAR:
      case MYSQL_TYPE_VAR_STRING:
        buf_len= fields[i].max_length + 1;
        break;
      case MYSQL_TYPE_LONGLONG:
        buf_len= sizeof(long long);
        break;
      case MYSQL_TYPE_LONG:
        buf_len = sizeof(long);
        break;
      default:
        break;
      }
      
      bind_result[i].buffer_type= fields[i].type;
      bind_result[i].buffer= malloc(buf_len);
      bind_result[i].buffer_length= buf_len;
      bind_result[i].is_null = (my_bool*)malloc(sizeof(my_bool));
      * bind_result[i].is_null = 0;
    }

    if (mysql_stmt_bind_result(stmt, bind_result)){
      report_error("Failed to bind result: ", m_mysql);
      mysql_stmt_close(stmt);
      return false;
    }

    while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
    {
      Properties curr(true);
      for (uint i= 0; i < num_fields; i++){
        if (* bind_result[i].is_null)
          continue;
        switch(fields[i].type){
        case MYSQL_TYPE_STRING:
	  ((char*)bind_result[i].buffer)[fields[i].max_length] = 0;
        case MYSQL_TYPE_VARCHAR:
        case MYSQL_TYPE_VAR_STRING:
          curr.put(fields[i].name, (char*)bind_result[i].buffer);
          break;

        case MYSQL_TYPE_LONGLONG:
          curr.put64(fields[i].name,
                     *(unsigned long long*)bind_result[i].buffer);
          break;

        default:
          curr.put(fields[i].name, *(int*)bind_result[i].buffer);
          break;
        }
      }
      rows.put("row", row++, &curr);
    }

    mysql_free_result(res);

    for (uint i= 0; i < num_fields; i++)
    {
      free(bind_result[i].buffer);
      free(bind_result[i].is_null);
    }
  }

  // Save stats in result set
  rows.put("rows", row);
  rows.put64("affected_rows", mysql_affected_rows(m_mysql));
  rows.put("mysql_errno", mysql_errno(m_mysql));
  rows.put("mysql_error", mysql_error(m_mysql));
  rows.put("mysql_sqlstate", mysql_sqlstate(m_mysql));
  rows.put64("insert_id", mysql_insert_id(m_mysql));

  mysql_stmt_close(stmt);
  return true;
}
예제 #15
0
int main (int argc, char *argv[]) {

    MYSQL *mysql;
    MYSQL_RES *result;
    MYSQL_ROW row;
    my_bool reconnect = 0;
    mysql = mysql_init(NULL);
    mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);

    CONN(0);

    MYSQL_STMT    *stmt;
    MYSQL_BIND    bind[1];
    MYSQL_RES     *prepare_meta_result;
    MYSQL_TIME    ts;
    unsigned long length[1];
    int           param_count, column_count, row_count;
    short         small_data;
    int           int_data;
    char          str_data[STRING_SIZE];
    my_bool       is_null[1];

    // 1. no cursor
    stmt = mysql_stmt_init(mysql);
    mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE));
    param_count= mysql_stmt_param_count(stmt);
    //prepare_meta_result = mysql_stmt_result_metadata(stmt);
    mysql_stmt_execute(stmt);

    memset(bind, 0, sizeof(bind));

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

    mysql_stmt_bind_result(stmt, bind);
    //mysql_stmt_store_result(stmt);

    while (!mysql_stmt_fetch(stmt)) {
        printf("1 - %d \n", int_data); 
    }

    mysql_stmt_close(stmt);


    // 2. cursor read only
    stmt = mysql_stmt_init(mysql);

    unsigned long type = (unsigned long) CURSOR_TYPE_READ_ONLY;
    mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);

    mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE));
    param_count= mysql_stmt_param_count(stmt);
    //prepare_meta_result = mysql_stmt_result_metadata(stmt);
    mysql_stmt_execute(stmt);

    memset(bind, 0, sizeof(bind));

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

    mysql_stmt_bind_result(stmt, bind);
    //mysql_stmt_store_result(stmt); // default 1

    while (!mysql_stmt_fetch(stmt)) {
        printf("1 - %d \n", int_data); 
    }

    mysql_stmt_close(stmt);

    // 3. set num 
    stmt = mysql_stmt_init(mysql);

    type = (unsigned long) CURSOR_TYPE_READ_ONLY;
    unsigned long prefetch_rows = 2;
    mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
    mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, (void*) &prefetch_rows);

    mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE));
    param_count= mysql_stmt_param_count(stmt);
    //prepare_meta_result = mysql_stmt_result_metadata(stmt);
    mysql_stmt_execute(stmt);

    memset(bind, 0, sizeof(bind));

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

    mysql_stmt_bind_result(stmt, bind);
    //mysql_stmt_store_result(stmt);

    while (!mysql_stmt_fetch(stmt)) {
        printf("1 - %d \n", int_data); 
    }

    mysql_stmt_close(stmt);
}
예제 #16
0
파일: db-mysql.c 프로젝트: Adjamo/pushpool
static char *my_pwdb_lookup(const char *user)
{
	MYSQL *db = srv.db_cxn;
	MYSQL_STMT *stmt;
	MYSQL_BIND bind_param[1], bind_res[1];
	unsigned long bind_lengths[1], bind_res_lengths[1];
	char password[256], *pass_ret;
	int pass_len;
	const char *step = "init";

	stmt = mysql_stmt_init(db);
	if (!stmt)
		return NULL;

	step = "prep";
	if (mysql_stmt_prepare(stmt, srv.db_stmt_pwdb,
			       strlen(srv.db_stmt_pwdb)))
		goto err_out;

	if (mysql_stmt_param_count(stmt))
	{
		memset(bind_param, 0, sizeof(bind_param));
		memset(bind_lengths, 0, sizeof(bind_lengths));
		bind_instr(bind_param, bind_lengths, 0, user);

		step = "bind-param";
		if (mysql_stmt_bind_param(stmt, bind_param))
			goto err_out;
	}

	memset(bind_res, 0, sizeof(bind_res));
	memset(bind_res_lengths, 0, sizeof(bind_res_lengths));
	bind_res[0].buffer_type = MYSQL_TYPE_STRING;
	bind_res[0].buffer = password;
	bind_res[0].buffer_length = sizeof(password);
	bind_res[0].length = &bind_res_lengths[0];

	step = "execute";
	if (mysql_stmt_execute(stmt))
		goto err_out;

	step = "bind-result";
	if (mysql_stmt_bind_result(stmt, bind_res))
		goto err_out;

	step = "store-result";
	if (mysql_stmt_store_result(stmt))
		goto err_out;

	step = "fetch";
	if (mysql_stmt_fetch(stmt))
		goto err_out;

	pass_len = bind_res_lengths[0];

	step = "malloc";
	pass_ret = malloc(pass_len + 1);
	if (!pass_ret)
		goto err_out;

	memcpy(pass_ret, password, pass_len);
	pass_ret[pass_len] = 0;

	mysql_stmt_close(stmt);
	return pass_ret;

err_out:
	mysql_stmt_close(stmt);

	applog(LOG_ERR, "mysql pwdb query failed at %s", step);
	return NULL;
}
예제 #17
0
파일: result.c 프로젝트: gammons/mysql2
static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, const result_each_args *args)
{
  VALUE rowVal;
  unsigned int i = 0;

  rb_encoding *default_internal_enc;
  rb_encoding *conn_enc;
  GET_RESULT(self);

  default_internal_enc = rb_default_internal_encoding();
  conn_enc = rb_to_encoding(wrapper->encoding);

  if (wrapper->fields == Qnil) {
    wrapper->numberOfFields = mysql_num_fields(wrapper->result);
    wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
  }
  if (args->asArray) {
    rowVal = rb_ary_new2(wrapper->numberOfFields);
  } else {
    rowVal = rb_hash_new();
  }

  if (wrapper->result_buffers == NULL) {
    rb_mysql_result_alloc_result_buffers(self, fields);
  }

  if (mysql_stmt_bind_result(wrapper->stmt_wrapper->stmt, wrapper->result_buffers)) {
    rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper);
  }

  {
    switch((uintptr_t)rb_thread_call_without_gvl(nogvl_stmt_fetch, wrapper->stmt_wrapper->stmt, RUBY_UBF_IO, 0)) {
      case 0:
        /* success */
        break;

      case 1:
        /* error */
        rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper);

      case MYSQL_NO_DATA:
        /* no more row */
        return Qnil;

      case MYSQL_DATA_TRUNCATED:
        rb_raise(cMysql2Error, "IMPLBUG: caught MYSQL_DATA_TRUNCATED. should not come here as buffer_length is set to fields[i].max_length.");
    }
  }

  for (i = 0; i < wrapper->numberOfFields; i++) {
    VALUE field = rb_mysql_result_fetch_field(self, i, args->symbolizeKeys);
    VALUE val = Qnil;
    MYSQL_TIME *ts;

    if (wrapper->is_null[i]) {
      val = Qnil;
    } else {
      const MYSQL_BIND* const result_buffer = &wrapper->result_buffers[i];

      switch(result_buffer->buffer_type) {
        case MYSQL_TYPE_TINY:         // signed char
          if (args->castBool && fields[i].length == 1) {
            val = (*((unsigned char*)result_buffer->buffer) != 0) ? Qtrue : Qfalse;
            break;
          }
          if (result_buffer->is_unsigned) {
            val = UINT2NUM(*((unsigned char*)result_buffer->buffer));
          } else {
            val = INT2NUM(*((signed char*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_BIT:        /* BIT field (MySQL 5.0.3 and up) */
          if (args->castBool && fields[i].length == 1) {
            val = (*((unsigned char*)result_buffer->buffer) != 0) ? Qtrue : Qfalse;
          }else{
            val = rb_str_new(result_buffer->buffer, *(result_buffer->length));
          }
          break;
        case MYSQL_TYPE_SHORT:        // short int
        case MYSQL_TYPE_YEAR:         // short int
          if (result_buffer->is_unsigned) {
            val = UINT2NUM(*((unsigned short int*)result_buffer->buffer));
          } else  {
            val = INT2NUM(*((short int*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_INT24:        // int
        case MYSQL_TYPE_LONG:         // int
          if (result_buffer->is_unsigned) {
            val = UINT2NUM(*((unsigned int*)result_buffer->buffer));
          } else {
            val = INT2NUM(*((int*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_LONGLONG:     // long long int
          if (result_buffer->is_unsigned) {
            val = ULL2NUM(*((unsigned long long int*)result_buffer->buffer));
          } else {
            val = LL2NUM(*((long long int*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_FLOAT:        // float
          val = rb_float_new((double)(*((float*)result_buffer->buffer)));
          break;
        case MYSQL_TYPE_DOUBLE:       // double
          val = rb_float_new((double)(*((double*)result_buffer->buffer)));
          break;
        case MYSQL_TYPE_DATE:         // MYSQL_TIME
        case MYSQL_TYPE_NEWDATE:      // MYSQL_TIME
          ts = (MYSQL_TIME*)result_buffer->buffer;
          val = rb_funcall(cDate, intern_new, 3, INT2NUM(ts->year), INT2NUM(ts->month), INT2NUM(ts->day));
          break;
        case MYSQL_TYPE_TIME:         // MYSQL_TIME
          ts = (MYSQL_TIME*)result_buffer->buffer;
          val = rb_funcall(rb_cTime, args->db_timezone, 7, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part));
          if (!NIL_P(args->app_timezone)) {
            if (args->app_timezone == intern_local) {
              val = rb_funcall(val, intern_localtime, 0);
            } else { // utc
              val = rb_funcall(val, intern_utc, 0);
            }
          }
          break;
        case MYSQL_TYPE_DATETIME:     // MYSQL_TIME
        case MYSQL_TYPE_TIMESTAMP: {  // MYSQL_TIME
          uint64_t seconds;

          ts = (MYSQL_TIME*)result_buffer->buffer;
          seconds = (ts->year*31557600ULL) + (ts->month*2592000ULL) + (ts->day*86400ULL) + (ts->hour*3600ULL) + (ts->minute*60ULL) + ts->second;

          if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead
            VALUE offset = INT2NUM(0);
            if (args->db_timezone == intern_local) {
              offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
            }
            val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset);
            if (!NIL_P(args->app_timezone)) {
              if (args->app_timezone == intern_local) {
                offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
                val = rb_funcall(val, intern_new_offset, 1, offset);
              } else { // utc
                val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset);
              }
            }
          } else {
            val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part));
            if (!NIL_P(args->app_timezone)) {
              if (args->app_timezone == intern_local) {
                val = rb_funcall(val, intern_localtime, 0);
              } else { // utc
                val = rb_funcall(val, intern_utc, 0);
              }
            }
          }
          break;
        }
        case MYSQL_TYPE_DECIMAL:      // char[]
        case MYSQL_TYPE_NEWDECIMAL:   // char[]
          val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(result_buffer->buffer, *(result_buffer->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_SET:          // char[]
        case MYSQL_TYPE_ENUM:         // char[]
        case MYSQL_TYPE_GEOMETRY:     // char[]
        default:
          val = rb_str_new(result_buffer->buffer, *(result_buffer->length));
          val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
          break;
      }
    }

    if (args->asArray) {
      rb_ary_push(rowVal, val);
    } else {
      rb_hash_aset(rowVal, field, val);
    }
  }

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

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

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

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

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

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

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

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

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

		}
	}

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

	/* We do not need the array of MYSQL_BIND anymore, mysql_stmt_bind_param
	 * creates a copy in the statement and we will update it there
	 */
	if (result) pkg_free(result);
	return 0;
   
 error:
	if (result) pkg_free(result);
	return err;
}
예제 #19
0
파일: sql.c 프로젝트: icxbb-xx/Hercules-1
/// Fetches the next row.
int SqlStmt_NextRow(SqlStmt* self)
{
	int err;
	size_t i;
	size_t cols;
	MYSQL_BIND* column;
	unsigned long length;

	if( self == NULL )
		return SQL_ERROR;

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

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

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

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

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

	return SQL_SUCCESS;
}
예제 #20
0
nsresult jxMySQL50Statement::BindOutput()
{
	PRInt32		ndx;
	PRInt32		col_type;

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

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

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

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

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

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

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

				}
				break;

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

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

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


			default:
				SET_ERROR_RETURN (JX_MYSQL50_ERROR_INVALID_TYPE);
				break;
		}
	}

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

	if (rc)
    {
        SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR);
	} else
    {
        if (mRES)
        {
            mysql_free_result(mRES);
            mRES = nsnull;
        }
         
		mRES = mysql_stmt_result_metadata(mSTMT);
        if (mRES)
        {
            if (mysql_stmt_store_result(mSTMT))
            {
#if 0
                int i=0;
                unsigned int en = mysql_stmt_errno(mSTMT);
                const char* es = mysql_stmt_error(mSTMT);
                // Not sure why this would fail.  Will need to be investigated
                // Per DOC, this needs to be called earlier.
                // SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR);
#endif
            }
        }
		return NS_OK;
	}
}
예제 #21
0
void database::get_client_channels(int ClientID, int *DeviceID,
                                   supla_client_channels *channels) {
  MYSQL_STMT *stmt;
  const char sql1[] =
      "SELECT `id`, `func`, `param1`, `param2`, `iodevice_id`, `location_id`, "
      "`caption`, `alt_icon`, `protocol_version` FROM `supla_v_client_channel` "
      "WHERE `client_id` = ? ORDER BY `iodevice_id`, `channel_number`";
  const char sql2[] =
      "SELECT `id`, `func`, `param1`, `param2`, `iodevice_id`, `location_id`, "
      "`caption`, `alt_icon`, `protocol_version` FROM `supla_v_client_channel` "
      "WHERE `client_id` = ? AND `iodevice_id` = ? ORDER BY `channel_number`";

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

  pbind[0].buffer_type = MYSQL_TYPE_LONG;
  pbind[0].buffer = (char *)&ClientID;

  pbind[1].buffer_type = MYSQL_TYPE_LONG;
  pbind[1].buffer = (char *)DeviceID;

  if (stmt_execute((void **)&stmt, DeviceID ? sql2 : sql1, pbind,
                   DeviceID ? 2 : 1, true)) {
    my_bool is_null;

    MYSQL_BIND rbind[9];
    memset(rbind, 0, sizeof(rbind));

    int id, func, param1, param2, iodevice_id, location_id, alt_icon,
        protocol_version;
    unsigned long size;
    char caption[401];

    rbind[0].buffer_type = MYSQL_TYPE_LONG;
    rbind[0].buffer = (char *)&id;

    rbind[1].buffer_type = MYSQL_TYPE_LONG;
    rbind[1].buffer = (char *)&func;

    rbind[2].buffer_type = MYSQL_TYPE_LONG;
    rbind[2].buffer = (char *)&param1;

    rbind[3].buffer_type = MYSQL_TYPE_LONG;
    rbind[3].buffer = (char *)&param2;

    rbind[4].buffer_type = MYSQL_TYPE_LONG;
    rbind[4].buffer = (char *)&iodevice_id;

    rbind[5].buffer_type = MYSQL_TYPE_LONG;
    rbind[5].buffer = (char *)&location_id;

    rbind[6].buffer_type = MYSQL_TYPE_STRING;
    rbind[6].buffer = caption;
    rbind[6].is_null = &is_null;
    rbind[6].buffer_length = 401;
    rbind[6].length = &size;

    rbind[7].buffer_type = MYSQL_TYPE_LONG;
    rbind[7].buffer = (char *)&alt_icon;

    rbind[8].buffer_type = MYSQL_TYPE_LONG;
    rbind[8].buffer = (char *)&protocol_version;

    if (mysql_stmt_bind_result(stmt, rbind)) {
      supla_log(LOG_ERR, "MySQL - stmt bind error - %s",
                mysql_stmt_error(stmt));
    } else {
      mysql_stmt_store_result(stmt);

      if (mysql_stmt_num_rows(stmt) > 0) {
        while (!mysql_stmt_fetch(stmt)) {
          if (is_null == false) {
            caption[size] = 0;
          }

          channels->update_channel(id, iodevice_id, location_id, func, param1,
                                   param2, is_null ? NULL : caption, alt_icon,
                                   protocol_version);
        }
      }
    }

    mysql_stmt_close(stmt);
  }
}
예제 #22
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;
}
예제 #23
0
int database::get_device(int DeviceID, bool *device_enabled,
                         int *original_location_id, int *location_id,
                         bool *location_enabled, int *UserID) {
  if (_mysql == NULL || DeviceID == 0) return 0;

  MYSQL_STMT *stmt = NULL;

  MYSQL_BIND pbind[1];
  memset(pbind, 0, sizeof(pbind));

  pbind[0].buffer_type = MYSQL_TYPE_LONG;
  pbind[0].buffer = (char *)&DeviceID;

  int _device_enabled = 0;
  int _original_location_id = 0;
  int _location_id = 0;
  int _location_enabled = 0;
  int _UserID = 0;

  bool result = false;

  if (stmt_execute((void **)&stmt,
                   "SELECT CAST(d.`enabled` AS unsigned integer) `d_enabled`, "
                   "IFNULL(d.original_location_id, 0), IFNULL(d.location_id, "
                   "0), IFNULL(CAST(l.`enabled` AS unsigned integer), 0) "
                   "`l_enabled`, d.`user_id` FROM supla_iodevice d LEFT JOIN "
                   "supla_location l ON l.id = d.location_id WHERE d.id = ?",
                   pbind, 1, true)) {
    MYSQL_BIND rbind[5];
    memset(rbind, 0, sizeof(rbind));

    rbind[0].buffer_type = MYSQL_TYPE_LONG;
    rbind[0].buffer = (char *)&_device_enabled;

    rbind[1].buffer_type = MYSQL_TYPE_LONG;
    rbind[1].buffer = (char *)&_original_location_id;

    rbind[2].buffer_type = MYSQL_TYPE_LONG;
    rbind[2].buffer = (char *)&_location_id;

    rbind[3].buffer_type = MYSQL_TYPE_LONG;
    rbind[3].buffer = (char *)&_location_enabled;

    rbind[4].buffer_type = MYSQL_TYPE_LONG;
    rbind[4].buffer = (char *)&_UserID;

    if (mysql_stmt_bind_result(stmt, rbind)) {
      supla_log(LOG_ERR, "MySQL - stmt bind error - %s",
                mysql_stmt_error(stmt));
    } else {
      mysql_stmt_store_result(stmt);

      if (mysql_stmt_num_rows(stmt) > 0 && !mysql_stmt_fetch(stmt)) {
        *device_enabled = _device_enabled == 1;
        *original_location_id = _original_location_id;
        *location_id = _location_id;
        *location_enabled = _location_enabled == 1;
        *UserID = _UserID;

        result = true;
      }
    }

    mysql_stmt_close(stmt);
  }

  return result ? DeviceID : 0;
}
예제 #24
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;
}
예제 #25
0
void readProposalData() {
	int i, k, flag;
	char sql[1024];
	
	sprintf(sql, "select Proposal.propID as propID, propName, propConf, t3.Priority as priority, coalesce(userRegions, 0) as nUserRegions from Proposal, (select t2.propID, Priority, userRegions  from (select count(*) as userRegions, nonPropID as propID from Config where Session_sessionID=%d and paramName='userRegion' group by propID) t1 RIGHT OUTER JOIN (select paramValue as Priority, nonPropID as propID from Config where Session_sessionID=%d and paramName='RelativeProposalPriority' group by propID ) t2 ON t1.propID=t2.propID) t3 where Proposal.propID=t3.propID;", sessionID, sessionID);

	MYSQL_STMT *stmt;
	MYSQL_BIND bind[5];
	my_bool error[5];
	
	struct proposal pbuffer;

	//fprintf(stderr , "forming query..");
	if( (stmt = mysql_stmt_init(&mysql))== (MYSQL_STMT *) NULL) {
		fprintf(stderr,"error in mysql_stmt_init: %s\n", mysql_stmt_error(stmt));
		exit(1);
	}

	flag = mysql_stmt_prepare(stmt, sql, strlen(sql));
	if(flag!=0) {
		fprintf(stderr,"error in mysql_stmt_prepare: %s\n", mysql_stmt_error(stmt));
		exit(1);
	}

	memset(bind, 0, sizeof(bind));

	i = 0;
	bind[i].buffer_type = FIELD_TYPE_LONG;
	bind[i].buffer = &(pbuffer.propID);
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_STRING;
	bind[i].buffer = &(pbuffer.propName);
	bind[i].buffer_length = 256;
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_STRING;
	bind[i].buffer = &(pbuffer.propConf);
	bind[i].buffer_length = 256;
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_DOUBLE;
	bind[i].buffer = &(pbuffer.priority);
	bind[i].error = &error[i];
	i++;
	bind[i].buffer_type = FIELD_TYPE_LONG;
	bind[i].buffer = &(pbuffer.nUserRegions);
	bind[i].error = &error[i];

	flag = mysql_stmt_bind_result(stmt, bind);
	if(flag!=0) {
		fprintf(stderr, "error in mysql_stmt_bind_result: %s", mysql_stmt_error(stmt));
		exit(1);
	}

	//fprintf(stderr,"executing query..");
	flag = mysql_stmt_execute(stmt);
	if(flag!=0) {
		fprintf(stderr, "error in mysql_stmt_execute: %s", mysql_stmt_error(stmt));
		exit(1);
	}

	//fprintf(stderr,"executed query..");
	flag = mysql_stmt_store_result(stmt);
	if(flag!=0) {
		fprintf(stderr, "error in mysql_stmt_store_result: %s", mysql_stmt_error(stmt));
		exit(1);
	}
	
	//fprintf(stderr,"stored result..");
	proposal_list_length = mysql_stmt_num_rows(stmt);
	//fprintf(stderr,"reading %d proposals..", proposal_list_length);

	i = 0;
	flag = 0;
	while(flag==0) {
		flag = mysql_stmt_fetch(stmt);
		if(flag!=0) {
			if(flag == MYSQL_NO_DATA) {
				//fprintf(stderr,"done fetching data..");
				flag = 1;
			}
			else if(flag == MYSQL_DATA_TRUNCATED) {
				flag = 1;
				for(k=0; k<10; k++) {
					if(error[k]!=0) printf("fetching data truncated in parameter %d\n",k);
				}
			}
			else {
				fprintf(stderr, "error in mysql_stmt_fetch: %s\n", mysql_stmt_error(stmt));
				exit(1);
			}
		}
	
		if(flag==0) {
			memcpy(&(proposal_list[i]), &(pbuffer), sizeof(struct proposal));
			i++;
		}
	}
	
	mysql_stmt_close(stmt);
	//fprintf(stderr,"done\n");
}
예제 #26
0
static int test_conversion(MYSQL *mysql)
{
  MYSQL_STMT *stmt;
  const char *stmt_text;
  int rc;
  MYSQL_BIND my_bind[1];
  uchar buff[4];
  ulong length;

  stmt_text= "DROP TABLE IF EXISTS t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);
  stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);
  stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
             " character_set_results=latin1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  stmt= mysql_stmt_init(mysql);
  FAIL_IF(!stmt, mysql_error(mysql));
  stmt_text= "INSERT INTO t1 (a) VALUES (?)";
  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_stmt_rc(rc, stmt);

  memset(my_bind, '\0', sizeof(my_bind));
  my_bind[0].buffer= (char*) buff;
  my_bind[0].length= &length;
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;

  mysql_stmt_bind_param(stmt, my_bind);

  buff[0]= (uchar) 0xC3;
  buff[1]= (uchar) 0xA0;
  length= 2;

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

  stmt_text= "SELECT a FROM t1";
  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_stmt_rc(rc, stmt);
  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);

  my_bind[0].buffer_length= sizeof(buff);
  mysql_stmt_bind_result(stmt, my_bind);

  rc= mysql_stmt_fetch(stmt);
  check_stmt_rc(rc, stmt);
  FAIL_UNLESS(length == 1, "length != 1");
  FAIL_UNLESS(buff[0] == 0xE0, "buff[0] != 0xE0");
  rc= mysql_stmt_fetch(stmt);
  FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");

  mysql_stmt_close(stmt);
  stmt_text= "DROP TABLE t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);
  stmt_text= "SET NAMES DEFAULT";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  return OK;
}
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;
}
예제 #28
0
static int test_ps_i18n(MYSQL *mysql)
{
  MYSQL_STMT *stmt;
  int rc;
  const char *stmt_text;
  MYSQL_BIND bind_array[2];

  /* Represented as numbers to keep UTF8 tools from clobbering them. */
  const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
  const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
  char buf1[16], buf2[16];
  ulong buf1_len, buf2_len;

  stmt_text= "DROP TABLE IF EXISTS t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  /*
    Create table with binary columns, set session character set to cp1251,
    client character set to koi8, and make sure that there is conversion
    on insert and no conversion on select
  */

  stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
                 "CHARACTER_SET_CONNECTION=cp1251, "
                 "CHARACTER_SET_RESULTS=koi8r";

  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  memset(bind_array, '\0', sizeof(bind_array));
  bind_array[0].buffer_type= MYSQL_TYPE_STRING;
  bind_array[0].buffer= (void *) koi8;
  bind_array[0].buffer_length= strlen(koi8);

  bind_array[1].buffer_type= MYSQL_TYPE_STRING;
  bind_array[1].buffer= (void *) koi8;
  bind_array[1].buffer_length= strlen(koi8);

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

  stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";

  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_stmt_rc(rc, stmt);
  mysql_stmt_bind_param(stmt, bind_array);

  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));

  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);
  stmt_text= "SELECT c1, c2 FROM t1";

  /* c1 and c2 are binary so no conversion will be done on select */
  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_stmt_rc(rc, stmt);
  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);
  bind_array[0].buffer= buf1;
  bind_array[0].buffer_length= sizeof(buf1);
  bind_array[0].length= &buf1_len;

  bind_array[1].buffer= buf2;
  bind_array[1].buffer_length= sizeof(buf2);
  bind_array[1].length= &buf2_len;

  mysql_stmt_bind_result(stmt, bind_array);

  rc= mysql_stmt_fetch(stmt);
  check_stmt_rc(rc, stmt);
  FAIL_UNLESS(buf1_len == strlen(cp1251), "buf1_len != strlen(cp1251)");
  FAIL_UNLESS(buf2_len == strlen(cp1251), "buf2_len != strlen(cp1251)");
  FAIL_UNLESS(!memcmp(buf1, cp1251, buf1_len), "buf1 != cp1251");
  FAIL_UNLESS(!memcmp(buf2, cp1251, buf1_len), "buf2 != cp1251");

  rc= mysql_stmt_fetch(stmt);
  FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");

  stmt_text= "DROP TABLE IF EXISTS t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  /*
    Now create table with two cp1251 columns, set client character
    set to koi8 and supply columns of one row as string and another as
    binary data. Binary data must not be converted on insert, and both
    columns must be converted to client character set on select.
  */

  stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
                              "c2 VARCHAR(255) CHARACTER SET cp1251)";

  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);

  stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";

  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_stmt_rc(rc, stmt);
  /* this data must be converted */
  bind_array[0].buffer_type= MYSQL_TYPE_STRING;
  bind_array[0].buffer= (void *) koi8;
  bind_array[0].buffer_length= strlen(koi8);

  bind_array[1].buffer_type= MYSQL_TYPE_STRING;
  bind_array[1].buffer= (void *) koi8;
  bind_array[1].buffer_length= strlen(koi8);

  mysql_stmt_bind_param(stmt, bind_array);

  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));

  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);
  /* this data must not be converted */
  bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
  bind_array[0].buffer= (void *) cp1251;
  bind_array[0].buffer_length= strlen(cp1251);

  bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
  bind_array[1].buffer= (void *) cp1251;
  bind_array[1].buffer_length= strlen(cp1251);

  mysql_stmt_bind_param(stmt, bind_array);

  mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));

  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);
  /* Fetch data and verify that rows are in koi8 */

  stmt_text= "SELECT c1, c2 FROM t1";

  /* c1 and c2 are binary so no conversion will be done on select */
  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_stmt_rc(rc, stmt);
  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);
  bind_array[0].buffer= buf1;
  bind_array[0].buffer_length= sizeof(buf1);
  bind_array[0].length= &buf1_len;

  bind_array[1].buffer= buf2;
  bind_array[1].buffer_length= sizeof(buf2);
  bind_array[1].length= &buf2_len;

  mysql_stmt_bind_result(stmt, bind_array);

  while ((rc= mysql_stmt_fetch(stmt)) == 0)
  {
    FAIL_UNLESS(buf1_len == strlen(koi8), "buf1_len != strlen(koi8)");
    FAIL_UNLESS(buf2_len == strlen(koi8), "buf2_len != strlen(koi8)");
    FAIL_UNLESS(!memcmp(buf1, koi8, buf1_len), "buf1 != koi8");
    FAIL_UNLESS(!memcmp(buf2, koi8, buf1_len), "buf2 != koi8");
  }
  FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
  mysql_stmt_close(stmt);

  stmt_text= "DROP TABLE t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);
  stmt_text= "SET NAMES DEFAULT";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  check_mysql_rc(rc, mysql);
  return OK;
}
예제 #29
0
PreparedResultSet::PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES *result, uint64 rowCount, uint32 fieldCount) :
m_rowCount(rowCount),
m_rowPosition(0),
m_fieldCount(fieldCount),
m_rBind(NULL),
m_stmt(stmt),
m_res(result),
m_isNull(NULL),
m_length(NULL)
{
    if (!m_res)
        return;

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

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

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

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

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

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

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

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

    m_rowCount = mysql_stmt_num_rows(m_stmt);

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

    /// All data is buffered, let go of mysql c api structures
    CleanUp();
}
예제 #30
0
int sqlrow(DB db,SQL sql,const char *format,...)
{
	int i;
	my_bool w;
	int *ii;
	char **t;
	MYSQL_FIELD *f;
	va_list ap;

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

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

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

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

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

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

	return 0;

out1:	printf("sqlrow format mismatch\n");
out0:	return -1;
}