parent
11c0a9ebcd
commit
16e6f36fc9
|
@ -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
|
||||||
|
|
|
@ -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%
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
Loading…
Reference in New Issue