Пример #1
0
static int gt_rdb_stmt_mysql_get_double(GtRDBStmt *st, GtUword field_no,
                                        double *result, GtError *err)
{
  GtRDBStmtMySQL *stm;
  MYSQL_BIND res_bind;
  int had_err = 0;
  double res_double = GT_UNDEF_DOUBLE;
  my_bool error, is_null;
  gt_assert(st && result);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  CHECK_INIT_STATEMENT
  if (!had_err) {
    memset(&res_bind, 0, sizeof (res_bind));
    res_bind.buffer_type = MYSQL_TYPE_DOUBLE;
    res_bind.buffer = &res_double;
    res_bind.error = &error;
    res_bind.is_null = &is_null;
    if ((had_err = mysql_stmt_fetch_column(stm->stmt, &res_bind, field_no, 0)))
      gt_error_set(err, GT_MYSQL_ERRMSG, had_err, mysql_stmt_error(stm->stmt));
  }
  if (!had_err)
    *result = res_double;
  return had_err;
}
Пример #2
0
static int gt_rdb_stmt_mysql_bind_string(GtRDBStmt *st, GtUword param_no,
                                         const char *val,
                                         GT_UNUSED GtError *err)
{
  GtRDBStmtMySQL *stm;
  int had_err = 0;
  char *str;
  GtUword *length;
  gt_assert(st);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  gt_assert(param_no < stm->num_params);
  /* allocate buffer for string until execution */
  str = gt_calloc(strlen(val)+1, sizeof (char));
  strncpy(str, val, strlen(val));
  gt_hashtable_add(stm->buffers, &str);
  /* allocate space for length */
  length = gt_malloc(sizeof (GtUword));
  *length = strlen(str);
  gt_hashtable_add(stm->buffers, &length);
  /* fill param structure */
  stm->params[param_no].buffer_type = MYSQL_TYPE_STRING;
  stm->params[param_no].buffer = str;
  stm->params[param_no].is_null = 0;
  stm->params[param_no].buffer_length = strlen(str);
  stm->params[param_no].length = length;
  return had_err;
}
Пример #3
0
static int gt_rdb_stmt_mysql_get_string(GtRDBStmt *st, GtUword field_no,
                                        GtStr *result, GtError *err)
{
  GtRDBStmtMySQL *stm;
  int had_err = 0;
  gt_assert(st && result);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  CHECK_INIT_STATEMENT
  if (!had_err
        && stm->results[field_no].buffer_type != MYSQL_TYPE_STRING
        && stm->results[field_no].buffer_type != MYSQL_TYPE_VAR_STRING
        && stm->results[field_no].buffer_type != MYSQL_TYPE_BLOB
        && stm->results[field_no].buffer_type != MYSQL_TYPE_TINY_BLOB
        && stm->results[field_no].buffer_type != MYSQL_TYPE_MEDIUM_BLOB
        && stm->results[field_no].buffer_type != MYSQL_TYPE_LONG_BLOB
        && stm->results[field_no].buffer_type != MYSQL_TYPE_BIT)
  {
    gt_error_set(err, "incompatible type!");
    had_err = -1;
  }
  if (!had_err) {
    gt_str_reset(result);
    gt_str_append_cstr_nt(result,
                          (char*)stm->results[field_no].buffer,
                          *stm->results[field_no].length);
  }
  return had_err;
}
Пример #4
0
static void gt_rdb_stmt_mysql_delete(GtRDBStmt *st)
{
  GtRDBStmtMySQL *stm;
  if (!st) return;
  stm = gt_rdb_stmt_mysql_cast(st);
  if (stm->stmt) {
    mysql_stmt_free_result(stm->stmt);
    mysql_stmt_close(stm->stmt);
  }
  gt_free(stm->params);
  gt_free(stm->results);
  gt_hashtable_delete(stm->buffers);
  gt_hashtable_delete(stm->returned_strings);
  gt_str_delete(stm->query);
}
Пример #5
0
static int gt_rdb_stmt_mysql_get_ulong(GtRDBStmt *st, GtUword field_no,
                                       GtUword *result, GtError *err)
{
  GtRDBStmtMySQL *stm;
  int had_err = 0;
  gt_assert(st && result);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  CHECK_INIT_STATEMENT
  if (!had_err && stm->results[field_no].buffer_type != MYSQL_TYPE_LONG) {
    gt_error_set(err, "incompatible type!");
    had_err = -1;
  }
  if (!had_err)
    *result = *(GtUword*) stm->results[field_no].buffer;
  return had_err;
}
Пример #6
0
static int gt_rdb_stmt_mysql_bind_int(GtRDBStmt *st, GtUword param_no,
                                      int val, GT_UNUSED GtError *err)
{
  GtRDBStmtMySQL *stm;
  int *lval, had_err = 0;
  gt_assert(st);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  gt_assert(param_no < stm->num_params);
  lval = gt_malloc(sizeof (int));
  *lval = val;
  gt_hashtable_add(stm->buffers, &lval);
  stm->params[param_no].buffer_type = MYSQL_TYPE_LONG;
  stm->params[param_no].buffer = (char*) lval;
  stm->params[param_no].is_null = 0;
  stm->params[param_no].length = 0;
  return had_err;
}
Пример #7
0
static int gt_rdb_stmt_mysql_bind_double(GtRDBStmt *st, GtUword param_no,
                                         double val, GT_UNUSED GtError *err)
{
  GtRDBStmtMySQL *stm;
  int had_err = 0;
  double *lval;
  gt_assert(st);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  gt_assert(param_no < stm->num_params);
  lval = gt_malloc(sizeof (double));
  *lval = val;
  gt_hashtable_add(stm->buffers, &lval);
  stm->params[param_no].buffer_type = MYSQL_TYPE_DOUBLE;
  stm->params[param_no].is_unsigned = false;
  stm->params[param_no].buffer = (char*) lval;
  stm->params[param_no].is_null = 0;
  stm->params[param_no].length = 0;
  return had_err;
}
Пример #8
0
static int gt_rdb_stmt_mysql_reset(GtRDBStmt *st, GtError *err)
{
  GtRDBStmtMySQL *stm;
  int rval, had_err = 0;
  gt_assert(st);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  gt_hashtable_reset(stm->buffers);
  gt_hashtable_reset(stm->returned_strings);
  mysql_stmt_free_result(stm->stmt);
  if ((rval = mysql_stmt_reset(stm->stmt))) {
    gt_error_set(err, GT_MYSQL_ERRMSG, rval, mysql_stmt_error(stm->stmt));
    had_err = -1;
  }
  memset(stm->params, 0, stm->num_params*sizeof (MYSQL_BIND));
  gt_free(stm->results);
  stm->results = NULL;
  if (!had_err)
    stm->executed = false;
  return had_err;
}
Пример #9
0
static int gt_rdb_stmt_mysql_bind_ulong(GtRDBStmt *st, unsigned long param_no,
                                        unsigned long val,
                                        GT_UNUSED GtError *err)
{
  GtRDBStmtMySQL *stm;
  unsigned long *lval;
  int had_err = 0;
  gt_assert(st);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  gt_assert(param_no < stm->num_params);
  lval = gt_malloc(sizeof (unsigned long));
  *lval = val;
  gt_hashtable_add(stm->buffers, &lval);
  stm->params[param_no].buffer_type = MYSQL_TYPE_LONG;
  stm->params[param_no].is_unsigned = true;
  stm->params[param_no].buffer = (char*) lval;
  stm->params[param_no].is_null = 0;
  stm->params[param_no].length = 0;
  return had_err;
}
Пример #10
0
static int gt_rdb_stmt_mysql_get_int(GtRDBStmt *st, GtUword field_no,
                                     int *result, GtError *err)
{
  GtRDBStmtMySQL *stm;
  int had_err = 0;
  gt_assert(st && result);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  CHECK_INIT_STATEMENT
  if (!had_err       /* TODO: check these VVV */
       && stm->results[field_no].buffer_type != MYSQL_TYPE_LONG
       && stm->results[field_no].buffer_type != MYSQL_TYPE_TINY
       && stm->results[field_no].buffer_type != MYSQL_TYPE_INT24
       && stm->results[field_no].buffer_type != MYSQL_TYPE_SHORT) {
    gt_error_set(err, "incompatible type: %d!",
                 stm->results[field_no].buffer_type);
    had_err = -1;
  }
  if (!had_err) {
    switch (stm->results[field_no].buffer_type) {
      case MYSQL_TYPE_LONG:
      case MYSQL_TYPE_INT24:
        {int val = *(int*) stm->results[field_no].buffer;
        *result = val;}
        break;
      case MYSQL_TYPE_SHORT:
        {short int val = *(short int*) stm->results[field_no].buffer;
        *result = (int) val;}
        break;
      case MYSQL_TYPE_TINY:
        {signed char val = *(signed char*) stm->results[field_no].buffer;
        *result = (int) val;}
        break;
      default:
        gt_assert(false); /* should not happen */
    }
  }
  return had_err;
}
Пример #11
0
static GtRDBStmt* gt_rdb_mysql_prepare(GtRDB *rdb, const char *query,
                                       GtUword num_params, GtError *err)
{
  GtRDBStmt *st = NULL;
  GtRDBStmtMySQL *stm = NULL;
  GtRDBMySQL *rdbm;
  int had_err = 0, retval = 0;
  /* we need these to keep track of result/parameter and string buffers */
  HashElemInfo str_buffer_hash = {
      gt_ht_ptr_elem_hash,
      { free_str },
      sizeof (GtStr*),
      gt_ht_ptr_elem_cmp,
      NULL,
      NULL
    },
    buffer_hash = {
      gt_ht_ptr_elem_hash,
      { free_buf },
      sizeof (void*),
      gt_ht_ptr_elem_cmp,
      NULL,
      NULL
    };
  MYSQL_STMT *tmp = NULL;
  gt_assert(rdb && query);
  gt_error_check(err);

  rdbm = gt_rdb_mysql_cast(rdb);
  tmp = mysql_stmt_init(&rdbm->conn);
  if ((retval = mysql_stmt_prepare(tmp, query, strlen(query)))) {
    gt_error_set(err, GT_MYSQL_ERRMSG, retval, mysql_stmt_error(tmp));
    had_err = -1;
  }
  if (!had_err) {
    int param_count;
    param_count = mysql_stmt_param_count(tmp);
    if (param_count != num_params) {
      gt_error_set(err, "invalid parameter count: "GT_WU" expected, %d given",
                   num_params, param_count);
      mysql_stmt_close(tmp);
      had_err = -1;
    }
  }
  if (!had_err) {
    st = gt_rdb_stmt_create(gt_rdb_stmt_mysql_class());
    stm = gt_rdb_stmt_mysql_cast(st);
    stm->num_params = num_params;
    stm->query = gt_str_new_cstr(query);
    stm->buffers = gt_hashtable_new(buffer_hash);
    stm->returned_strings = gt_hashtable_new(str_buffer_hash);
    stm->stmt = tmp;
    stm->update_maxlengths = true;
    stm->params = gt_calloc(num_params, sizeof (MYSQL_BIND));
    mysql_stmt_attr_set(tmp, STMT_ATTR_UPDATE_MAX_LENGTH,
                        &stm->update_maxlengths);
    memset(stm->params, 0, num_params*sizeof (MYSQL_BIND));
    stm->conn = &rdbm->conn;
  }
  return st;
}
Пример #12
0
static int gt_rdb_stmt_mysql_exec(GtRDBStmt *st, GtError *err)
{
  GtRDBStmtMySQL *stm;
  int rval, had_err = 0, num_fields;
  MYSQL_RES *meta_res = NULL;
  gt_assert(st);
  gt_error_check(err);
  stm = gt_rdb_stmt_mysql_cast(st);
  if (!stm->executed) {
    if (stm->num_params > 0) {
      gt_assert(stm->stmt && stm->params);
      if ((rval = mysql_stmt_bind_param(stm->stmt, stm->params))) {
        gt_error_set(err, GT_MYSQL_ERRMSG, rval, mysql_stmt_error(stm->stmt));
        had_err = -1;
      }
    }
    if (!had_err && (rval = mysql_stmt_execute(stm->stmt))) {
      gt_error_set(err, GT_MYSQL_ERRMSG, rval, mysql_stmt_error(stm->stmt));
      had_err = -1;
    }
    if (!had_err) {
      stm->executed = true;
      if (mysql_stmt_store_result(stm->stmt)) {
        gt_error_set(err, GT_MYSQL_ERRMSG,
                     had_err, mysql_stmt_error(stm->stmt));
        had_err = -1;
      }
      meta_res = mysql_stmt_result_metadata(stm->stmt);
      if (!had_err && meta_res) {
        int i = 0;
        /* statement returned a result */
        num_fields = mysql_num_fields(meta_res);
        stm->results = gt_calloc(num_fields, sizeof (MYSQL_BIND));
        /* prepare result buffers for each field */
        for (i=0;i<num_fields;i++) {
          MYSQL_FIELD *field;
          field = mysql_fetch_field(meta_res);
          stm->results[i].buffer_type = field->type;
          switch (field->type) {
            case MYSQL_TYPE_DOUBLE:
              {double *dbl = gt_calloc(1, sizeof (double));
              gt_hashtable_add(stm->buffers, &dbl);
              stm->results[i].buffer_length = sizeof (double);
              stm->results[i].buffer = dbl;}
              break;
            case MYSQL_TYPE_LONG:
            case MYSQL_TYPE_INT24:
            {int *l = gt_calloc(1, sizeof (int));
              gt_hashtable_add(stm->buffers, &l);
              stm->results[i].is_unsigned = false;
              stm->results[i].buffer_length = sizeof (int);
              stm->results[i].buffer = l;}
            case MYSQL_TYPE_SHORT:
            {short int *l = gt_calloc(1, sizeof (short int));
              gt_hashtable_add(stm->buffers, &l);
              stm->results[i].is_unsigned = false;
              stm->results[i].buffer_length = sizeof (short int);
              stm->results[i].buffer = l;}
            case MYSQL_TYPE_TINY:
              {signed char *l = gt_calloc(1, sizeof (signed char));
              gt_hashtable_add(stm->buffers, &l);
              stm->results[i].is_unsigned = false;
              stm->results[i].buffer_length = sizeof (signed char);
              stm->results[i].buffer = l;}
              break;
            case MYSQL_TYPE_STRING:
            case MYSQL_TYPE_VAR_STRING:
            case MYSQL_TYPE_BLOB:
            case MYSQL_TYPE_TINY_BLOB:
            case MYSQL_TYPE_MEDIUM_BLOB:
            case MYSQL_TYPE_LONG_BLOB:
            case MYSQL_TYPE_BIT:
              {char *str = gt_calloc(field->max_length+1, sizeof (char));
              gt_hashtable_add(stm->buffers, &str);
              GtUword *length = gt_calloc(1, sizeof (GtUword));
              gt_hashtable_add(stm->buffers, &length);
              stm->results[i].buffer = str;
              stm->results[i].buffer_length = field->max_length;
              stm->results[i].length = length;}
              break;
            default:
              /* unsupported data type */
              break;
          }
        }
        if (!had_err)
          mysql_stmt_bind_result(stm->stmt, stm->results);
        mysql_free_result(meta_res);
      } else {
        return 1;
      }
    }
  }
  if (!had_err) {
    switch ((rval = mysql_stmt_fetch(stm->stmt))) {
      case 0:
      default:
        break;
      case MYSQL_NO_DATA:
        had_err = 1;  /* last row read */
        break;
      case 1:
        gt_error_set(err, GT_MYSQL_ERRMSG, mysql_stmt_errno(stm->stmt),
                     mysql_stmt_error(stm->stmt));
        had_err = -1;
        break;
    }
  }
  return had_err;
}