From ea73010a049b0686fda9285675bfa3e0615f69ba Mon Sep 17 00:00:00 2001 From: erg Date: Mon, 9 Oct 2006 03:33:38 +0000 Subject: [PATCH] sqlite updates -- throw error name, modernize to FUNCTION: and put ffi in libsqlite.factor, remove indirect structs --- contrib/sqlite/libsqlite.factor | 111 +++++++++++++++++++++++++ contrib/sqlite/load.factor | 1 + contrib/sqlite/sqlite.factor | 139 ++------------------------------ contrib/sqlite/tuple-db.factor | 21 ----- 4 files changed, 120 insertions(+), 152 deletions(-) create mode 100644 contrib/sqlite/libsqlite.factor diff --git a/contrib/sqlite/libsqlite.factor b/contrib/sqlite/libsqlite.factor new file mode 100644 index 0000000000..c5dadde590 --- /dev/null +++ b/contrib/sqlite/libsqlite.factor @@ -0,0 +1,111 @@ +! Copyright (C) 2005 Chris Double, Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +! +! An interface to the sqlite database. Tested against sqlite v3.0.8. +! Remeber to pass the following to factor: +! -libraries:sqlite=libsqlite3.so +! +! Not all functions have been wrapped yet. Only those directly involving +! executing SQL calls and obtaining results. +! +IN: libsqlite +USING: alien compiler errors kernel math namespaces sequences strings ; + +! Return values from sqlite functions +: SQLITE_OK 0 ; ! Successful result +: SQLITE_ERROR 1 ; ! SQL error or missing database +: SQLITE_INTERNAL 2 ; ! An internal logic error in SQLite +: SQLITE_PERM 3 ; ! Access permission denied +: SQLITE_ABORT 4 ; ! Callback routine requested an abort +: SQLITE_BUSY 5 ; ! The database file is locked +: SQLITE_LOCKED 6 ; ! A table in the database is locked +: SQLITE_NOMEM 7 ; ! A malloc() failed +: SQLITE_READONLY 8 ; ! Attempt to write a readonly database +: SQLITE_INTERRUPT 9 ; ! Operation terminated by sqlite_interrupt() +: SQLITE_IOERR 10 ; ! Some kind of disk I/O error occurred +: SQLITE_CORRUPT 11 ; ! The database disk image is malformed +: SQLITE_NOTFOUND 12 ; ! (Internal Only) Table or record not found +: SQLITE_FULL 13 ; ! Insertion failed because database is full +: SQLITE_CANTOPEN 14 ; ! Unable to open the database file +: SQLITE_PROTOCOL 15 ; ! Database lock protocol error +: SQLITE_EMPTY 16 ; ! (Internal Only) Database table is empty +: SQLITE_SCHEMA 17 ; ! The database schema changed +: SQLITE_TOOBIG 18 ; ! Too much data for one row of a table +: SQLITE_CONSTRAINT 19 ; ! Abort due to contraint violation +: SQLITE_MISMATCH 20 ; ! Data type mismatch +: SQLITE_MISUSE 21 ; ! Library used incorrectly +: SQLITE_NOLFS 22 ; ! Uses OS features not supported on host +: SQLITE_AUTH 23 ; ! Authorization denied +: SQLITE_FORMAT 24 ; ! Auxiliary database format error +: SQLITE_RANGE 25 ; ! 2nd parameter to sqlite3_bind out of range +: SQLITE_NOTADB 26 ; ! File opened that is not a database file + +: sqlite-error-messages ( -- seq ) { + "Successful result" + "SQL error or missing database" + "An internal logic error in SQLite" + "Access permission denied" + "Callback routine requested an abort" + "The database file is locked" + "A table in the database is locked" + "A malloc() failed" + "Attempt to write a readonly database" + "Operation terminated by sqlite_interrupt()" + "Some kind of disk I/O error occurred" + "The database disk image is malformed" + "(Internal Only) Table or record not found" + "Insertion failed because database is full" + "Unable to open the database file" + "Database lock protocol error" + "(Internal Only) Database table is empty" + "The database schema changed" + "Too much data for one row of a table" + "Abort due to contraint violation" + "Data type mismatch" + "Library used incorrectly" + "Uses OS features not supported on host" + "Authorization denied" + "Auxiliary database format error" + "2nd parameter to sqlite3_bind out of range" + "File opened that is not a database file" +} ; + +: SQLITE_ROW 100 ; ! sqlite_step() has another row ready +: SQLITE_DONE 101 ; ! sqlite_step() has finished executing + +! Return values from the sqlite3_column_type function +: SQLITE_INTEGER 1 ; +: SQLITE_FLOAT 2 ; +: SQLITE_TEXT 3 ; +: SQLITE_BLOB 4 ; +: SQLITE_NULL 5 ; + +! Values for the 'destructor' parameter of the 'bind' routines. +: SQLITE_STATIC 0 ; +: SQLITE_TRANSIENT -1 ; + +TYPEDEF: void sqlite3 +TYPEDEF: void sqlite3_stmt + +LIBRARY: sqlite +FUNCTION: int sqlite3_open ( char* filename, void* ppDb ) ; +FUNCTION: int sqlite3_close ( sqlite3* pDb ) ; +FUNCTION: int sqlite3_prepare ( sqlite3* pDb, char* zSql, int nBytes, void* ppStmt, void* pzTail ) ; +FUNCTION: int sqlite3_finalize ( sqlite3_stmt* pStmt ) ; +FUNCTION: int sqlite3_reset ( sqlite3_stmt* pStmt ) ; +FUNCTION: int sqlite3_step ( sqlite3_stmt* pStmt ) ; +FUNCTION: int sqlite3_last_insert_rowid ( sqlite3* pStmt ) ; +FUNCTION: int sqlite3_bind_blob ( sqlite3_stmt* pStmt, int index, void* ptr, int len, int destructor ) ; +FUNCTION: int sqlite3_bind_int ( sqlite3_stmt* pStmt, int index, int n ) ; +FUNCTION: int sqlite3_bind_null ( sqlite3_stmt* pStmt, int n ) ; +FUNCTION: int sqlite3_bind_text ( sqlite3_stmt* pStmt, int index, char* text, int len, int destructor ) ; +FUNCTION: int sqlite3_bind_parameter_index ( sqlite3_stmt* pStmt, char* name ) ; +FUNCTION: int sqlite3_column_count ( sqlite3_stmt* pStmt ) ; +FUNCTION: void* sqlite3_column_blob ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: int sqlite3_column_bytes ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: char* sqlite3_column_decltype ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: int sqlite3_column_int ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: int sqlite3_column_name ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: char* sqlite3_column_text ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: int sqlite3_column_type ( sqlite3_stmt* pStmt, int col ) ; + diff --git a/contrib/sqlite/load.factor b/contrib/sqlite/load.factor index 28cf012015..16c8efa945 100644 --- a/contrib/sqlite/load.factor +++ b/contrib/sqlite/load.factor @@ -1,4 +1,5 @@ PROVIDE: contrib/sqlite { + "libsqlite.factor" "sqlite.factor" "sqlite.facts" "tuple-db.factor" diff --git a/contrib/sqlite/sqlite.factor b/contrib/sqlite/sqlite.factor index be56d806e3..046b52637a 100644 --- a/contrib/sqlite/sqlite.factor +++ b/contrib/sqlite/sqlite.factor @@ -9,148 +9,25 @@ ! executing SQL calls and obtaining results. ! IN: sqlite -USE: kernel -USE: alien -USE: errors -USE: strings -USE: namespaces -USE: sequences -USE: compiler +USING: alien compiler errors libsqlite kernel namespaces sequences strings ; -"sqlite" windows? [ "sqlite3.dll" ] [ "libsqlite3.so" ] if "cdecl" add-library -BEGIN-STRUCT: sqlite3 -END-STRUCT - -BEGIN-STRUCT: sqlite3-indirect - FIELD: sqlite3* pointer -END-STRUCT - -BEGIN-STRUCT: sqlite3-stmt -END-STRUCT - -BEGIN-STRUCT: sqlite3-stmt-indirect - FIELD: sqlite3-stmt* pointer -END-STRUCT - -BEGIN-STRUCT: char*-indirect - FIELD: char* pointer -END-STRUCT - -! Return values from sqlite functions -: SQLITE_OK 0 ; ! Successful result -: SQLITE_ERROR 1 ; ! SQL error or missing database -: SQLITE_INTERNAL 2 ; ! An internal logic error in SQLite -: SQLITE_PERM 3 ; ! Access permission denied -: SQLITE_ABORT 4 ; ! Callback routine requested an abort -: SQLITE_BUSY 5 ; ! The database file is locked -: SQLITE_LOCKED 6 ; ! A table in the database is locked -: SQLITE_NOMEM 7 ; ! A malloc() failed -: SQLITE_READONLY 8 ; ! Attempt to write a readonly database -: SQLITE_INTERRUPT 9 ; ! Operation terminated by sqlite_interrupt() -: SQLITE_IOERR 10 ; ! Some kind of disk I/O error occurred -: SQLITE_CORRUPT 11 ; ! The database disk image is malformed -: SQLITE_NOTFOUND 12 ; ! (Internal Only) Table or record not found -: SQLITE_FULL 13 ; ! Insertion failed because database is full -: SQLITE_CANTOPEN 14 ; ! Unable to open the database file -: SQLITE_PROTOCOL 15 ; ! Database lock protocol error -: SQLITE_EMPTY 16 ; ! (Internal Only) Database table is empty -: SQLITE_SCHEMA 17 ; ! The database schema changed -: SQLITE_TOOBIG 18 ; ! Too much data for one row of a table -: SQLITE_CONSTRAINT 19 ; ! Abort due to contraint violation -: SQLITE_MISMATCH 20 ; ! Data type mismatch -: SQLITE_MISUSE 21 ; ! Library used incorrectly -: SQLITE_NOLFS 22 ; ! Uses OS features not supported on host -: SQLITE_AUTH 23 ; ! Authorization denied -: SQLITE_ROW 100 ; ! sqlite_step() has another row ready -: SQLITE_DONE 101 ; ! sqlite_step() has finished executing - -! Return values from the sqlite3_column_type function -: SQLITE_INTEGER 1 ; -: SQLITE_FLOAT 2 ; -: SQLITE_TEXT 3 ; -: SQLITE_BLOB 4 ; -: SQLITE_NULL 5 ; - -! Values for the 'destructor' parameter of the 'bind' routines. -: SQLITE_STATIC 0 ; -: SQLITE_TRANSIENT -1 ; - -: sqlite3_open ( filename sqlite3-indirect -- result ) - "int" "sqlite" "sqlite3_open" [ "char*" "sqlite3-indirect*" ] alien-invoke ; - -: sqlite3_close ( db -- result ) - "int" "sqlite" "sqlite3_close" [ "sqlite3*" ] alien-invoke ; - -: sqlite3_prepare ( db sql sql-len sqlite3-stmt-indirect tail -- result ) - "int" "sqlite" "sqlite3_prepare" [ "sqlite3*" "char*" "int" "sqlite3-stmt-indirect*" "char*-indirect*" ] alien-invoke ; - -: sqlite3_finalize ( stmt -- result ) - "int" "sqlite" "sqlite3_finalize" [ "sqlite3-stmt*" ] alien-invoke ; - -: sqlite3_reset ( stmt -- result ) - "int" "sqlite" "sqlite3_reset" [ "sqlite3-stmt*" ] alien-invoke ; - -: sqlite3_step ( stmt -- result ) - "int" "sqlite" "sqlite3_step" [ "sqlite3-stmt*" ] alien-invoke ; - -: sqlite3_last_insert_rowid ( stmt -- result ) - "int" "sqlite" "sqlite3_last_insert_rowid" [ "sqlite3*" ] alien-invoke ; - -: sqlite3_bind_blob ( stmt index pointer len destructor -- result ) - "int" "sqlite" "sqlite3_bind_blob" [ "sqlite3-stmt*" "int" "void*" "int" "int" ] alien-invoke ; - -: sqlite3_bind_int ( stmt index int -- result ) - "int" "sqlite" "sqlite3_bind_int" [ "sqlite3-stmt*" "int" "int" ] alien-invoke ; - -: sqlite3_bind_null ( stmt index -- result ) - "int" "sqlite" "sqlite3_bind_null" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_bind_text ( stmt index text len destructor -- result ) - "int" "sqlite" "sqlite3_bind_text" [ "sqlite3-stmt*" "int" "char*" "int" "int" ] alien-invoke ; - -: sqlite3_bind_parameter_index ( stmt name -- result ) - "int" "sqlite" "sqlite3_bind_parameter_index" [ "sqlite3-stmt*" "char*" ] alien-invoke ; - -: sqlite3_column_count ( stmt -- count ) - "int" "sqlite" "sqlite3_column_count" [ "sqlite3-stmt*" ] alien-invoke ; - -: sqlite3_column_blob ( stmt col -- void* ) - "void*" "sqlite" "sqlite3_column_blob" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_column_bytes ( stmt col -- int ) - "int" "sqlite" "sqlite3_column_bytes" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_column_decltype ( stmt col -- string ) - "char*" "sqlite" "sqlite3_column_decltype" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_column_int ( stmt col -- int ) - "int" "sqlite" "sqlite3_column_int" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_column_name ( stmt col -- string ) - "char*" "sqlite" "sqlite3_column_name" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_column_text ( stmt col -- string ) - "char*" "sqlite" "sqlite3_column_text" [ "sqlite3-stmt*" "int" ] alien-invoke ; - -: sqlite3_column_type ( stmt col -- int ) - "int" "sqlite" "sqlite3_column_type" [ "sqlite3-stmt*" "int" ] alien-invoke ; +TUPLE: sqlite-error n message ; ! High level sqlite routines : sqlite-check-result ( result -- ) #! Check the result from a sqlite call is ok. If it is - #! return, otherwise throw an error. TODO: Throw the actual - #! error text message. + #! return, otherwise throw an error. dup SQLITE_OK = [ drop ] [ - "sqlite returned an error. See datastack for the error value." throw + dup sqlite-error-messages nth throw ] if ; : sqlite-open ( filename -- db ) #! Open the database referenced by the filename and return #! a handle to that database. An error is thrown if the database #! failed to open. - "sqlite3-indirect" tuck sqlite3_open sqlite-check-result sqlite3-indirect-pointer ; + "void*" [ sqlite3_open sqlite-check-result ] keep *void* ; : sqlite-close ( db -- ) #! Close the given database @@ -164,9 +41,9 @@ END-STRUCT #! Prepare a SQL statement. Returns the statement which #! can have values bound to parameters or simply executed. #! TODO: Support multiple statements in the SQL string. - dup length "sqlite3-stmt-indirect" dup >r - "char*-indirect" sqlite3_prepare sqlite-check-result - r> sqlite3-stmt-indirect-pointer ; + dup length "void*" "void*" + [ sqlite3_prepare sqlite-check-result ] 2keep + drop *void* ; : sqlite-bind-text ( statement index text -- ) #! Bind the text to the parameterized value in the statement. diff --git a/contrib/sqlite/tuple-db.factor b/contrib/sqlite/tuple-db.factor index 91ee29d286..98597e4743 100644 --- a/contrib/sqlite/tuple-db.factor +++ b/contrib/sqlite/tuple-db.factor @@ -1,25 +1,4 @@ ! Copyright (C) 2005 Chris Double. -! -! Redistribution and use in source and binary forms, with or without -! modification, are permitted provided that the following conditions are met: -! -! 1. Redistributions of source code must retain the above copyright notice, -! this list of conditions and the following disclaimer. -! -! 2. Redistributions in binary form must reproduce the above copyright notice, -! this list of conditions and the following disclaimer in the documentation -! and/or other materials provided with the distribution. -! -! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! ! A tuple that is persistent has its delegate set as 'persistent'. ! 'persistent' holds the numeric rowid for that tuple in its table.