Merge branch 'master' of git://factorcode.org/git/factor into regexp

db4
Daniel Ehrenberg 2009-02-21 14:22:42 -06:00
commit 033e4321a8
11 changed files with 118 additions and 76 deletions

View File

@ -2,17 +2,17 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays assocs classes continuations destructors kernel math USING: arrays assocs classes continuations destructors kernel math
namespaces sequences classes.tuple words strings namespaces sequences classes.tuple words strings
tools.walker accessors combinators fry ; tools.walker accessors combinators fry db.errors ;
IN: db IN: db
<PRIVATE
TUPLE: db-connection TUPLE: db-connection
handle handle
insert-statements insert-statements
update-statements update-statements
delete-statements ; delete-statements ;
<PRIVATE
: new-db-connection ( class -- obj ) : new-db-connection ( class -- obj )
new new
H{ } clone >>insert-statements H{ } clone >>insert-statements
@ -23,6 +23,7 @@ PRIVATE>
GENERIC: db-open ( db -- db-connection ) GENERIC: db-open ( db -- db-connection )
HOOK: db-close db-connection ( handle -- ) HOOK: db-close db-connection ( handle -- )
HOOK: parse-db-error db-connection ( error -- error' )
: dispose-statements ( assoc -- ) values dispose-each ; : dispose-statements ( assoc -- ) values dispose-each ;
@ -77,7 +78,11 @@ GENERIC: bind-tuple ( tuple statement -- )
GENERIC: execute-statement* ( statement type -- ) GENERIC: execute-statement* ( statement type -- )
M: object execute-statement* ( statement type -- ) M: object execute-statement* ( statement type -- )
drop query-results dispose ; '[
_ _ drop query-results dispose
] [
parse-db-error rethrow
] recover ;
: execute-one-statement ( statement -- ) : execute-one-statement ( statement -- )
dup type>> execute-statement* ; dup type>> execute-statement* ;

View File

@ -8,3 +8,11 @@ ERROR: sql-error ;
ERROR: table-exists ; ERROR: table-exists ;
ERROR: bad-schema ; ERROR: bad-schema ;
ERROR: sql-syntax-error error ;
ERROR: sql-table-exists table ;
C: <sql-table-exists> sql-table-exists
ERROR: sql-table-missing table ;
C: <sql-table-missing> sql-table-missing

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1,4 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test db.errors.postgresql ;
IN: db.errors.postgresql.tests

View File

@ -0,0 +1,4 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: ;
IN: db.errors.postgresql

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -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 <sqlite-db> [
[
"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

View File

@ -0,0 +1,25 @@
! 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
ERROR: unparsed-sqlite-error error ;
SINGLETONS: table-exists table-missing ;
: sqlite-table-error ( table message -- error )
{
{ table-exists [ <sql-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 <sql-table-missing> ]]
;EBNF

View File

@ -3,7 +3,7 @@ prettyprint sequences namespaces tools.test db db.private
db.tuples db.types unicode.case accessors system ; db.tuples db.types unicode.case accessors system ;
IN: db.postgresql.tests IN: db.postgresql.tests
: test-db ( -- postgresql-db ) : postgresql-test-db ( -- postgresql-db )
<postgresql-db> <postgresql-db>
"localhost" >>host "localhost" >>host
"postgres" >>username "postgres" >>username
@ -11,10 +11,10 @@ IN: db.postgresql.tests
"factor-test" >>database ; "factor-test" >>database ;
os windows? cpu x86.64? and [ os windows? cpu x86.64? and [
[ ] [ test-db [ ] with-db ] unit-test [ ] [ postgresql-test-db [ ] with-db ] unit-test
[ ] [ [ ] [
test-db [ postgresql-test-db [
[ "drop table person;" sql-command ] ignore-errors [ "drop table person;" sql-command ] ignore-errors
"create table person (name varchar(30), country varchar(30));" "create table person (name varchar(30), country varchar(30));"
sql-command sql-command
@ -30,7 +30,7 @@ os windows? cpu x86.64? and [
{ "Jane" "New Zealand" } { "Jane" "New Zealand" }
} }
] [ ] [
test-db [ postgresql-test-db [
"select * from person" sql-query "select * from person" sql-query
] with-db ] with-db
] unit-test ] unit-test
@ -40,11 +40,11 @@ os windows? cpu x86.64? and [
{ "John" "America" } { "John" "America" }
{ "Jane" "New Zealand" } { "Jane" "New Zealand" }
} }
] [ test-db [ "select * from person" sql-query ] with-db ] unit-test ] [ postgresql-test-db [ "select * from person" sql-query ] with-db ] unit-test
[ [
] [ ] [
test-db [ postgresql-test-db [
"insert into person(name, country) values('Jimmy', 'Canada')" "insert into person(name, country) values('Jimmy', 'Canada')"
sql-command sql-command
] with-db ] with-db
@ -56,10 +56,10 @@ os windows? cpu x86.64? and [
{ "Jane" "New Zealand" } { "Jane" "New Zealand" }
{ "Jimmy" "Canada" } { "Jimmy" "Canada" }
} }
] [ test-db [ "select * from person" sql-query ] with-db ] unit-test ] [ postgresql-test-db [ "select * from person" sql-query ] with-db ] unit-test
[ [
test-db [ postgresql-test-db [
[ [
"insert into person(name, country) values('Jose', 'Mexico')" sql-command "insert into person(name, country) values('Jose', 'Mexico')" sql-command
"insert into person(name, country) values('Jose', 'Mexico')" sql-command "insert into person(name, country) values('Jose', 'Mexico')" sql-command
@ -69,14 +69,14 @@ os windows? cpu x86.64? and [
] must-fail ] must-fail
[ 3 ] [ [ 3 ] [
test-db [ postgresql-test-db [
"select * from person" sql-query length "select * from person" sql-query length
] with-db ] with-db
] unit-test ] unit-test
[ [
] [ ] [
test-db [ postgresql-test-db [
[ [
"insert into person(name, country) values('Jose', 'Mexico')" "insert into person(name, country) values('Jose', 'Mexico')"
sql-command sql-command
@ -87,7 +87,7 @@ os windows? cpu x86.64? and [
] unit-test ] unit-test
[ 5 ] [ [ 5 ] [
test-db [ postgresql-test-db [
"select * from person" sql-query length "select * from person" sql-query length
] with-db ] with-db
] unit-test ] unit-test

View File

@ -5,8 +5,8 @@ kernel math math.parser namespaces make prettyprint quotations
sequences debugger db db.postgresql.lib db.postgresql.ffi sequences debugger db db.postgresql.lib db.postgresql.ffi
db.tuples db.types tools.annotations math.ranges db.tuples db.types tools.annotations math.ranges
combinators classes locals words tools.walker db.private combinators classes locals words tools.walker db.private
nmake accessors random db.queries destructors db.tuples.private ; nmake accessors random db.queries destructors db.tuples.private
USE: tools.walker db.postgresql ;
IN: db.postgresql IN: db.postgresql
TUPLE: postgresql-db host port pgopts pgtty database username password ; TUPLE: postgresql-db host port pgopts pgtty database username password ;
@ -280,3 +280,6 @@ M: postgresql-db-connection compound ( string object -- string' )
{ "references" [ >reference-string ] } { "references" [ >reference-string ] }
[ drop no-compound-found ] [ drop no-compound-found ]
} case ; } case ;
M: postgresql-db-connection parse-db-error
;

View File

@ -6,7 +6,8 @@ sequences strings classes.tuple alien.c-types continuations
db.sqlite.lib db.sqlite.ffi db.tuples words db.types combinators db.sqlite.lib db.sqlite.ffi db.tuples words db.types combinators
math.intervals io nmake accessors vectors math.ranges random math.intervals io nmake accessors vectors math.ranges random
math.bitwise db.queries destructors db.tuples.private interpolate math.bitwise db.queries destructors db.tuples.private interpolate
io.streams.string multiline make db.private sequences.deep ; io.streams.string multiline make db.private sequences.deep
db.errors.sqlite ;
IN: db.sqlite IN: db.sqlite
TUPLE: sqlite-db path ; TUPLE: sqlite-db path ;
@ -223,13 +224,6 @@ M: sqlite-db-connection persistent-table ( -- assoc )
"> interpolate "> interpolate
] with-string-writer ; ] with-string-writer ;
: drop-insert-trigger ( -- string )
[
<"
DROP TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id;
"> interpolate
] with-string-writer ;
: update-trigger ( -- string ) : update-trigger ( -- string )
[ [
<" <"
@ -255,13 +249,6 @@ M: sqlite-db-connection persistent-table ( -- assoc )
"> interpolate "> interpolate
] with-string-writer ; ] with-string-writer ;
: drop-update-trigger ( -- string )
[
<"
DROP TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id;
"> interpolate
] with-string-writer ;
: delete-trigger-restrict ( -- string ) : delete-trigger-restrict ( -- string )
[ [
<" <"
@ -274,13 +261,6 @@ M: sqlite-db-connection persistent-table ( -- assoc )
"> interpolate "> interpolate
] with-string-writer ; ] with-string-writer ;
: drop-delete-trigger-restrict ( -- string )
[
<"
DROP TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id;
"> interpolate
] with-string-writer ;
: delete-trigger-cascade ( -- string ) : delete-trigger-cascade ( -- string )
[ [
<" <"
@ -292,13 +272,6 @@ M: sqlite-db-connection persistent-table ( -- assoc )
"> interpolate "> interpolate
] with-string-writer ; ] with-string-writer ;
: drop-delete-trigger-cascade ( -- string )
[
<"
DROP TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id;
"> interpolate
] with-string-writer ;
: can-be-null? ( -- ? ) : can-be-null? ( -- ? )
"sql-spec" get modifiers>> [ +not-null+ = ] any? not ; "sql-spec" get modifiers>> [ +not-null+ = ] any? not ;
@ -322,33 +295,22 @@ M: sqlite-db-connection persistent-table ( -- assoc )
delete-trigger-restrict sqlite-trigger, delete-trigger-restrict sqlite-trigger,
] if ; ] if ;
: drop-sqlite-triggers ( -- ) : create-db-triggers ( sql-specs -- )
drop-insert-trigger sqlite-trigger, [ modifiers>> [ +foreign-id+ = ] deep-any? ] filter
drop-update-trigger sqlite-trigger, [
delete-cascade? [ [ class>> db-table-name "db-table" set ]
drop-delete-trigger-cascade sqlite-trigger,
] [
drop-delete-trigger-restrict sqlite-trigger,
] if ;
: db-triggers ( sql-specs word -- )
'[
[ modifiers>> [ +foreign-id+ = ] deep-any? ] filter
[ [
[ class>> db-table-name "db-table" set ] [ "sql-spec" set ]
[ column-name>> "table-id" set ]
[ ] tri
modifiers>> [ [ +foreign-id+ = ] deep-any? ] filter
[ [
[ "sql-spec" set ] [ second db-table-name "foreign-table-name" set ]
[ column-name>> "table-id" set ] [ third "foreign-table-id" set ] bi
[ ] tri create-sqlite-triggers
modifiers>> [ [ +foreign-id+ = ] deep-any? ] filter ] each
[ ] bi
[ second db-table-name "foreign-table-name" set ] ] each ;
[ third "foreign-table-id" set ] bi
_ execute
] each
] bi
] each
] call ; inline
: sqlite-create-table ( sql-specs class-name -- ) : sqlite-create-table ( sql-specs class-name -- )
[ [
@ -373,15 +335,12 @@ M: sqlite-db-connection persistent-table ( -- assoc )
M: sqlite-db-connection create-sql-statement ( class -- statement ) M: sqlite-db-connection create-sql-statement ( class -- statement )
[ [
! specs name
[ sqlite-create-table ] [ sqlite-create-table ]
[ drop \ create-sqlite-triggers db-triggers ] 2bi [ drop create-db-triggers ] 2bi
] query-make ; ] query-make ;
M: sqlite-db-connection drop-sql-statement ( class -- statements ) M: sqlite-db-connection drop-sql-statement ( class -- statements )
[ [ nip "drop table " 0% 0% ";" 0% ] query-make ;
nip "drop table " 0% 0% ";" 0%
] query-make ;
M: sqlite-db-connection compound ( string seq -- new-string ) M: sqlite-db-connection compound ( string seq -- new-string )
over { over {
@ -389,3 +348,9 @@ M: sqlite-db-connection compound ( string seq -- new-string )
{ "references" [ >reference-string ] } { "references" [ >reference-string ] }
[ 2drop ] [ 2drop ]
} case ; } case ;
M: sqlite-db-connection parse-db-error
dup n>> {
{ 1 [ string>> parse-sqlite-sql-error ] }
[ drop ]
} case ;