Пример #1
0
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");
}
Пример #2
0
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");
}
Пример #3
0
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;

    enif_inspect_iolist_as_binary(env, arg, &bin);

    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)
	    return make_sqlite3_error_tuple(env, rc, conn->db);

    enif_keep_resource(conn);
    stmt->connection = conn;

    esqlite_stmt = enif_make_resource(env, stmt);
    enif_release_resource(stmt);

    return make_ok_tuple(env, esqlite_stmt);
}
Пример #4
0
static ERL_NIF_TERM
do_reset(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt)
{
    int rc = sqlite3_reset(stmt);

    if(rc == SQLITE_OK)
        return make_atom(env, "ok");

    return make_sqlite3_error_tuple(env, rc, db);
}
Пример #5
0
static ERL_NIF_TERM
do_close(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg)
{
    int rc;
     
    rc = sqlite3_close(conn->db);
    if(rc != SQLITE_OK) 
	    return make_sqlite3_error_tuple(env, rc, conn->db);

    conn->db = NULL;
    return make_atom(env, "ok");
}
Пример #6
0
static ERL_NIF_TERM
do_exec(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg)
{
    ErlNifBinary bin;
    int rc;

    enif_inspect_iolist_as_binary(env, arg, &bin);

    rc = sqlite3_exec(conn->db, (char *) bin.data, NULL, NULL, NULL);
    if(rc != SQLITE_OK)
	    return make_sqlite3_error_tuple(env, rc, conn->db);

    return make_atom(env, "ok");
}
Пример #7
0
static ERL_NIF_TERM
do_multi_step(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt, const ERL_NIF_TERM arg)
{
    ERL_NIF_TERM status;
    ERL_NIF_TERM rows = enif_make_list_from_array(env, NULL, 0);
    ERL_NIF_TERM *rowBuffer = NULL;
    int rowBufferSize = 0;

    int chunk_size = 0;
    enif_get_int(env, arg, &chunk_size);

    int rc = sqlite3_step(stmt);
    while (rc == SQLITE_ROW && chunk_size-- > 0)
    {
        if (!rowBufferSize)
            rowBufferSize = sqlite3_column_count(stmt);
        if (rowBuffer == NULL)
            rowBuffer = (ERL_NIF_TERM *) enif_alloc(sizeof(ERL_NIF_TERM)*rowBufferSize);

        rows = enif_make_list_cell(env, make_row(env, stmt, rowBuffer, rowBufferSize), rows);

        if (chunk_size > 0)
            rc = sqlite3_step(stmt);
    }

    switch(rc) {
    case SQLITE_ROW:
        status = make_atom(env, "rows");
        break;
    case SQLITE_BUSY:
        status = make_atom(env, "$busy");
        break;
    case SQLITE_DONE:
        /*
        * Automatically reset the statement after a done so
        * column_names will work after the statement is done.
        *
        * Not resetting the statement can lead to vm crashes.
        */
        sqlite3_reset(stmt);
        status = make_atom(env, "$done");
        break;
    default:
        /* We use prepare_v2, so any error code can be returned. */
        return make_sqlite3_error_tuple(env, rc, db);
    }

    enif_free(rowBuffer);
    return enif_make_tuple2(env, status, rows);
}
Пример #8
0
/*
* insert action
*/
static ERL_NIF_TERM
do_insert(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg)
{
    ErlNifBinary bin;
    int rc;
    ERL_NIF_TERM eos = enif_make_int(env, 0);

    enif_inspect_iolist_as_binary(env,
        enif_make_list2(env, arg, eos), &bin);

    rc = sqlite3_exec(conn->db, (char *) bin.data, NULL, NULL, NULL);
    if(rc != SQLITE_OK)
        return make_sqlite3_error_tuple(env, rc, conn->db);
    sqlite3_int64 last_rowid = sqlite3_last_insert_rowid(conn->db);
    ERL_NIF_TERM last_rowid_term = enif_make_int64(env, last_rowid);
    return make_ok_tuple(env, last_rowid_term);
}
Пример #9
0
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");
}
Пример #10
0
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_BUSY)
        return make_atom(env, "$busy");

    if(rc == SQLITE_DONE) { 
        /* 
         * Automatically reset the statement after a done so 
         * column_names will work after the statement is done.
         *
         * Not resetting the statement can lead to vm crashes.
         */
        sqlite3_reset(stmt);
        return make_atom(env, "$done");
    }

    /* We use prepare_v2, so any error code can be returned. */
    return make_sqlite3_error_tuple(env, rc, db);
}