From 2f0ecec287ce4933dd5d46c96f7c28d02edcefd2 Mon Sep 17 00:00:00 2001 From: Rafael Laboissiere Date: Mon, 15 Oct 2007 18:46:05 -0200 Subject: Import slsqlite_0.4.0.orig.tar.gz [dgit import orig slsqlite_0.4.0.orig.tar.gz] --- COPYING | 340 +++++++++++++++++++ Makefile | 71 ++++ sqlite-module.c | 1003 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ sqlite.hlp | 136 ++++++++ sqlite.sl | 7 + sqlitefuns.tm | 101 ++++++ 6 files changed, 1658 insertions(+) create mode 100644 COPYING create mode 100644 Makefile create mode 100644 sqlite-module.c create mode 100644 sqlite.hlp create mode 100644 sqlite.sl create mode 100644 sqlitefuns.tm diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..619e75a --- /dev/null +++ b/Makefile @@ -0,0 +1,71 @@ +#--------------------------------------------------------------------------- +# Installation Directories +#--------------------------------------------------------------------------- +prefix = /usr/local +exec_prefix = ${prefix} +MODULE_INSTALL_DIR = ${exec_prefix}/lib/slang/v2/modules +SL_FILES_INSTALL_DIR = ${prefix}/share/slsh/local-packages +HLP_FILES_INSTALL_DIR = $(SL_FILES_INSTALL_DIR)/help + +#--------------------------------------------------------------------------- +# DESTDIR is designed to facilitate making packages. Normally it is empty +#--------------------------------------------------------------------------- +DESTDIR = +DEST_MODULE_INSTALL_DIR = $(DESTDIR)$(MODULE_INSTALL_DIR) +DEST_SL_FILES_INSTALL_DIR = $(DESTDIR)$(SL_FILES_INSTALL_DIR) +DEST_HLP_FILES_INSTALL_DIR = $(DESTDIR)$(HLP_FILES_INSTALL_DIR) + +#--------------------------------------------------------------------------- +# Location of the S-Lang library and its include file +#--------------------------------------------------------------------------- +SLANG_INC = -I/usr/local/include +SLANG_LIB = -L/usr/local/lib -lslang + +#--------------------------------------------------------------------------- +# C Compiler to create a shared library +#--------------------------------------------------------------------------- +CC_SHARED = $(CC) $(CFLAGS) -shared -Wall -fPIC + +#--------------------------------------------------------------------------- +# Misc Programs required for installation +#--------------------------------------------------------------------------- +INSTALL = /usr/bin/install -m 644 +MKINSDIR = /usr/bin/install -d +#--------------------------------------------------------------------------- +# You shouldn't need to edit anything below this line +#--------------------------------------------------------------------------- + +LIBS = $(SLANG_LIB) -lm -lsqlite3 +INCS = $(SLANG_INC) + +all: sqlite-module.so + +sqlite-module.so: sqlite-module.c + $(CC_SHARED) $(INCS) -g sqlite-module.c -o sqlite-module.so $(LIBS) + +sqlite.o: sqlite-module.c + gcc $(CFLAGS) $(INCS) -O2 -c -g sqlite-module.c -o sqlite.o + +sqlite.hlp: sqlitefuns.tm + tmexpand -Mslhlp sqlitefuns.tm sqlite.hlp + + +clean: + rm -f sqlite-module.so *.o + +#--------------------------------------------------------------------------- +# Installation Rules +#--------------------------------------------------------------------------- +install_directories: + $(MKINSDIR) $(DEST_MODULE_INSTALL_DIR) + $(MKINSDIR) $(DEST_SL_FILES_INSTALL_DIR) + $(MKINSDIR) $(DEST_HLP_FILES_INSTALL_DIR) + +install_modules: + $(INSTALL) sqlite-module.so $(DEST_MODULE_INSTALL_DIR) +install_slfiles: + $(INSTALL) sqlite.sl $(DEST_SL_FILES_INSTALL_DIR) +install_hlpfiles: + $(INSTALL) sqlite.hlp $(DEST_HLP_FILES_INSTALL_DIR) + +install: all install_directories install_modules install_slfiles install_hlpfiles diff --git a/sqlite-module.c b/sqlite-module.c new file mode 100644 index 0000000..8c1b541 --- /dev/null +++ b/sqlite-module.c @@ -0,0 +1,1003 @@ +/* sqlite-module.c + * S-Lang bindings for the sqlite3 library + * This was tested with sqlite3 version 3.3.8 + * + * $Id: sqlite-module.c,v 1.5 2007/10/13 12:39:36 paul Exp paul $ + * + * Copyright (c) 2006, 2007 Paul Boekholt. + * Released under the terms of the GNU GPL (version 2 or later). + */ +#include +#include +#include + +SLANG_MODULE(sqlite); + +#define MODULE_MAJOR_VERSION 0 +#define MODULE_MINOR_VERSION 4 +#define MODULE_PATCH_LEVEL 0 +static char *Module_Version_String = "0.4.0"; +#define MODULE_VERSION_NUMBER \ + (MODULE_MAJOR_VERSION*10000+MODULE_MINOR_VERSION*100+MODULE_PATCH_LEVEL) + +/*{{{ sqlite type */ + +static int DB_Type_Id = 0; + +typedef struct +{ + sqlite3 * db; +} db_type; + +#define DUMMY_SQLITE_TYPE 255 +/*}}}*/ +/*{{{ exceptions */ +static int Sqlite_Error = 0; +static int Sqlite_Internal_Error = 0; +static int Sqlite_Perm_Error = 0; +static int Sqlite_Abort_Error = 0; +static int Sqlite_Busy_Error = 0; +static int Sqlite_Locked_Error = 0; +static int Sqlite_Nomem_Error = 0; +static int Sqlite_Readonly_Error = 0; +static int Sqlite_Interrupt_Error = 0; +static int Sqlite_Ioerr_Error = 0; +static int Sqlite_Corrupt_Error = 0; +static int Sqlite_Notfound_Error = 0; +static int Sqlite_Full_Error = 0; +static int Sqlite_Cantopen_Error = 0; +static int Sqlite_Protocol_Error = 0; +static int Sqlite_Empty_Error = 0; +static int Sqlite_Schema_Error = 0; +static int Sqlite_Toobig_Error = 0; +static int Sqlite_Constraint_Error = 0; +static int Sqlite_Mismatch_Error = 0; +static int Sqlite_Misuse_Error = 0; +static int Sqlite_Nolfs_Error = 0; +static int Sqlite_Auth_Error = 0; +static int Sqlite_Format_Error = 0; +static int Sqlite_Range_Error = 0; +static int Sqlite_Notadb_Error = 0; + +typedef struct +{ + int error_code; + int *errcode_ptr; + char *name; + char *description; +} +Sqlite_Exception_Table_Type; + +static const Sqlite_Exception_Table_Type Sqlite_Exception_Table [] = +{ + { SQLITE_ERROR, &Sqlite_Error, "Sqlite_Error", "Sqlite Error"}, + { SQLITE_INTERNAL, &Sqlite_Internal_Error, "Sqlite_Internal_Error", "NOT USED. Internal logic error in SQLite"}, + { SQLITE_PERM, &Sqlite_Perm_Error, "Sqlite_Perm_Error", "Access permission denied"}, + { SQLITE_ABORT, &Sqlite_Abort_Error, "Sqlite_Abort_Error", "Callback routine requested an abort"}, + { SQLITE_BUSY, &Sqlite_Busy_Error, "Sqlite_Busy_Error", "The database file is locked"}, + { SQLITE_LOCKED, &Sqlite_Locked_Error, "Sqlite_Locked_Error", "A table in the database is locked"}, + { SQLITE_NOMEM, &Sqlite_Nomem_Error, "Sqlite_Nomem_Error", "A malloc() failed"}, + { SQLITE_READONLY, &Sqlite_Readonly_Error, "Sqlite_Readonly_Error", "Attempt to write a readonly database"}, + { SQLITE_INTERRUPT, &Sqlite_Interrupt_Error, "Sqlite_Interrupt_Error", "Operation terminated by sqlite3_interrupt()*/"}, + { SQLITE_IOERR, &Sqlite_Ioerr_Error, "Sqlite_Ioerr_Error", "Some kind of disk I/O error occurred"}, + { SQLITE_CORRUPT, &Sqlite_Corrupt_Error, "Sqlite_Corrupt_Error", "The database disk image is malformed"}, + { SQLITE_NOTFOUND, &Sqlite_Notfound_Error, "Sqlite_Notfound_Error", "NOT USED. Table or record not found"}, + { SQLITE_FULL, &Sqlite_Full_Error, "Sqlite_Full_Error", "Insertion failed because database is full"}, + { SQLITE_CANTOPEN, &Sqlite_Cantopen_Error, "Sqlite_Cantopen_Error", "Unable to open the database file"}, + { SQLITE_PROTOCOL, &Sqlite_Protocol_Error, "Sqlite_Protocol_Error", "Database lock protocol error"}, + { SQLITE_EMPTY, &Sqlite_Empty_Error, "Sqlite_Empty_Error", "Database is empty"}, + { SQLITE_SCHEMA, &Sqlite_Schema_Error, "Sqlite_Schema_Error", "The database schema changed"}, + { SQLITE_TOOBIG, &Sqlite_Toobig_Error, "Sqlite_Toobig_Error", "NOT USED. Too much data for one row"}, + { SQLITE_CONSTRAINT, &Sqlite_Constraint_Error, "Sqlite_Constraint_Error", "Abort due to contraint violation"}, + { SQLITE_MISMATCH, &Sqlite_Mismatch_Error, "Sqlite_Mismatch_Error", "Data type mismatch"}, + { SQLITE_MISUSE, &Sqlite_Misuse_Error, "Sqlite_Misuse_Error", "Library used incorrectly"}, + { SQLITE_NOLFS, &Sqlite_Nolfs_Error, "Sqlite_Nolfs_Error", "Uses OS features not supported on host"}, + { SQLITE_AUTH, &Sqlite_Auth_Error, "Sqlite_Auth_Error", "Authorization denied"}, + { SQLITE_FORMAT, &Sqlite_Format_Error, "Sqlite_Format_Error", "Auxiliary database format error"}, + { SQLITE_RANGE, &Sqlite_Range_Error, "Sqlite_Range_Error", "2nd parameter to sqlite3_bind out of range"}, + { SQLITE_NOTADB, &Sqlite_Notadb_Error, "Sqlite_Notadb_Error", "File opened that is not a database file"}, + { SQLITE_OK, 0, 0, 0 } +}; + +static int check_error (sqlite3 *db, int error_code) +{ + const Sqlite_Exception_Table_Type *b; + int error; + if (error_code == SQLITE_OK || error_code == SQLITE_DONE) return 0; + b = Sqlite_Exception_Table; + + while (b->errcode_ptr != NULL) + { + if (b->error_code == error_code) + break; + b++; + } + if (b->errcode_ptr == NULL) error = Sqlite_Error; + else error = *(b->errcode_ptr); + SLang_verror (error, (char *) sqlite3_errmsg(db)); + return 1; +} + +/*}}}*/ +/*{{{ helper functions */ + +static void free_db_type (db_type *pt) +{ + if (pt->db != NULL) + sqlite3_close(pt->db); + SLfree ((char *) pt); +} + +static void destroy_sqlite (SLtype type, VOID_STAR f) +{ + (void) type; + free_db_type ((db_type *) f); +} + +static SLang_MMT_Type *allocate_db_type (sqlite3 *db) +{ + db_type *pt; + SLang_MMT_Type *mmt; + + pt = (db_type *) SLmalloc (sizeof (db_type)); + if (pt == NULL) + return NULL; + memset ((char *) pt, 0, sizeof (db_type)); + + pt->db = db; + + if (NULL == (mmt = SLang_create_mmt (DB_Type_Id, (VOID_STAR) pt))) + { + free_db_type (pt); + return NULL; + } + return mmt; +} + +static int sqlite_step(sqlite3 *db, sqlite3_stmt *ppStmt) +{ + int i, res; + SLang_BString_Type *bstr; + res = sqlite3_step(ppStmt); + if (res == SQLITE_ROW) + { + for (i = 0; i < sqlite3_data_count (ppStmt); i++) + { + switch (sqlite3_column_type(ppStmt, i)) + { + case SQLITE_INTEGER: + SLang_push_integer(sqlite3_column_int(ppStmt, i)); + break; + case SQLITE_FLOAT: + SLang_push_double(sqlite3_column_double(ppStmt, i)); + break; + case SQLITE_TEXT: + SLang_push_string((char *)sqlite3_column_text(ppStmt, i)); + break; + case SQLITE_BLOB: + bstr = SLbstring_create((unsigned char *)sqlite3_column_blob(ppStmt, i), + sqlite3_column_bytes(ppStmt, i)); + if (bstr != NULL) + (void) SLang_push_bstring(bstr); + SLbstring_free(bstr); + break; + case SQLITE_NULL: + SLang_push_null(); + } + } + return 1; + } + if (res != SQLITE_DONE) + check_error(db, sqlite3_reset(ppStmt)); + return -1; +} + +static int sqlite_bind(sqlite3 *db, sqlite3_stmt *ppStmt, int num) +{ + int i; + int ivalue; + float fvalue; + double dvalue; + char *svalue; + SLang_BString_Type *bvalue; + unsigned int bstrlen; + unsigned char *bptr; + + for (i = 1; i <= num; i++) + { + switch (SLang_peek_at_stack()) + { + case SLANG_INT_TYPE: + SLang_pop_int(&ivalue); + if (check_error(db, sqlite3_bind_int(ppStmt, i, ivalue))) + return -1; + break; + case SLANG_FLOAT_TYPE: + SLang_pop_float(&fvalue); + if (check_error(db, sqlite3_bind_double(ppStmt, i, (double) fvalue))) + return -1; + break; + case SLANG_DOUBLE_TYPE: + SLang_pop_double(&dvalue); + if (check_error(db, sqlite3_bind_double(ppStmt, i, dvalue))) + return -1; + break; + case SLANG_STRING_TYPE: + SLang_pop_slstring(&svalue); + if (check_error(db, sqlite3_bind_text(ppStmt, i, svalue, + strlen(svalue), (void *)&SLang_free_slstring))) + return -1; + break; + case SLANG_BSTRING_TYPE: + SLang_pop_bstring(&bvalue); + bptr = SLbstring_get_pointer(bvalue, &bstrlen); + if (check_error(db, sqlite3_bind_blob(ppStmt, i, bptr, + bstrlen, SQLITE_TRANSIENT))) + { + SLbstring_free(bvalue); + return -1; + } + SLbstring_free(bvalue); + break; + default: + SLdo_pop_n(num + 1 - i); + SLang_verror(SL_Usage_Error, "attempt to bind unsupported type"); + return -1; + } + } + return 0; +} + +/*}}}*/ +/*{{{ exported functions */ + +static void slsqlite_open(char *name) +{ + SLang_MMT_Type *mmt; + sqlite3 *db; + + if (check_error(db, sqlite3_open(name, &db)) + || (NULL == (mmt = allocate_db_type (db)))) + { + (void) SLang_push_null(); + sqlite3_close(db); + return; + } + + if (-1 == SLang_push_mmt (mmt)) + { + SLang_free_mmt (mmt); + (void) SLang_push_null(); + return; + } +} + +static void slsqlite_get_table (const char *sql) +{ + db_type *p; + SLang_MMT_Type *mmt; + SLindex_Type dims[2]; + int nrow, ncolumn; + char **resultp; + SLang_Array_Type *at; + if (NULL == (mmt = SLang_pop_mmt (DB_Type_Id))) + { + SLang_free_mmt (mmt); + (void) SLang_push_null(); + return; + } + p = SLang_object_from_mmt (mmt); + + if (check_error(p->db, sqlite3_get_table(p->db, sql, &resultp, &nrow, &ncolumn, NULL))) + { + SLang_free_mmt(mmt); + return; + } + + dims[0] = nrow + 1; + dims[1] = ncolumn; + + at = SLang_create_array(SLANG_STRING_TYPE, 0, NULL, dims, 2); + + if (at != NULL) + { + char **p = resultp; + SLindex_Type j, k, d[2]; + for (j=0; jdb, sqlite3_prepare(p->db, sql, strlen(sql), &ppStmt, NULL))) + { + goto free_return; + } + + if (sqlite_bind(p->db, ppStmt, nargs - 2)) + { + sqlite3_finalize(ppStmt); + goto free_return; + } + + if (-1 == sqlite_step(p->db, ppStmt)) + SLang_verror (Sqlite_Error, "Query returned no result"); + + check_error(p->db, sqlite3_finalize (ppStmt)); + +free_return: + SLang_free_slstring(sql); + SLang_free_mmt(mmt); + +} + +/*{{{ sqlite_get_array */ + +static void sqlite_get_integer_array(sqlite3_stmt *ppStmt) +{ + unsigned int num_items = 0, max_num_items = 1024; + SLindex_Type dims[2]; + int *list; + SLang_Array_Type *at; + list = (int *) SLmalloc (sizeof (int) * max_num_items); + if (list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + return; + } + dims[0] = 0; + + while (SQLITE_ROW == sqlite3_step(ppStmt)) + { + int i; + dims[0]++; + dims[1] = sqlite3_data_count(ppStmt); + + for (i = 0; i < sqlite3_data_count (ppStmt); i++) + { + int value = sqlite3_column_int(ppStmt, i); + if (max_num_items == num_items) + { + int *new_list; + max_num_items += 4096; + + new_list = (int *) SLrealloc ((char *)list, sizeof (int) * max_num_items); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + + list[num_items] = value; + num_items++; + } + } + if (num_items != max_num_items) + { + int *new_list = (int *)SLrealloc ((char *)list, sizeof (int) * (num_items + 1)); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + if ((NULL == (at = SLang_create_array (SLANG_INT_TYPE, 0, (VOID_STAR) list, dims, 2))) + || (-1 == SLang_push_array (at, 1))) + SLang_push_null (); + return; + +return_error: + SLfree ((char *)list); +} + +static void sqlite_get_double_array(sqlite3_stmt *ppStmt) +{ + unsigned int num_items = 0, max_num_items = 1024; + SLindex_Type dims[2]; + double *list; + SLang_Array_Type *at; + list = (double *) SLmalloc (sizeof (double) * max_num_items); + if (list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + return; + } + + dims[0] = 0; + + while (SQLITE_ROW == sqlite3_step(ppStmt)) + { + int i; + dims[0]++; + dims[1] = sqlite3_data_count(ppStmt); + + for (i = 0; i < sqlite3_data_count (ppStmt); i++) + { + double value = sqlite3_column_double(ppStmt, i); + if (max_num_items == num_items) + { + double *new_list; + max_num_items += 4096; + + new_list = (double *) SLrealloc ((char *)list, sizeof (double) * max_num_items); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + + list[num_items] = value; + num_items++; + } + + } + + if (num_items != max_num_items) + { + double *new_list = (double *)SLrealloc ((char *)list, sizeof (double) * (num_items + 1)); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + if ((NULL == (at = SLang_create_array (SLANG_DOUBLE_TYPE, 0, (VOID_STAR) list, dims, 2))) + || (-1 == SLang_push_array (at, 1))) + SLang_push_null (); + return; + +return_error: + SLfree ((char *)list); +} + +static void sqlite_get_string_array(sqlite3_stmt *ppStmt) +{ + unsigned int num_items = 0, max_num_items = 1024; + SLindex_Type dims[2]; + char **list; + SLang_Array_Type *at; + list = (char **) SLmalloc (sizeof (char *) * max_num_items); + if (list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + return; + } + + dims[0] = 0; + + while (SQLITE_ROW == sqlite3_step(ppStmt)) + { + int i; + dims[0]++; + dims[1] = sqlite3_data_count(ppStmt); + + for (i = 0; i < sqlite3_data_count (ppStmt); i++) + { + char * strp = (char *)sqlite3_column_text(ppStmt, i); + if (max_num_items == num_items) + { + char **new_list; + max_num_items += 4096; + + new_list = (char **) SLrealloc ((char *)list, sizeof (char *) * max_num_items); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + strp = SLang_create_slstring(strp); + + list[num_items] = strp; + num_items++; + } + + } + + if (num_items != max_num_items) + { + char **new_list = (char **)SLrealloc ((char *)list, sizeof (char *) * (num_items + 1)); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + if ((NULL == (at = SLang_create_array (SLANG_STRING_TYPE, 0, (VOID_STAR) list, dims, 2))) + || (-1 == SLang_push_array (at, 1))) + SLang_push_null (); + return; + +return_error: + while (num_items > 0) + { + num_items--; + SLang_free_slstring (list[num_items]); + } + SLfree ((char *)list); +} +static void sqlite_get_bstring_array(sqlite3_stmt *ppStmt) +{ + unsigned int num_items = 0, max_num_items = 1024; + SLindex_Type dims[2]; + SLang_BString_Type **list; + SLang_Array_Type *at; + SLang_BString_Type *bstr; + + list = (SLang_BString_Type **) SLmalloc (sizeof (SLang_BString_Type *) * max_num_items); + if (list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + return; + } + + dims[0] = 0; + + while (SQLITE_ROW == sqlite3_step(ppStmt)) + { + int i; + dims[0]++; + dims[1] = sqlite3_data_count(ppStmt); + + for (i = 0; i < sqlite3_data_count (ppStmt); i++) + { + if (max_num_items == num_items) + { + SLang_BString_Type **new_list; + max_num_items += 4096; + + new_list = (SLang_BString_Type **) SLrealloc ((char *)list, sizeof (SLang_BString_Type *) * max_num_items); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + bstr = SLbstring_create((unsigned char *)sqlite3_column_blob(ppStmt, i), + sqlite3_column_bytes(ppStmt, i)); + + list[num_items] = bstr; + num_items++; + } + + } + + if (num_items != max_num_items) + { + SLang_BString_Type **new_list = (SLang_BString_Type **)SLrealloc ((char *)list, sizeof (SLang_BString_Type *) * (num_items + 1)); + if (new_list == NULL) + { + SLang_verror(SL_Malloc_Error, "Out of memory"); + goto return_error; + } + list = new_list; + } + if ((NULL == (at = SLang_create_array (SLANG_BSTRING_TYPE, 0, (VOID_STAR) list, dims, 2))) + || (-1 == SLang_push_array (at, 1))) + SLang_push_null (); + return; + +return_error: + while (num_items > 0) + { + num_items--; + SLbstring_free (list[num_items]); + } + SLfree ((char *)list); +} + +static void slsqlite_get_array(void) +{ + db_type *p; + SLang_MMT_Type *mmt; + sqlite3_stmt *ppStmt; + int nargs; + char *sql; + SLtype type; + + nargs = SLang_Num_Function_Args; + + if (nargs < 3) + { + SLang_verror(SL_Usage_Error, "usage: sqlite_get_array(Sqlite db, DataType type, String sql, ...)"); + SLdo_pop_n (SLang_Num_Function_Args); + return; + } + + SLreverse_stack(nargs); + + if (NULL == (mmt = SLang_pop_mmt (DB_Type_Id))) + { + SLang_free_mmt (mmt); + return; + } + p = SLang_object_from_mmt (mmt); + + nargs--; + + if (-1 == SLang_pop_datatype (&type)) + { + SLang_verror(SL_Application_Error, "error in sqlite_get_array"); + SLang_free_mmt (mmt); + SLdo_pop_n(nargs); + return; + } + + + switch(type) + { + case SLANG_INT_TYPE: + case SLANG_DOUBLE_TYPE: + case SLANG_STRING_TYPE: + case SLANG_BSTRING_TYPE: + break; + default: + SLang_verror(SL_Usage_Error, "only Integer, Double, String and Bstring types allowed"); + SLdo_pop_n (nargs - 1); + return; + } + + + if (-1 == SLang_pop_slstring(&sql)) + { + SLang_verror(SL_Usage_Error, "usage: sqlite_get_array(type, Sqlite db, String sql, ...)"); + SLang_free_mmt(mmt); + return; + } + + if (check_error(p->db, sqlite3_prepare(p->db, sql, strlen(sql), &ppStmt, NULL))) + { + goto free_return; + } + + if (sqlite_bind(p->db, ppStmt, nargs - 2)) + { + sqlite3_finalize(ppStmt); + goto free_return; + } + + switch(type) + { + case SLANG_INT_TYPE: + sqlite_get_integer_array(ppStmt); break; + case SLANG_DOUBLE_TYPE: + sqlite_get_double_array(ppStmt); break; + case SLANG_STRING_TYPE: + sqlite_get_string_array(ppStmt); break; + case SLANG_BSTRING_TYPE: + sqlite_get_bstring_array(ppStmt); break; + } +free_return: + check_error(p->db, sqlite3_finalize (ppStmt)); + + SLang_free_slstring(sql); + SLang_free_mmt(mmt); +} + +/*}}}*/ + +static void slsqlite_exec(void) +{ + db_type *p; + SLang_MMT_Type *mmt; + sqlite3_stmt *ppStmt; + int nargs; + char *sql; + + nargs = SLang_Num_Function_Args; + + if (nargs < 2) + { + SLang_verror(SL_Usage_Error, "usage: sqlite_exec(Sqlite db, String sql, ...)"); + return; + } + + SLreverse_stack(nargs); + if (NULL == (mmt = SLang_pop_mmt (DB_Type_Id))) + { + SLang_free_mmt (mmt); + return; + } + p = SLang_object_from_mmt (mmt); + + if (-1 == SLang_pop_slstring(&sql)) + { + SLang_verror(SL_Usage_Error, "usage: sqlite_get_row(Sqlite db, String sql, ...)"); + SLang_free_mmt(mmt); + return; + } + + if (check_error(p->db, sqlite3_prepare(p->db, sql, strlen(sql), &ppStmt, NULL))) + { + goto free_return; + } + + if (sqlite_bind(p->db, ppStmt, nargs - 2)) + { + sqlite3_finalize(ppStmt); + goto free_return; + } + + if (SQLITE_ERROR == sqlite3_step(ppStmt)) + { + check_error(p->db, sqlite3_reset(ppStmt)); + sqlite3_finalize(ppStmt); + } + else + check_error(p->db, sqlite3_finalize (ppStmt)); + +free_return: + SLang_free_slstring(sql); + SLang_free_mmt(mmt); +} + +static int slsqlite_changes() +{ + db_type *p; + SLang_MMT_Type *mmt; + int res; + if (NULL == (mmt = SLang_pop_mmt (DB_Type_Id))) + { + SLang_free_mmt (mmt); + return 0; + } + p = SLang_object_from_mmt (mmt); + res = sqlite3_changes(p->db); + SLang_free_mmt (mmt); + return res; +} + +/*}}}*/ +/*{{{ intrinsics */ + +static SLang_Intrin_Fun_Type Module_Intrinsics [] = +{ + MAKE_INTRINSIC_S("sqlite_open", slsqlite_open, SLANG_VOID_TYPE), + MAKE_INTRINSIC_S("sqlite_get_table", slsqlite_get_table, SLANG_VOID_TYPE), + MAKE_INTRINSIC_0("sqlite_get_row", slsqlite_get_row, SLANG_VOID_TYPE), + MAKE_INTRINSIC_0("sqlite_get_array", slsqlite_get_array, SLANG_VOID_TYPE), + MAKE_INTRINSIC_0("sqlite_exec", slsqlite_exec, SLANG_VOID_TYPE), + MAKE_INTRINSIC_0("sqlite_changes", slsqlite_changes, SLANG_INT_TYPE), + SLANG_END_INTRIN_FUN_TABLE +}; + +static SLang_Intrin_Var_Type Module_Variables [] = +{ + MAKE_VARIABLE("_sqlite_module_version_string", &Module_Version_String, SLANG_STRING_TYPE, 1), + SLANG_END_INTRIN_VAR_TABLE +}; + +static SLang_IConstant_Type Module_Constants [] = +{ + MAKE_ICONSTANT("_sqlite_module_version", MODULE_VERSION_NUMBER), + SLANG_END_ICONST_TABLE +}; + +/*}}}*/ +/*{{{ foreach */ + +struct _pSLang_Foreach_Context_Type +{ + SLang_MMT_Type *mmt; + db_type *p; + sqlite3_stmt *ppStmt; +}; + + +static SLang_Foreach_Context_Type *cl_foreach_open (SLtype type, unsigned int num) +{ + SLang_Foreach_Context_Type *c = NULL; + SLang_MMT_Type *mmt = NULL; + char *s; + + (void) type; + + if (NULL == (mmt = SLang_pop_mmt (DB_Type_Id))) + return NULL; + + if (!num) + { + SLang_verror (SL_Usage_Error, "Sqlite_Type requires an sql statement"); + SLang_free_mmt (mmt); + return NULL; + } + + SLreverse_stack(num); + if (-1 == SLang_pop_slstring (&s)) + { + SLang_verror (SL_Usage_Error, "Sqlite_Type requires an sql statement"); + SLang_free_mmt (mmt); + return NULL; + } + + if (NULL == (c = (SLang_Foreach_Context_Type *) SLmalloc (sizeof (SLang_Foreach_Context_Type)))) + goto free_return; + + memset ((char *) c, 0, sizeof (SLang_Foreach_Context_Type)); + + c->mmt = mmt; + c->p = (db_type *) SLang_object_from_mmt (mmt); + if (check_error(c->p->db, sqlite3_prepare(c->p->db, s, strlen(s), &c->ppStmt, NULL))) + goto free_return; + + if (sqlite_bind(c->p->db, c->ppStmt, num - 1)) + { + sqlite3_finalize(c->ppStmt); + goto free_return; + } + + return c; + +free_return: + SLang_free_slstring (s); + SLang_free_mmt(mmt); + return NULL; +} + +static void cl_foreach_close (SLtype type, SLang_Foreach_Context_Type *c) +{ + (void) type; + if (c == NULL) return; + if (SQLITE_OK != sqlite3_finalize (c->ppStmt)) + SLang_verror (Sqlite_Error, "foreach_close failed"); + SLang_free_mmt (c->mmt); + SLfree ((char *) c); +} + +static int cl_foreach (SLtype type, SLang_Foreach_Context_Type *c) +{ + (void) type; + + if (c == NULL) + return -1; + return sqlite_step(c->p->db, c->ppStmt); +} + +/*}}}*/ +/*{{{ register class */ + +static void patchup_intrinsic_table (SLang_Intrin_Fun_Type *table, + unsigned char dummy, unsigned char type) +{ + while (table->name != NULL) + { + unsigned int i, nargs; + SLtype *args; + + nargs = table->num_args; + args = table->arg_types; + for (i = 0; i < nargs; i++) + { + if (args[i] == dummy) + args[i] = type; + } + + /* For completeness */ + if (table->return_type == dummy) + table->return_type = type; + + table++; + } +} + +static int register_sqlite_type (void) +{ + SLang_Class_Type *cl; + + if (DB_Type_Id != 0) + return 0; + + if (NULL == (cl = SLclass_allocate_class ("Sqlite_Type"))) + return -1; + + if (-1 == SLclass_set_destroy_function (cl, destroy_sqlite)) + return -1; + + if (-1 == SLclass_set_foreach_functions(cl, cl_foreach_open, cl_foreach, cl_foreach_close)) + return -1; + + /* By registering as SLANG_VOID_TYPE, slang will dynamically allocate a + * type. + */ + if (-1 == SLclass_register_class (cl, SLANG_VOID_TYPE, sizeof (db_type), SLANG_CLASS_TYPE_MMT)) + return -1; + + DB_Type_Id = SLclass_get_class_id (cl); + + patchup_intrinsic_table (Module_Intrinsics, DUMMY_SQLITE_TYPE, DB_Type_Id); + + return 0; +} + +/*}}}*/ +/*{{{ init */ + +int init_sqlite_module_ns (char *ns_name) +{ + SLang_NameSpace_Type *ns = SLns_create_namespace (ns_name); + if (ns == NULL) + return -1; + if (-1 == register_sqlite_type ()) + return -1; + + if (Sqlite_Error == 0) + { + const Sqlite_Exception_Table_Type *b; + b = Sqlite_Exception_Table; + + if (-1 == (Sqlite_Error = SLerr_new_exception (SL_RunTime_Error, "SqliteError", "Sqlite error"))) + return -1; + b++; + while (b->errcode_ptr != NULL) + { + *b->errcode_ptr = SLerr_new_exception (Sqlite_Error, b->name, b->description); + if (*b->errcode_ptr == -1) + return -1; + b++; + } + } + + if ((-1 == SLns_add_intrin_fun_table (ns, Module_Intrinsics, NULL)) + || (-1 == SLns_add_intrin_var_table (ns, Module_Variables, NULL)) + || (-1 == SLns_add_iconstant_table (ns, Module_Constants, NULL))) + return -1; + + return 0; +} + +/*}}}*/ diff --git a/sqlite.hlp b/sqlite.hlp new file mode 100644 index 0000000..090a542 --- /dev/null +++ b/sqlite.hlp @@ -0,0 +1,136 @@ +sqlite_open + + SYNOPSIS + Open a SQLite database + + USAGE + Sqlite_Type sqlite_open(String_Type filename) + + DESCRIPTION + Open the sqlite database file `filename'. If the database file does + not exist, then a new database will be created as needed. On failure a + `SqliteError' exception is thrown. + + SEE ALSO + sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_exec, sqlite_changes + +-------------------------------------------------------------- + +sqlite_get_table + + SYNOPSIS + Get a table of results from a SQLite query + + USAGE + String_Type[] sqlite_get_table(Sqlite_Type db, String_Type query) + + DESCRIPTION + This executes a query and returns the result as a 2d array of strings. + The first row of the array contains the column headers. This function does + not support placeholders. + + NOTES + You should only use this function if you need the column headers. + Otherwise, use `sqlite_get_table' + + SEE ALSO + sqlite_open, sqlite_get_row, sqlite_exec, sqlite_changes + +-------------------------------------------------------------- + +sqlite_get_row + + SYNOPSIS + Get a row of results from a SQLite query + + USAGE + sqlite_get_row(Sqlite_Type db, String_Type query, ...) + + DESCRIPTION + This executes a query and pushes the elements of the first row of the + result on the stack. This supports string, integer, float and blob + datatatypes. Blobs are returned as bstrings. If there are no rows, a + `SqliteError' exception is thrown even if the query executed flawlessly. + Question marks in the query are placeholders. Extra arguments to the + function are bound to these placeholders from left to right. + + EXAMPLE + + (foo, bar) = sqlite_get_row("SELECT foo, bar FROM table WHERE baz = ?", "quux"); + + + NOTES + To get the result of a query that returns multiple rows, use + `sqlite_get_array' or use + + foreach foo, bar (db) using ("SELECT foo, bar FROM table WHERE baz = ?", "quux") + { + .... + } + + + SEE ALSO + sqlite_open, sqlite_get_table, sqlite_exec, sqlite_changes + +-------------------------------------------------------------- + +sqlite_get_array + + SYNOPSIS + Get a 2-D array from a SQLite query + + USAGE + Array_Type sqlite_get_array(Sqlite_Type db, DataType_type type, String_Type query, ...) + + DESCRIPTION + Executes a query and returns the result as a 2d array of type `type'. + This supports string, integer, float and blob datatatypes. Question marks + in the query are placeholders. Extra arguments to the function are bound + to these placeholders from left to right. + + SEE ALSO + sqlite_open, sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_exec, sqlite_changes + +-------------------------------------------------------------- + +sqlite_exec + + SYNOPSIS + Execute a SQLite query + + USAGE + sqlite_exec(Sqlite_Type db, String_Type query, ...) + + DESCRIPTION + Execute a SQL query on a sqlite database, without returning a result. + Question marks in the query are placeholders. Extra arguments to the + function are bound to these placeholders from left to right. + + EXAMPLE + + sqlite_exec("INSERT INTO table(foo,bar,baz) VALUES (?,?,?)", 1, 2, 3); + + + SEE ALSO + sqlite_open, sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_changes + +-------------------------------------------------------------- + +sqlite_changes + + SYNOPSIS + Get the number of rows affected by a SQLite query + + USAGE + Int_Type sqlite_changes(Sqlite_Type db) + + DESCRIPTION + This function returns the number of database rows that were changed (or + inserted or deleted) by the most recently completed INSERT, UPDATE, or + DELETE statement. The change count for "DELETE FROM table" will be zero + regardless of the number of elements that were originally in the table. + + SEE ALSO + sqlite_open, sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_exec + +-------------------------------------------------------------- diff --git a/sqlite.sl b/sqlite.sl new file mode 100644 index 0000000..926adaa --- /dev/null +++ b/sqlite.sl @@ -0,0 +1,7 @@ +import ("sqlite"); + +$1 = path_concat (path_concat (path_dirname (__FILE__), "help"), "sqlite.hlp"); +if (NULL != stat_file ($1)) + add_doc_file ($1); + +provide ("sqlite"); diff --git a/sqlitefuns.tm b/sqlitefuns.tm new file mode 100644 index 0000000..670aaf7 --- /dev/null +++ b/sqlitefuns.tm @@ -0,0 +1,101 @@ +#s+ +custom_variable("tm_format", "slhlp"); +if (tm_format == "html") +{ + tm_add_macro("vdt", "\\dtdd{\\code{$1}}{$2}", 2, 2); + tm_add_macro("n", "\\newline", 0, 0); + tm_add_macro("link", "\\href{#$1}{$1}", 1, 1); +} +else +{ + tm_add_macro("dl", "$1", 1, 1); + tm_add_macro("vdt", "\\var{$1}: $2\\__newline__", 2, 2); + tm_add_macro("n", "", 0, 0); + tm_add_macro("link", "$1", 1, 1); +} +#s- + +\function{sqlite_open} +\synopsis{Open a SQLite database} +\usage{Sqlite_Type sqlite_open(String_Type filename)} +\description + Open the sqlite database file \var{filename}. If the database file does + not exist, then a new database will be created as needed. On failure a + \var{SqliteError} exception is thrown. +\seealso{sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_exec, sqlite_changes} +\done + +\function{sqlite_get_table} +\synopsis{Get a table of results from a SQLite query} +\usage{String_Type[] sqlite_get_table(Sqlite_Type db, String_Type query)} +\description + This executes a query and returns the result as a 2d array of strings. + The first row of the array contains the column headers. This function does + not support placeholders. +\notes + You should only use this function if you need the column headers. + Otherwise, use \ifun{sqlite_get_table} +\seealso{sqlite_open, sqlite_get_row, sqlite_exec, sqlite_changes} +\done + +\function{sqlite_get_row} +\synopsis{Get a row of results from a SQLite query} +\usage{sqlite_get_row(Sqlite_Type db, String_Type query, ...)} +\description + This executes a query and pushes the elements of the first row of the + result on the stack. This supports string, integer, float and blob + datatatypes. Blobs are returned as bstrings. If there are no rows, a + \var{SqliteError} exception is thrown even if the query executed flawlessly. + Question marks in the query are placeholders. Extra arguments to the + function are bound to these placeholders from left to right. +\example +#v+ + (foo, bar) = sqlite_get_row("SELECT foo, bar FROM table WHERE baz = ?", "quux"); +#v- +\notes + To get the result of a query that returns multiple rows, use + \ifun{sqlite_get_array} or use +#v+ + foreach foo, bar (db) using ("SELECT foo, bar FROM table WHERE baz = ?", "quux") + { + .... + } +#v- +\seealso{sqlite_open, sqlite_get_table, sqlite_exec, sqlite_changes} +\done + +\function{sqlite_get_array} +\synopsis{Get a 2-D array from a SQLite query} +\usage{Array_Type sqlite_get_array(Sqlite_Type db, DataType_type type, String_Type query, ...)} +\description + Executes a query and returns the result as a 2d array of type \var{type}. + This supports string, integer, float and blob datatatypes. Question marks + in the query are placeholders. Extra arguments to the function are bound + to these placeholders from left to right. +\seealso{sqlite_open, sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_exec, sqlite_changes} +\done + +\function{sqlite_exec} +\synopsis{Execute a SQLite query} +\usage{sqlite_exec(Sqlite_Type db, String_Type query, ...)} +\description + Execute a SQL query on a sqlite database, without returning a result. + Question marks in the query are placeholders. Extra arguments to the + function are bound to these placeholders from left to right. +\example +#v+ + sqlite_exec("INSERT INTO table(foo,bar,baz) VALUES (?,?,?)", 1, 2, 3); +#v- +\seealso{sqlite_open, sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_changes} +\done + +\function{sqlite_changes} +\synopsis{Get the number of rows affected by a SQLite query} +\usage{Int_Type sqlite_changes(Sqlite_Type db)} +\description + This function returns the number of database rows that were changed (or + inserted or deleted) by the most recently completed INSERT, UPDATE, or + DELETE statement. The change count for "DELETE FROM table" will be zero + regardless of the number of elements that were originally in the table. +\seealso{sqlite_open, sqlite_get_table, sqlite_get_array, sqlite_get_row, sqlite_exec} +\done -- cgit v1.2.3 From da994c6578f233070c3454d98ad31ccf1809a47e Mon Sep 17 00:00:00 2001 From: Rafael Laboissiere Date: Mon, 1 Aug 2016 17:07:41 -0300 Subject: slsqlite (0.4.0-4) unstable; urgency=medium * QA (group) upload * d/control: + Remove myself from the Uploaders list (closes: #571883) + Set Maintainer to Debian QA Group (orhpaned package) [dgit import package slsqlite 0.4.0-4] --- debian/changelog | 68 +++++++++++++++++++++++++++++ debian/compat | 1 + debian/control | 20 +++++++++ debian/copyright | 17 ++++++++ debian/patches/01-add-format-argument.patch | 11 +++++ debian/patches/series | 1 + debian/rules | 7 +++ debian/watch | 2 + 8 files changed, 127 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/patches/01-add-format-argument.patch create mode 100644 debian/patches/series create mode 100755 debian/rules create mode 100644 debian/watch diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..7927ab7 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,68 @@ +slsqlite (0.4.0-4) unstable; urgency=medium + + * QA (group) upload + * d/control: + + Remove myself from the Uploaders list (closes: #571883) + + Set Maintainer to Debian QA Group (orhpaned package) + + -- Rafael Laboissiere Mon, 01 Aug 2016 17:07:41 -0300 + +slsqlite (0.4.0-3.1) unstable; urgency=low + + * Non-maintainer upload. + * 01-add-format-argument.patch: add format argument to avoid format-security + error while building. (Closes: #646487) + * debian/control, debian/rules: Add quilt system to apply patches. + + -- Mònica Ramírez Arceda Sun, 04 Dec 2011 13:24:33 +0100 + +slsqlite (0.4.0-3) unstable; urgency=low + + * debian/control: + + Bump Standards-Version to 3.8.1 (no changes needed) + + The package is now maintained with Git at alioth.debian.org. Add + Vcs-Git field and change Vcs-Browser accordingly. + + Fix Lintian warning debhelper-but-no-misc-depends + + Bump build dependency on debhelper to >= 7 + * debian/compat: Set compatibility level of debhelper to 7 + + -- Rafael Laboissiere Sun, 26 Apr 2009 12:11:34 +0200 + +slsqlite (0.4.0-2) unstable; urgency=low + + * debian/control: + + Use the now official Vcs-* fields instead of the obsolete XS-Vcs-* + + Dropped the Homepage pseudo-header from the extended description + + Bumped Standards-Version to 3.7.3 + + -- Rafael Laboissiere Sun, 16 Dec 2007 00:27:05 +0100 + +slsqlite (0.4.0-1) unstable; urgency=low + + * New upstream release + * debian/control: Added Homepage field + + -- Rafael Laboissiere Mon, 15 Oct 2007 22:46:05 +0200 + +slsqlite (0.3.0-1) unstable; urgency=low + + * First official release to unstable (closes: #440262, #440399) + + -- Rafael Laboissiere Sat, 01 Sep 2007 09:57:35 +0200 + +slsqlite (0.3.0-1~pre1) unstable; urgency=low + + * Initial pre-release + + -- Rafael Laboissiere Fri, 31 Aug 2007 13:51:23 +0200 + +Local Variables: +eval: (add-local-hook + 'debian-changelog-add-version-hook + (lambda () + (save-excursion + (forward-line -1) + (beginning-of-line) + (insert "\n [ " + (or (getenv "DEBFULLNAME") (user-full-name)) "]")))) +End: diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..be2b82b --- /dev/null +++ b/debian/control @@ -0,0 +1,20 @@ +Source: slsqlite +Section: interpreters +Priority: optional +Maintainer: Debian QA Group +Build-Depends: debhelper (>= 7), libslang2-dev (>= 2.0.4-6), + libsqlite3-dev, cdbs, quilt +Standards-Version: 3.8.1 +Homepage: http://www.cheesit.com/downloads/slang/slsqlite.html +Vcs-Git: git://git.debian.org/git/pkg-jed/slsqlite.git +Vcs-Browser: http://git.debian.org/?p=pkg-jed/slsqlite.git + +Package: slang-sqlite +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends} +Suggests: slsh (>= 2.0) | jed (>= 0.99.17) | slrn (>= 0.9.8.1pl1-4) +Description: S-Lang bindings to the sqlite3 database library + The S-Lang module contained in this package provides bindings to the + SQLite3 database engine. This module can be used in slsh (the S-Lang + shell), in the JED editor, and in the news reader slrn. + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8979ed6 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,17 @@ +This package was debianized by Rafael Laboissiere on +Fri, 31 Aug 2007 13:41:44 +0200 + +It was downloaded from + + http://www.cheesit.com/downloads/slang/slsqlite.html + +Copyright Holder: Paul Boekholt + +License: + +According to slsqlite.html: + slsqlite is Copyright (c) 2006, 2007 Paul Boekholt. Released under the + terms of the GNU GPL (version 2 or later). + +In Debian systems, the complete text of the Gnu GPL can be found in +`/usr/share/common-licenses/GPL-2'. diff --git a/debian/patches/01-add-format-argument.patch b/debian/patches/01-add-format-argument.patch new file mode 100644 index 0000000..0628b30 --- /dev/null +++ b/debian/patches/01-add-format-argument.patch @@ -0,0 +1,11 @@ +--- a/sqlite-module.c ++++ b/sqlite-module.c +@@ -114,7 +114,7 @@ + } + if (b->errcode_ptr == NULL) error = Sqlite_Error; + else error = *(b->errcode_ptr); +- SLang_verror (error, (char *) sqlite3_errmsg(db)); ++ SLang_verror (error, "%s", (char *) sqlite3_errmsg(db)); + return 1; + } + diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..de7fbb9 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +01-add-format-argument.patch diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..567274a --- /dev/null +++ b/debian/rules @@ -0,0 +1,7 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/class/makefile.mk +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/patchsys-quilt.mk + +DEB_MAKE_INSTALL_TARGET := install prefix=/usr DESTDIR=$(DEB_DESTDIR) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..2f61368 --- /dev/null +++ b/debian/watch @@ -0,0 +1,2 @@ +version=3 +http://www.cheesit.com/downloads/slang/slsqlite.html .*/slsqlite-([\d.]+).tgz -- cgit v1.2.3 From f3d93fb2c175a94cd6edfae2092babff63f74f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Laboissi=C3=A8re?= Date: Sun, 21 Nov 2021 04:21:06 -0300 Subject: Honor the environment variables CPPFLAGS and LDFLAGS Forwarded: https://lists.jedsoft.org/lists/slang-devel/2021/0000014.html Last-Update: 2021-11-21 This is required in Debian, such that hardening flags like -D_FORTIFY_SOURCE=2 and -Wl,-z,relro are used in the compilation and linking of C files. Gbp-Pq: Name honor-cppflags-ldflags.patch --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 619e75a..94d8dcc 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ INCS = $(SLANG_INC) all: sqlite-module.so sqlite-module.so: sqlite-module.c - $(CC_SHARED) $(INCS) -g sqlite-module.c -o sqlite-module.so $(LIBS) + $(CC_SHARED) $(CPPFLAGS) $(INCS) $(LDFLAGS) -g sqlite-module.c -o sqlite-module.so $(LIBS) sqlite.o: sqlite-module.c gcc $(CFLAGS) $(INCS) -O2 -c -g sqlite-module.c -o sqlite.o -- cgit v1.2.3 From 01df3ea2272d27ddbd5682fa69dc1671dc5f25c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Laboissi=C3=A8re?= Date: Thu, 2 Dec 2021 12:29:58 -0300 Subject: Update configuration files to Autoconf 2.71 Forwarded: not-needed Last-Update: 2021-11-24 This is a Debian-specific change. Gbp-Pq: Name update-autoconf-2.71.patch --- autoconf/aclocal.m4 | 6 +++--- autoconf/configure.ac | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/autoconf/aclocal.m4 b/autoconf/aclocal.m4 index ed41f0a..067ac16 100644 --- a/autoconf/aclocal.m4 +++ b/autoconf/aclocal.m4 @@ -353,7 +353,7 @@ dnl#}}} AC_DEFUN([JD_GCC_WARNINGS], dnl#{{{ [ AC_ARG_ENABLE(warnings, - AC_HELP_STRING([--enable-warnings],[turn on GCC compiler warnings]), + AS_HELP_STRING([--enable-warnings],[turn on GCC compiler warnings]), [gcc_warnings=$enableval]) if test -n "$GCC" then @@ -536,11 +536,11 @@ dnl#}}} AC_DEFUN([JD_ANSI_CC], dnl#{{{ [ -AC_AIX +AC_USE_SYSTEM_EXTENSIONS AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_CPP]) AC_REQUIRE([AC_PROG_GCC_TRADITIONAL]) -AC_ISC_POSIX +AC_SEARCH_LIBS([strerror],[cposix]) dnl #This stuff came from Yorick config script dnl diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 44361b3..6fe20ec 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -1,5 +1,6 @@ dnl -*- sh -*- -AC_INIT(src/sqlite-module.c) +AC_INIT +AC_CONFIG_SRCDIR([src/sqlite-module.c]) AC_PREFIX_DEFAULT(/usr/local) AC_CONFIG_AUX_DIR(autoconf) @@ -40,8 +41,9 @@ JD_CHECK_LONG_LONG ELF_CFLAGS="$ELF_CFLAGS $IEEE_CFLAGS" CFLAGS="$CFLAGS $IEEE_CFLAGS" -AC_CONFIG_HEADER(src/config.h:src/config.hin) -AC_OUTPUT(Makefile:autoconf/Makefile.in src/Makefile) +AC_CONFIG_HEADERS([src/config.h:src/config.hin]) +AC_CONFIG_FILES([Makefile:autoconf/Makefile.in src/Makefile]) +AC_OUTPUT echo "" echo "You are compiling with the following compiler configuration:" -- cgit v1.2.3 From 87606523c959e7a2ffa9339858959640617078c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Laboissi=C3=A8re?= Date: Sat, 4 Dec 2021 04:06:22 -0300 Subject: Update configuration files to Autoconf 2.71 Forwarded: not-needed Last-Update: 2021-11-24 This is a Debian-specific change. Gbp-Pq: Name update-autoconf-2.71.patch --- autoconf/aclocal.m4 | 6 +++--- autoconf/configure.ac | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/autoconf/aclocal.m4 b/autoconf/aclocal.m4 index ed41f0a..067ac16 100644 --- a/autoconf/aclocal.m4 +++ b/autoconf/aclocal.m4 @@ -353,7 +353,7 @@ dnl#}}} AC_DEFUN([JD_GCC_WARNINGS], dnl#{{{ [ AC_ARG_ENABLE(warnings, - AC_HELP_STRING([--enable-warnings],[turn on GCC compiler warnings]), + AS_HELP_STRING([--enable-warnings],[turn on GCC compiler warnings]), [gcc_warnings=$enableval]) if test -n "$GCC" then @@ -536,11 +536,11 @@ dnl#}}} AC_DEFUN([JD_ANSI_CC], dnl#{{{ [ -AC_AIX +AC_USE_SYSTEM_EXTENSIONS AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_CPP]) AC_REQUIRE([AC_PROG_GCC_TRADITIONAL]) -AC_ISC_POSIX +AC_SEARCH_LIBS([strerror],[cposix]) dnl #This stuff came from Yorick config script dnl diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 44361b3..6fe20ec 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -1,5 +1,6 @@ dnl -*- sh -*- -AC_INIT(src/sqlite-module.c) +AC_INIT +AC_CONFIG_SRCDIR([src/sqlite-module.c]) AC_PREFIX_DEFAULT(/usr/local) AC_CONFIG_AUX_DIR(autoconf) @@ -40,8 +41,9 @@ JD_CHECK_LONG_LONG ELF_CFLAGS="$ELF_CFLAGS $IEEE_CFLAGS" CFLAGS="$CFLAGS $IEEE_CFLAGS" -AC_CONFIG_HEADER(src/config.h:src/config.hin) -AC_OUTPUT(Makefile:autoconf/Makefile.in src/Makefile) +AC_CONFIG_HEADERS([src/config.h:src/config.hin]) +AC_CONFIG_FILES([Makefile:autoconf/Makefile.in src/Makefile]) +AC_OUTPUT echo "" echo "You are compiling with the following compiler configuration:" -- cgit v1.2.3 From 6f7f5eada077425dfe3609a4e72d3d5a997fe6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Laboissi=C3=A8re?= Date: Wed, 8 Dec 2021 09:57:04 -0300 Subject: Update configuration files to Autoconf 2.71 Forwarded: not-needed Last-Update: 2021-11-24 This is a Debian-specific change. Gbp-Pq: Name update-autoconf-2.71.patch --- autoconf/aclocal.m4 | 6 +++--- autoconf/configure.ac | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/autoconf/aclocal.m4 b/autoconf/aclocal.m4 index ed41f0a..067ac16 100644 --- a/autoconf/aclocal.m4 +++ b/autoconf/aclocal.m4 @@ -353,7 +353,7 @@ dnl#}}} AC_DEFUN([JD_GCC_WARNINGS], dnl#{{{ [ AC_ARG_ENABLE(warnings, - AC_HELP_STRING([--enable-warnings],[turn on GCC compiler warnings]), + AS_HELP_STRING([--enable-warnings],[turn on GCC compiler warnings]), [gcc_warnings=$enableval]) if test -n "$GCC" then @@ -536,11 +536,11 @@ dnl#}}} AC_DEFUN([JD_ANSI_CC], dnl#{{{ [ -AC_AIX +AC_USE_SYSTEM_EXTENSIONS AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_CPP]) AC_REQUIRE([AC_PROG_GCC_TRADITIONAL]) -AC_ISC_POSIX +AC_SEARCH_LIBS([strerror],[cposix]) dnl #This stuff came from Yorick config script dnl diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 44361b3..6fe20ec 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -1,5 +1,6 @@ dnl -*- sh -*- -AC_INIT(src/sqlite-module.c) +AC_INIT +AC_CONFIG_SRCDIR([src/sqlite-module.c]) AC_PREFIX_DEFAULT(/usr/local) AC_CONFIG_AUX_DIR(autoconf) @@ -40,8 +41,9 @@ JD_CHECK_LONG_LONG ELF_CFLAGS="$ELF_CFLAGS $IEEE_CFLAGS" CFLAGS="$CFLAGS $IEEE_CFLAGS" -AC_CONFIG_HEADER(src/config.h:src/config.hin) -AC_OUTPUT(Makefile:autoconf/Makefile.in src/Makefile) +AC_CONFIG_HEADERS([src/config.h:src/config.hin]) +AC_CONFIG_FILES([Makefile:autoconf/Makefile.in src/Makefile]) +AC_OUTPUT echo "" echo "You are compiling with the following compiler configuration:" -- cgit v1.2.3