View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000011 | LDMud 3.3 | Efuns | public | 2003-08-14 15:13 | 2018-01-29 21:57 |
Reporter | dafire | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | closed | Resolution | fixed | ||
Fixed in Version | 3.3.713 | ||||
Summary | 0000011: sqlite support (patch included) | ||||
Description | I created a small patch to access sqlite databases from ldmud. sqlite is in several excercises faster then mysql and since it embeds the database engine into the driver there is no need for extra daemons or stuff. more sqlite information on http://www.hwaci.com/sw/sqlite/ you can find a experimental patch for latest 3-3 drivers on http://ff.mud.de/~dafire/sqlite | ||||
Tags | No tags attached. | ||||
Attached Files | pkg_sqlite.diff (10,992 bytes)
diff -Nru 3-3/src/Makefile.in 3-3.sqlite/src/Makefile.in --- 3-3/src/Makefile.in 2003-09-28 06:08:29.000000000 +0200 +++ 3-3.sqlite/src/Makefile.in 2004-03-28 17:02:18.541126536 +0200 @@ -67,7 +67,7 @@ # CFLAGS= @EXTRA_CFLAGS@ $(OPTIMIZE) $(DEBUG) $(WARN) $(MPATH) $(PROFIL) # -LIBS=@LIBS@ @PKGLIBS@ +LIBS=@LIBS@ @PKGLIBS@ -lsqlite # LDFLAGS=$(PROFIL) @LDFLAGS@ # @@ -83,7 +83,7 @@ lex.c main.c mapping.c md5.c mempools.c mregex.c mstrings.c object.c \ otable.c\ parser.c parse.c pkg-alists.c pkg-mccp.c pkg-mysql.c pkg-pcre.c \ - pkg-pgsql.c pkg-tls.c \ + pkg-pgsql.c pkg-tls.c pkg-sqlite.c \ ptmalloc.c port.c ptrtable.c \ random.c regexp.c simulate.c simul_efun.c stdstrings.c \ strfuns.c structs.c sprintf.c swap.c wiz_list.c xalloc.c @@ -94,7 +94,7 @@ lex.o main.o mapping.o md5.o mempools.o mregex.o mstrings.o object.o \ otable.o \ parser.o parse.o pkg-alists.o pkg-mccp.o pkg-mysql.o pkg-pcre.o \ - pkg-pgsql.o pkg-tls.o \ + pkg-pgsql.o pkg-tls.o pkg-sqlite.o \ ptmalloc.o port.o ptrtable.o \ random.o regexp.o simulate.o simul_efun.o stdstrings.o \ strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@ diff -Nru 3-3/src/config.h.in 3-3.sqlite/src/config.h.in --- 3-3/src/config.h.in 2003-09-28 06:39:40.000000000 +0200 +++ 3-3.sqlite/src/config.h.in 2004-03-28 17:02:18.542126384 +0200 @@ -7,6 +7,8 @@ #ifndef CONFIG_H__ #define CONFIG_H__ 1 +#define USE_SQLITE + /* ----------- Commandline Argument Defaults ---------- * These options provide default settings for those options which can * also be set on the commandline. diff -Nru 3-3/src/func_spec 3-3.sqlite/src/func_spec --- 3-3/src/func_spec 2003-11-22 06:43:46.000000000 +0100 +++ 3-3.sqlite/src/func_spec 2004-03-28 17:02:18.543126232 +0200 @@ -698,6 +698,16 @@ #endif /* USE_PGSQL */ + +#ifdef USE_SQLITE + +int sl_open(string); +mixed sl_exec(string); +int sl_insert_id(); +void sl_close(); + +#endif /* USE_SQLITE */ + #ifdef USE_TLS int tls_query_connection_state(object default: F_THIS_OBJECT); diff -Nru 3-3/src/lex.c 3-3.sqlite/src/lex.c --- 3-3/src/lex.c 2004-03-28 17:00:14.063050080 +0200 +++ 3-3.sqlite/src/lex.c 2004-03-28 17:02:18.546125776 +0200 @@ -808,6 +808,9 @@ #ifdef USE_MYSQL add_permanent_define("__MYSQL__", -1, string_copy("1"), MY_FALSE); #endif +#ifdef USE_SQLITE + add_permanent_define("__SQLITE__", -1, string_copy("1"), MY_FALSE); +#endif #ifdef USE_PGSQL add_permanent_define("__PGSQL__", -1, string_copy("1"), MY_FALSE); #endif diff -Nru 3-3/src/object.c 3-3.sqlite/src/object.c --- 3-3/src/object.c 2003-11-22 06:43:46.000000000 +0100 +++ 3-3.sqlite/src/object.c 2004-03-28 17:02:18.551125016 +0200 @@ -42,6 +42,7 @@ * wiz_list_t * user; * wiz_list_t * eff_user; * int extra_num_variables; (ifdef DEBUG) + * int open_sqlite_db (ifdef USE_SQLITE) * svalue_t * variables; * unsigned long ticks, gigaticks; * } diff -Nru 3-3/src/object.h 3-3.sqlite/src/object.h --- 3-3/src/object.h 2003-04-14 05:12:51.000000000 +0200 +++ 3-3.sqlite/src/object.h 2004-03-28 17:02:18.551125016 +0200 @@ -49,6 +49,9 @@ int extra_num_variables; /* amylaar : used to determine where to check ref counts at all... */ #endif +#ifdef USE_SQLITE + int open_sqlite_db; /* does this object have an open sqlite db */ +#endif svalue_t *variables; /* All variables to this object: an array of svalues, allocated * in a separate block. diff -Nru 3-3/src/pkg-sqlite.c 3-3.sqlite/src/pkg-sqlite.c --- 3-3/src/pkg-sqlite.c 1970-01-01 01:00:00.000000000 +0100 +++ 3-3.sqlite/src/pkg-sqlite.c 2004-03-28 17:02:42.996408768 +0200 @@ -0,0 +1,268 @@ + +#include "config.h" +#ifdef USE_SQLITE + +#include <sqlite.h> +#include "typedefs.h" + +#include "my-alloca.h" +#include <errno.h> +#include <stddef.h> +#include <time.h> +#include <unistd.h> +#include <stdio.h> +#include "array.h" +#include "interpret.h" +#include "mstrings.h" +#include "simulate.h" +#include "svalue.h" +#include "xalloc.h" +#include "object.h" +#include "stdstrings.h" + +typedef struct sqlite_rows_s sqlite_rows_t; +typedef struct sqlite_dbs_s sqlite_dbs_t; + +/* Since we don't know the number of rows while we retrieve the + * rows from a query we save the data in a single-linked list first + * and move them into an array after the retrieval has finished + */ +struct sqlite_rows_s +{ + vector_t * row; + sqlite_rows_t * last; +}; + +/* Database connections should be bound to the object which opens + * database file. We will store all database connections in a + * linked list. + */ +struct sqlite_dbs_s +{ + sqlite * db; + object_t * obj; + sqlite_dbs_t * next; + sqlite_dbs_t * prev; +}; + +/* The list of database connections. + */ +static sqlite_dbs_t *head = NULL; + +// HELPER FUNS +sqlite_dbs_t *find_db (object_t * obj) +{ + sqlite_dbs_t *tmp=NULL; + if (!head) return NULL; + else tmp = head; + + while (tmp) + { + if (tmp->obj==obj) return tmp; + tmp=tmp->prev; + } + return NULL; +} + +sqlite_dbs_t * new_db() +{ + sqlite_dbs_t *tmp; + tmp = pxalloc (sizeof (*tmp)); + tmp->db=NULL; + tmp->obj=NULL; + tmp->next=NULL; + if (head) { + head->next=tmp; + tmp->prev=head; + head=tmp; + } else { + tmp->prev=NULL; + head=tmp; + } + return tmp; +} + +void remove_db(sqlite_dbs_t *db) +{ + if (db==head) + { + if (head->prev) + { + head->prev->next=NULL; + head=head->prev; + } else { + head=NULL; + } + } else { + if (db->next) db->next->prev=db->prev; + if (db->prev) db->prev->next=db->next; + } + pfree(db); + db=NULL; +} + +// EFUNS GO FROM HERE +svalue_t * +f_sl_open (svalue_t *sp) +{ + string_t *file; + sqlite *db; + sqlite_dbs_t *tmp; + + file = check_valid_path(sp->u.str, current_object, STR_SQLITE_OPEN , MY_TRUE); + if (!file) + { + error ("file access error\n"); + return sp; + } + + tmp = find_db (current_object); + if (tmp) + { + error ("DB already open.\n"); + return sp; + } + db = sqlite_open (get_txt(file), 0, NULL); + if (!db) + { + error ("SQLITE: Could not open Database.\n"); + return sp; + } + + /* create a new chain link and hang on the old chain */ + tmp=new_db(); + tmp->db = db; + tmp->obj = current_object; + current_object->open_sqlite_db=1; + free_string_svalue (sp); + put_number (sp, 1); + return sp; +} + +svalue_t * +f_sl_exec (svalue_t * sp) +{ + sqlite_vm * vm; + const char *tail = 0; + char *zErrMsg = NULL; + char *errmsg = NULL; + char *sql; + const char **cols = 0; + const char **value = 0; + int i, pN = 0; + int rows = 0; + sqlite_rows_t *plast = NULL, *pthis = NULL; + sqlite_dbs_t *db=NULL; + vector_t * v = NULL; + sql = get_txt (sp->u.str); + + db = find_db (current_object); + if (!db) + { + error ("No DB open.\n"); + return sp; + } + + // compile the query / create vm + if (sqlite_compile (db->db, sql, &tail, &vm, &zErrMsg)) + { + errmsg = pxalloc (strlen (zErrMsg) + 15); + sprintf (errmsg, "sl_exec: %s\n", zErrMsg); + free (zErrMsg); + error (errmsg); + pfree (errmsg); + return sp; + } + + // get all rows + while (SQLITE_ROW == sqlite_step (vm, &pN, &value, &cols)) + { + ++rows; + pthis = pxalloc (sizeof (*pthis)); + if (plast) + pthis->last = plast; + else + pthis->last = NULL; + pthis->row = allocate_array (pN); + if (!pthis->row) + { + error("Out of memory.\n"); + return sp; + } + for (i = 0; i < pN; i++) + if (value[i]) + put_c_string (pthis->row->item + i, (const char *) value[i]); + else + put_number (pthis->row->item + i, 0); + plast = pthis; + } + + sqlite_finalize (vm, NULL); + + free_string_svalue (sp); + + if (rows) + { + v = allocate_array (rows); + if (!v) + { + error("Out of memory.\n"); + return sp; + } + while (rows--) + { + put_array (v->item + rows, pthis->row); + pthis = plast->last; + // pfree (plast); + plast = pthis; + } + put_array (sp, v); + } + else + { + put_number (sp, 0); + } + + return sp; +} + +int +sl_close (object_t *ob) +{ + sqlite_dbs_t *db=NULL; + db = find_db(ob); + if (!db) return 0; + sqlite_close(db->db); + ob->open_sqlite_db=0; + remove_db(db); + return 1; +} + +svalue_t * +f_sl_insert_id (svalue_t * sp) +{ + sqlite_dbs_t *db=NULL; + int id; + db=find_db(current_object); + if (!db) + { + error ("No DB open.\n"); + return sp; + } + id=sqlite_last_insert_rowid(db->db); + sp++; + put_number(sp,id); + return sp; +} + +svalue_t * +f_sl_close (svalue_t * sp) +{ + if (!sl_close(current_object)) + { + error ("No DB open.\n"); + } + return sp; +} + +#endif /* USE_SQLITE */ diff -Nru 3-3/src/pkg-sqlite.h 3-3.sqlite/src/pkg-sqlite.h --- 3-3/src/pkg-sqlite.h 1970-01-01 01:00:00.000000000 +0100 +++ 3-3.sqlite/src/pkg-sqlite.h 2004-03-28 17:02:18.553124712 +0200 @@ -0,0 +1,2 @@ + +int sl_close (object_t *ob); diff -Nru 3-3/src/simulate.c 3-3.sqlite/src/simulate.c --- 3-3/src/simulate.c 2004-03-28 17:00:14.068049320 +0200 +++ 3-3.sqlite/src/simulate.c 2004-03-28 17:02:53.389828728 +0200 @@ -53,6 +53,9 @@ #include "mstrings.h" #include "object.h" #include "otable.h" +#ifdef USE_SQLITE +#include "pkg-sqlite.h" +#endif #ifdef USE_TLS #include "pkg-tls.h" #endif @@ -1905,6 +1908,9 @@ ob->load_name = new_tabled(name); /* but here it is */ ob->prog = prog; ob->ticks = ob->gigaticks = 0; +#ifdef USE_SQLITE + ob->open_sqlite_db=0; +#endif ob->next_all = obj_list; ob->prev_all = NULL; if (obj_list) @@ -2147,6 +2153,9 @@ if (!current_object) fatal("clone_object() from no current_object !\n"); #endif +#ifdef USE_SQLITE + new_ob->open_sqlite_db=0; +#endif new_ob->next_all = obj_list; new_ob->prev_all = NULL; if (obj_list) @@ -2382,6 +2391,10 @@ #ifdef CHECK_OBJECT_REF xallocate(shadow, sizeof(*shadow), "destructed object shadow"); #endif /* CHECK_OBJECT_REF */ + +#ifdef USE_SQLITE + if (ob->open_sqlite_db) sl_close(ob); +#endif ob->time_reset = 0; /* We need the object in memory */ diff -Nru 3-3/src/string_spec 3-3.sqlite/src/string_spec --- 3-3/src/string_spec 2003-11-22 06:43:46.000000000 +0100 +++ 3-3.sqlite/src/string_spec 2004-03-28 17:02:18.557124104 +0200 @@ -211,5 +211,8 @@ PG_RESET_FAILED "Reset failed, connection aborted." SUCCESS "success" #endif +#ifdef USE_SQLITE +SQLITE_OPEN "sl_open" +#endif /***************************************************************************/ sqlite.html (3,135 bytes)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <head> <title>Index of /~dafire/sqlite</title> </head> <body> <h1>sqlite embedded sql server for ldmud 3.3</h1> <p><h2>this is a first working version</h2></p> <p><h3>Needed Libraries</h3> <ul> <li> SQLite C library <a href=http://www.hwaci.com/sw/sqlite/>http://www.hwaci.com/sw/sqlite/</a> </ul> <p><h3>Known Issues</h3> <ul><li> guess there might be memory leaks <li> sqlite return values are not checked properly </ul> </p> <p><h3>Progress</h3> <ul> <li><b>01-Jul-2003</b> <ul><li>first experiments :) </ul> <li><b>03-Jul-2003</b> <ul><li> Every Object can open its own db. (dbs are bound to objects) </ul> <li><b>14-Aug-2003</b> <ul><li> DB's get closed when the bound object gets destroyed. <li> fixed some memory leaks.. should be sort of usable now </ul> <li><b>24-Aug-2003</b> <ul> <li>sl_insert_id() returns the autoincrement value from the last insert <li>__SQLITE__ define predefined in all objects</li> </ul> <li><b>31-Aug-2003</b> <ul> <li>filenames of databases are checked by valid_write</li> </ul> <li><b>28-Mar-2004</b> <ul> <li>The list holding the database connection lost a connection sometimes (list improved)</li> <li>fixed a small mem leak</li> <li>database connections opened by clones where not closed when the object got destructed</li> </ul> </ul> </p> <p><h3>Planed Features</h3> <ul> <li> optional asynchron queries using callbacks </ul> </p> <h3>How It Works</h3> <h4>Included EFUNS</h4> <ul><li>sl_open(string filename); <li>sl_exec(string sqlstatement); <li>sl_insert_id(); <li>sl_close(); </ul> This example uses the testmaster you find in this directory. <pre> <font color=red>// opens/creates the file /myfirst.db </test></font> > slopen myfirst.db <font color=red>// create a table with 3 columns</font> > sl create table firsttable ("column 1","column 2","column 3") data: 0 <font color=red>// ups.. i made an error:</font> > sl insert into firsttable (2,5,9) *sl_exec: near "2": syntax error <font color=red>// insert some data</font> > sl insert into firsttable values (2,5,9) data: 0 > sl insert into firsttable values ("this","is","data") data: 0 <font color=red>// get the data back</font> > sl select * from firsttable data: ({ /* #1, size: 2 */ ({ /* #2, size: 3 */ "2", "5", "9" }), ({ /* #3, size: 3 */ "this", "is", "data" }) }) </pre> <pre><img src="/icons/blank.gif" alt="Icon "> <a href="?C=N;O=D">Name</a> <a href="?C=M;O=A">Last modified</a> <a href="?C=S;O=A">Size</a> <a href="?C=D;O=A">Description</a><hr><img src="/icons/back.gif" alt="[DIR]"> <a href="/~dafire/">Parent Directory</a> - <img src="/icons/unknown.gif" alt="[ ]"> <a href="pkg_sqlite.diff">pkg_sqlite.diff</a> 28-Mar-2004 17:05 11K <img src="/icons/c.gif" alt="[ ]"> <a href="test_master.c">test_master.c</a> 14-Aug-2003 23:02 8.7K <hr></pre> <address>Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.6a DAV/2 PHP/4.3.7 SVN/1.0.5 Server at ff.mud.de Port 80</address> </body></html> sqlite3.diff (16,467 bytes)
diff -Naur 711-1516.U007/src/config.h.in 711-1516.U007.sqlite/src/config.h.in --- 711-1516.U007/src/config.h.in 2005-11-08 20:58:08.000000000 +0100 +++ 711-1516.U007.sqlite/src/config.h.in 2005-11-12 01:50:32.933417636 +0100 @@ -7,6 +7,8 @@ #ifndef CONFIG_H__ #define CONFIG_H__ 1 +#define USE_SQLITE + /* ----------- Commandline Argument Defaults ---------- * These options provide default settings for those options which can * also be set on the commandline. diff -Naur 711-1516.U007/src/func_spec 711-1516.U007.sqlite/src/func_spec --- 711-1516.U007/src/func_spec 2005-11-08 20:58:08.000000000 +0100 +++ 711-1516.U007.sqlite/src/func_spec 2005-11-11 23:51:51.000000000 +0100 @@ -722,6 +722,16 @@ #endif /* USE_PGSQL */ + +#ifdef USE_SQLITE + +int sl_open(string); +mixed sl_exec(string, ...); +int sl_insert_id(); +void sl_close(); + +#endif /* USE_SQLITE */ + #ifdef USE_TLS int tls_query_connection_state(object default: F_THIS_OBJECT); diff -Naur 711-1516.U007/src/lex.c 711-1516.U007.sqlite/src/lex.c --- 711-1516.U007/src/lex.c 2005-11-08 20:58:07.000000000 +0100 +++ 711-1516.U007.sqlite/src/lex.c 2005-11-11 22:26:13.000000000 +0100 @@ -824,6 +824,9 @@ #ifdef USE_MYSQL add_permanent_define("__MYSQL__", -1, string_copy("1"), MY_FALSE); #endif +#ifdef USE_SQLITE + add_permanent_define("__SQLITE__", -1, string_copy("1"), MY_FALSE); +#endif #ifdef USE_PGSQL add_permanent_define("__PGSQL__", -1, string_copy("1"), MY_FALSE); #endif diff -Naur 711-1516.U007/src/Makefile.in 711-1516.U007.sqlite/src/Makefile.in --- 711-1516.U007/src/Makefile.in 2005-11-08 20:58:07.000000000 +0100 +++ 711-1516.U007.sqlite/src/Makefile.in 2005-11-12 01:49:59.149728934 +0100 @@ -74,7 +74,7 @@ # CFLAGS= @EXTRA_CFLAGS@ $(OPTIMIZE) $(DEBUG) $(WARN) $(MPATH) $(PROFIL) # -LIBS=@LIBS@ @PKGLIBS@ +LIBS=@LIBS@ @PKGLIBS@ -lsqlite3 # LDFLAGS=$(PROFIL) @LDFLAGS@ # @@ -90,7 +90,7 @@ lex.c main.c mapping.c md5.c mempools.c mregex.c mstrings.c object.c \ otable.c\ parser.c parse.c pkg-alists.c pkg-mccp.c pkg-mysql.c pkg-pcre.c \ - pkg-pgsql.c pkg-tls.c \ + pkg-pgsql.c pkg-tls.c pkg-sqlite.c \ ptmalloc.c port.c ptrtable.c \ random.c regexp.c sha1.c simulate.c simul_efun.c stdstrings.c \ strfuns.c structs.c sprintf.c swap.c wiz_list.c xalloc.c @@ -101,7 +101,7 @@ lex.o main.o mapping.o md5.o mempools.o mregex.o mstrings.o object.o \ otable.o \ parser.o parse.o pkg-alists.o pkg-mccp.o pkg-mysql.o pkg-pcre.o \ - pkg-pgsql.o pkg-tls.o \ + pkg-pgsql.o pkg-tls.o pkg-sqlite.o \ ptmalloc.o port.o ptrtable.o \ random.o regexp.o sha1.o simulate.o simul_efun.o stdstrings.o \ strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@ diff -Naur 711-1516.U007/src/object.c 711-1516.U007.sqlite/src/object.c --- 711-1516.U007/src/object.c 2005-11-08 20:58:07.000000000 +0100 +++ 711-1516.U007.sqlite/src/object.c 2005-11-11 22:26:13.000000000 +0100 @@ -43,6 +43,7 @@ * wiz_list_t * user; * wiz_list_t * eff_user; * int extra_num_variables; (ifdef DEBUG) + * int open_sqlite_db (ifdef USE_SQLITE) * svalue_t * variables; * unsigned long ticks, gigaticks; * } diff -Naur 711-1516.U007/src/object.h 711-1516.U007.sqlite/src/object.h --- 711-1516.U007/src/object.h 2005-11-08 20:58:07.000000000 +0100 +++ 711-1516.U007.sqlite/src/object.h 2005-11-11 22:26:13.000000000 +0100 @@ -50,6 +50,9 @@ int extra_num_variables; /* amylaar : used to determine where to check ref counts at all... */ #endif +#ifdef USE_SQLITE + int open_sqlite_db; /* does this object have an open sqlite db */ +#endif svalue_t *variables; /* All variables to this object: an array of svalues, allocated * in a separate block. diff -Naur 711-1516.U007/src/pkg-sqlite.h 711-1516.U007.sqlite/src/pkg-sqlite.h --- 711-1516.U007/src/pkg-sqlite.h 1970-01-01 01:00:00.000000000 +0100 +++ 711-1516.U007.sqlite/src/pkg-sqlite.h 2005-11-11 22:26:13.000000000 +0100 @@ -0,0 +1,2 @@ + +int sl_close (object_t *ob); diff -Naur 711-1516.U007/src/simulate.c 711-1516.U007.sqlite/src/simulate.c --- 711-1516.U007/src/simulate.c 2005-11-08 20:58:08.000000000 +0100 +++ 711-1516.U007.sqlite/src/simulate.c 2005-11-11 22:26:13.000000000 +0100 @@ -53,6 +53,9 @@ #include "mstrings.h" #include "object.h" #include "otable.h" +#ifdef USE_SQLITE +#include "pkg-sqlite.h" +#endif #ifdef USE_TLS #include "pkg-tls.h" #endif @@ -2050,6 +2053,9 @@ ob->load_name = new_tabled(name); /* but here it is */ ob->prog = prog; ob->ticks = ob->gigaticks = 0; +#ifdef USE_SQLITE + ob->open_sqlite_db=0; +#endif ob->next_all = obj_list; ob->prev_all = NULL; if (obj_list) @@ -2293,6 +2299,9 @@ if (!current_object) fatal("clone_object() from no current_object !\n"); #endif +#ifdef USE_SQLITE + new_ob->open_sqlite_db=0; +#endif new_ob->next_all = obj_list; new_ob->prev_all = NULL; if (obj_list) @@ -2535,6 +2544,10 @@ #ifdef CHECK_OBJECT_REF xallocate(shadow, sizeof(*shadow), "destructed object shadow"); #endif /* CHECK_OBJECT_REF */ + +#ifdef USE_SQLITE + if (ob->open_sqlite_db) sl_close(ob); +#endif ob->time_reset = 0; /* We need the object in memory */ diff -Naur 711-1516.U007/src/string_spec 711-1516.U007.sqlite/src/string_spec --- 711-1516.U007/src/string_spec 2005-11-08 20:58:08.000000000 +0100 +++ 711-1516.U007.sqlite/src/string_spec 2005-11-11 22:26:13.000000000 +0100 @@ -229,5 +229,8 @@ SUCCESS "success" #endif +#ifdef USE_SQLITE +SQLITE_OPEN "sl_open" +#endif /***************************************************************************/ diff -Nur 711-1516.U007/src/pkg-sqlite.c 711-1516.U007.sql/src/pkg-sqlite.c --- 711-1516.U007/src/pkg-sqlite.c 1970-01-01 01:00:00.000000000 +0100 +++ 711-1516.U007.sql/src/pkg-sqlite.c 2005-11-12 03:22:22.835804032 +0100 @@ -0,0 +1,438 @@ + +#include "config.h" +#ifdef USE_SQLITE + +#include <sqlite3.h> +#include "typedefs.h" + +#include "my-alloca.h" +#include <errno.h> +#include <stddef.h> +#include <time.h> +#include <unistd.h> +#include <stdio.h> +#include "array.h" +#include "interpret.h" +#include "mstrings.h" +#include "simulate.h" +#include "svalue.h" +#include "xalloc.h" +#include "object.h" +#include "stdstrings.h" + +typedef struct sqlite_rows_s sqlite_rows_t; +typedef struct sqlite_dbs_s sqlite_dbs_t; + +/* Since we don't know the number of rows while we retrieve the + * rows from a query we save the data in a single-linked list first + * and move them into an array after the retrieval has finished + */ +struct sqlite_rows_s +{ + vector_t * row; + sqlite_rows_t * last; +}; + +/* This structure is used for error handling. In case of an error + * our handler gets called with a pointer to this structure. + */ +struct sl_exec_cleanup_s +{ + svalue_t head; /* push_error_handler saves the link to our + handler here. */ + + sqlite3_stmt *stmt; + sqlite_rows_t *rows; +}; + +/* Database connections should be bound to the object which opens + * database file. We will store all database connections in a + * linked list. + */ +struct sqlite_dbs_s +{ + sqlite3 * db; + object_t * obj; + sqlite_dbs_t * next; + sqlite_dbs_t * prev; +}; + +/* The list of database connections. + */ +static sqlite_dbs_t *head = NULL; + +// HELPER FUNS +sqlite_dbs_t *find_db (object_t * obj) +{ + sqlite_dbs_t *tmp = head; + + while (tmp) + { + if (tmp->obj==obj) return tmp; + tmp=tmp->prev; + } + return NULL; +} + +sqlite_dbs_t * new_db() +{ + sqlite_dbs_t *tmp; + tmp = pxalloc (sizeof (*tmp)); + if(!tmp) return NULL; + + tmp->db=NULL; + tmp->obj=NULL; + tmp->next=NULL; + tmp->prev=head; + if (head) head->next=tmp; + head=tmp; + + return tmp; +} + +void remove_db(sqlite_dbs_t *db) +{ + if (db==head) + { + if (head->prev) + { + head->prev->next=NULL; + head=head->prev; + } + else + { + head=NULL; + } + } + else + { + if (db->next) db->next->prev=db->prev; + if (db->prev) db->prev->next=db->next; + } + pfree(db); +} + +static int +my_sqlite3_authorizer(void* data, int what, const char* arg1, const char* arg2, + const char* dbname, const char* view) +{ + /* TODO: Check them via privilege_violation resp. valid_write. + (Don't know, whether sqlite can handle longjmps out of + its code in case of an error...) + */ + + switch(what) + { + case SQLITE_PRAGMA: + if(!strcasecmp(arg1, "synchronous")) + return SQLITE_OK; + return SQLITE_DENY; + + case SQLITE_ATTACH: + case SQLITE_DETACH: + return SQLITE_DENY; + + default: + return SQLITE_OK; + } +} + +// EFUNS GO FROM HERE +svalue_t * +f_sl_open (svalue_t *sp) +{ + string_t *file; + sqlite3 *db; + sqlite_dbs_t *tmp; + int err; + + file = check_valid_path(sp->u.str, current_object, STR_SQLITE_OPEN , MY_TRUE); + if (!file) + errorf("Illegal use of sl_open('%s')\n", get_txt(sp->u.str)); + + tmp = find_db (current_object); + if (tmp) + { + free_mstring(file); + errorf("The current object already has a database open.\n"); + } + + err = sqlite3_open (get_txt(file), &db); + free_mstring(file); + if (err) + { + const char* msg = sqlite3_errmsg(db); + sqlite3_close(db); + errorf("sl_open: %s\n", msg ); + /* NOTREACHED */ + } + + /* create a new chain link and hang on the old chain */ + tmp=new_db(); + if(!tmp) + { + sqlite3_close(db); + errorf("(sl_open) Out of memory: (%lu bytes)\n", + (unsigned long) sizeof(*tmp)); + } + + tmp->db = db; + tmp->obj = current_object; + current_object->open_sqlite_db=1; + + /* Synchronous is damn slow. Forget it. */ + sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, NULL); + sqlite3_set_authorizer(db, my_sqlite3_authorizer, NULL); + + free_string_svalue (sp); + put_number (sp, 1); + return sp; +} + +static void +sl_exec_cleanup (svalue_t * arg) +{ + sqlite_rows_t *row; + struct sl_exec_cleanup_s * data; + + data = (struct sl_exec_cleanup_s *)arg; + + if(data->stmt) + sqlite3_finalize(data->stmt); + + row = data->rows; + while(row) + { + sqlite_rows_t *temp; + + if(row->row) + free_array(row->row); + temp = row; + row = row->last; + pfree(temp); + } + + xfree(data); +} + +svalue_t * +v_sl_exec (svalue_t * sp, int num_arg) +{ + svalue_t *argp; + sqlite_dbs_t *db; + sqlite3_stmt *stmt; + const char* tail; + int err, rows, cols, num; + struct sl_exec_cleanup_s * rec_data; + vector_t * result; + + argp = sp - num_arg + 1; /* First argument: the SQL query */ + + db = find_db (current_object); + if (!db) + errorf("The current object doesn't have a database open.\n"); + + err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str), + &stmt, &tail); + if(err) + { + const char* msg = sqlite3_errmsg(db->db); + if(stmt) + sqlite3_finalize(stmt); + errorf("sl_exec: %s\n", msg); + /* NOTREACHED */ + } + + /* Now bind all parameters. */ + for(argp++, num=1; argp <= sp; argp++, num++) + { + switch(argp->type) + { + default: + sqlite3_finalize(stmt); + errorf("Bad argument %d to sl_exec(): type %s\n", + num+1, typename(argp->type)); + break; /* NOTREACHED */ + + case T_FLOAT: + sqlite3_bind_double(stmt, num, READ_DOUBLE(argp)); + break; + + case T_NUMBER: + sqlite3_bind_int(stmt, num, argp->u.number); + break; + + case T_STRING: + sqlite3_bind_text(stmt, num, get_txt(argp->u.str), + mstrsize(argp->u.str), SQLITE_STATIC); + break; + } + } + + rows = 0; + cols = sqlite3_column_count(stmt); + + rec_data = xalloc(sizeof(*rec_data)); + if(!rec_data) + { + sqlite3_finalize(stmt); + errorf("(sl_exec) Out of memory: (%lu bytes) for cleanup structure\n", + (unsigned long) sizeof(*rec_data)); + } + rec_data->rows = NULL; + rec_data->stmt = stmt; + + push_error_handler(sl_exec_cleanup, &(rec_data->head)); + sp = inter_sp; + + while((err = sqlite3_step(stmt)) == SQLITE_ROW) + { + int col; + sqlite_rows_t *this_row; + + rows++; + this_row = pxalloc(sizeof(*this_row)); + if(!this_row) + errorf("(sl_exec) Out of memory: (%lu bytes)\n", + (unsigned long) sizeof(*this_row)); + + this_row->last = rec_data->rows; + rec_data->rows = this_row; + this_row->row = NULL; /* Because allocate_array may throw an error. */ + + this_row->row = allocate_array(cols); + if(!this_row->row) + errorf("(sl_exec) Out of memory: row vector\n"); + + for(col = 0; col < cols; col++) + { + STORE_DOUBLE_USED; + svalue_t * entry; + + entry = this_row->row->item + col; + + switch(sqlite3_column_type(stmt, col)) + { + default: + errorf("sl_exec: Unknown type %d.\n", + sqlite3_column_type(stmt, col)); + break; + + case SQLITE_BLOB: + errorf("sl_exec: Blob columns are not supported.\n"); + break; + + case SQLITE_INTEGER: + put_number(entry, sqlite3_column_int(stmt, col)); + break; + + case SQLITE_FLOAT: + entry->type = T_FLOAT; + STORE_DOUBLE(entry, sqlite3_column_double(stmt, col)); + break; + + case SQLITE_TEXT: + put_c_n_string(entry, + sqlite3_column_text(stmt, col), + sqlite3_column_bytes(stmt, col)); + break; + + case SQLITE_NULL: + /* All elements from this_row->row are initialized to 0. */ + break; + } + } + } + + sqlite3_finalize(stmt); + rec_data->stmt = NULL; + + switch(err) + { + default: + errorf("sl_exec: Unknown return code from sqlite3_step: %d.\n", err); + break; + + case SQLITE_BUSY: + errorf("sl_exec: Database is locked.\n"); + break; + + case SQLITE_ERROR: + errorf("sl_exec: %s\n", sqlite3_errmsg(db->db)); + break; + + case SQLITE_MISUSE: + errorf("sl_exec: sqlite3_step was called inappropriately.\n"); + break; + + case SQLITE_DONE: + break; + } + + if(rows) + { + sqlite_rows_t *this_row; + + result = allocate_array(rows); + if(!result) + errorf("(sl_exec) Out of memory: result vector\n"); + + this_row = rec_data->rows; + while(rows--) + { + put_array(result->item + rows, this_row->row); + this_row->row = NULL; + this_row = this_row->last; + } + } + else + result = NULL; + + // Pop arguments and our error handler. + // Our error handler gets called and cleans the row stuff. + sp = pop_n_elems(num_arg + 1, sp) + 1; + + if(rows) + put_array(sp,result); + else + put_number(sp, 0); + + return sp; +} + +int +sl_close (object_t *ob) +{ + sqlite_dbs_t *db = find_db(ob); + if (!db) return 0; + + sqlite3_close(db->db); + ob->open_sqlite_db=0; + remove_db(db); + return 1; +} + +svalue_t * +f_sl_insert_id (svalue_t * sp) +{ + sqlite_dbs_t *db = find_db(current_object); + int id; + + if (!db) + errorf("The current object doesn't have a database open.\n"); + + id=sqlite3_last_insert_rowid(db->db); + sp++; + put_number(sp,id); + return sp; +} + +svalue_t * +f_sl_close (svalue_t * sp) +{ + if (!sl_close(current_object)) + errorf("The current object doesn't have a database open.\n"); + return sp; +} + +#endif /* USE_SQLITE */ sqlite3.doc.diff (6,162 bytes)
diff -Naur alt/doc/efun/sl_close neu/doc/efun/sl_close --- alt/doc/efun/sl_close 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun/sl_close 2005-11-20 23:22:20.000000000 +0100 @@ -0,0 +1,13 @@ +OPTIONAL +SYNOPSIS + void sl_close() + +DESCRIPTION + Closes the SQLite database that is associated with the + current object. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_open, sl_exec, sl_insert_id diff -Naur alt/doc/efun/sl_exec neu/doc/efun/sl_exec --- alt/doc/efun/sl_exec 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun/sl_exec 2005-11-20 23:51:45.000000000 +0100 @@ -0,0 +1,21 @@ +OPTIONAL +SYNOPSIS + mixed* sl_exec(string statement, ...) + +DESCRIPTION + Executes the SQL statement <statement> for the current + SQLite database. The SQL statement may contain wildcards like + '?' and '?nnn', where 'nnn' is an integer. These wildcards + can be given as further parameters to sl_exec. With '?nnn' + the number of a specific parameter can be given, the first + parameter has number 1. + + If the statement returns data, sl_exec returns an array + with each row (which is itself an array of columns) as + an element. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_open, sl_insert_id, sl_close diff -Naur alt/doc/efun/sl_insert_id neu/doc/efun/sl_insert_id --- alt/doc/efun/sl_insert_id 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun/sl_insert_id 2005-11-20 23:51:51.000000000 +0100 @@ -0,0 +1,14 @@ +OPTIONAL +SYNOPSIS + int sl_insert_id() + +DESCRIPTION + After inserting a line into a table with an AUTO_INCREMENT field, + this efun can be used to return the (new) value of the AUTO_INCREMENT + field. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_open, sl_exec, sl_close diff -Naur alt/doc/efun/sl_open neu/doc/efun/sl_open --- alt/doc/efun/sl_open 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun/sl_open 2005-11-23 20:27:23.000000000 +0100 @@ -0,0 +1,15 @@ +OPTIONAL +SYNOPSIS + int sl_open(string filename) + +DESCRIPTION + Opens the file <filename> for use as a SQLite database. + If the file doesn't exists it will be created. + Only one open file per object is allowed. On success this + function returns 1, otherwise usually an error is thrown. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_exec, sl_insert_id, sl_close diff -Naur alt/doc/efun.de/sl_close.de neu/doc/efun.de/sl_close.de --- alt/doc/efun.de/sl_close.de 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun.de/sl_close.de 2005-11-23 20:33:03.000000000 +0100 @@ -0,0 +1,14 @@ +OPTIONAL +SYNOPSIS + void sl_close() + +BESCHREIBUNG + Schliesst die SQLite-Datenbank, welche vom aktuellen Objekt + geoeffnet wurde. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_open, sl_exec, sl_insert_id diff -Naur alt/doc/efun.de/sl_exec.de neu/doc/efun.de/sl_exec.de --- alt/doc/efun.de/sl_exec.de 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun.de/sl_exec.de 2005-11-23 20:41:30.000000000 +0100 @@ -0,0 +1,22 @@ +OPTIONAL +SYNOPSIS + mixed* sl_exec(string statement, ...) + +BESCHREIBUNG + Fuehrt den SQL-Befehl <statement> in der aktuell geoeffneten + SQLite-Datenbank aus. Dieser SQL-Befehl kann Wildcards wie '?' + nd '?nnn', wobei 'nnn' eine Zahl ist, enthalten. Diese Wildcards + koennen als weitere Parameter an sl_exec uebergeben werden. + Mit '?nnn' kann direkt die Nummer eines bestimmten Parameters + angegeben werden, der erste Parameter hat die Nummer 1. + + Falls der SQL-Befehl Daten zurueckliefert, liefert sl_exec ein + Array aus den einzelnen Zeilen (welche wieder Arrays der einzelnen + Felder sind) zurueck. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_open, sl_insert_id, sl_close diff -Naur alt/doc/efun.de/sl_insert_id.de neu/doc/efun.de/sl_insert_id.de --- alt/doc/efun.de/sl_insert_id.de 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun.de/sl_insert_id.de 2005-11-23 20:34:44.000000000 +0100 @@ -0,0 +1,15 @@ +OPTIONAL +SYNOPSIS + int sl_insert_id() + +BESCHREIBUNG + Nachdem eine Zeile in eine Tabelle mit einer AUTO_INCREMENT-Spalte + eingefuegt wurde, kann man mit dieser Funktion den (neuen) Wert + dieses AUTO_INCREMENT-Feldes der eingefuegten Zeile abfragen. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_open, sl_exec, sl_close diff -Naur alt/doc/efun.de/sl_open.de neu/doc/efun.de/sl_open.de --- alt/doc/efun.de/sl_open.de 1970-01-01 01:00:00.000000000 +0100 +++ neu/doc/efun.de/sl_open.de 2005-11-23 20:29:46.000000000 +0100 @@ -0,0 +1,17 @@ +OPTIONAL +SYNOPSIS + int sl_open(string filename) + +BESCHREIBUNG + Oeffnet die Datei <filename> als SQLite-Datenbank. Falls + sie noch nicht existiert, wird sie erstellt. Es ist nur + eine geoeffnete Datenbank pro Objekt erlaubt. Im Erfolgsfalle + liefert diese Funktion 1 zurueck, anderenfalls wird + normalerweise ein Fehler ausgeloest. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_exec, sl_insert_id, sl_close sqlite3_all.diff (30,401 bytes)
diff -Naur 3.3/doc/efun/sl_close 3.3sqlite/doc/efun/sl_close --- 3.3/doc/efun/sl_close 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun/sl_close 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,13 @@ +OPTIONAL +SYNOPSIS + void sl_close() + +DESCRIPTION + Closes the SQLite database that is associated with the + current object. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_open, sl_exec, sl_insert_id diff -Naur 3.3/doc/efun/sl_exec 3.3sqlite/doc/efun/sl_exec --- 3.3/doc/efun/sl_exec 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun/sl_exec 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,21 @@ +OPTIONAL +SYNOPSIS + mixed* sl_exec(string statement, ...) + +DESCRIPTION + Executes the SQL statement <statement> for the current + SQLite database. The SQL statement may contain wildcards like + '?' and '?nnn', where 'nnn' is an integer. These wildcards + can be given as further parameters to sl_exec. With '?nnn' + the number of a specific parameter can be given, the first + parameter has number 1. + + If the statement returns data, sl_exec returns an array + with each row (which is itself an array of columns) as + an element. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_open, sl_insert_id, sl_close diff -Naur 3.3/doc/efun/sl_insert_id 3.3sqlite/doc/efun/sl_insert_id --- 3.3/doc/efun/sl_insert_id 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun/sl_insert_id 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,14 @@ +OPTIONAL +SYNOPSIS + int sl_insert_id() + +DESCRIPTION + After inserting a line into a table with an AUTO_INCREMENT field, + this efun can be used to return the (new) value of the AUTO_INCREMENT + field. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_open, sl_exec, sl_close diff -Naur 3.3/doc/efun/sl_open 3.3sqlite/doc/efun/sl_open --- 3.3/doc/efun/sl_open 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun/sl_open 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,15 @@ +OPTIONAL +SYNOPSIS + int sl_open(string filename) + +DESCRIPTION + Opens the file <filename> for use as a SQLite database. + If the file doesn't exists it will be created. + Only one open file per object is allowed. On success this + function returns 1, otherwise usually an error is thrown. + + The function is available only if the driver is compiled with + SQLite support. In that case, __SQLITE__ is defined. + +SEE ALSO + sl_exec, sl_insert_id, sl_close diff -Naur 3.3/doc/efun.de/sl_close.de 3.3sqlite/doc/efun.de/sl_close.de --- 3.3/doc/efun.de/sl_close.de 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun.de/sl_close.de 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,14 @@ +OPTIONAL +SYNOPSIS + void sl_close() + +BESCHREIBUNG + Schliesst die SQLite-Datenbank, welche vom aktuellen Objekt + geoeffnet wurde. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_open, sl_exec, sl_insert_id diff -Naur 3.3/doc/efun.de/sl_exec.de 3.3sqlite/doc/efun.de/sl_exec.de --- 3.3/doc/efun.de/sl_exec.de 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun.de/sl_exec.de 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,22 @@ +OPTIONAL +SYNOPSIS + mixed* sl_exec(string statement, ...) + +BESCHREIBUNG + Fuehrt den SQL-Befehl <statement> in der aktuell geoeffneten + SQLite-Datenbank aus. Dieser SQL-Befehl kann Wildcards wie '?' + nd '?nnn', wobei 'nnn' eine Zahl ist, enthalten. Diese Wildcards + koennen als weitere Parameter an sl_exec uebergeben werden. + Mit '?nnn' kann direkt die Nummer eines bestimmten Parameters + angegeben werden, der erste Parameter hat die Nummer 1. + + Falls der SQL-Befehl Daten zurueckliefert, liefert sl_exec ein + Array aus den einzelnen Zeilen (welche wieder Arrays der einzelnen + Felder sind) zurueck. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_open, sl_insert_id, sl_close diff -Naur 3.3/doc/efun.de/sl_insert_id.de 3.3sqlite/doc/efun.de/sl_insert_id.de --- 3.3/doc/efun.de/sl_insert_id.de 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun.de/sl_insert_id.de 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,15 @@ +OPTIONAL +SYNOPSIS + int sl_insert_id() + +BESCHREIBUNG + Nachdem eine Zeile in eine Tabelle mit einer AUTO_INCREMENT-Spalte + eingefuegt wurde, kann man mit dieser Funktion den (neuen) Wert + dieses AUTO_INCREMENT-Feldes der eingefuegten Zeile abfragen. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_open, sl_exec, sl_close diff -Naur 3.3/doc/efun.de/sl_open.de 3.3sqlite/doc/efun.de/sl_open.de --- 3.3/doc/efun.de/sl_open.de 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/doc/efun.de/sl_open.de 2005-12-06 00:06:06.000000000 +0100 @@ -0,0 +1,17 @@ +OPTIONAL +SYNOPSIS + int sl_open(string filename) + +BESCHREIBUNG + Oeffnet die Datei <filename> als SQLite-Datenbank. Falls + sie noch nicht existiert, wird sie erstellt. Es ist nur + eine geoeffnete Datenbank pro Objekt erlaubt. Im Erfolgsfalle + liefert diese Funktion 1 zurueck, anderenfalls wird + normalerweise ein Fehler ausgeloest. + + Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite- + Unterstuetzung compiliert wurde. In diesem Fall ist das Makro + __SQLITE__ definiert. + +SIEHE AUCH + sl_exec, sl_insert_id, sl_close diff -Naur 3.3/src/autoconf/acconfig.h 3.3sqlite/src/autoconf/acconfig.h --- 3.3/src/autoconf/acconfig.h 2005-06-22 14:51:58.000000000 +0200 +++ 3.3sqlite/src/autoconf/acconfig.h 2005-12-05 22:45:32.000000000 +0100 @@ -99,6 +99,12 @@ /* Does the machine offer PostgreSQL? */ #undef HAS_PGSQL +/* Does the machine offer SQLite3? */ +#undef HAS_SQLITE3 + +/* Does SQLite3 use pthreads? */ +#undef SQLITE3_USES_PTHREADS + /* Does the machine offer GnuTLS? */ #undef HAS_GNUTLS #undef HAS_GNUTLS_VERSION diff -Naur 3.3/src/autoconf/configure.in 3.3sqlite/src/autoconf/configure.in --- 3.3/src/autoconf/configure.in 2005-11-08 08:31:42.000000000 +0100 +++ 3.3sqlite/src/autoconf/configure.in 2005-12-06 00:01:36.000000000 +0100 @@ -120,6 +120,7 @@ AC_MY_ARG_ENABLE(use-mccp,no,,[Enables MCCP support]) AC_MY_ARG_ENABLE(use-mysql,no,,[Enables mySQL support]) AC_MY_ARG_ENABLE(use-pgsql,no,,[Enables PostgreSQL support]) +AC_MY_ARG_ENABLE(use-sqlite3,no,,[Enables SQLite3 support]) AC_MY_ARG_ENABLE(use-pthreads,no,,[enable using of threads for socket writes]) AC_MY_ARG_ENABLE(use-pcre,yes,,[Enables PCRE: no/yes/builtin/no-builtin]) AC_MY_ARG_ENABLE(use-deprecated,yes,,[Enables obsolete and deprecated efuns]) @@ -305,6 +306,20 @@ enable_use_pgsql="yes" fi +AC_UPDATE_VAR(enable_use_sqlite3) +if test "x$enable_use_sqlite3" = "x" || test "x$enable_use_sqlite3" = "xyes"; then + cdef_use_sqlite3="#define" + sqlite3_path= + enable_use_sqlite3="yes" +elif test "x$enable_use_sqlite3" = "xno"; then + cdef_use_sqlite3="#undef" + sqlite3_path= +else + cdef_use_sqlite3="#define" + sqlite3_path="$enable_use_sqlite3" + enable_use_sqlite3="yes" +fi + AC_UPDATE_VAR(enable_use_tls) if test "x$enable_use_tls" = "x" || test "x$enable_use_tls" = "xyes"; then cdef_use_tls="#define" @@ -1505,6 +1520,129 @@ fi fi +# --- + +# --- SQLite3 --- + +AC_CACHE_CHECK(for SQLite3,lp_cv_has_sqlite3, +for TESTPATH in "" "$sqlite3_path" "$sqlite3_path/include" "/usr/local/sqlite3/include" "/usr/local/include/sqlite3" "/usr/include/sqlite3" "/usr/lib/sqlite3" "/usr/local/include"; do + saveflags="$CFLAGS" + if test "x$TESTPATH" != "x"; then + CFLAGS="$saveflags -I$TESTPATH" + fi +AC_TRY_COMPILE([ +#include <sqlite3.h> + +sqlite3 * foo(void) +{ + static sqlite3 * var; + + return var; +} +],, +lp_cv_has_sqlite3=yes +if test "x$TESTPATH" != "x"; then + EXTRA_CFLAGS="-I$TESTPATH $EXTRA_CFLAGS" +fi +break; +, +lp_cv_has_sqlite3=no +CFLAGS="$saveflags" +) +done +) + +# The system has the include files - now search for the libraries. +if test $lp_cv_has_sqlite3 = yes; then + saveflags="$CFLAGS" + AC_DEFINE(HAS_SQLITE3) + + if test $enable_use_sqlite3 = yes; then + tmp="" + + + if test "x$sqlite3_path" = "x"; then + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -lsqlite3") + if test "x$tmp" = "x"; then + if test -d "/usr/local/sqlite3/lib/sqlite3"; then + unset ac_cv_lib_sqlite3_main + CFLAGS="$saveflags -L/usr/local/sqlite3/lib/sqlite3" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L/usr/local/sqlite3/lib/sqlite3 -lsqlite3") + elif test -d "/usr/local/sqlite3/lib"; then + unset ac_cv_lib_sqlite3_main + CFLAGS="$saveflags -L/usr/local/sqlite3/lib" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L/usr/local/sqlite3/lib -lsqlite3") + elif test -d "/usr/local/lib"; then + unset ac_cv_lib_sqlite3_main + CFLAGS="$saveflags -L/usr/local/lib" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L/usr/local/lib -lsqlite3") + elif test -d "/usr/lib/sqlite3/lib"; then + unset ac_cv_lib_sqlite3_main + CFLAGS="$saveflags -L/usr/lib/sqlite3/lib" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L/usr/lib/sqlite3/lib -lsqlite3") + fi + fi + else + if test -d "${sqlite3_path}/lib/sqlite3"; then + CFLAGS="$saveflags -L${sqlite3_path}/lib/sqlite3" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L${sqlite3_path}/lib/sqlite3 -lsqlite3") + elif test -d "${sqlite3_path}/lib"; then + CFLAGS="$saveflags -L${sqlite3_path}/lib" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L${sqlite3_path}/lib -lsqlite3") + elif test -d "${sqlite3_path}"; then + CFLAGS="$saveflags -L$sqlite3_path" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L$sqlite3_path -lsqlite3") + fi + fi + + if test "x$tmp" = "x"; then + unset ac_cv_lib_sqlite3_main + if test -d "/usr/local/sqlite3/lib"; then + CFLAGS="$saveflags -L/usr/local/sqlite3/lib" + AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L/usr/local/sqlite3/lib -lsqlite3") + fi + fi + + if test "x$tmp" == "x"; then + echo "libsqlite3 library not found - disabling SQLite3 support" + AC_NOT_AVAILABLE(use-sqlite3) + cdef_use_sqlite3="#undef" + enable_use_sqlite3="no" + sqlite3_path= + lp_cv_has_sqlite3="no" + else + PKGLIBS="$tmp" + fi + fi + + if test $enable_use_sqlite3 = yes; then + savelibs="$LIBS" + LIBS="$LIBS $PKGLIBS" + + # Check if it uses pthreads + + AC_CHECK_LIB(sqlite3, pthread_create, + lp_cv_sqlite3_uses_pthreads=yes, + lp_cv_sqlite3_uses_pthreads=no + ) + + if test $lp_cv_sqlite3_uses_pthreads = yes ; then + AC_DEFINE(SQLITE3_USES_PTHREADS) + fi + + LIBS="$savelibs" + fi + + CFLAGS="$saveflags" +else + if test $enable_use_sqlite3 = yes; then + AC_NOT_AVAILABLE(use-sqlite3) + cdef_use_sqlite3="#undef" + enable_use_sqlite3=no + fi +fi +# --- + # --- Check if we need zlib libraries for mccp --- if test "x$enable_use_mccp" = "x" || test "x$enable_use_mccp" = "xyes"; then @@ -2506,6 +2644,7 @@ AC_SUBST(cdef_use_ipv6) AC_SUBST(cdef_use_mysql) AC_SUBST(cdef_use_pgsql) +AC_SUBST(cdef_use_sqlite3) AC_SUBST(cdef_use_pthreads) AC_SUBST(cdef_use_alists) AC_SUBST(cdef_use_mccp) diff -Naur 3.3/src/config.h.in 3.3sqlite/src/config.h.in --- 3.3/src/config.h.in 2005-06-22 14:52:18.000000000 +0200 +++ 3.3sqlite/src/config.h.in 2005-12-06 00:25:12.000000000 +0100 @@ -348,6 +348,11 @@ */ @cdef_use_pgsql@ USE_PGSQL +/* Define this if you want SQLite3 support (assuming that your host + * actually offers this. + */ +@cdef_use_sqlite3@ USE_SQLITE3 + /* Define this if you want alist support. */ @cdef_use_alists@ USE_ALISTS diff -Naur 3.3/src/func_spec 3.3sqlite/src/func_spec --- 3.3/src/func_spec 2005-11-25 08:19:27.000000000 +0100 +++ 3.3sqlite/src/func_spec 2005-12-06 00:05:58.000000000 +0100 @@ -722,6 +722,16 @@ #endif /* USE_PGSQL */ + +#ifdef USE_SQLITE3 + +int sl_open(string); +mixed sl_exec(string, ...); +int sl_insert_id(); +void sl_close(); + +#endif /* USE_SQLITE3 */ + #ifdef USE_TLS int tls_query_connection_state(object default: F_THIS_OBJECT); diff -Naur 3.3/src/lex.c 3.3sqlite/src/lex.c --- 3.3/src/lex.c 2005-11-08 08:31:45.000000000 +0100 +++ 3.3sqlite/src/lex.c 2005-12-06 00:05:58.000000000 +0100 @@ -824,6 +824,9 @@ #ifdef USE_MYSQL add_permanent_define("__MYSQL__", -1, string_copy("1"), MY_FALSE); #endif +#ifdef USE_SQLITE3 + add_permanent_define("__SQLITE__", -1, string_copy("1"), MY_FALSE); +#endif #ifdef USE_PGSQL add_permanent_define("__PGSQL__", -1, string_copy("1"), MY_FALSE); #endif diff -Naur 3.3/src/main.c 3.3sqlite/src/main.c --- 3.3/src/main.c 2005-06-22 14:52:18.000000000 +0200 +++ 3.3sqlite/src/main.c 2005-12-06 00:26:50.000000000 +0100 @@ -1792,6 +1792,9 @@ #ifdef USE_PGSQL , "PostgreSQL supported\n" #endif +#ifdef USE_SQLITE3 + , "SQLite3 supported\n" +#endif #ifdef USE_PTHREADS , "PThreads supported\n" #endif diff -Naur 3.3/src/Makefile.in 3.3sqlite/src/Makefile.in --- 3.3/src/Makefile.in 2005-11-25 08:19:27.000000000 +0100 +++ 3.3sqlite/src/Makefile.in 2005-12-06 00:07:39.000000000 +0100 @@ -90,7 +90,7 @@ lex.c main.c mapping.c md5.c mempools.c mregex.c mstrings.c object.c \ otable.c\ parser.c parse.c pkg-alists.c pkg-mccp.c pkg-mysql.c pkg-pcre.c \ - pkg-pgsql.c pkg-tls.c \ + pkg-pgsql.c pkg-tls.c pkg-sqlite3.c \ ptmalloc.c port.c ptrtable.c \ random.c regexp.c sha1.c simulate.c simul_efun.c stdstrings.c \ strfuns.c structs.c sprintf.c swap.c wiz_list.c xalloc.c @@ -101,7 +101,7 @@ lex.o main.o mapping.o md5.o mempools.o mregex.o mstrings.o object.o \ otable.o \ parser.o parse.o pkg-alists.o pkg-mccp.o pkg-mysql.o pkg-pcre.o \ - pkg-pgsql.o pkg-tls.o \ + pkg-pgsql.o pkg-tls.o pkg-sqlite3.o \ ptmalloc.o port.o ptrtable.o \ random.o regexp.o sha1.o simulate.o simul_efun.o stdstrings.o \ strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@ diff -Naur 3.3/src/object.c 3.3sqlite/src/object.c --- 3.3/src/object.c 2005-11-25 08:19:27.000000000 +0100 +++ 3.3sqlite/src/object.c 2005-12-06 00:05:58.000000000 +0100 @@ -43,6 +43,7 @@ * wiz_list_t * user; * wiz_list_t * eff_user; * int extra_num_variables; (ifdef DEBUG) + * int open_sqlite_db (ifdef USE_SQLITE3) * svalue_t * variables; * unsigned long ticks, gigaticks; * } diff -Naur 3.3/src/object.h 3.3sqlite/src/object.h --- 3.3/src/object.h 2005-11-25 08:19:27.000000000 +0100 +++ 3.3sqlite/src/object.h 2005-12-06 00:05:58.000000000 +0100 @@ -50,6 +50,9 @@ int extra_num_variables; /* amylaar : used to determine where to check ref counts at all... */ #endif +#ifdef USE_SQLITE3 + int open_sqlite_db; /* does this object have an open sqlite db */ +#endif svalue_t *variables; /* All variables to this object: an array of svalues, allocated * in a separate block. diff -Naur 3.3/src/pkg-sqlite3.c 3.3sqlite/src/pkg-sqlite3.c --- 3.3/src/pkg-sqlite3.c 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/src/pkg-sqlite3.c 2005-12-06 00:07:14.000000000 +0100 @@ -0,0 +1,437 @@ +#include "config.h" +#ifdef USE_SQLITE3 + +#include <sqlite3.h> +#include "typedefs.h" + +#include "my-alloca.h" +#include <errno.h> +#include <stddef.h> +#include <time.h> +#include <unistd.h> +#include <stdio.h> +#include "array.h" +#include "interpret.h" +#include "mstrings.h" +#include "simulate.h" +#include "svalue.h" +#include "xalloc.h" +#include "object.h" +#include "stdstrings.h" + +typedef struct sqlite_rows_s sqlite_rows_t; +typedef struct sqlite_dbs_s sqlite_dbs_t; + +/* Since we don't know the number of rows while we retrieve the + * rows from a query we save the data in a single-linked list first + * and move them into an array after the retrieval has finished + */ +struct sqlite_rows_s +{ + vector_t * row; + sqlite_rows_t * last; +}; + +/* This structure is used for error handling. In case of an error + * our handler gets called with a pointer to this structure. + */ +struct sl_exec_cleanup_s +{ + svalue_t head; /* push_error_handler saves the link to our + handler here. */ + + sqlite3_stmt *stmt; + sqlite_rows_t *rows; +}; + +/* Database connections should be bound to the object which opens + * database file. We will store all database connections in a + * linked list. + */ +struct sqlite_dbs_s +{ + sqlite3 * db; + object_t * obj; + sqlite_dbs_t * next; + sqlite_dbs_t * prev; +}; + +/* The list of database connections. + */ +static sqlite_dbs_t *head = NULL; + +// HELPER FUNS +sqlite_dbs_t *find_db (object_t * obj) +{ + sqlite_dbs_t *tmp = head; + + while (tmp) + { + if (tmp->obj==obj) return tmp; + tmp=tmp->prev; + } + return NULL; +} + +sqlite_dbs_t * new_db() +{ + sqlite_dbs_t *tmp; + tmp = pxalloc (sizeof (*tmp)); + if(!tmp) return NULL; + + tmp->db=NULL; + tmp->obj=NULL; + tmp->next=NULL; + tmp->prev=head; + if (head) head->next=tmp; + head=tmp; + + return tmp; +} + +void remove_db(sqlite_dbs_t *db) +{ + if (db==head) + { + if (head->prev) + { + head->prev->next=NULL; + head=head->prev; + } + else + { + head=NULL; + } + } + else + { + if (db->next) db->next->prev=db->prev; + if (db->prev) db->prev->next=db->next; + } + pfree(db); +} + +static int +my_sqlite3_authorizer(void* data, int what, const char* arg1, const char* arg2, + const char* dbname, const char* view) +{ + /* TODO: Check them via privilege_violation resp. valid_write. + (Don't know, whether sqlite can handle longjmps out of + its code in case of an error...) + */ + + switch(what) + { + case SQLITE_PRAGMA: + if(!strcasecmp(arg1, "synchronous")) + return SQLITE_OK; + return SQLITE_DENY; + + case SQLITE_ATTACH: + case SQLITE_DETACH: + return SQLITE_DENY; + + default: + return SQLITE_OK; + } +} + +// EFUNS GO FROM HERE +svalue_t * +f_sl_open (svalue_t *sp) +{ + string_t *file; + sqlite3 *db; + sqlite_dbs_t *tmp; + int err; + + file = check_valid_path(sp->u.str, current_object, STR_SQLITE_OPEN , MY_TRUE); + if (!file) + errorf("Illegal use of sl_open('%s')\n", get_txt(sp->u.str)); + + tmp = find_db (current_object); + if (tmp) + { + free_mstring(file); + errorf("The current object already has a database open.\n"); + } + + err = sqlite3_open (get_txt(file), &db); + free_mstring(file); + if (err) + { + const char* msg = sqlite3_errmsg(db); + sqlite3_close(db); + errorf("sl_open: %s\n", msg ); + /* NOTREACHED */ + } + + /* create a new chain link and hang on the old chain */ + tmp=new_db(); + if(!tmp) + { + sqlite3_close(db); + errorf("(sl_open) Out of memory: (%lu bytes)\n", + (unsigned long) sizeof(*tmp)); + } + + tmp->db = db; + tmp->obj = current_object; + current_object->open_sqlite_db=1; + + /* Synchronous is damn slow. Forget it. */ + sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, NULL); + sqlite3_set_authorizer(db, my_sqlite3_authorizer, NULL); + + free_string_svalue (sp); + put_number (sp, 1); + return sp; +} + +static void +sl_exec_cleanup (svalue_t * arg) +{ + sqlite_rows_t *row; + struct sl_exec_cleanup_s * data; + + data = (struct sl_exec_cleanup_s *)arg; + + if(data->stmt) + sqlite3_finalize(data->stmt); + + row = data->rows; + while(row) + { + sqlite_rows_t *temp; + + if(row->row) + free_array(row->row); + temp = row; + row = row->last; + pfree(temp); + } + + xfree(data); +} + +svalue_t * +v_sl_exec (svalue_t * sp, int num_arg) +{ + svalue_t *argp; + sqlite_dbs_t *db; + sqlite3_stmt *stmt; + const char* tail; + int err, rows, cols, num; + struct sl_exec_cleanup_s * rec_data; + vector_t * result; + + argp = sp - num_arg + 1; /* First argument: the SQL query */ + + db = find_db (current_object); + if (!db) + errorf("The current object doesn't have a database open.\n"); + + err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str), + &stmt, &tail); + if(err) + { + const char* msg = sqlite3_errmsg(db->db); + if(stmt) + sqlite3_finalize(stmt); + errorf("sl_exec: %s\n", msg); + /* NOTREACHED */ + } + + /* Now bind all parameters. */ + for(argp++, num=1; argp <= sp; argp++, num++) + { + switch(argp->type) + { + default: + sqlite3_finalize(stmt); + errorf("Bad argument %d to sl_exec(): type %s\n", + num+1, typename(argp->type)); + break; /* NOTREACHED */ + + case T_FLOAT: + sqlite3_bind_double(stmt, num, READ_DOUBLE(argp)); + break; + + case T_NUMBER: + sqlite3_bind_int(stmt, num, argp->u.number); + break; + + case T_STRING: + sqlite3_bind_text(stmt, num, get_txt(argp->u.str), + mstrsize(argp->u.str), SQLITE_STATIC); + break; + } + } + + rows = 0; + cols = sqlite3_column_count(stmt); + + rec_data = xalloc(sizeof(*rec_data)); + if(!rec_data) + { + sqlite3_finalize(stmt); + errorf("(sl_exec) Out of memory: (%lu bytes) for cleanup structure\n", + (unsigned long) sizeof(*rec_data)); + } + rec_data->rows = NULL; + rec_data->stmt = stmt; + + push_error_handler(sl_exec_cleanup, &(rec_data->head)); + sp = inter_sp; + + while((err = sqlite3_step(stmt)) == SQLITE_ROW) + { + int col; + sqlite_rows_t *this_row; + + rows++; + this_row = pxalloc(sizeof(*this_row)); + if(!this_row) + errorf("(sl_exec) Out of memory: (%lu bytes)\n", + (unsigned long) sizeof(*this_row)); + + this_row->last = rec_data->rows; + rec_data->rows = this_row; + this_row->row = NULL; /* Because allocate_array may throw an error. */ + + this_row->row = allocate_array(cols); + if(!this_row->row) + errorf("(sl_exec) Out of memory: row vector\n"); + + for(col = 0; col < cols; col++) + { + STORE_DOUBLE_USED; + svalue_t * entry; + + entry = this_row->row->item + col; + + switch(sqlite3_column_type(stmt, col)) + { + default: + errorf("sl_exec: Unknown type %d.\n", + sqlite3_column_type(stmt, col)); + break; + + case SQLITE_BLOB: + errorf("sl_exec: Blob columns are not supported.\n"); + break; + + case SQLITE_INTEGER: + put_number(entry, sqlite3_column_int(stmt, col)); + break; + + case SQLITE_FLOAT: + entry->type = T_FLOAT; + STORE_DOUBLE(entry, sqlite3_column_double(stmt, col)); + break; + + case SQLITE_TEXT: + put_c_n_string(entry, + sqlite3_column_text(stmt, col), + sqlite3_column_bytes(stmt, col)); + break; + + case SQLITE_NULL: + /* All elements from this_row->row are initialized to 0. */ + break; + } + } + } + + sqlite3_finalize(stmt); + rec_data->stmt = NULL; + + switch(err) + { + default: + errorf("sl_exec: Unknown return code from sqlite3_step: %d.\n", err); + break; + + case SQLITE_BUSY: + errorf("sl_exec: Database is locked.\n"); + break; + + case SQLITE_ERROR: + errorf("sl_exec: %s\n", sqlite3_errmsg(db->db)); + break; + + case SQLITE_MISUSE: + errorf("sl_exec: sqlite3_step was called inappropriately.\n"); + break; + + case SQLITE_DONE: + break; + } + + if(rows) + { + sqlite_rows_t *this_row; + + result = allocate_array(rows); + if(!result) + errorf("(sl_exec) Out of memory: result vector\n"); + + this_row = rec_data->rows; + while(rows--) + { + put_array(result->item + rows, this_row->row); + this_row->row = NULL; + this_row = this_row->last; + } + } + else + result = NULL; + + // Pop arguments and our error handler. + // Our error handler gets called and cleans the row stuff. + sp = pop_n_elems(num_arg + 1, sp) + 1; + + if(rows) + put_array(sp,result); + else + put_number(sp, 0); + + return sp; +} + +int +sl_close (object_t *ob) +{ + sqlite_dbs_t *db = find_db(ob); + if (!db) return 0; + + sqlite3_close(db->db); + ob->open_sqlite_db=0; + remove_db(db); + return 1; +} + +svalue_t * +f_sl_insert_id (svalue_t * sp) +{ + sqlite_dbs_t *db = find_db(current_object); + int id; + + if (!db) + errorf("The current object doesn't have a database open.\n"); + + id=sqlite3_last_insert_rowid(db->db); + sp++; + put_number(sp,id); + return sp; +} + +svalue_t * +f_sl_close (svalue_t * sp) +{ + if (!sl_close(current_object)) + errorf("The current object doesn't have a database open.\n"); + return sp; +} + +#endif /* USE_SQLITE3 */ diff -Naur 3.3/src/pkg-sqlite3.h 3.3sqlite/src/pkg-sqlite3.h --- 3.3/src/pkg-sqlite3.h 1970-01-01 01:00:00.000000000 +0100 +++ 3.3sqlite/src/pkg-sqlite3.h 2005-12-06 00:07:18.000000000 +0100 @@ -0,0 +1,5 @@ +#ifdef USE_SQLITE3 + +int sl_close (object_t *ob); + +#endif /* USE_SQLITE3 */ diff -Naur 3.3/src/simulate.c 3.3sqlite/src/simulate.c --- 3.3/src/simulate.c 2005-11-25 08:19:27.000000000 +0100 +++ 3.3sqlite/src/simulate.c 2005-12-06 00:27:40.000000000 +0100 @@ -53,6 +53,9 @@ #include "mstrings.h" #include "object.h" #include "otable.h" +#ifdef USE_SQLITE3 +#include "pkg-sqlite3.h" +#endif #ifdef USE_TLS #include "pkg-tls.h" #endif @@ -2059,6 +2062,9 @@ ob->load_name = new_tabled(name); /* but here it is */ ob->prog = prog; ob->ticks = ob->gigaticks = 0; +#ifdef USE_SQLITE3 + ob->open_sqlite_db=0; +#endif ob->next_all = obj_list; ob->prev_all = NULL; if (obj_list) @@ -2302,6 +2308,9 @@ if (!current_object) fatal("clone_object() from no current_object !\n"); #endif +#ifdef USE_SQLITE3 + new_ob->open_sqlite_db=0; +#endif new_ob->next_all = obj_list; new_ob->prev_all = NULL; if (obj_list) @@ -2544,6 +2553,10 @@ #ifdef CHECK_OBJECT_REF xallocate(shadow, sizeof(*shadow), "destructed object shadow"); #endif /* CHECK_OBJECT_REF */ + +#ifdef USE_SQLITE3 + if (ob->open_sqlite_db) sl_close(ob); +#endif ob->time_reset = 0; /* We need the object in memory */ diff -Naur 3.3/src/slaballoc.c 3.3sqlite/src/slaballoc.c --- 3.3/src/slaballoc.c 2005-06-22 14:52:18.000000000 +0200 +++ 3.3sqlite/src/slaballoc.c 2005-12-06 00:13:39.000000000 +0100 @@ -230,7 +230,7 @@ #if defined(SBRK_OK) # ifdef MALLOC_SBRK -# if !defined(USE_PTHREADS) +# if !defined(USE_PTHREADS) && (!defined(USE_SQLITE3) || !defined(SQLITE3_USES_PTHREADS)) # define REPLACE_MALLOC # else # undef SBRK_OK diff -Naur 3.3/src/smalloc.c 3.3sqlite/src/smalloc.c --- 3.3/src/smalloc.c 2005-11-08 08:31:45.000000000 +0100 +++ 3.3sqlite/src/smalloc.c 2005-12-06 00:13:18.000000000 +0100 @@ -243,7 +243,7 @@ #if defined(SBRK_OK) # ifdef MALLOC_SBRK -# if !defined(USE_PTHREADS) +# if !defined(USE_PTHREADS) && (!defined(USE_SQLITE3) || !defined(SQLITE3_USES_PTHREADS)) # define REPLACE_MALLOC # else # undef SBRK_OK diff -Naur 3.3/src/string_spec 3.3sqlite/src/string_spec --- 3.3/src/string_spec 2005-11-08 08:31:45.000000000 +0100 +++ 3.3sqlite/src/string_spec 2005-12-06 00:05:58.000000000 +0100 @@ -229,5 +229,8 @@ SUCCESS "success" #endif +#ifdef USE_SQLITE3 +SQLITE_OPEN "sl_open" +#endif /***************************************************************************/ diff -Naur 3.3/src/xalloc.c 3.3sqlite/src/xalloc.c --- 3.3/src/xalloc.c 2005-11-25 08:19:27.000000000 +0100 +++ 3.3sqlite/src/xalloc.c 2005-12-06 00:12:03.000000000 +0100 @@ -329,6 +329,15 @@ # warning "" #endif +#if defined(USE_SQLITE3) && defined(SQLITE3_USES_PTHREADS) && !defined(MEM_THREADSAFE) && !defined(MEM_MAIN_THREADSAFE) +# warning "" +# warning "-----------------------------------" +# warning "SQLite3 uses PThreads, but the allocator" +# warning "is not threadsafe!" +# warning "-----------------------------------" +# warning "" +#endif + #if defined(MALLOC_ptmalloc) && defined(GC_SUPPORT) && defined(__FreeBSD__) # warning "" # warning "-----------------------------------" | ||||
|
updated the patch |
|
updated again :) |
|
partly rewrote .. fixed a few bugs last version was in the finalfrontier driver for about 6 month without causing troubles ;) |
|
I ported Dafire's patch to SQLite 3 and uploaded the diff. I especially paid attention not to have memory leaks. There is a todo item though, which requires to call LPC functions from within a sqlite callback. I have to figure out, how to do this carefully. Greetings, Gnomi. |
|
Uploaded documentation for the efuns (documentation for sl_exec is specific to the SQLite3 version). |
|
When SQLite3 is compiled as threadsafe it uses Pthreads and therefore LDMud should not replace malloc (SBRK_OK should be undef'd in machine.h), also a threadsafe memory allocator should be used. |
|
So, I made a new diff (sqlite3_all.diff) that contains both code and documentation and also has patches for configure.in (but I didn't run autoreconf before making the diff). The configure script now also checks whether libsqlite3 uses pthreads (and the memory allocators act accordingly). |
|
I have implemented the SQLite-3 version now - is the older one still useful? I leave it to Gnomi to implement the still-missing callback, as he has a better idea of what it needs to do. |
Date Modified | Username | Field | Change |
---|---|---|---|
2003-08-14 15:13 | dafire | New Issue | |
2003-08-24 13:52 | dafire | Note Added: 0000025 | |
2003-08-31 07:53 | dafire | Note Added: 0000026 | |
2004-03-28 08:11 | dafire | Note Added: 0000035 | |
2005-05-01 12:40 |
|
File Added: pkg_sqlite.diff | |
2005-05-01 12:41 |
|
File Added: sqlite.html | |
2005-11-11 20:37 | Gnomi | File Added: sqlite3.diff | |
2005-11-11 20:46 | Gnomi | Note Added: 0000403 | |
2005-11-23 13:48 | Gnomi | File Added: sqlite3.doc.diff | |
2005-11-23 13:50 | Gnomi | Note Added: 0000409 | |
2005-11-28 14:05 | Gnomi | Note Added: 0000429 | |
2005-12-05 18:20 | Gnomi | File Added: sqlite3_all.diff | |
2005-12-05 18:25 | Gnomi | Note Added: 0000445 | |
2005-12-05 19:26 |
|
Status | new => resolved |
2005-12-05 19:26 |
|
Fixed in Version | => 3.3.713 |
2005-12-05 19:26 |
|
Resolution | open => fixed |
2005-12-05 19:26 |
|
Assigned To | => lars |
2005-12-05 19:26 |
|
Note Added: 0000446 | |
2006-02-28 20:04 |
|
Status | resolved => closed |
2010-11-16 09:42 |
|
Source_changeset_attached | => ldmud.git master 80d9e420 |
2018-01-29 18:59 |
|
Source_changeset_attached | => ldmud.git master 80d9e420 |
2018-01-29 21:57 |
|
Source_changeset_attached | => ldmud.git master 80d9e420 |