Ejemplo n.º 1
0
void *testcase_realloc(void *ptr, size_t size)
{
    return driver_realloc(ptr, size);
}
Ejemplo n.º 2
0
static void hash_table_insert(char *key_file, time_t mtime,
			     SSL_CTX *ssl_ctx)
{
   int level, split;
   uint32_t hash = str_hash(key_file);
   size_t bucket;
   int do_split = 0;
   struct bucket *el;
   struct bucket *new_bucket_el;

   split = ht.split;
   level = ht.level;

   bucket = hash & ((1 << level) - 1);
   if (bucket < split)
      bucket = hash & ((1 << (level + 1)) - 1);

   el = ht.buckets[bucket];
   while (el != NULL) {
      if (el->hash == hash && strcmp(el->key_file, key_file) == 0) {
	 el->mtime = mtime;
	 if (el->ssl_ctx != NULL)
	    SSL_CTX_free(el->ssl_ctx);
	 el->ssl_ctx = ssl_ctx;
	 break;
      }
      el = el->next;
   }

   if (el == NULL) {
      if (ht.buckets[bucket] != NULL)
	 do_split = !0;

      new_bucket_el = (struct bucket *)driver_alloc(sizeof(struct bucket));
      new_bucket_el->hash = hash;
      new_bucket_el->key_file = (char *)driver_alloc(strlen(key_file) + 1);
      strcpy(new_bucket_el->key_file, key_file);
      new_bucket_el->mtime = mtime;
      new_bucket_el->ssl_ctx = ssl_ctx;
      new_bucket_el->next = ht.buckets[bucket];
      ht.buckets[bucket] = new_bucket_el;
   }

   if (do_split) {
      struct bucket **el_ptr = &ht.buckets[split];
      size_t new_bucket = split + (1 << level);
      while (*el_ptr != NULL) {
	 uint32_t hash = (*el_ptr)->hash;
	 if ((hash & ((1 << (level + 1)) - 1)) == new_bucket) {
	    struct bucket *moved_el = *el_ptr;
	    *el_ptr = (*el_ptr)->next;
	    moved_el->next = ht.buckets[new_bucket];
	    ht.buckets[new_bucket] = moved_el;
	 } else
	    el_ptr = &(*el_ptr)->next;
      }
      split++;
      if (split == 1 << level) {
	 size_t size;
	 size_t i;
	 split = 0;
	 level++;
	 size = 1 << (level + 1);
	 ht.split = split;
	 ht.level = level;
	 ht.buckets = (struct bucket **)
	    driver_realloc(ht.buckets, sizeof(struct bucket *) * size);
	 for (i = 1 << level; i < size; i++)
	    ht.buckets[i] = NULL;
      } else
	 ht.split = split;
   }
}
Ejemplo n.º 3
0
static void sql_exec_async(void *_async_command) {
  async_sqlite3_command *async_command =
      (async_sqlite3_command *) _async_command;

  sqlite3_stmt *statement = NULL;
  int result;
  const char *rest;
  const char *end;
  int num_statements = 0;
  int term_count = 0, term_allocated = 0;
  ErlDrvTermData *dataset = NULL;

  sqlite3_drv_t *drv = async_command->driver_data;

  term_count += 2;
  if (term_count > term_allocated) {
    term_allocated = max(term_count, term_allocated*2);
    dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
  }
  dataset[term_count - 2] = ERL_DRV_PORT;
  dataset[term_count - 1] = driver_mk_port(drv->port);

  switch (async_command->type) {
  case t_stmt:
    statement = async_command->statement;
    sql_exec_one_statement(statement, async_command, &term_count,
                           &term_allocated, &dataset);
    break;
  case t_script:
    rest = async_command->script;
    end = async_command->end;

    while ((rest < end) && !(async_command->error_code)) {
      if (statement) {
        sqlite3_finalize(statement);
      }
      result = sqlite3_prepare_v2(drv->db, rest, end - rest, &statement, &rest);
      if (result != SQLITE_OK) {
        num_statements++;
        return_error(drv, result, sqlite3_errmsg(drv->db), &dataset,
                     &term_count, &term_allocated, &async_command->error_code);
        break;
      } else if (statement == NULL) {
        break;
      } else {
        num_statements++;
        result = sql_exec_one_statement(statement, async_command, &term_count,
                                        &term_allocated, &dataset);
        if (result) {
          break;
        }
      }
    }

    term_count += 3;
    if (term_count > term_allocated) {
      term_allocated = max(term_count, term_allocated*2);
      dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
    }
    dataset[term_count - 3] = ERL_DRV_NIL;
    dataset[term_count - 2] = ERL_DRV_LIST;
    dataset[term_count - 1] = num_statements + 1;
  }

  term_count += 2;
  if (term_count > term_allocated) {
    term_allocated = max(term_count, term_allocated*2);
    dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
  }
  dataset[term_count - 2] = ERL_DRV_TUPLE;
  dataset[term_count - 1] = 2;

  // print_dataset(dataset, term_count);

  async_command->term_count = term_count;
  async_command->term_allocated = term_allocated;
  async_command->dataset = dataset;
}
Ejemplo n.º 4
0
static void sql_step_async(void *_async_command) {
  async_sqlite3_command *async_command =
      (async_sqlite3_command *) _async_command;
  int term_count = 0;
  int term_allocated = 0;
  ErlDrvTermData *dataset = NULL;
  sqlite3_drv_t *drv = async_command->driver_data;

  int column_count = 0;
  sqlite3_stmt *statement = async_command->statement;

  ptr_list *ptrs = NULL;
  ptr_list *binaries = NULL;
  int i;
  int result;

  switch(result = sqlite3_step(statement)) {
  case SQLITE_ROW:
    column_count = sqlite3_column_count(statement);
    term_count += 2;
    if (term_count > term_allocated) {
      term_allocated = max(term_count, term_allocated*2);
      dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
    }
    dataset[term_count - 2] = ERL_DRV_PORT;
    dataset[term_count - 1] = driver_mk_port(drv->port);

    for (i = 0; i < column_count; i++) {
#ifdef DEBUG
      fprintf(drv->log, "Column %d type: %d\n", i, sqlite3_column_type(statement, i));
      fflush(drv->log);
#endif
      switch (sqlite3_column_type(statement, i)) {
      case SQLITE_INTEGER: {
        ErlDrvSInt64 *int64_ptr = driver_alloc(sizeof(ErlDrvSInt64));
        *int64_ptr = (ErlDrvSInt64) sqlite3_column_int64(statement, i);
        ptrs = add_to_ptr_list(ptrs, int64_ptr);

        term_count += 2;
        if (term_count > term_allocated) {
          term_allocated = max(term_count, term_allocated*2);
          dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
        }
        dataset[term_count - 2] = ERL_DRV_INT64;
        dataset[term_count - 1] = (ErlDrvTermData) int64_ptr;
        break;
      }
      case SQLITE_FLOAT: {
        double *float_ptr = driver_alloc(sizeof(double));
        *float_ptr = sqlite3_column_double(statement, i);
        ptrs = add_to_ptr_list(ptrs, float_ptr);

        term_count += 2;
        if (term_count > term_allocated) {
          term_allocated = max(term_count, term_allocated*2);
          dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
        }
        dataset[term_count - 2] = ERL_DRV_FLOAT;
        dataset[term_count - 1] = (ErlDrvTermData) float_ptr;
        break;
      }
      case SQLITE_BLOB: {
        int bytes = sqlite3_column_bytes(statement, i);
        ErlDrvBinary* binary = driver_alloc_binary(bytes);
        binary->orig_size = bytes;
        memcpy(binary->orig_bytes,
               sqlite3_column_blob(statement, i), bytes);
        binaries = add_to_ptr_list(binaries, binary);

        term_count += 8;
        if (term_count > term_allocated) {
          term_allocated = max(term_count, term_allocated*2);
          dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
        }
        dataset[term_count - 8] = ERL_DRV_ATOM;
        dataset[term_count - 7] = drv->atom_blob;
        dataset[term_count - 6] = ERL_DRV_BINARY;
        dataset[term_count - 5] = (ErlDrvTermData) binary;
        dataset[term_count - 4] = bytes;
        dataset[term_count - 3] = 0;
        dataset[term_count - 2] = ERL_DRV_TUPLE;
        dataset[term_count - 1] = 2;
        break;
      }
      case SQLITE_TEXT: {
        int bytes = sqlite3_column_bytes(statement, i);
        ErlDrvBinary* binary = driver_alloc_binary(bytes);
        binary->orig_size = bytes;
        memcpy(binary->orig_bytes,
               sqlite3_column_blob(statement, i), bytes);
        binaries = add_to_ptr_list(binaries, binary);

        term_count += 4;
        if (term_count > term_allocated) {
          term_allocated = max(term_count, term_allocated*2);
          dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
        }
        dataset[term_count - 4] = ERL_DRV_BINARY;
        dataset[term_count - 3] = (ErlDrvTermData) binary;
        dataset[term_count - 2] = bytes;
        dataset[term_count - 1] = 0;
        break;
      }
      case SQLITE_NULL: {
        term_count += 2;
        if (term_count > term_allocated) {
          term_allocated = max(term_count, term_allocated*2);
          dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
        }
        dataset[term_count - 2] = ERL_DRV_ATOM;
        dataset[term_count - 1] = drv->atom_null;
        break;
      }
      }
    }
    term_count += 2;
    if (term_count > term_allocated) {
      term_allocated = max(term_count, term_allocated*2);
      dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
    }
    dataset[term_count - 2] = ERL_DRV_TUPLE;
    dataset[term_count - 1] = column_count;

    async_command->ptrs = ptrs;
    async_command->binaries = binaries;
    break;
  case SQLITE_DONE:
    term_count += 4;
    if (term_count > term_allocated) {
      term_allocated = max(term_count, term_allocated*2);
      dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
    }
    dataset[term_count - 4] = ERL_DRV_PORT;
    dataset[term_count - 3] = driver_mk_port(drv->port);
    dataset[term_count - 2] = ERL_DRV_ATOM;
    dataset[term_count - 1] = drv->atom_done;
    sqlite3_reset(statement);
    break;
  case SQLITE_BUSY:
    return_error(drv, SQLITE_BUSY, "SQLite3 database is busy",
                 &dataset, &term_count, &term_allocated,
                 &async_command->error_code);
    sqlite3_reset(statement);
    goto POPULATE_COMMAND;
    break;
  default:
    return_error(drv, result, sqlite3_errmsg(drv->db),
                 &dataset, &term_count, &term_allocated,
                 &async_command->error_code);
    sqlite3_reset(statement);
    goto POPULATE_COMMAND;
  }

  term_count += 2;
  if (term_count > term_allocated) {
    term_allocated = max(term_count, term_allocated*2);
    dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated);
  }
  dataset[term_count - 2] = ERL_DRV_TUPLE;
  dataset[term_count - 1] = 2;

POPULATE_COMMAND:
  async_command->dataset = dataset;
  async_command->term_count = term_count;
  async_command->ptrs = ptrs;
  async_command->binaries = binaries;
  async_command->row_count = 1;
#ifdef DEBUG
  fprintf(drv->log, "Total term count: %p %d, columns count: %d\n", statement, term_count, column_count);
  fflush(drv->log);
#endif
}
Ejemplo n.º 5
0
static int sql_exec_one_statement(
    sqlite3_stmt *statement, async_sqlite3_command *async_command,
    int *term_count_p, int *term_allocated_p, ErlDrvTermData **dataset_p) {
  int column_count = sqlite3_column_count(statement);
  int row_count = 0, next_row;
  int base_term_count;
  sqlite3_drv_t *drv = async_command->driver_data;
  ptr_list **ptrs_p = &(async_command->ptrs);
  ptr_list **binaries_p = &(async_command->binaries);
  // printf("\nsql_exec_one_statement. SQL:\n%s\n Term count: %d, terms alloc: %d\n", sqlite3_sql(statement), *term_count_p, *term_allocated_p);

  int i;

  if (column_count > 0) {
    *term_count_p += 2;
    if (*term_count_p > *term_allocated_p) {
      *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
      *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
    }
    (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM;
    (*dataset_p)[*term_count_p - 1] = drv->atom_columns;
    base_term_count = *term_count_p;
    get_columns(
        drv, statement, column_count, base_term_count, term_count_p, term_allocated_p, dataset_p);
    *term_count_p += 4;
    if (*term_count_p > *term_allocated_p) {
      *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
      *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
    }
    (*dataset_p)[base_term_count + column_count * 3 + 3] = ERL_DRV_TUPLE;
    (*dataset_p)[base_term_count + column_count * 3 + 4] = 2;

    (*dataset_p)[base_term_count + column_count * 3 + 5] = ERL_DRV_ATOM;
    (*dataset_p)[base_term_count + column_count * 3 + 6] = drv->atom_rows;
  }

#ifdef DEBUG
  fprintf(drv->log, "Exec: %s\n", sqlite3_sql(statement));
  fflush(drv->log);
#endif

  while ((next_row = sqlite3_step(statement)) == SQLITE_ROW) {
    for (i = 0; i < column_count; i++) {
#ifdef DEBUG
      fprintf(drv->log, "Column %d type: %d\n", i, sqlite3_column_type(statement, i));
      fflush(drv->log);
#endif
      switch (sqlite3_column_type(statement, i)) {
      case SQLITE_INTEGER: {
        ErlDrvSInt64 *int64_ptr = driver_alloc(sizeof(ErlDrvSInt64));
        *int64_ptr = (ErlDrvSInt64) sqlite3_column_int64(statement, i);
        *ptrs_p = add_to_ptr_list(*ptrs_p, int64_ptr);

        *term_count_p += 2;
        if (*term_count_p > *term_allocated_p) {
          *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
          *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
        }
        (*dataset_p)[*term_count_p - 2] = ERL_DRV_INT64;
        (*dataset_p)[*term_count_p - 1] = (ErlDrvTermData) int64_ptr;
        break;
      }
      case SQLITE_FLOAT: {
        double *float_ptr = driver_alloc(sizeof(double));
        *float_ptr = sqlite3_column_double(statement, i);
        *ptrs_p = add_to_ptr_list(*ptrs_p, float_ptr);

        *term_count_p += 2;
        if (*term_count_p > *term_allocated_p) {
          *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
          *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
        }
        (*dataset_p)[*term_count_p - 2] = ERL_DRV_FLOAT;
        (*dataset_p)[*term_count_p - 1] = (ErlDrvTermData) float_ptr;
        break;
      }
      case SQLITE_BLOB: {
        int bytes = sqlite3_column_bytes(statement, i);
        ErlDrvBinary* binary = driver_alloc_binary(bytes);
        binary->orig_size = bytes;
        memcpy(binary->orig_bytes,
               sqlite3_column_blob(statement, i), bytes);
        *binaries_p = add_to_ptr_list(*binaries_p, binary);

        *term_count_p += 8;
        if (*term_count_p > *term_allocated_p) {
          *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
          *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
        }
        (*dataset_p)[*term_count_p - 8] = ERL_DRV_ATOM;
        (*dataset_p)[*term_count_p - 7] = drv->atom_blob;
        (*dataset_p)[*term_count_p - 6] = ERL_DRV_BINARY;
        (*dataset_p)[*term_count_p - 5] = (ErlDrvTermData) binary;
        (*dataset_p)[*term_count_p - 4] = bytes;
        (*dataset_p)[*term_count_p - 3] = 0;
        (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE;
        (*dataset_p)[*term_count_p - 1] = 2;
        break;
      }
      case SQLITE_TEXT: {
        int bytes = sqlite3_column_bytes(statement, i);
        ErlDrvBinary* binary = driver_alloc_binary(bytes);
        binary->orig_size = bytes;
        memcpy(binary->orig_bytes,
               sqlite3_column_blob(statement, i), bytes);
        *binaries_p = add_to_ptr_list(*binaries_p, binary);

        *term_count_p += 4;
        if (*term_count_p > *term_allocated_p) {
          *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
          *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
        }
        (*dataset_p)[*term_count_p - 4] = ERL_DRV_BINARY;
        (*dataset_p)[*term_count_p - 3] = (ErlDrvTermData) binary;
        (*dataset_p)[*term_count_p - 2] = bytes;
        (*dataset_p)[*term_count_p - 1] = 0;
        break;
      }
      case SQLITE_NULL: {
        *term_count_p += 2;
        if (*term_count_p > *term_allocated_p) {
          *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
          *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
        }
        (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM;
        (*dataset_p)[*term_count_p - 1] = drv->atom_null;
        break;
      }
      }
    }
    *term_count_p += 2;
    if (*term_count_p > *term_allocated_p) {
      *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
      *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
    }
    (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE;
    (*dataset_p)[*term_count_p - 1] = column_count;

    row_count++;
  }

  if (next_row == SQLITE_BUSY) {
    return_error(drv, SQLITE_BUSY, "SQLite3 database is busy",
                 dataset_p, term_count_p,
                 term_allocated_p, &async_command->error_code);
    async_command->finalize_statement_on_free = 1;
    return next_row;
  }
  if (next_row != SQLITE_DONE) {
    return_error(drv, next_row, sqlite3_errmsg(drv->db),
                 dataset_p, term_count_p,
                 term_allocated_p, &async_command->error_code);
    async_command->finalize_statement_on_free = 1;
    return next_row;
  }

  if (column_count > 0) {
    *term_count_p += 3+2+3;
    if (*term_count_p > *term_allocated_p) {
      *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
      *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
    }
    (*dataset_p)[*term_count_p - 8] = ERL_DRV_NIL;
    (*dataset_p)[*term_count_p - 7] = ERL_DRV_LIST;
    (*dataset_p)[*term_count_p - 6] = row_count + 1;

    (*dataset_p)[*term_count_p - 5] = ERL_DRV_TUPLE;
    (*dataset_p)[*term_count_p - 4] = 2;

    (*dataset_p)[*term_count_p - 3] = ERL_DRV_NIL;
    (*dataset_p)[*term_count_p - 2] = ERL_DRV_LIST;
    (*dataset_p)[*term_count_p - 1] = 3;
  } else if (sql_is_insert(sqlite3_sql(statement))) {
    ErlDrvSInt64 *rowid_ptr = driver_alloc(sizeof(ErlDrvSInt64));
    *rowid_ptr = (ErlDrvSInt64) sqlite3_last_insert_rowid(drv->db);
    *ptrs_p = add_to_ptr_list(*ptrs_p, rowid_ptr);
    *term_count_p += 6;
    if (*term_count_p > *term_allocated_p) {
      *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
      *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
    }
    (*dataset_p)[*term_count_p - 6] = ERL_DRV_ATOM;
    (*dataset_p)[*term_count_p - 5] = drv->atom_rowid;
    (*dataset_p)[*term_count_p - 4] = ERL_DRV_INT64;
    (*dataset_p)[*term_count_p - 3] = (ErlDrvTermData) rowid_ptr;
    (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE;
    (*dataset_p)[*term_count_p - 1] = 2;
  } else {
    *term_count_p += 2;
    if (*term_count_p > *term_allocated_p) {
      *term_allocated_p = max(*term_count_p, *term_allocated_p*2);
      *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p);
    }
    (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM;
    (*dataset_p)[*term_count_p - 1] = drv->atom_ok;
  }

#ifdef DEBUG
  fprintf(drv->log, "Total term count: %p %d, rows count: %dx%d\n", statement, *term_count_p, column_count, row_count);
  fflush(drv->log);
#endif
  async_command->finalize_statement_on_free = 1;

  return 0;
}