refactor db

start on random-id
db4
Doug Coleman 2008-03-17 00:26:05 -05:00
parent 11c0a9ebcd
commit 16e6f36fc9
6 changed files with 79 additions and 34 deletions

View File

@ -33,6 +33,19 @@ HOOK: db-close db ( handle -- )
TUPLE: statement handle sql in-params out-params bind-params bound? ; TUPLE: statement handle sql in-params out-params bind-params bound? ;
TUPLE: simple-statement ; TUPLE: simple-statement ;
TUPLE: prepared-statement ; TUPLE: prepared-statement ;
TUPLE: nonthrowable-statement ;
: make-nonthrowable ( obj -- obj' )
dup sequence? [
[ make-nonthrowable ] map
] [
nonthrowable-statement construct-delegate
] if ;
MIXIN: throwable-statement
INSTANCE: statement throwable-statement
INSTANCE: simple-statement throwable-statement
INSTANCE: prepared-statement throwable-statement
TUPLE: result-set sql in-params out-params handle n max ; TUPLE: result-set sql in-params out-params handle n max ;
: <statement> ( sql in out -- statement ) : <statement> ( sql in out -- statement )
{ (>>sql) (>>in-params) (>>out-params) } statement construct ; { (>>sql) (>>in-params) (>>out-params) } statement construct ;
@ -50,13 +63,22 @@ GENERIC# row-column-typed 1 ( result-set column -- sql )
GENERIC: advance-row ( result-set -- ) GENERIC: advance-row ( result-set -- )
GENERIC: more-rows? ( result-set -- ? ) GENERIC: more-rows? ( result-set -- ? )
: execute-statement ( statement -- ) GENERIC: execute-statement ( statement -- )
M: throwable-statement execute-statement ( statement -- )
dup sequence? [ dup sequence? [
[ execute-statement ] each [ execute-statement ] each
] [ ] [
query-results dispose query-results dispose
] if ; ] if ;
M: nonthrowable-statement execute-statement ( statement -- )
dup sequence? [
[ execute-statement ] each
] [
[ query-results dispose ] [ 2drop ] recover
] if ;
: bind-statement ( obj statement -- ) : bind-statement ( obj statement -- )
swap >>bind-params swap >>bind-params
[ bind-statement* ] keep [ bind-statement* ] keep

View File

@ -10,6 +10,7 @@ IN: db.postgresql
TUPLE: postgresql-db host port pgopts pgtty db user pass ; TUPLE: postgresql-db host port pgopts pgtty db user pass ;
TUPLE: postgresql-statement ; TUPLE: postgresql-statement ;
INSTANCE: postgresql-statement throwable-statement
TUPLE: postgresql-result-set ; TUPLE: postgresql-result-set ;
: <postgresql-statement> ( statement in out -- postgresql-statement ) : <postgresql-statement> ( statement in out -- postgresql-statement )
<statement> <statement>
@ -194,7 +195,7 @@ M: postgresql-db <insert-native-statement> ( class -- statement )
");" 0% ");" 0%
] postgresql-make ; ] postgresql-make ;
M: postgresql-db <insert-assigned-statement> ( class -- statement ) M: postgresql-db <insert-nonnative-statement> ( class -- statement )
[ [
"insert into " 0% 0% "insert into " 0% 0%
"(" 0% "(" 0%

View File

@ -6,6 +6,7 @@ prettyprint sequences strings tuples alien.c-types
continuations db.sqlite.lib db.sqlite.ffi db.tuples continuations db.sqlite.lib db.sqlite.ffi db.tuples
words combinators.lib db.types combinators words combinators.lib db.types combinators
combinators.cleave io namespaces.lib ; combinators.cleave io namespaces.lib ;
USE: tools.walker
IN: db.sqlite IN: db.sqlite
TUPLE: sqlite-db path ; TUPLE: sqlite-db path ;
@ -22,6 +23,8 @@ M: sqlite-db dispose ( db -- ) dispose-db ;
: with-sqlite ( path quot -- ) sqlite-db swap with-db ; inline : with-sqlite ( path quot -- ) sqlite-db swap with-db ; inline
TUPLE: sqlite-statement ; TUPLE: sqlite-statement ;
INSTANCE: sqlite-statement throwable-statement
TUPLE: sqlite-result-set has-more? ; TUPLE: sqlite-result-set has-more? ;
M: sqlite-db <simple-statement> ( str in out -- obj ) M: sqlite-db <simple-statement> ( str in out -- obj )
@ -33,13 +36,20 @@ M: sqlite-db <prepared-statement> ( str in out -- obj )
set-statement-in-params set-statement-in-params
set-statement-out-params set-statement-out-params
} statement construct } statement construct
db get db-handle over statement-sql sqlite-prepare
over set-statement-handle
sqlite-statement construct-delegate ; sqlite-statement construct-delegate ;
: sqlite-maybe-prepare ( statement -- statement )
dup statement-handle [
[
delegate
db get db-handle over statement-sql sqlite-prepare
swap set-statement-handle
] keep
] unless ;
M: sqlite-statement dispose ( statement -- ) M: sqlite-statement dispose ( statement -- )
statement-handle statement-handle
[ sqlite3_reset drop ] keep sqlite-finalize ; [ [ sqlite3_reset drop ] keep sqlite-finalize ] when* ;
M: sqlite-result-set dispose ( result-set -- ) M: sqlite-result-set dispose ( result-set -- )
f swap set-result-set-handle ; f swap set-result-set-handle ;
@ -47,9 +57,12 @@ M: sqlite-result-set dispose ( result-set -- )
: sqlite-bind ( triples handle -- ) : sqlite-bind ( triples handle -- )
swap [ first3 sqlite-bind-type ] with each ; swap [ first3 sqlite-bind-type ] with each ;
: reset-statement ( statement -- ) statement-handle sqlite-reset ; : reset-statement ( statement -- )
sqlite-maybe-prepare
statement-handle sqlite-reset ;
M: sqlite-statement bind-statement* ( statement -- ) M: sqlite-statement bind-statement* ( statement -- )
sqlite-maybe-prepare
dup statement-bound? [ dup reset-statement ] when dup statement-bound? [ dup reset-statement ] when
[ statement-bind-params ] [ statement-handle ] bi [ statement-bind-params ] [ statement-handle ] bi
sqlite-bind ; sqlite-bind ;
@ -90,6 +103,7 @@ M: sqlite-result-set more-rows? ( result-set -- ? )
sqlite-result-set-has-more? ; sqlite-result-set-has-more? ;
M: sqlite-statement query-results ( query -- result-set ) M: sqlite-statement query-results ( query -- result-set )
sqlite-maybe-prepare
dup statement-handle sqlite-result-set <result-set> dup statement-handle sqlite-result-set <result-set>
dup advance-row ; dup advance-row ;
@ -126,7 +140,7 @@ M: sqlite-db <insert-native-statement> ( tuple -- statement )
");" 0% ");" 0%
] sqlite-make ; ] sqlite-make ;
M: sqlite-db <insert-assigned-statement> ( tuple -- statement ) M: sqlite-db <insert-nonnative-statement> ( tuple -- statement )
<insert-native-statement> ; <insert-native-statement> ;
: where-primary-key% ( specs -- ) : where-primary-key% ( specs -- )
@ -176,6 +190,7 @@ M: sqlite-db modifier-table ( -- hashtable )
H{ H{
{ +native-id+ "primary key" } { +native-id+ "primary key" }
{ +assigned-id+ "primary key" } { +assigned-id+ "primary key" }
! { +nonnative-id+ "primary key" }
{ +autoincrement+ "autoincrement" } { +autoincrement+ "autoincrement" }
{ +unique+ "unique" } { +unique+ "unique" }
{ +default+ "default" } { +default+ "default" }

View File

@ -9,7 +9,7 @@ IN: db.tuples.tests
TUPLE: person the-id the-name the-number the-real TUPLE: person the-id the-name the-number the-real
ts date time blob factor-blob ; ts date time blob factor-blob ;
: <person> ( name age real ts date time blob -- person ) : <person> ( name age real ts date time blob factor-blob -- person )
{ {
set-person-the-name set-person-the-name
set-person-the-number set-person-the-number
@ -190,18 +190,16 @@ TUPLE: annotation n paste-id summary author mode contents ;
: test-postgresql ( -- ) : test-postgresql ( -- )
>r { "localhost" "postgres" "foob" "factor-test" } postgresql-db r> with-db ; >r { "localhost" "postgres" "foob" "factor-test" } postgresql-db r> with-db ;
[ native-person-schema test-tuples ] test-sqlite
[ assigned-person-schema test-tuples ] test-sqlite
: test-repeated-insert : test-repeated-insert
[ ] [ person ensure-table ] unit-test [ ] [ person ensure-table ] unit-test
[ ] [ person1 get insert-tuple ] unit-test [ ] [ person1 get insert-tuple ] unit-test
[ person1 get insert-tuple ] must-fail ; [ person1 get insert-tuple ] must-fail ;
[ native-person-schema test-tuples ] test-sqlite
[ assigned-person-schema test-tuples ] test-sqlite
[ native-person-schema test-tuples ] test-postgresql [ native-person-schema test-tuples ] test-postgresql
[ assigned-person-schema test-tuples ] test-postgresql [ assigned-person-schema test-tuples ] test-postgresql
[ assigned-person-schema test-repeated-insert ] test-sqlite [ assigned-person-schema test-repeated-insert ] test-sqlite
[ assigned-person-schema test-repeated-insert ] test-postgresql [ assigned-person-schema test-repeated-insert ] test-postgresql

View File

@ -28,7 +28,7 @@ HOOK: create-sql-statement db ( class -- obj )
HOOK: drop-sql-statement db ( class -- obj ) HOOK: drop-sql-statement db ( class -- obj )
HOOK: <insert-native-statement> db ( class -- obj ) HOOK: <insert-native-statement> db ( class -- obj )
HOOK: <insert-assigned-statement> db ( class -- obj ) HOOK: <insert-nonnative-statement> db ( class -- obj )
HOOK: <update-tuple-statement> db ( class -- obj ) HOOK: <update-tuple-statement> db ( class -- obj )
HOOK: <update-tuples-statement> db ( class -- obj ) HOOK: <update-tuples-statement> db ( class -- obj )
@ -75,21 +75,25 @@ HOOK: insert-tuple* db ( tuple statement -- )
drop-sql-statement [ execute-statement ] with-disposals ; drop-sql-statement [ execute-statement ] with-disposals ;
: ensure-table ( class -- ) : ensure-table ( class -- )
[ dup drop-table ] ignore-errors create-table ; [
drop-sql-statement make-nonthrowable
[ execute-statement ] with-disposals
] [ create-table ] bi ;
: insert-native ( tuple -- ) : insert-native ( tuple -- )
dup class dup class
db get db-insert-statements [ <insert-native-statement> ] cache db get db-insert-statements [ <insert-native-statement> ] cache
[ bind-tuple ] 2keep insert-tuple* ; [ bind-tuple ] 2keep insert-tuple* ;
: insert-assigned ( tuple -- ) : insert-nonnative ( tuple -- )
! TODO logic here for unique ids
dup class dup class
db get db-insert-statements [ <insert-assigned-statement> ] cache db get db-insert-statements [ <insert-nonnative-statement> ] cache
[ bind-tuple ] keep execute-statement ; [ bind-tuple ] keep execute-statement ;
: insert-tuple ( tuple -- ) : insert-tuple ( tuple -- )
dup class db-columns find-primary-key assigned-id? [ dup class db-columns find-primary-key nonnative-id? [
insert-assigned insert-nonnative
] [ ] [
insert-native insert-native
] if ; ] if ;

View File

@ -3,7 +3,8 @@
USING: arrays assocs db kernel math math.parser USING: arrays assocs db kernel math math.parser
sequences continuations sequences.deep sequences.lib sequences continuations sequences.deep sequences.lib
words namespaces tools.walker slots slots.private classes words namespaces tools.walker slots slots.private classes
mirrors tuples combinators calendar.format symbols ; mirrors tuples combinators calendar.format symbols
singleton ;
IN: db.types IN: db.types
HOOK: modifier-table db ( -- hash ) HOOK: modifier-table db ( -- hash )
@ -14,22 +15,32 @@ HOOK: compound-type db ( str n -- hash )
TUPLE: sql-spec class slot-name column-name type modifiers primary-key ; TUPLE: sql-spec class slot-name column-name type modifiers primary-key ;
SYMBOLS: +native-id+ +assigned-id+ +autoincrement+
+serial+ +unique+ +default+ +null+ +not-null+ SINGLETON: +native-id+
SINGLETON: +assigned-id+
SINGLETON: +random-id+
UNION: +primary-key+ +native-id+ +assigned-id+ +random-id+ ;
UNION: +nonnative-id+ +random-id+ +assigned-id+ ;
! +native-id+ +assigned-id+ +random-assigned-id+
SYMBOLS: +autoincrement+ +serial+ +unique+ +default+ +null+ +not-null+
+foreign-id+ +has-many+ ; +foreign-id+ +has-many+ ;
: (primary-key?) ( obj -- ? )
{ +native-id+ +assigned-id+ } member? ;
: primary-key? ( spec -- ? ) : primary-key? ( spec -- ? )
sql-spec-primary-key (primary-key?) ; sql-spec-primary-key +primary-key+? ;
: native-id? ( spec -- ? )
sql-spec-primary-key +native-id+? ;
: nonnative-id? ( spec -- ? )
sql-spec-primary-key +nonnative-id+? ;
: normalize-spec ( spec -- ) : normalize-spec ( spec -- )
dup sql-spec-type dup (primary-key?) [ dup sql-spec-type dup +primary-key+? [
swap set-sql-spec-primary-key swap set-sql-spec-primary-key
] [ ] [
drop dup sql-spec-modifiers [ drop dup sql-spec-modifiers [
(primary-key?) +primary-key+?
] deep-find ] deep-find
[ swap set-sql-spec-primary-key ] [ drop ] if* [ swap set-sql-spec-primary-key ] [ drop ] if*
] if ; ] if ;
@ -37,12 +48,6 @@ SYMBOLS: +native-id+ +assigned-id+ +autoincrement+
: find-primary-key ( specs -- obj ) : find-primary-key ( specs -- obj )
[ sql-spec-primary-key ] find nip ; [ sql-spec-primary-key ] find nip ;
: native-id? ( spec -- ? )
sql-spec-primary-key +native-id+ = ;
: assigned-id? ( spec -- ? )
sql-spec-primary-key +assigned-id+ = ;
: relation? ( spec -- ? ) [ +has-many+ = ] deep-find ; : relation? ( spec -- ? ) [ +has-many+ = ] deep-find ;
SYMBOLS: INTEGER BIG-INTEGER DOUBLE REAL BOOLEAN TEXT VARCHAR SYMBOLS: INTEGER BIG-INTEGER DOUBLE REAL BOOLEAN TEXT VARCHAR
@ -69,7 +74,7 @@ TUPLE: no-sql-modifier ;
dup number? [ number>string ] when ; dup number? [ number>string ] when ;
: maybe-remove-id ( specs -- obj ) : maybe-remove-id ( specs -- obj )
[ native-id? not ] subset ; [ +native-id+? not ] subset ;
: remove-relations ( specs -- newcolumns ) : remove-relations ( specs -- newcolumns )
[ relation? not ] subset ; [ relation? not ] subset ;