diff --git a/README.md b/README.md index 805c05b..5cd8efc 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,51 @@ process. This is done by handling all commands from erlang within a lightweight thread. The erlang scheduler will get control back when the command has been added to the command-queue of the thread. +SQLite Compile Options +---------------------- + +Esqlite contains an embedded version of sqlite3. Currently version +`3.37.2` is embedded in the repositoy. It is also possible to use +sqlite provided by the system by using the `ESQLITE_USE_SYSTEM` +environment flag. + +When sqlite is compiled, the following compile flags are used. These +flags are recommended by sqlite. + +``` +SQLITE_DQS=0 SQLITE_THREADSAFE=1 SQLITE_DEFAULT_MEMSTATUS=0 +SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 SQLITE_LIKE_DOESNT_MATCH_BLOBS +SQLITE_MAX_EXPR_DEPTH=0 SQLITE_OMIT_DEPRECATED +SQLITE_OMIT_PROGRESS_CALLBACK SQLITE_USE_ALLOCA +SQLITE_OMIT_AUTOINIT SQLITE_USE_URI +SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS +SQLITE_ENABLE_FTS4 +SQLITE_ENABLE_FTS5 +SQLITE_ENABLE_MATH_FUNCTIONS +SQLITE_ENABLE_JSON1 +SQLITE_ENABLE_RTREE +SQLITE_ENABLE_GEOPOLY +``` + +The use of flag `SQLITE_DQS=0` is new in version `0.7`. It can lead +to incompatibilities with respect to the use of single and double +qouted values. Historically sqlite didn't differentiate between double +and single quoted values, but SQL does. In retrospect, the authors of +sqlite, think this was a mistake, and introduced this compile flag +to correct this mistake. It means that string literals **must** use +single quotes: + +``` +INSERT INTO table VALUES('abcd', 1234); +``` + +When double quotes are used the value is seen as object values in +SQL. So a query like: + +``` +INSERT INTO table VALUES("abcd", 1234); +``` + +Will not work, because it sees the value 'abcd' as a SQL object +value, and not a string literal. + diff --git a/c_src/esqlite3_nif.c b/c_src/esqlite3_nif.c index 932c5e0..d34f5f0 100644 --- a/c_src/esqlite3_nif.c +++ b/c_src/esqlite3_nif.c @@ -1712,6 +1712,9 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) atom_esqlite3 = make_atom(env, "esqlite3"); + if(SQLITE_OK != sqlite3_initialize()) + return -1; + return 0; } diff --git a/rebar.config.script b/rebar.config.script index f58ba6a..2443850 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -1,7 +1,7 @@ NifSharedSources = ["c_src/esqlite3_nif.c", "c_src/queue.c"]. NifStaticSources = NifSharedSources ++ ["c_src/sqlite3/sqlite3.c"]. -CFlagsDefault = "$CFLAGS -DSQLITE_THREADSAFE=1 -DSQLITE_USE_URI -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS". +CFlagsDefault = "$CFLAGS -Os -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=1 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_USE_ALLOCA -DSQLITE_OMIT_AUTOINIT -DSQLITE_USE_URI -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY". DrvLdFlagsDefault = "-shared -lsqlite3". DrvLdFlags = diff --git a/test/esqlite_test.erl b/test/esqlite_test.erl index d418623..202cbe4 100644 --- a/test/esqlite_test.erl +++ b/test/esqlite_test.erl @@ -81,14 +81,14 @@ simple_query_test() -> {ok, Db} = esqlite3:open(":memory:"), ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), {ok, 1} = esqlite3:changes(Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "11" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello2', 11);", Db), {ok, 1} = esqlite3:changes(Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello3\"", ",", "12" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello3', 12);", Db), {ok, 1} = esqlite3:changes(Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello4\"", ",", "13" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello4', 13);", Db), {ok, 1} = esqlite3:changes(Db), ok = esqlite3:exec("commit;", Db), ok = esqlite3:exec("select * from test_table;", Db), @@ -102,12 +102,12 @@ prepare_test() -> {ok, Db} = esqlite3:open(":memory:"), esqlite3:exec("begin;", Db), esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - {ok, Statement} = esqlite3:prepare("insert into test_table values(\"one\", 2)", Db), + {ok, Statement} = esqlite3:prepare("insert into test_table values('one', 2)", Db), '$done' = esqlite3:step(Statement), {ok, 1} = esqlite3:changes(Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello4\"", ",", "13" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello4', 13);", Db), %% Check if the values are there. [{<<"one">>, 2}, {<<"hello4">>, 13}] = esqlite3:q("select * from test_table order by two", Db), @@ -201,8 +201,8 @@ column_names_test() -> {ok, Db} = esqlite3:open(":memory:"), ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "20" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), + ok = esqlite3:exec("insert into test_table values('hello2', 20);", Db), ok = esqlite3:exec("commit;", Db), %% All columns @@ -248,8 +248,8 @@ column_types_test() -> {ok, Db} = esqlite3:open(":memory:"), ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "20" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), + ok = esqlite3:exec("insert into test_table values('hello2', 20);", Db), ok = esqlite3:exec("commit;", Db), %% All columns @@ -308,10 +308,12 @@ foreach_test() -> ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "11" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello3\"", ",", "12" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello4\"", ",", "13" ");"], Db), + + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), + ok = esqlite3:exec("insert into test_table values('hello2', 11);", Db), + ok = esqlite3:exec("insert into test_table values('hello3', 12);", Db), + ok = esqlite3:exec("insert into test_table values('hello4', 13);", Db), + ok = esqlite3:exec("commit;", Db), F = fun(Row) -> @@ -337,10 +339,10 @@ bind_for_foreach_test() -> ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "11" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello3\"", ",", "12" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello4\"", ",", "13" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), + ok = esqlite3:exec("insert into test_table values('hello2', 11);", Db), + ok = esqlite3:exec("insert into test_table values('hello3', 12);", Db), + ok = esqlite3:exec("insert into test_table values('hello4', 13);", Db), ok = esqlite3:exec("commit;", Db), F = fun(Row) -> @@ -363,10 +365,10 @@ map_test() -> ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "11" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello3\"", ",", "12" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello4\"", ",", "13" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), + ok = esqlite3:exec("insert into test_table values('hello2', 11);", Db), + ok = esqlite3:exec("insert into test_table values('hello3', 12);", Db), + ok = esqlite3:exec("insert into test_table values('hello4', 13);", Db), ok = esqlite3:exec("commit;", Db), F = fun(Row) -> Row end, @@ -393,10 +395,10 @@ bind_for_map_test() -> ok = esqlite3:exec("begin;", Db), ok = esqlite3:exec("create table test_table(one varchar(10), two int);", Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello1\"", ",", "10" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello2\"", ",", "11" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello3\"", ",", "12" ");"], Db), - ok = esqlite3:exec(["insert into test_table values(", "\"hello4\"", ",", "13" ");"], Db), + ok = esqlite3:exec("insert into test_table values('hello1', 10);", Db), + ok = esqlite3:exec("insert into test_table values('hello2', 11);", Db), + ok = esqlite3:exec("insert into test_table values('hello3', 12);", Db), + ok = esqlite3:exec("insert into test_table values('hello4', 13);", Db), ok = esqlite3:exec("commit;", Db), F = fun(Row) -> Row end,