static ERL_NIF_TERM do_column_names(ErlNifEnv *env, sqlite3_stmt *stmt) { int i, size; const char *name; ERL_NIF_TERM *array; ERL_NIF_TERM column_names; size = sqlite3_column_count(stmt); if(size <= 0) return make_error_tuple(env, "no_columns"); array = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * size); if(!array) return make_error_tuple(env, "no_memory"); for(i = 0; i < size; i++) { name = sqlite3_column_name(stmt, i); if(name == NULL) { free(array); return make_error_tuple(env, "sqlite3_malloc_failure"); } array[i] = make_atom(env, name); } column_names = enif_make_tuple_from_array(env, array, size); free(array); return column_names; }
static ERL_NIF_TERM do_bind(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt, const ERL_NIF_TERM arg) { int parameter_count = sqlite3_bind_parameter_count(stmt); int i, is_list, r; ERL_NIF_TERM list, head, tail; unsigned int list_length; is_list = enif_get_list_length(env, arg, &list_length); if(!is_list) return make_error_tuple(env, "bad_arg_list"); if(parameter_count != list_length) return make_error_tuple(env, "args_wrong_length"); sqlite3_reset(stmt); list = arg; for(i=0; i < list_length; i++) { enif_get_list_cell(env, list, &head, &tail); r = bind_cell(env, head, stmt, i+1); if(r == -1) return make_error_tuple(env, "wrong_type"); if(r != SQLITE_OK) return make_sqlite3_error_tuple(env, r, db); list = tail; } return make_atom(env, "ok"); }
static ERL_NIF_TERM do_prepare(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg) { ErlNifBinary bin; esqlite_statement *stmt; ERL_NIF_TERM esqlite_stmt; const char *tail; int rc; ERL_NIF_TERM eos = enif_make_int(env, 0); if(!enif_inspect_iolist_as_binary(env, enif_make_list2(env, arg, eos), &bin)) return make_error_tuple(env, "not an iolist"); stmt = enif_alloc_resource(esqlite_statement_type, sizeof(esqlite_statement)); if(!stmt) return make_error_tuple(env, "no_memory"); rc = sqlite3_prepare_v2(conn->db, (char *) bin.data, bin.size, &(stmt->statement), &tail); if(rc != SQLITE_OK) { enif_release_resource(stmt); return make_sqlite3_error_tuple(env, rc, conn->db); } esqlite_stmt = enif_make_resource(env, stmt); enif_release_resource(stmt); return make_ok_tuple(env, esqlite_stmt); }
/* * Open the database */ static ERL_NIF_TERM esqlite_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { esqlite_connection *db; esqlite_command *cmd = NULL; ErlNifPid pid; if(argc != 4) return enif_make_badarg(env); if(!enif_get_resource(env, argv[0], esqlite_connection_type, (void **) &db)) return enif_make_badarg(env); if(!enif_is_ref(env, argv[1])) return make_error_tuple(env, "invalid_ref"); if(!enif_get_local_pid(env, argv[2], &pid)) return make_error_tuple(env, "invalid_pid"); /* Note, no check is made for the type of the argument */ cmd = command_create(); if(!cmd) return make_error_tuple(env, "command_create_failed"); cmd->type = cmd_open; cmd->ref = enif_make_copy(cmd->env, argv[1]); cmd->pid = pid; cmd->arg = enif_make_copy(cmd->env, argv[3]); return push_command(env, db, cmd); }
/* * Start the processing thread */ static ERL_NIF_TERM esqlite_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { esqlite_connection *conn; ERL_NIF_TERM db_conn; /* Initialize the resource */ conn = enif_alloc_resource(esqlite_connection_type, sizeof(esqlite_connection)); if(!conn) return make_error_tuple(env, "no_memory"); conn->db = NULL; /* Create command queue */ conn->commands = queue_create(); if(!conn->commands) { enif_release_resource(conn); return make_error_tuple(env, "command_queue_create_failed"); } /* Start command processing thread */ conn->opts = enif_thread_opts_create("esqldb_thread_opts"); if(enif_thread_create("esqlite_connection", &conn->tid, esqlite_connection_run, conn, conn->opts) != 0) { enif_release_resource(conn); return make_error_tuple(env, "thread_create_failed"); } db_conn = enif_make_resource(env, conn); enif_release_resource(conn); return make_ok_tuple(env, db_conn); }
/* * Prepare the sql statement */ static ERL_NIF_TERM esqlite_prepare(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { esqlite_connection *conn; esqlite_command *cmd = NULL; ErlNifPid pid; if(argc != 4) return enif_make_badarg(env); if(!enif_get_resource(env, argv[0], esqlite_connection_type, (void **) &conn)) return enif_make_badarg(env); if(!enif_is_ref(env, argv[1])) return make_error_tuple(env, "invalid_ref"); if(!enif_get_local_pid(env, argv[2], &pid)) return make_error_tuple(env, "invalid_pid"); cmd = command_create(); if(!cmd) return make_error_tuple(env, "command_create_failed"); cmd->type = cmd_prepare; cmd->ref = enif_make_copy(cmd->env, argv[1]); cmd->pid = pid; cmd->arg = enif_make_copy(cmd->env, argv[3]); return push_command(env, conn, cmd); }
/* * Bind a variable to a prepared statement */ static ERL_NIF_TERM esqlite_bind(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { esqlite_statement *stmt; esqlite_command *cmd = NULL; ErlNifPid pid; if(argc != 4) return enif_make_badarg(env); if(!enif_get_resource(env, argv[0], esqlite_statement_type, (void **) &stmt)) return enif_make_badarg(env); if(!enif_is_ref(env, argv[1])) return make_error_tuple(env, "invalid_ref"); if(!enif_get_local_pid(env, argv[2], &pid)) return make_error_tuple(env, "invalid_pid"); cmd = command_create(); if(!cmd) return make_error_tuple(env, "command_create_failed"); cmd->type = cmd_bind; cmd->ref = enif_make_copy(cmd->env, argv[1]); cmd->pid = pid; cmd->stmt = stmt->statement; cmd->arg = enif_make_copy(cmd->env, argv[3]); if(!stmt->connection) return make_error_tuple(env, "no_connection"); if(!stmt->connection->commands) return make_error_tuple(env, "no_command_queue"); return push_command(env, stmt->connection, cmd); }
static ERL_NIF_TERM elua_newstate_async(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { msg_t *msg; ErlNifPid pid; if(argc != 2) { return enif_make_badarg(env); } // ref if(!enif_is_ref(env, argv[0])){ return make_error_tuple(env, "invalid_ref"); } // dest pid if(!enif_get_local_pid(env, argv[1], &pid)) { return make_error_tuple(env, "invalid_pid"); } msg = msg_create(); if(!msg) { return make_error_tuple(env, "command_create_failed"); } msg->type = msg_newstate; msg->ref = enif_make_copy(msg->env, argv[0]); msg->pid = pid; msg->hold_env = env; msg->res=NULL; return push_command(env, NULL, msg); }
static ERL_NIF_TERM do_column_types(ErlNifEnv *env, sqlite3_stmt *stmt) { int i, size; const char *type; ERL_NIF_TERM *array; ERL_NIF_TERM column_types; size = sqlite3_column_count(stmt); if(size == 0) return enif_make_tuple(env, 0); else if(size < 0) return make_error_tuple(env, "invalid_column_count"); array = (ERL_NIF_TERM *) enif_alloc(sizeof(ERL_NIF_TERM) * size); if(!array) return make_error_tuple(env, "no_memory"); for(i = 0; i < size; i++) { type = sqlite3_column_decltype(stmt, i); if(type == NULL) { type = "nil"; } array[i] = make_atom(env, type); } column_types = enif_make_tuple_from_array(env, array, size); enif_free(array); return column_types; }
static ERL_NIF_TERM do_set_update_hook(ErlNifEnv *env, esqlite_connection *db, const ERL_NIF_TERM arg) { if(!enif_get_local_pid(env, arg, &db->notification_pid)) return make_error_tuple(env, "invalid_pid"); sqlite3_update_hook(db->db, NULL, NULL); if(sqlite3_update_hook(db->db, update_callback, db) != SQLITE_OK) return make_error_tuple(env, "sqlite3_update_hook_fail"); return make_atom(env, "ok"); }
static ERL_NIF_TERM emmap_pread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned long pos, bytes; mhandle *handle; if (argc==3 && enif_get_resource(env, argv[0], MMAP_RESOURCE, (void**)&handle) && enif_get_ulong(env, argv[1], &pos) && enif_get_ulong(env, argv[2], &bytes) && pos >= 0 && bytes >= 0 && (pos + bytes) <= handle->len ) { ErlNifBinary bin; if ((handle->prot & PROT_READ) == 0) { return make_error_tuple(env, EACCES); } // if this mmap is direct, use a resource binary if (handle->direct) { ERL_NIF_TERM res = enif_make_resource_binary (env, handle, (void*) (((char*)handle->mem) + pos), bytes); return enif_make_tuple2(env, ATOM_OK, res); } else { // When it is non-direct, we have to allocate the binary if (!enif_alloc_binary((size_t) bytes, &bin)) { return make_error_tuple(env, ENOMEM); } R_LOCK; if (handle->closed) { R_UNLOCK; return enif_make_badarg(env); } memcpy(bin.data, (void*) (((char*)handle->mem) + pos), bytes); R_UNLOCK; ERL_NIF_TERM res = enif_make_binary(env, &bin); return enif_make_tuple2(env, ATOM_OK, res); } } else { return enif_make_badarg(env); } }
static ERL_NIF_TERM evaluate_command(esqlite_command *cmd, esqlite_connection *conn) { switch(cmd->type) { case cmd_open: return do_open(cmd->env, conn, cmd->arg); case cmd_exec: return do_exec(cmd->env, conn, cmd->arg); case cmd_changes: return do_changes(cmd->env, conn, cmd->arg); case cmd_prepare: return do_prepare(cmd->env, conn, cmd->arg); case cmd_step: return do_step(cmd->env, conn->db, cmd->stmt); case cmd_reset: return do_reset(cmd->env, conn->db, cmd->stmt); case cmd_bind: return do_bind(cmd->env, conn->db, cmd->stmt, cmd->arg); case cmd_column_names: return do_column_names(cmd->env, cmd->stmt); case cmd_close: return do_close(cmd->env, conn, cmd->arg); case cmd_insert: return do_insert(cmd->env, conn, cmd->arg); default: return make_error_tuple(cmd->env, "invalid_command"); } }
ERL_NIF_TERM x_conf_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char * func_name = "x_conf_set()"; logger.debug(MOD_NAME, func_name, "Entered"); uint64_t id; char option[MAX_NAME_LEN]; memset(option, 0, MAX_NAME_LEN); char value[MAX_NAME_LEN]; memset(value, 0, MAX_NAME_LEN); if (!enif_get_uint64(env, argv[0], &id) || !enif_get_string(env, argv[1], option, MAX_NAME_LEN, ERL_NIF_LATIN1) || !enif_get_string(env, argv[1], option, MAX_NAME_LEN, ERL_NIF_LATIN1)) { logger.error(MOD_NAME, func_name, "enif get params failed"); return enif_make_badarg(env); } logger.debug(MOD_NAME, func_name, "cluster : %ld", id); rados_t cluster = map_cluster_get(id); if (cluster == NULL) { logger.error(MOD_NAME, func_name, "cluster non-existing : %ld", id); return enif_make_badarg(env); } int err = rados_conf_set(cluster, option, value); if (err < 0) { return make_error_tuple(env, -err); } return enif_make_atom(env, "ok"); }
static ERL_NIF_TERM push_command(ErlNifEnv *env, esqlite_connection *conn, esqlite_command *cmd) { if(!queue_push(conn->commands, cmd)) return make_error_tuple(env, "command_push_failed"); return make_atom(env, "ok"); }
static ERL_NIF_TERM do_open(ErlNifEnv *env, esqlite_connection *db, const ERL_NIF_TERM arg) { char filename[MAX_PATHNAME]; unsigned int size; int rc; ERL_NIF_TERM error; size = enif_get_string(env, arg, filename, MAX_PATHNAME, ERL_NIF_LATIN1); if(size <= 0) return make_error_tuple(env, "invalid_filename"); /* Open the database. */ rc = sqlite3_open(filename, &db->db); if(rc != SQLITE_OK) { error = make_sqlite3_error_tuple(env, rc, db->db); sqlite3_close(db->db); db->db = NULL; return error; } return make_atom(env, "ok"); }
ERL_NIF_TERM x_create_with_user(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char * func_name = "x_create_with_user()"; logger.debug(MOD_NAME, func_name, "Entered"); char name[MAX_NAME_LEN]; memset(name, 0, MAX_NAME_LEN); if (!enif_get_string(env, argv[0], name, MAX_NAME_LEN, ERL_NIF_LATIN1)) { logger.error(MOD_NAME, func_name, "enif get params failed"); return enif_make_badarg(env); } rados_t cluster; int err = rados_create(&cluster, name); if (err < 0) { logger.error(MOD_NAME, func_name, "Unable to create cluster handle with name: %s", name); return make_error_tuple(env, -err); } uint64_t id = new_id(); map_cluster_add(id, cluster); logger.debug(MOD_NAME, func_name, "cluster : %ld", id); return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_uint64(env, id)); }
static ERL_NIF_TERM push_command(ErlNifEnv *env, elua_t *res, msg_t *msg) { Tracker *tracker = (Tracker*) enif_priv_data(env); int hash_idx; if(res==NULL){ hash_idx=0; }else{ hash_idx=worker_hash(res->L); } assert(hash_idx>=0 && hash_idx< WORKER_NO); worker_t *w = &tracker->workers[hash_idx]; if(res!=NULL) { enif_keep_resource(res); } if(!queue_push(w->q, msg)){ if(res!=NULL) { enif_release_resource(res); } return make_error_tuple(env, "command_push_failed"); } // printf("%d send\n", w->id); return atom_ok; }
ERL_NIF_TERM x_pool_lookup(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { uint64_t id; char pool_name[MAX_NAME_LEN]; if (!enif_get_uint64(env, argv[0], &id) || !enif_get_string(env, argv[1], pool_name, MAX_NAME_LEN, ERL_NIF_LATIN1)) { return enif_make_badarg(env); } rados_t cluster = map_cluster_get(id); if (cluster == NULL) { return enif_make_badarg(env); } int64_t err = rados_pool_lookup(cluster, pool_name); if (err < 0) { return make_error_tuple(env, -err); } return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_int64(env, err)); // Pool ID }
static ERL_NIF_TERM emmap_pwrite(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; unsigned long pos; mhandle *handle; if (argc==3 && enif_get_resource(env, argv[0], MMAP_RESOURCE, (void**)&handle) && enif_get_ulong(env, argv[1], &pos) && enif_inspect_binary(env, argv[2], &bin) && pos >= 0 && (pos + bin.size) <= handle->len ) { if ((handle->prot & PROT_WRITE) == 0) { return make_error_tuple(env, EACCES); } RW_LOCK; if (handle->closed) { RW_UNLOCK; return enif_make_badarg(env); } else { memcpy((void*) (((char*)handle->mem) + pos), bin.data, bin.size); RW_UNLOCK; } return ATOM_OK; } else { return enif_make_badarg(env); } }
ERL_NIF_TERM x_pool_create_for_user(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { uint64_t id; char pool_name[MAX_NAME_LEN]; uint64_t uid; if (!enif_get_uint64(env, argv[0], &id) || !enif_get_string(env, argv[1], pool_name, MAX_NAME_LEN, ERL_NIF_LATIN1) || !enif_get_uint64(env, argv[2], &uid)) { return enif_make_badarg(env); } rados_t cluster = map_cluster_get(id); if (cluster == NULL) { return enif_make_badarg(env); } int err = rados_pool_create_with_auid(cluster, pool_name, uid); if (err < 0) { return make_error_tuple(env, -err); } return enif_make_atom(env, "ok"); }
ERL_NIF_TERM x_conf_read_file(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char * func_name = "x_conf_read_file()"; logger.debug(MOD_NAME, func_name, "Entered"); uint64_t id; if (!enif_get_uint64(env, argv[0], &id)) { logger.error(MOD_NAME, func_name, "enif get params failed"); return enif_make_badarg(env); } logger.debug(MOD_NAME, func_name, "cluster : %ld", id); rados_t cluster = map_cluster_get(id); if (cluster == NULL) { logger.error(MOD_NAME, func_name, "cluster non-existing : %ld", id); return enif_make_badarg(env); } int err = rados_conf_read_file(cluster, NULL); if (err < 0) { logger.error(MOD_NAME, func_name, "failed to read default config file for cluster: %ld", id); return make_error_tuple(env, -err); } return enif_make_atom(env, "ok"); }
ERL_NIF_TERM x_create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char * func_name = "x_create()"; logger.debug(MOD_NAME, func_name, "Entered"); logger.flush(); rados_t cluster; int err = rados_create(&cluster, NULL); if (err < 0) { logger.error(MOD_NAME, func_name, "Unable to create cluster handle"); return make_error_tuple(env, -err); } logger.debug(MOD_NAME, func_name, "cluster created"); logger.flush(); uint64_t id = new_id(); map_cluster_add(id, cluster); logger.debug(MOD_NAME, func_name, "cluster added to local map: %ld", id); logger.flush(); return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_uint64(env, id)); }
static ERL_NIF_TERM elua_gencall_async(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { elua_t *res; msg_t *msg; ErlNifPid pid; if(argc != 6) { return enif_make_badarg(env); } // first arg: ref if(!enif_get_resource(env, argv[0], RES_SYNC, (void**) &res)) { return enif_make_badarg(env); } // ref if(!enif_is_ref(env, argv[1])) { return make_error_tuple(env, "invalid_ref"); } // dest pid if(!enif_get_local_pid(env, argv[2], &pid)) { return make_error_tuple(env, "invalid_pid"); } // fourth arg: list of input args if(!enif_is_list(env, argv[5])) { return enif_make_badarg(env); } msg = msg_create(); if(!msg) { return make_error_tuple(env, "command_create_failed"); } msg->type = msg_gencall; msg->ref = enif_make_copy(msg->env, argv[1]); msg->pid = pid; msg->arg1 = enif_make_copy(msg->env, argv[3]); msg->arg2 = enif_make_copy(msg->env, argv[4]); msg->arg3 = enif_make_copy(msg->env, argv[5]); msg->res = res; return push_command(env, res, msg); }
ERL_NIF_TERM x_cluster_stat(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char * func_name = "x_cluster_stat()"; uint64_t id; if (!enif_get_uint64(env, argv[0], &id)) { logger.error(MOD_NAME, func_name, "enif get params failed"); return enif_make_badarg(env); } logger.debug(MOD_NAME, func_name, "cluster : %ld", id); rados_t cluster = map_cluster_get(id); if (cluster == NULL) { logger.error(MOD_NAME, func_name, "cluster non-existing : %ld", id); return enif_make_badarg(env); } rados_cluster_stat_t stat; int err = rados_cluster_stat(cluster, &stat); if (err < 0) { logger.error(MOD_NAME, func_name, "failed to get stat for %ld: %s", id, strerror(-err)); return make_error_tuple(env, -err); } ERL_NIF_TERM term_list = enif_make_list(env, 0); ERL_NIF_TERM t = enif_make_uint64(env, stat.num_objects); term_list = enif_make_list_cell(env, enif_make_tuple2(env, enif_make_atom(env, "num_objects"), t), term_list); t = enif_make_uint64(env, stat.kb_avail); term_list = enif_make_list_cell(env, enif_make_tuple2(env, enif_make_atom(env, "kb_avail"), t), term_list); t = enif_make_uint64(env, stat.kb_used); term_list = enif_make_list_cell(env, enif_make_tuple2(env, enif_make_atom(env, "kb_used"), t), term_list); t = enif_make_uint64(env, stat.kb); term_list = enif_make_list_cell(env, enif_make_tuple2(env, enif_make_atom(env, "kb"), t), term_list); return enif_make_tuple2(env, enif_make_atom(env, "ok"), term_list); }
static ERL_NIF_TERM do_step(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt) { int rc = sqlite3_step(stmt); if(rc == SQLITE_ROW) return make_row(env, stmt); if(rc == SQLITE_DONE) return make_atom(env, "$done"); if(rc == SQLITE_BUSY) return make_atom(env, "$busy"); if(rc == SQLITE_ERROR) return make_sqlite3_error_tuple(env, rc, db); if(rc == SQLITE_MISUSE) return make_error_tuple(env, "misuse"); return make_error_tuple(env, "unexpected_return_value"); }
static ERL_NIF_TERM dofile(ErlNifEnv *env, lua_State *L, const ERL_NIF_TERM arg) { char buff_str[STACK_STRING_BUFF]; int size = enif_get_string(env, arg, buff_str, STACK_STRING_BUFF, ERL_NIF_LATIN1); if(size <= 0) { return make_error_tuple(env, "invalid_filename"); } if(luaL_dofile(L, buff_str) !=LUA_OK) { const char *error = lua_tostring(L, -1); ERL_NIF_TERM error_tuple = make_error_tuple(env, error); lua_pop(L,1); return error_tuple; } // printf("do file well\n"); return atom_ok; }
/* * Multi step to a prepared statement */ static ERL_NIF_TERM esqlite_multi_step(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { esqlite_connection *conn; esqlite_statement *stmt; esqlite_command *cmd = NULL; ErlNifPid pid; int chunk_size = 0; if(argc != 5) return enif_make_badarg(env); if(!enif_get_resource(env, argv[0], esqlite_connection_type, (void **) &conn)) return enif_make_badarg(env); if(!enif_get_resource(env, argv[1], esqlite_statement_type, (void **) &stmt)) return enif_make_badarg(env); if(!enif_get_int(env, argv[2], &chunk_size)) return make_error_tuple(env, "invalid_chunk_size"); if(!enif_is_ref(env, argv[3])) return make_error_tuple(env, "invalid_ref"); if(!enif_get_local_pid(env, argv[4], &pid)) return make_error_tuple(env, "invalid_pid"); if(!stmt->statement) return make_error_tuple(env, "no_prepared_statement"); cmd = command_create(); if(!cmd) return make_error_tuple(env, "command_create_failed"); cmd->type = cmd_multi_step; cmd->ref = enif_make_copy(cmd->env, argv[3]); cmd->pid = pid; cmd->stmt = enif_make_copy(cmd->env, argv[1]); cmd->arg = enif_make_copy(cmd->env, argv[2]); return push_command(env, conn, cmd); }
static ERL_NIF_TERM evaluate_command(esqlite_command *cmd, esqlite_connection *conn) { esqlite_statement *stmt = NULL; if(cmd->stmt) { if(!enif_get_resource(cmd->env, cmd->stmt, esqlite_statement_type, (void **) &stmt)) { return make_error_tuple(cmd->env, "invalid_statement"); } } switch(cmd->type) { case cmd_open: return do_open(cmd->env, conn, cmd->arg); case cmd_update_hook_set: return do_set_update_hook(cmd->env, conn, cmd->arg); case cmd_exec: return do_exec(cmd->env, conn, cmd->arg); case cmd_changes: return do_changes(cmd->env, conn, cmd->arg); case cmd_prepare: return do_prepare(cmd->env, conn, cmd->arg); case cmd_multi_step: return do_multi_step(cmd->env, conn->db, stmt->statement, cmd->arg); case cmd_reset: return do_reset(cmd->env, conn->db, stmt->statement); case cmd_bind: return do_bind(cmd->env, conn->db, stmt->statement, cmd->arg); case cmd_column_names: return do_column_names(cmd->env, stmt->statement); case cmd_column_types: return do_column_types(cmd->env, stmt->statement); case cmd_close: return do_close(cmd->env, conn, cmd->arg); case cmd_insert: return do_insert(cmd->env, conn, cmd->arg); case cmd_get_autocommit: return do_get_autocommit(cmd->env, conn); default: return make_error_tuple(cmd->env, "invalid_command"); } }
static ERL_NIF_TERM make_row(ErlNifEnv *env, sqlite3_stmt *statement, ERL_NIF_TERM *array, int size) { if(!array) return make_error_tuple(env, "no_memory"); for(int i = 0; i < size; i++) array[i] = make_cell(env, statement, i); return enif_make_tuple_from_array(env, array, size); }
static void push_fatal_error(pycbc_MultiResultObject* mres) { PyObject *etuple; mres->all_ok = 0; if (!mres->exceptions) { mres->exceptions = PyList_New(0); } etuple = make_error_tuple(); PyList_Append(mres->exceptions, etuple); Py_DECREF(etuple); }