diff --git a/extra/db2/connections/connections.factor b/extra/db2/connections/connections.factor index 0caee54726..7957cb918a 100644 --- a/extra/db2/connections/connections.factor +++ b/extra/db2/connections/connections.factor @@ -11,7 +11,6 @@ TUPLE: db-connection handle ; GENERIC: db-open ( db -- db-connection ) GENERIC: db-close ( handle -- ) -HOOK: parse-db-error db-connection ( error -- error' ) M: db-connection dispose ( db-connection -- ) [ db-close ] [ f >>handle drop ] bi ; diff --git a/extra/db2/db2.factor b/extra/db2/db2.factor index 16afbd2782..e1723160c0 100644 --- a/extra/db2/db2.factor +++ b/extra/db2/db2.factor @@ -18,3 +18,4 @@ PRIVATE> : sql-query ( sql -- sequence ) f f [ statement>result-sequence ] with-disposal ; + diff --git a/extra/db2/sqlite/connections/connections.factor b/extra/db2/sqlite/connections/connections.factor index ba9869633b..b99603f4ef 100644 --- a/extra/db2/sqlite/connections/connections.factor +++ b/extra/db2/sqlite/connections/connections.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: accessors combinators db2.connections db2.sqlite -db2.sqlite.errors db2.sqlite.lib kernel ; +db2.sqlite.errors db2.sqlite.lib kernel db2.errors ; IN: db2.sqlite.connections TUPLE: sqlite-db-connection < db-connection ; @@ -15,7 +15,7 @@ M: sqlite-db db-open ( db -- db-connection ) M: sqlite-db-connection db-close ( db-connection -- ) handle>> sqlite-close ; -M: sqlite-db-connection parse-db-error ( error -- error' ) +M: sqlite-db-connection parse-sql-error ( error -- error' ) dup n>> { { 1 [ string>> parse-sqlite-sql-error ] } [ drop ] diff --git a/extra/db2/sqlite/errors/errors.factor b/extra/db2/sqlite/errors/errors.factor index eff73b6796..61e70f210d 100644 --- a/extra/db2/sqlite/errors/errors.factor +++ b/extra/db2/sqlite/errors/errors.factor @@ -8,9 +8,6 @@ IN: db2.sqlite.errors 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 ; @@ -18,20 +15,21 @@ ERROR: sqlite-sql-error < sql-error n string ; TUPLE: unparsed-sqlite-error error ; C: unparsed-sqlite-error -: sqlite-table-error ( table message -- error ) - { - { sql-table-exists [ ] } - } case ; - EBNF: parse-sqlite-sql-error -TableMessage = " already exists" => [[ sql-table-exists ]] +TableMessage = " already exists" +SyntaxError = ": syntax error" SqliteError = "table " (!(TableMessage).)+:table TableMessage:message - => [[ table >string message sqlite-table-error ]] + => [[ table >string ]] + | "near " (!(SyntaxError).)+:syntax SyntaxError:message + => [[ syntax >string ]] | "no such table: " .+:table => [[ table >string ]] | .*:error => [[ error >string ]] ;EBNF + +: throw-sqlite-error ( n -- * ) + dup sqlite-error-messages nth sqlite-error ; diff --git a/extra/db2/sqlite/lib/lib.factor b/extra/db2/sqlite/lib/lib.factor index f3e3058582..34918efb8d 100644 --- a/extra/db2/sqlite/lib/lib.factor +++ b/extra/db2/sqlite/lib/lib.factor @@ -8,7 +8,6 @@ IN: db2.sqlite.lib : ?when ( object quot -- object' ) dupd when ; inline - : sqlite-check-result ( n -- ) { { SQLITE_OK [ ] } diff --git a/extra/db2/sqlite/result-sets/result-sets.factor b/extra/db2/sqlite/result-sets/result-sets.factor index 14e8e52f0e..a8bf11fc56 100644 --- a/extra/db2/sqlite/result-sets/result-sets.factor +++ b/extra/db2/sqlite/result-sets/result-sets.factor @@ -1,7 +1,27 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: db2.result-sets ; +USING: accessors db2.result-sets db2.sqlite.statements +db2.statements kernel db2.sqlite.lib destructors ; IN: db2.sqlite.result-sets TUPLE: sqlite-result-set < result-set has-more? ; +M: sqlite-result-set dispose + f >>handle drop ; + +M: sqlite-statement statement>result-set* + sqlite-maybe-prepare + dup handle>> sqlite-result-set new-result-set + dup advance-row ; + +M: sqlite-result-set advance-row ( result-set -- ) + dup handle>> sqlite-next >>has-more? drop ; + +M: sqlite-result-set more-rows? ( result-set -- ) + has-more?>> ; + +M: sqlite-result-set #columns ( result-set -- n ) + handle>> sqlite-#columns ; + +M: sqlite-result-set column ( result-set n -- obj ) + [ handle>> ] [ sqlite-column ] bi* ; diff --git a/extra/db2/sqlite/statements/statements.factor b/extra/db2/sqlite/statements/statements.factor index fde2de7bf6..a856c48075 100644 --- a/extra/db2/sqlite/statements/statements.factor +++ b/extra/db2/sqlite/statements/statements.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: db2.connections db2.statements db2.sqlite.connections -db2.sqlite.lib ; +USING: accessors db2.connections db2.sqlite.connections +db2.sqlite.ffi db2.sqlite.lib db2.statements destructors kernel +namespaces ; IN: db2.sqlite.statements TUPLE: sqlite-statement < statement ; @@ -9,3 +10,12 @@ TUPLE: sqlite-statement < statement ; M: sqlite-db-connection ( string in out -- obj ) sqlite-statement new-statement ; +M: sqlite-statement dispose + handle>> + [ [ sqlite3_reset drop ] [ sqlite-finalize ] bi ] when* ; + +: sqlite-maybe-prepare ( statement -- statement ) + dup handle>> [ + db-connection get handle>> over sql>> sqlite-prepare + >>handle + ] unless ; diff --git a/extra/db2/statements/statements-tests.factor b/extra/db2/statements/statements-tests.factor index 548300b417..43564c8b29 100644 --- a/extra/db2/statements/statements-tests.factor +++ b/extra/db2/statements/statements-tests.factor @@ -1,13 +1,38 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: tools.test db2.statements kernel ; +USING: tools.test db2.statements kernel db2 db2.tester +continuations db2.errors ; IN: db2.statements.tests { 1 0 } [ [ drop ] statement-each ] must-infer-as { 1 1 } [ [ ] statement-map ] must-infer-as -[ ] -[ - "insert into computer (name, os) values('rocky', 'mac');" + +: test-sql-command ( -- ) + [ "drop table computer;" sql-command ] ignore-errors + + [ ] [ + "create table computer(name varchar, os varchar);" + sql-command + ] unit-test -] unit-test + [ ] [ + "insert into computer (name, os) values('rocky', 'mac');" + sql-command + ] unit-test + + [ { { "rocky" "mac" } } ] + [ + "select name, os from computer;" sql-query + ] unit-test + + [ "insert into" sql-command ] + [ sql-syntax-error? ] must-fail-with + + [ "selectt" sql-query ] + [ sql-syntax-error? ] must-fail-with + + ; + +[ test-sql-command ] test-dbs + diff --git a/extra/db2/statements/statements.factor b/extra/db2/statements/statements.factor index 282fb7d5bf..006cda3532 100644 --- a/extra/db2/statements/statements.factor +++ b/extra/db2/statements/statements.factor @@ -1,10 +1,10 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: accessors continuations destructors fry kernel -sequences db2.result-sets db2.connections ; +sequences db2.result-sets db2.connections db2.errors ; IN: db2.statements -TUPLE: statement handle sql in out ; +TUPLE: statement handle sql in out type ; : new-statement ( sql in out class -- statement ) new @@ -13,12 +13,15 @@ TUPLE: statement handle sql in out ; swap >>sql ; HOOK: db-connection ( sql in out -- statement ) +GENERIC: statement>result-set* ( statement -- result-set ) GENERIC: execute-statement* ( statement type -- ) -GENERIC: statement>result-set ( statement -- result-set ) + +: statement>result-set ( statement -- result-set ) + [ statement>result-set* ] + [ dup sql-error? [ parse-sql-error ] when rethrow ] recover ; M: object execute-statement* ( statement type -- ) - drop '[ _ statement>result-set dispose ] - [ parse-db-error rethrow ] recover ; + drop statement>result-set dispose ; : execute-one-statement ( statement -- ) dup type>> execute-statement* ;