Ejemplo n.º 1
0
static int set_schema_version(pool *p, const char *schema_name,
    unsigned int schema_version) {
  int res, xerrno = 0;
  const char *stmt, *errstr = NULL;
  array_header *results;

  /* CREATE TABLE $schema_name.schema_version (
   *   schema TEXT NOT NULL PRIMARY KEY,
   *   version INTEGER NOT NULL
   * );
   */
  stmt = pstrcat(p, "CREATE TABLE IF NOT EXISTS ", schema_name, ".schema_version (schema TEXT NOT NULL PRIMARY KEY, version INTEGER NOT NULL);", NULL);
  res = proxy_db_exec_stmt(p, stmt, &errstr);
  if (res < 0) {
    (void) pr_log_debug(DEBUG3, MOD_PROXY_VERSION
      ": error executing statement '%s': %s", stmt, errstr);
    errno = EPERM;
    return -1;
  }

  stmt = pstrcat(p, "INSERT INTO ", schema_name, ".schema_version (schema, version) VALUES (?, ?);", NULL);
  res = proxy_db_prepare_stmt(p, stmt);
  if (res < 0) {
    xerrno = errno;

    (void) pr_log_debug(DEBUG3, MOD_PROXY_VERSION
      ": error preparing statement '%s': %s", stmt, strerror(xerrno));
    errno = xerrno;
    return -1;
  }

  res = proxy_db_bind_stmt(p, stmt, 1, PROXY_DB_BIND_TYPE_TEXT,
    (void *) schema_name);
  if (res < 0) {
    return -1;
  }

  res = proxy_db_bind_stmt(p, stmt, 2, PROXY_DB_BIND_TYPE_INT,
    (void *) &schema_version);
  if (res < 0) {
    return -1;
  }

  results = proxy_db_exec_prepared_stmt(p, stmt, &errstr);
  if (results == NULL) {
    (void) pr_log_debug(DEBUG3, MOD_PROXY_VERSION
      ": error executing statement '%s': %s", stmt,
      errstr ? errstr : strerror(errno));
    errno = EPERM;
    return -1;
  }

  return 0;
}
Ejemplo n.º 2
0
static int get_schema_version(pool *p, const char *schema_name,
    unsigned int *schema_version) {
  int res, version;
  const char *stmt, *errstr = NULL;
  array_header *results;

  stmt = pstrcat(p, "SELECT version FROM ", schema_name, ".schema_version WHERE schema = ?;", NULL);
  res = proxy_db_prepare_stmt(p, stmt);
  if (res < 0) {
    /* This can happen when the schema_version table does not exist; treat
     * as "missing".
     */
    pr_trace_msg(trace_channel, 5,
      "error preparing statement '%s', treating as missing schema version",
      stmt);
    *schema_version = 0;
    return 0;
  }

  res = proxy_db_bind_stmt(p, stmt, 1, PROXY_DB_BIND_TYPE_TEXT,
    (void *) schema_name);
  if (res < 0) {
    return -1;
  }

  results = proxy_db_exec_prepared_stmt(p, stmt, &errstr);
  if (results == NULL) {
    *schema_version = 0;
    return 0;
  }

  if (results->nelts != 1) {
    pr_log_debug(DEBUG3, MOD_PROXY_VERSION
      ": expected 1 result from statement '%s', got %d", stmt,
      results->nelts);
    errno = EINVAL;
    return -1;
  }

  version = atoi(((char **) results->elts)[0]);
  if (version < 0) {
    /* Invalid schema version; treat as "missing". */
    pr_trace_msg(trace_channel, 5,
      "statement '%s' yielded invalid schema version %d, treating as missing",
      stmt, version);
    *schema_version = 0;
    return 0;
  }

  *schema_version = version;
  return 0;
}
Ejemplo n.º 3
0
END_TEST

START_TEST (db_bind_stmt_test) {
  int res;
  const char *table_path, *schema_name, *stmt;
  int idx, int_val;
  long long_val;
  char *text_val;

  res = proxy_db_bind_stmt(NULL, NULL, -1, -1, NULL);
  fail_unless(res < 0, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  res = proxy_db_bind_stmt(p, NULL, -1, -1, NULL);
  fail_unless(res < 0, "Failed to handle null statement");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  stmt = "SELECT COUNT(*) FROM table";
  idx = -1;
  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, NULL);
  fail_unless(res < 0, "Failed to handle invalid index %d", idx);
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  idx = 1;
  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, NULL);
  fail_unless(res < 0, "Failed to handle unprepared statement");
  fail_unless(errno == ENOENT, "Expected ENOENT (%d), got '%s' (%d)", ENOENT,
    strerror(errno), errno);

  (void) unlink(db_test_table);
  table_path = db_test_table;
  schema_name = "proxy_test";

  res = proxy_db_open(p, table_path, schema_name);
  fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s",
    table_path, schema_name, strerror(errno));

  res = create_table(p, schema_name, "foo");
  fail_unless(res == 0, "Failed to create table 'foo': %s", strerror(errno));

  stmt = "SELECT COUNT(*) FROM foo;";
  res = proxy_db_prepare_stmt(p, stmt);
  fail_unless(res == 0, "Failed to prepare statement '%s': %s", stmt,
    strerror(errno));

  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, NULL);
  fail_unless(res < 0, "Failed to handle missing INT value");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  int_val = 7;
  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, &int_val);
  fail_unless(res < 0, "Failed to handle invalid index value");
  fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM,
    strerror(errno), errno);

  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_LONG, NULL);
  fail_unless(res < 0, "Failed to handle missing LONG value");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  long_val = 7;
  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_LONG, &long_val);
  fail_unless(res < 0, "Failed to handle invalid index value");
  fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM,
    strerror(errno), errno);

  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_TEXT, NULL);
  fail_unless(res < 0, "Failed to handle missing TEXT value");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  text_val = "testing";
  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_TEXT, text_val);
  fail_unless(res < 0, "Failed to handle invalid index value");
  fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM,
    strerror(errno), errno);

  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_NULL, NULL);
  fail_unless(res < 0, "Failed to handle invalid NULL value");
  fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM,
    strerror(errno), errno);

  stmt = "SELECT COUNT(*) FROM foo WHERE id = ?;";
  res = proxy_db_prepare_stmt(p, stmt);
  fail_unless(res == 0, "Failed to prepare statement '%s': %s", stmt,
    strerror(errno));

  int_val = 7;
  res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, &int_val);
  fail_unless(res == 0, "Failed to bind INT value: %s", strerror(errno));

  res = proxy_db_close(p, NULL);
  fail_unless(res == 0, "Failed to close database: %s", strerror(errno));
  (void) unlink(db_test_table);
}