From 72205363fdff7b8dcdb8cfda0f24a4b9c208990f Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sat, 11 Apr 2009 13:44:06 -0500 Subject: [PATCH] porting more things over to extra/db2 --- extra/db2/errors/errors.factor | 40 +++++ extra/db2/errors/postgresql/authors.txt | 1 + .../errors/postgresql/postgresql-tests.factor | 32 ++++ extra/db2/errors/postgresql/postgresql.factor | 53 +++++++ extra/db2/errors/sqlite/authors.txt | 1 + extra/db2/errors/sqlite/sqlite-tests.factor | 26 ++++ extra/db2/errors/sqlite/sqlite.factor | 28 ++++ extra/db2/errors/summary.txt | 1 + extra/db2/pools/authors.txt | 1 + extra/db2/pools/pools-tests.factor | 22 +++ extra/db2/pools/pools.factor | 20 +++ extra/db2/result-sets/result-sets.factor | 1 - extra/db2/sqlite/authors.txt | 1 + extra/db2/sqlite/ffi/ffi.factor | 142 ++++++++++++++++++ extra/db2/sqlite/lib/lib.factor | 119 +++++++++++++++ extra/db2/sqlite/sqlite.factor | 4 + extra/db2/sqlite/types/authors.txt | 1 + extra/db2/sqlite/types/types.factor | 62 ++++++++ extra/db2/transactions/transactions.factor | 3 +- extra/db2/types/authors.txt | 1 + extra/db2/types/types.factor | 17 +++ 21 files changed, 573 insertions(+), 3 deletions(-) create mode 100644 extra/db2/errors/errors.factor create mode 100644 extra/db2/errors/postgresql/authors.txt create mode 100644 extra/db2/errors/postgresql/postgresql-tests.factor create mode 100644 extra/db2/errors/postgresql/postgresql.factor create mode 100644 extra/db2/errors/sqlite/authors.txt create mode 100644 extra/db2/errors/sqlite/sqlite-tests.factor create mode 100644 extra/db2/errors/sqlite/sqlite.factor create mode 100644 extra/db2/errors/summary.txt create mode 100644 extra/db2/pools/authors.txt create mode 100644 extra/db2/pools/pools-tests.factor create mode 100644 extra/db2/pools/pools.factor create mode 100644 extra/db2/sqlite/authors.txt create mode 100644 extra/db2/sqlite/ffi/ffi.factor create mode 100644 extra/db2/sqlite/lib/lib.factor create mode 100644 extra/db2/sqlite/sqlite.factor create mode 100644 extra/db2/sqlite/types/authors.txt create mode 100644 extra/db2/sqlite/types/types.factor create mode 100644 extra/db2/types/authors.txt create mode 100644 extra/db2/types/types.factor diff --git a/extra/db2/errors/errors.factor b/extra/db2/errors/errors.factor new file mode 100644 index 0000000000..bd330e6191 --- /dev/null +++ b/extra/db2/errors/errors.factor @@ -0,0 +1,40 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel continuations fry words constructors ; +IN: db2.errors + +ERROR: db-error ; +ERROR: sql-error location ; + +ERROR: sql-unknown-error < sql-error message ; +CONSTRUCTOR: sql-unknown-error ( message -- error ) ; + +ERROR: sql-table-exists < sql-error table ; +CONSTRUCTOR: sql-table-exists ( table -- error ) ; + +ERROR: sql-table-missing < sql-error table ; +CONSTRUCTOR: sql-table-missing ( table -- error ) ; + +ERROR: sql-syntax-error < sql-error message ; +CONSTRUCTOR: sql-syntax-error ( message -- error ) ; + +ERROR: sql-function-exists < sql-error message ; +CONSTRUCTOR: sql-function-exists ( message -- error ) ; + +ERROR: sql-function-missing < sql-error message ; +CONSTRUCTOR: sql-function-missing ( message -- error ) ; + +: ignore-error ( quot word -- ) + '[ dup _ execute [ drop ] [ rethrow ] if ] recover ; inline + +: ignore-table-exists ( quot -- ) + \ sql-table-exists? ignore-error ; inline + +: ignore-table-missing ( quot -- ) + \ sql-table-missing? ignore-error ; inline + +: ignore-function-exists ( quot -- ) + \ sql-function-exists? ignore-error ; inline + +: ignore-function-missing ( quot -- ) + \ sql-function-missing? ignore-error ; inline diff --git a/extra/db2/errors/postgresql/authors.txt b/extra/db2/errors/postgresql/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/db2/errors/postgresql/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/db2/errors/postgresql/postgresql-tests.factor b/extra/db2/errors/postgresql/postgresql-tests.factor new file mode 100644 index 0000000000..f6668031e5 --- /dev/null +++ b/extra/db2/errors/postgresql/postgresql-tests.factor @@ -0,0 +1,32 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators.short-circuit db db.errors +db.errors.postgresql db.postgresql io.files.unique kernel namespaces +tools.test db.tester continuations ; +IN: db.errors.postgresql.tests + +[ + + [ "drop table foo;" sql-command ] ignore-errors + [ "drop table ship;" sql-command ] ignore-errors + + [ + "insert into foo (id) values('1');" sql-command + ] [ + { [ sql-table-missing? ] [ table>> "foo" = ] } 1&& + ] must-fail-with + + [ + "create table ship(id integer);" sql-command + "create table ship(id integer);" sql-command + ] [ + { [ sql-table-exists? ] [ table>> "ship" = ] } 1&& + ] must-fail-with + + [ + "create table foo(id) lol;" sql-command + ] [ + sql-syntax-error? + ] must-fail-with + +] test-postgresql diff --git a/extra/db2/errors/postgresql/postgresql.factor b/extra/db2/errors/postgresql/postgresql.factor new file mode 100644 index 0000000000..02b43ecd88 --- /dev/null +++ b/extra/db2/errors/postgresql/postgresql.factor @@ -0,0 +1,53 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel db.errors peg.ebnf strings sequences math +combinators.short-circuit accessors math.parser quoting ; +IN: db.errors.postgresql + +EBNF: parse-postgresql-sql-error + +Error = "ERROR:" [ ]+ + +TableError = + Error ("relation "|"table ")(!(" already exists").)+:table " already exists" + => [[ table >string unquote ]] + | Error ("relation "|"table ")(!(" does not exist").)+:table " does not exist" + => [[ table >string unquote ]] + +FunctionError = + Error "function" (!(" already exists").)+:table " already exists" + => [[ table >string ]] + | Error "function" (!(" does not exist").)+:table " does not exist" + => [[ table >string ]] + +SyntaxError = + Error "syntax error at end of input":error + => [[ error >string ]] + | Error "syntax error at or near " .+:syntaxerror + => [[ syntaxerror >string unquote ]] + +UnknownError = .* => [[ >string ]] + +PostgresqlSqlError = (TableError | FunctionError | SyntaxError | UnknownError) + +;EBNF + + +ERROR: parse-postgresql-location column line text ; +C: parse-postgresql-location + +EBNF: parse-postgresql-line-error + +Line = "LINE " [0-9]+:line ": " .+:sql + => [[ f line >string string>number sql >string ]] + +;EBNF + +:: set-caret-position ( error caret-line -- error ) + caret-line length + error line>> number>string length "LINE : " length + + - [ error ] dip >>column ; + +: postgresql-location ( line column -- obj ) + [ parse-postgresql-line-error ] dip + set-caret-position ; diff --git a/extra/db2/errors/sqlite/authors.txt b/extra/db2/errors/sqlite/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/db2/errors/sqlite/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/db2/errors/sqlite/sqlite-tests.factor b/extra/db2/errors/sqlite/sqlite-tests.factor new file mode 100644 index 0000000000..68ae55f8a8 --- /dev/null +++ b/extra/db2/errors/sqlite/sqlite-tests.factor @@ -0,0 +1,26 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators.short-circuit db db.errors +db.errors.sqlite db.sqlite io.files.unique kernel namespaces +tools.test ; +IN: db.errors.sqlite.tests + +: sqlite-error-test-db-path ( -- path ) + "sqlite" "error-test" make-unique-file ; + +sqlite-error-test-db-path [ + + [ + "insert into foo (id) values('1');" sql-command + ] [ + { [ sql-table-missing? ] [ table>> "foo" = ] } 1&& + ] must-fail-with + + [ + "create table foo(id);" sql-command + "create table foo(id);" sql-command + ] [ + { [ sql-table-exists? ] [ table>> "foo" = ] } 1&& + ] must-fail-with + +] with-db \ No newline at end of file diff --git a/extra/db2/errors/sqlite/sqlite.factor b/extra/db2/errors/sqlite/sqlite.factor new file mode 100644 index 0000000000..c73409b850 --- /dev/null +++ b/extra/db2/errors/sqlite/sqlite.factor @@ -0,0 +1,28 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators db kernel sequences peg.ebnf +strings db.errors ; +IN: db.errors.sqlite + +TUPLE: unparsed-sqlite-error error ; +C: unparsed-sqlite-error + +SINGLETONS: table-exists table-missing ; + +: sqlite-table-error ( table message -- error ) + { + { table-exists [ ] } + } case ; + +EBNF: parse-sqlite-sql-error + +TableMessage = " already exists" => [[ table-exists ]] + +SqliteError = + "table " (!(TableMessage).)+:table TableMessage:message + => [[ table >string message sqlite-table-error ]] + | "no such table: " .+:table + => [[ table >string ]] + | .*:error + => [[ error >string ]] +;EBNF diff --git a/extra/db2/errors/summary.txt b/extra/db2/errors/summary.txt new file mode 100644 index 0000000000..1cd102173f --- /dev/null +++ b/extra/db2/errors/summary.txt @@ -0,0 +1 @@ +Errors thrown by database library diff --git a/extra/db2/pools/authors.txt b/extra/db2/pools/authors.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/extra/db2/pools/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/extra/db2/pools/pools-tests.factor b/extra/db2/pools/pools-tests.factor new file mode 100644 index 0000000000..7ff2a33d92 --- /dev/null +++ b/extra/db2/pools/pools-tests.factor @@ -0,0 +1,22 @@ +IN: db.pools.tests +USING: db.pools tools.test continuations io.files io.files.temp +io.directories namespaces accessors kernel math destructors ; + +\ must-infer + +{ 1 0 } [ [ ] with-db-pool ] must-infer-as + +{ 1 0 } [ [ ] with-pooled-db ] must-infer-as + +! Test behavior after image save/load +USE: db.sqlite + +[ "pool-test.db" temp-file delete-file ] ignore-errors + +[ ] [ "pool-test.db" temp-file "pool" set ] unit-test + +[ ] [ "pool" get expired>> t >>expired drop ] unit-test + +[ ] [ 1000 [ "pool" get [ ] with-pooled-db ] times ] unit-test + +[ ] [ "pool" get dispose ] unit-test diff --git a/extra/db2/pools/pools.factor b/extra/db2/pools/pools.factor new file mode 100644 index 0000000000..b22dbde398 --- /dev/null +++ b/extra/db2/pools/pools.factor @@ -0,0 +1,20 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors db2.connections fry io.pools kernel +namespaces ; +IN: db.pools + +TUPLE: db-pool < pool db ; + +: ( db -- pool ) + db-pool + swap >>db ; + +: with-db-pool ( db quot -- ) + [ ] dip with-pool ; inline + +M: db-pool make-connection ( pool -- ) + db>> db-open ; + +: with-pooled-db ( pool quot -- ) + '[ db-connection _ with-variable ] with-pooled-connection ; inline diff --git a/extra/db2/result-sets/result-sets.factor b/extra/db2/result-sets/result-sets.factor index 0f242da473..8e35dc3862 100644 --- a/extra/db2/result-sets/result-sets.factor +++ b/extra/db2/result-sets/result-sets.factor @@ -26,4 +26,3 @@ GENERIC# column-typed 1 ( result-set column -- sql ) : sql-row-typed ( result-set -- seq ) dup #columns [ column-typed ] with map ; - diff --git a/extra/db2/sqlite/authors.txt b/extra/db2/sqlite/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/db2/sqlite/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/db2/sqlite/ffi/ffi.factor b/extra/db2/sqlite/ffi/ffi.factor new file mode 100644 index 0000000000..2594978ddf --- /dev/null +++ b/extra/db2/sqlite/ffi/ffi.factor @@ -0,0 +1,142 @@ +! Copyright (C) 2005 Chris Double, Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +! Not all functions have been wrapped. +USING: alien alien.libraries alien.syntax combinators system ; +IN: db2.sqlite.ffi + +<< "sqlite" { + { [ os winnt? ] [ "sqlite3.dll" ] } + { [ os macosx? ] [ "/usr/lib/libsqlite3.dylib" ] } + { [ os unix? ] [ "libsqlite3.so" ] } + } cond "cdecl" add-library >> + +LIBRARY: sqlite + +! Return values from sqlite functions +CONSTANT: SQLITE_OK 0 ! Successful result +CONSTANT: SQLITE_ERROR 1 ! SQL error or missing database +CONSTANT: SQLITE_INTERNAL 2 ! An internal logic error in SQLite +CONSTANT: SQLITE_PERM 3 ! Access permission denied +CONSTANT: SQLITE_ABORT 4 ! Callback routine requested an abort +CONSTANT: SQLITE_BUSY 5 ! The database file is locked +CONSTANT: SQLITE_LOCKED 6 ! A table in the database is locked +CONSTANT: SQLITE_NOMEM 7 ! A malloc() failed +CONSTANT: SQLITE_READONLY 8 ! Attempt to write a readonly database +CONSTANT: SQLITE_INTERRUPT 9 ! Operation terminated by sqlite_interrupt() +CONSTANT: SQLITE_IOERR 10 ! Some kind of disk I/O error occurred +CONSTANT: SQLITE_CORRUPT 11 ! The database disk image is malformed +CONSTANT: SQLITE_NOTFOUND 12 ! (Internal Only) Table or record not found +CONSTANT: SQLITE_FULL 13 ! Insertion failed because database is full +CONSTANT: SQLITE_CANTOPEN 14 ! Unable to open the database file +CONSTANT: SQLITE_PROTOCOL 15 ! Database lock protocol error +CONSTANT: SQLITE_EMPTY 16 ! (Internal Only) Database table is empty +CONSTANT: SQLITE_SCHEMA 17 ! The database schema changed +CONSTANT: SQLITE_TOOBIG 18 ! Too much data for one row of a table +CONSTANT: SQLITE_CONSTRAINT 19 ! Abort due to contraint violation +CONSTANT: SQLITE_MISMATCH 20 ! Data type mismatch +CONSTANT: SQLITE_MISUSE 21 ! Library used incorrectly +CONSTANT: SQLITE_NOLFS 22 ! Uses OS features not supported on host +CONSTANT: SQLITE_AUTH 23 ! Authorization denied +CONSTANT: SQLITE_FORMAT 24 ! Auxiliary database format error +CONSTANT: SQLITE_RANGE 25 ! 2nd parameter to sqlite3_bind out of range +CONSTANT: SQLITE_NOTADB 26 ! File opened that is not a database file + +CONSTANT: sqlite-error-messages +{ + "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" +} + +! Return values from sqlite3_step +CONSTANT: SQLITE_ROW 100 +CONSTANT: SQLITE_DONE 101 + +! Return values from the sqlite3_column_type function +CONSTANT: SQLITE_INTEGER 1 +CONSTANT: SQLITE_FLOAT 2 +CONSTANT: SQLITE_TEXT 3 +CONSTANT: SQLITE_BLOB 4 +CONSTANT: SQLITE_NULL 5 + +! Values for the 'destructor' parameter of the 'bind' routines. +CONSTANT: SQLITE_STATIC 0 +CONSTANT: SQLITE_TRANSIENT -1 + +CONSTANT: SQLITE_OPEN_READONLY HEX: 00000001 +CONSTANT: SQLITE_OPEN_READWRITE HEX: 00000002 +CONSTANT: SQLITE_OPEN_CREATE HEX: 00000004 +CONSTANT: SQLITE_OPEN_DELETEONCLOSE HEX: 00000008 +CONSTANT: SQLITE_OPEN_EXCLUSIVE HEX: 00000010 +CONSTANT: SQLITE_OPEN_MAIN_DB HEX: 00000100 +CONSTANT: SQLITE_OPEN_TEMP_DB HEX: 00000200 +CONSTANT: SQLITE_OPEN_TRANSIENT_DB HEX: 00000400 +CONSTANT: SQLITE_OPEN_MAIN_JOURNAL HEX: 00000800 +CONSTANT: SQLITE_OPEN_TEMP_JOURNAL HEX: 00001000 +CONSTANT: SQLITE_OPEN_SUBJOURNAL HEX: 00002000 +CONSTANT: SQLITE_OPEN_MASTER_JOURNAL HEX: 00004000 + +TYPEDEF: void sqlite3 +TYPEDEF: void sqlite3_stmt +TYPEDEF: longlong sqlite3_int64 +TYPEDEF: ulonglong sqlite3_uint64 + +FUNCTION: int sqlite3_open ( char* filename, void* ppDb ) ; +FUNCTION: int sqlite3_close ( sqlite3* pDb ) ; +FUNCTION: char* sqlite3_errmsg ( sqlite3* pDb ) ; +FUNCTION: int sqlite3_prepare ( sqlite3* pDb, char* zSql, int nBytes, void* ppStmt, void* pzTail ) ; +FUNCTION: int sqlite3_prepare_v2 ( 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: sqlite3_uint64 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_double ( sqlite3_stmt* pStmt, int index, double x ) ; +FUNCTION: int sqlite3_bind_int ( sqlite3_stmt* pStmt, int index, int n ) ; +FUNCTION: int sqlite3_bind_int64 ( sqlite3_stmt* pStmt, int index, sqlite3_int64 n ) ; +! Bind the same function as above, but for unsigned 64bit integers +: sqlite3-bind-uint64 ( pStmt index in64 -- int ) + "int" "sqlite" "sqlite3_bind_int64" + { "sqlite3_stmt*" "int" "sqlite3_uint64" } alien-invoke ; +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_clear_bindings ( sqlite3_stmt* pStmt ) ; +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: sqlite3_int64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col ) ; +! Bind the same function as above, but for unsigned 64bit integers +: sqlite3-column-uint64 ( pStmt col -- uint64 ) + "sqlite3_uint64" "sqlite" "sqlite3_column_int64" + { "sqlite3_stmt*" "int" } alien-invoke ; +FUNCTION: double sqlite3_column_double ( sqlite3_stmt* pStmt, int col ) ; +FUNCTION: char* 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/extra/db2/sqlite/lib/lib.factor b/extra/db2/sqlite/lib/lib.factor new file mode 100644 index 0000000000..2fe6d9cbdf --- /dev/null +++ b/extra/db2/sqlite/lib/lib.factor @@ -0,0 +1,119 @@ +! Copyright (C) 2008 Chris Double, Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors alien.c-types arrays calendar.format +combinators db2.connections db2.sqlite.ffi db2.errors +io.backend io.encodings.string io.encodings.utf8 kernel math +namespaces present sequences serialize urls ; +IN: db2.sqlite.lib + +: ?when ( object quot -- object' ) dupd when ; inline + +ERROR: sqlite-error < db-error n string ; +ERROR: sqlite-sql-error < sql-error n string ; + +: throw-sqlite-error ( n -- * ) + dup sqlite-error-messages nth sqlite-error ; + +: sqlite-statement-error ( -- * ) + SQLITE_ERROR + db-connection get handle>> sqlite3_errmsg sqlite-sql-error ; + +: sqlite-check-result ( n -- ) + { + { SQLITE_OK [ ] } + { SQLITE_ERROR [ sqlite-statement-error ] } + [ throw-sqlite-error ] + } case ; + +: sqlite-open ( path -- db ) + normalize-path + "void*" + [ sqlite3_open sqlite-check-result ] keep *void* ; + +: sqlite-close ( db -- ) + sqlite3_close sqlite-check-result ; + +: sqlite-prepare ( db sql -- handle ) + utf8 encode dup length "void*" "void*" + [ sqlite3_prepare_v2 sqlite-check-result ] 2keep + drop *void* ; + +: sqlite-bind-parameter-index ( handle name -- index ) + sqlite3_bind_parameter_index ; + +: parameter-index ( handle name text -- handle name text ) + [ dupd sqlite-bind-parameter-index ] dip ; + +: sqlite-bind-text ( handle index text -- ) + utf8 encode dup length SQLITE_TRANSIENT + sqlite3_bind_text sqlite-check-result ; + +: sqlite-bind-int ( handle i n -- ) + sqlite3_bind_int sqlite-check-result ; + +: sqlite-bind-int64 ( handle i n -- ) + sqlite3_bind_int64 sqlite-check-result ; + +: sqlite-bind-uint64 ( handle i n -- ) + sqlite3-bind-uint64 sqlite-check-result ; + +: sqlite-bind-double ( handle i x -- ) + sqlite3_bind_double sqlite-check-result ; + +: sqlite-bind-null ( handle i -- ) + sqlite3_bind_null sqlite-check-result ; + +: sqlite-bind-blob ( handle i byte-array -- ) + dup length SQLITE_TRANSIENT + sqlite3_bind_blob sqlite-check-result ; + +: sqlite-bind-text-by-name ( handle name text -- ) + parameter-index sqlite-bind-text ; + +: sqlite-bind-int-by-name ( handle name int -- ) + parameter-index sqlite-bind-int ; + +: sqlite-bind-int64-by-name ( handle name int64 -- ) + parameter-index sqlite-bind-int64 ; + +: sqlite-bind-uint64-by-name ( handle name int64 -- ) + parameter-index sqlite-bind-uint64 ; + +: sqlite-bind-boolean-by-name ( handle name obj -- ) + >boolean 1 0 ? parameter-index sqlite-bind-int ; + +: sqlite-bind-double-by-name ( handle name double -- ) + parameter-index sqlite-bind-double ; + +: sqlite-bind-blob-by-name ( handle name blob -- ) + parameter-index sqlite-bind-blob ; + +: sqlite-bind-null-by-name ( handle name obj -- ) + parameter-index drop sqlite-bind-null ; + +: sqlite-finalize ( handle -- ) sqlite3_finalize sqlite-check-result ; +: sqlite-reset ( handle -- ) sqlite3_reset sqlite-check-result ; +: sqlite-clear-bindings ( handle -- ) + sqlite3_clear_bindings sqlite-check-result ; +: sqlite-#columns ( query -- int ) sqlite3_column_count ; +: sqlite-column ( handle index -- string ) sqlite3_column_text ; +: sqlite-column-name ( handle index -- string ) sqlite3_column_name ; +: sqlite-column-type ( handle index -- string ) sqlite3_column_type ; + +: sqlite-column-blob ( handle index -- byte-array/f ) + [ sqlite3_column_bytes ] 2keep + pick zero? [ + 3drop f + ] [ + sqlite3_column_blob swap memory>byte-array + ] if ; + +: sqlite-step-has-more-rows? ( prepared -- ? ) + { + { SQLITE_ROW [ t ] } + { SQLITE_DONE [ f ] } + [ sqlite-check-result f ] + } case ; + +: sqlite-next ( prepared -- ? ) + sqlite3_step sqlite-step-has-more-rows? ; diff --git a/extra/db2/sqlite/sqlite.factor b/extra/db2/sqlite/sqlite.factor new file mode 100644 index 0000000000..edb74dd06f --- /dev/null +++ b/extra/db2/sqlite/sqlite.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: ; +IN: db2.sqlite diff --git a/extra/db2/sqlite/types/authors.txt b/extra/db2/sqlite/types/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/db2/sqlite/types/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/db2/sqlite/types/types.factor b/extra/db2/sqlite/types/types.factor new file mode 100644 index 0000000000..86ad92c60e --- /dev/null +++ b/extra/db2/sqlite/types/types.factor @@ -0,0 +1,62 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: arrays calendar.format combinators db2.types +db2.sqlite.ffi db2.sqlite.lib +kernel present sequences serialize urls ; +IN: db2.sqlite.types + +: (bind-sqlite-type) ( handle key value type -- ) + dup array? [ first ] when + { + { INTEGER [ sqlite-bind-int-by-name ] } + { BIG-INTEGER [ sqlite-bind-int64-by-name ] } + { SIGNED-BIG-INTEGER [ sqlite-bind-int64-by-name ] } + { UNSIGNED-BIG-INTEGER [ sqlite-bind-uint64-by-name ] } + { BOOLEAN [ sqlite-bind-boolean-by-name ] } + { TEXT [ sqlite-bind-text-by-name ] } + { VARCHAR [ sqlite-bind-text-by-name ] } + { DOUBLE [ sqlite-bind-double-by-name ] } + { DATE [ timestamp>ymd sqlite-bind-text-by-name ] } + { TIME [ timestamp>hms sqlite-bind-text-by-name ] } + { DATETIME [ timestamp>ymdhms sqlite-bind-text-by-name ] } + { TIMESTAMP [ timestamp>ymdhms sqlite-bind-text-by-name ] } + { BLOB [ sqlite-bind-blob-by-name ] } + { FACTOR-BLOB [ object>bytes sqlite-bind-blob-by-name ] } + { URL [ present sqlite-bind-text-by-name ] } + { +db-assigned-id+ [ sqlite-bind-int-by-name ] } + { +random-id+ [ sqlite-bind-int64-by-name ] } + { NULL [ sqlite-bind-null-by-name ] } + [ no-sql-type ] + } case ; + +: bind-sqlite-type ( handle key value type -- ) + #! null and empty values need to be set by sqlite-bind-null-by-name + over [ + NULL = [ 2drop NULL NULL ] when + ] [ + drop NULL + ] if* (bind-sqlite-type) ; + +: sqlite-type ( handle index type -- obj ) + dup array? [ first ] when + { + { +db-assigned-id+ [ sqlite3_column_int64 ] } + { +random-id+ [ sqlite3-column-uint64 ] } + { INTEGER [ sqlite3_column_int ] } + { BIG-INTEGER [ sqlite3_column_int64 ] } + { SIGNED-BIG-INTEGER [ sqlite3_column_int64 ] } + { UNSIGNED-BIG-INTEGER [ sqlite3-column-uint64 ] } + { BOOLEAN [ sqlite3_column_int 1 = ] } + { DOUBLE [ sqlite3_column_double ] } + { TEXT [ sqlite3_column_text ] } + { VARCHAR [ sqlite3_column_text ] } + { DATE [ sqlite3_column_text [ ymd>timestamp ] ?when ] } + { TIME [ sqlite3_column_text [ hms>timestamp ] ?when ] } + { TIMESTAMP [ sqlite3_column_text [ ymdhms>timestamp ] ?when ] } + { DATETIME [ sqlite3_column_text [ ymdhms>timestamp ] ?when ] } + { BLOB [ sqlite-column-blob ] } + { URL [ sqlite3_column_text [ >url ] ?when ] } + { FACTOR-BLOB [ sqlite-column-blob [ bytes>object ] ?when ] } + [ no-sql-type ] + } case ; + diff --git a/extra/db2/transactions/transactions.factor b/extra/db2/transactions/transactions.factor index 081c8dbe57..eb8c48e336 100644 --- a/extra/db2/transactions/transactions.factor +++ b/extra/db2/transactions/transactions.factor @@ -1,9 +1,8 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: db2 ; +USING: continuations db2 db2.connections namespaces ; IN: db2.transactions -! Transactions SYMBOL: in-transaction HOOK: begin-transaction db-connection ( -- ) diff --git a/extra/db2/types/authors.txt b/extra/db2/types/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/db2/types/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/db2/types/types.factor b/extra/db2/types/types.factor new file mode 100644 index 0000000000..97f9ca0a0c --- /dev/null +++ b/extra/db2/types/types.factor @@ -0,0 +1,17 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: ; +IN: db2.types + +SINGLETONS: +db-assigned-id+ +user-assigned-id+ +random-id+ ; +UNION: +primary-key+ +db-assigned-id+ +user-assigned-id+ +random-id+ ; + +SYMBOLS: +autoincrement+ +serial+ +unique+ +default+ +null+ +not-null+ ++foreign-id+ +has-many+ +on-update+ +on-delete+ +restrict+ +cascade+ ++set-null+ +set-default+ ; + +SINGLETONS: INTEGER BIG-INTEGER SIGNED-BIG-INTEGER UNSIGNED-BIG-INTEGER +DOUBLE REAL BOOLEAN TEXT VARCHAR DATE TIME DATETIME TIMESTAMP BLOB +FACTOR-BLOB NULL URL ; + +ERROR: no-sql-type type ;