Added bind blob & text
This commit is contained in:
@@ -486,37 +486,23 @@ make_cell(ErlNifEnv *env, sqlite3_stmt *statement, unsigned int i)
|
|||||||
int type = sqlite3_column_type(statement, i);
|
int type = sqlite3_column_type(statement, i);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case SQLITE_NULL:
|
||||||
|
return make_atom(env, "undefined");
|
||||||
case SQLITE_INTEGER:
|
case SQLITE_INTEGER:
|
||||||
return enif_make_int64(env, sqlite3_column_int64(statement, i));
|
return enif_make_int64(env, sqlite3_column_int64(statement, i));
|
||||||
case SQLITE_FLOAT:
|
case SQLITE_FLOAT:
|
||||||
return enif_make_double(env, sqlite3_column_double(statement, i));
|
return enif_make_double(env, sqlite3_column_double(statement, i));
|
||||||
case SQLITE_BLOB:
|
case SQLITE_BLOB:
|
||||||
return enif_make_tuple2(env, make_atom(env, "blob"),
|
return make_binary(env, sqlite3_column_blob(statement, i),
|
||||||
make_binary(env, sqlite3_column_blob(statement, i),
|
sqlite3_column_bytes(statement, i));
|
||||||
sqlite3_column_bytes(statement, i)));
|
|
||||||
case SQLITE_NULL:
|
|
||||||
return make_atom(env, "undefined");
|
|
||||||
case SQLITE_TEXT:
|
case SQLITE_TEXT:
|
||||||
return make_binary(env, sqlite3_column_text(statement, i),
|
return make_binary(env, sqlite3_column_text(statement, i),
|
||||||
sqlite3_column_bytes(statement, i));
|
sqlite3_column_bytes(statement, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return enif_raise_exception(env, make_atom(env, "internal_error"));
|
return enif_raise_exception(env, make_atom(env, "internal_error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
do_reset(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt)
|
|
||||||
{
|
|
||||||
int rc = sqlite3_reset(stmt);
|
|
||||||
if(rc != SQLITE_OK)
|
|
||||||
return make_sqlite3_error_tuple(env, rc, db);
|
|
||||||
|
|
||||||
return make_atom(env, "ok");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
do_backup_init(ErlNifEnv *env, sqlite3 *db, const ERL_NIF_TERM arg)
|
do_backup_init(ErlNifEnv *env, sqlite3 *db, const ERL_NIF_TERM arg)
|
||||||
@@ -1136,6 +1122,82 @@ esqlite_bind_double(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|||||||
return make_atom(env, "ok");
|
return make_atom(env, "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ERL_NIF_TERM
|
||||||
|
esqlite_bind_text(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
|
{
|
||||||
|
esqlite3_stmt *stmt;
|
||||||
|
int index;
|
||||||
|
ErlNifBinary text;
|
||||||
|
|
||||||
|
if(argc != 3) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_get_resource(env, argv[0], esqlite3_stmt_type, (void **) &stmt)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stmt->statement) {
|
||||||
|
return enif_raise_exception(env, make_atom(env, "no_prepared_statement"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_get_int(env, argv[1], &index)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_inspect_iolist_as_binary(env, argv[1], &text)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't do any checks on the input data, sqlite handes all kinds of input. It is
|
||||||
|
* garbage-in, garbage-out.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int rc = sqlite3_bind_text64(stmt->statement, index, text.data, text.size, SQLITE_TRANSIENT, SQLITE_UTF8);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
return make_sqlite3_error_tuple(env, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_atom(env, "ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ERL_NIF_TERM
|
||||||
|
esqlite_bind_blob(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
|
{
|
||||||
|
esqlite3_stmt *stmt;
|
||||||
|
int index;
|
||||||
|
ErlNifBinary blob;
|
||||||
|
|
||||||
|
if(argc != 3) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_get_resource(env, argv[0], esqlite3_stmt_type, (void **) &stmt)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stmt->statement) {
|
||||||
|
return enif_raise_exception(env, make_atom(env, "no_prepared_statement"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_get_int(env, argv[1], &index)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_inspect_iolist_as_binary(env, argv[1], &blob)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = sqlite3_bind_blob64(stmt->statement, index, blob.data, blob.size, SQLITE_TRANSIENT);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
return make_sqlite3_error_tuple(env, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_atom(env, "ok");
|
||||||
|
}
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
esqlite_bind_null(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
esqlite_bind_null(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
{
|
{
|
||||||
@@ -1543,23 +1605,22 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"bind_int", 3, esqlite_bind_int},
|
{"bind_int", 3, esqlite_bind_int},
|
||||||
{"bind_int64", 3, esqlite_bind_int64},
|
{"bind_int64", 3, esqlite_bind_int64},
|
||||||
{"bind_double", 3, esqlite_bind_double},
|
{"bind_double", 3, esqlite_bind_double},
|
||||||
|
{"bind_text", 3, esqlite_bind_text},
|
||||||
|
{"bind_blob", 3, esqlite_bind_blob},
|
||||||
{"bind_null", 2, esqlite_bind_null},
|
{"bind_null", 2, esqlite_bind_null},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{"bind_text", 3, esqlite_bind_blob},
|
{"bind_text", 3, esqlite_bind_blob},
|
||||||
{"bind_blob", 3, esqlite_bind_blob},
|
|
||||||
{"bind_null", 2, esqlite_bind_blob},
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{"step", 1, esqlite_step},
|
{"step", 1, esqlite_step},
|
||||||
{"reset", 1, esqlite_reset},
|
{"reset", 1, esqlite_reset},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Other interesting additions... trace.
|
* Other interesting additions... trace.
|
||||||
wal_hook triggered after every commit.
|
* wal_hook triggered after every commit.
|
||||||
also interesting commit and rollback_hooks
|
* also interesting commit and rollback_hooks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{"interrupt", 1, esqlite_interrupt, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
{"interrupt", 1, esqlite_interrupt, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
||||||
{"last_insert_rowid", 1, esqlite_last_insert_rowid},
|
{"last_insert_rowid", 1, esqlite_last_insert_rowid},
|
||||||
@@ -1567,9 +1628,6 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"changes", 1, esqlite_changes},
|
{"changes", 1, esqlite_changes},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
{"exec", 4, esqlite_exec, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
|
||||||
|
|
||||||
{"backup_init", 6, esqlite_backup_init},
|
{"backup_init", 6, esqlite_backup_init},
|
||||||
{"backup_step", 5, esqlite_backup_step},
|
{"backup_step", 5, esqlite_backup_step},
|
||||||
{"backup_remaining", 4, esqlite_backup_remaining},
|
{"backup_remaining", 4, esqlite_backup_remaining},
|
||||||
|
|||||||
@@ -22,13 +22,13 @@
|
|||||||
open/1, close/1,
|
open/1, close/1,
|
||||||
|
|
||||||
%% db connection functions
|
%% db connection functions
|
||||||
|
|
||||||
set_update_hook/2,
|
set_update_hook/2,
|
||||||
|
|
||||||
get_autocommit/1,
|
get_autocommit/1,
|
||||||
last_insert_rowid/1,
|
last_insert_rowid/1,
|
||||||
changes/1,
|
changes/1,
|
||||||
|
|
||||||
|
%% queries
|
||||||
exec/2,
|
exec/2,
|
||||||
prepare/2,
|
prepare/2,
|
||||||
prepare/3,
|
prepare/3,
|
||||||
@@ -41,13 +41,13 @@
|
|||||||
bind_int64/3,
|
bind_int64/3,
|
||||||
bind_double/3,
|
bind_double/3,
|
||||||
% bind_text/3,
|
% bind_text/3,
|
||||||
% bind_blob/3,
|
bind_blob/3,
|
||||||
bind_null/2,
|
bind_null/2,
|
||||||
|
|
||||||
step/1,
|
step/1,
|
||||||
reset/1
|
reset/1
|
||||||
|
|
||||||
%
|
|
||||||
% fetchone/1,
|
% fetchone/1,
|
||||||
% fetchall/1, fetchall/2, fetchall/3,
|
% fetchall/1, fetchall/2, fetchall/3,
|
||||||
%
|
%
|
||||||
@@ -63,7 +63,6 @@
|
|||||||
-define(DEFAULT_TIMEOUT, infinity).
|
-define(DEFAULT_TIMEOUT, infinity).
|
||||||
-define(DEFAULT_CHUNK_SIZE, 5000).
|
-define(DEFAULT_CHUNK_SIZE, 5000).
|
||||||
|
|
||||||
|
|
||||||
-define(SQLITE_PREPARE_PERSISTENT, 16#01).
|
-define(SQLITE_PREPARE_PERSISTENT, 16#01).
|
||||||
-define(SQLITE_PREPARE_NO_VTAB, 16#04).
|
-define(SQLITE_PREPARE_NO_VTAB, 16#04).
|
||||||
|
|
||||||
@@ -391,6 +390,14 @@ bind_int64(#esqlite3_stmt{stmt=Stmt}, Index, Value) ->
|
|||||||
bind_double(#esqlite3_stmt{stmt=Stmt}, Index, Value) ->
|
bind_double(#esqlite3_stmt{stmt=Stmt}, Index, Value) ->
|
||||||
esqlite3_nif:bind_double(Stmt, Index, Value).
|
esqlite3_nif:bind_double(Stmt, Index, Value).
|
||||||
|
|
||||||
|
-spec bind_blob(Statement, Index, Value) -> BindResult
|
||||||
|
when Statement :: esqlite3_stmt(),
|
||||||
|
Index :: integer(),
|
||||||
|
Value :: iodata(),
|
||||||
|
BindResult :: ok | {error, _}.
|
||||||
|
bind_blob(#esqlite3_stmt{stmt=Stmt}, Index, Value) ->
|
||||||
|
esqlite3_nif:bind_blob(Stmt, Index, Value).
|
||||||
|
|
||||||
-spec bind_null(Statement, Index) -> BindResult
|
-spec bind_null(Statement, Index) -> BindResult
|
||||||
when Statement :: esqlite3_stmt(),
|
when Statement :: esqlite3_stmt(),
|
||||||
Index :: integer(),
|
Index :: integer(),
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
bind_int/3,
|
bind_int/3,
|
||||||
bind_int64/3,
|
bind_int64/3,
|
||||||
bind_double/3,
|
bind_double/3,
|
||||||
%bind_text/3,
|
bind_text/3,
|
||||||
%bind_blob/3,
|
bind_blob/3,
|
||||||
bind_null/2,
|
bind_null/2,
|
||||||
|
|
||||||
step/1,
|
step/1,
|
||||||
@@ -46,15 +46,6 @@
|
|||||||
reset/1,
|
reset/1,
|
||||||
|
|
||||||
interrupt/1
|
interrupt/1
|
||||||
% exec/4,
|
|
||||||
% changes/3,
|
|
||||||
%
|
|
||||||
% multi_step/5,
|
|
||||||
% reset/4,
|
|
||||||
% finalize/4,
|
|
||||||
% bind/5,
|
|
||||||
|
|
||||||
% column_types/4,
|
|
||||||
|
|
||||||
% backup_init/6,
|
% backup_init/6,
|
||||||
% backup_step/5,
|
% backup_step/5,
|
||||||
@@ -137,6 +128,12 @@ bind_int64(_Statement, _Index, _Value) ->
|
|||||||
bind_double(_Statement, _Index, _Value) ->
|
bind_double(_Statement, _Index, _Value) ->
|
||||||
erlang:nif_error(nif_library_not_loaded).
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
|
bind_blob(_Statement, _Index, _Value) ->
|
||||||
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
|
bind_text(_Statement, _Index, _Value) ->
|
||||||
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
bind_null(_Statement, _Index) ->
|
bind_null(_Statement, _Index) ->
|
||||||
erlang:nif_error(nif_library_not_loaded).
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,13 @@ close_test() ->
|
|||||||
ok = esqlite3:close(C),
|
ok = esqlite3:close(C),
|
||||||
|
|
||||||
%% Check if functions still return sensible values.
|
%% Check if functions still return sensible values.
|
||||||
% {error, closed} = esqlite3:set_update_hook(self(), C),
|
{error, closed} = esqlite3:set_update_hook(C, self()),
|
||||||
{error, closed} = esqlite3:changes(C),
|
{error, closed} = esqlite3:changes(C),
|
||||||
{error, closed} = esqlite3:get_autocommit(C),
|
{error, closed} = esqlite3:get_autocommit(C),
|
||||||
{error, closed} = esqlite3:last_insert_rowid(C),
|
{error, closed} = esqlite3:last_insert_rowid(C),
|
||||||
|
|
||||||
?assertEqual({error, {misuse, invoked_incorrectly}}, esqlite3:exec(C, "create table test(one, two, three)")),
|
?assertEqual({error, {misuse, invoked_incorrectly}},
|
||||||
|
esqlite3:exec(C, "create table test(one, two, three)")),
|
||||||
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user