From 86667aee238c9e710ffad94dbd1393474d9ff627 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 14 Feb 2008 01:27:54 -0600 Subject: [PATCH 01/11] execute-statement is now a word not a generic sqlite works for tuple-tests postgresql create/drop/insert works better now --- extra/db/db.factor | 22 ++- extra/db/postgresql/lib/lib.factor | 11 +- extra/db/postgresql/postgresql-tests.factor | 6 +- extra/db/postgresql/postgresql.factor | 141 ++++++++++++++------ extra/db/sqlite/lib/lib.factor | 3 +- extra/db/sqlite/sqlite.factor | 9 +- extra/db/tuples/tuples-tests.factor | 12 +- extra/db/tuples/tuples.factor | 6 +- extra/db/types/types.factor | 1 + 9 files changed, 130 insertions(+), 81 deletions(-) diff --git a/extra/db/db.factor b/extra/db/db.factor index 46b257ce7a..365f0c009c 100755 --- a/extra/db/db.factor +++ b/extra/db/db.factor @@ -36,13 +36,17 @@ HOOK: db ( str -- statement ) GENERIC: prepare-statement ( statement -- ) GENERIC: bind-statement* ( obj statement -- ) GENERIC: reset-statement ( statement -- ) -GENERIC: execute-statement* ( statement -- result-set ) +GENERIC: insert-statement ( statement -- id ) HOOK: last-id db ( res -- id ) -: execute-statement ( statement -- ) - execute-statement* dispose ; -: execute-statement-last-id ( statement -- id ) - execute-statement* [ last-id ] with-disposal ; +TUPLE: result-set sql params handle n max ; +GENERIC: query-results ( query -- result-set ) +GENERIC: #rows ( result-set -- n ) +GENERIC: #columns ( result-set -- n ) +GENERIC# row-column 1 ( result-set n -- obj ) +GENERIC: advance-row ( result-set -- ? ) + +: execute-statement ( statement -- ) query-results dispose ; : bind-statement ( obj statement -- ) dup statement-bound? [ dup reset-statement ] when @@ -50,14 +54,6 @@ HOOK: last-id db ( res -- id ) [ set-statement-params ] keep t swap set-statement-bound? ; -TUPLE: result-set sql params handle n max ; - -GENERIC: query-results ( query -- result-set ) -GENERIC: #rows ( result-set -- n ) -GENERIC: #columns ( result-set -- n ) -GENERIC# row-column 1 ( result-set n -- obj ) -GENERIC: advance-row ( result-set -- ? ) - : init-result-set ( result-set -- ) dup #rows over set-result-set-max -1 swap set-result-set-n ; diff --git a/extra/db/postgresql/lib/lib.factor b/extra/db/postgresql/lib/lib.factor index d8381ca83a..c48eff964a 100644 --- a/extra/db/postgresql/lib/lib.factor +++ b/extra/db/postgresql/lib/lib.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: arrays continuations db io kernel math namespaces -quotations sequences db.postgresql.ffi alien alien.c-types ; +quotations sequences db.postgresql.ffi alien alien.c-types +db.types ; IN: db.postgresql.lib : postgresql-result-error-message ( res -- str/f ) @@ -37,13 +38,9 @@ IN: db.postgresql.lib >r db get db-handle r> [ statement-sql ] keep [ statement-params length f ] keep - statement-params [ second malloc-char-string ] map >c-void*-array + statement-params + [ first number>string* malloc-char-string ] map >c-void*-array f f 0 PQexecParams dup postgresql-result-ok? [ dup postgresql-result-error-message swap PQclear throw ] unless ; - -: pq-oid-value ( res -- n ) - PQoidValue dup InvalidOid = [ - "postgresql returned an InvalidOid" throw - ] when ; diff --git a/extra/db/postgresql/postgresql-tests.factor b/extra/db/postgresql/postgresql-tests.factor index 8c6791c767..36b6fc829b 100644 --- a/extra/db/postgresql/postgresql-tests.factor +++ b/extra/db/postgresql/postgresql-tests.factor @@ -2,7 +2,7 @@ ! Set username and password in the 'connect' word. USING: kernel db.postgresql alien continuations io prettyprint -sequences namespaces tools.test db ; +sequences namespaces tools.test db db.types ; IN: temporary IN: scratchpad @@ -40,13 +40,13 @@ IN: temporary test-db [ "select * from person where name = $1 and country = $2" [ - { "Jane" "New Zealand" } + { { "Jane" TEXT } { "New Zealand" TEXT } } over do-bound-query { { "Jane" "New Zealand" } } = [ "test fails" throw ] unless - { "John" "America" } + { { "John" TEXT } { "America" TEXT } } swap do-bound-query ] with-disposal ] with-db diff --git a/extra/db/postgresql/postgresql.factor b/extra/db/postgresql/postgresql.factor index dac4d78b78..93c66708b4 100755 --- a/extra/db/postgresql/postgresql.factor +++ b/extra/db/postgresql/postgresql.factor @@ -3,7 +3,7 @@ USING: arrays assocs alien alien.syntax continuations io kernel math math.parser namespaces prettyprint quotations sequences debugger db db.postgresql.lib db.postgresql.ffi -db.tuples db.types ; +db.tuples db.types tools.annotations ; IN: db.postgresql TUPLE: postgresql-db host port pgopts pgtty db user pass ; @@ -52,8 +52,11 @@ M: postgresql-result-set #columns ( result-set -- n ) M: postgresql-result-set row-column ( result-set n -- obj ) >r dup result-set-handle swap result-set-n r> PQgetvalue ; -M: postgresql-statement execute-statement* ( statement -- obj ) - query-results ; +M: postgresql-statement execute-statement ( statement -- obj ) + query-results dispose ; + +M: postgresql-statement insert-statement ( statement -- id ) + query-results dispose ; : increment-n ( result-set -- n ) dup result-set-n 1+ dup rot set-result-set-n ; @@ -105,72 +108,137 @@ M: postgresql-db commit-transaction ( -- ) M: postgresql-db rollback-transaction ( -- ) "ROLLBACK" sql-command ; +SYMBOL: postgresql-counter + +: make-postgresql-counter ( quot -- ) + [ postgresql-counter off ] swap compose "" make ; + +: counter% ( -- ) + CHAR: $ , + postgresql-counter [ inc ] keep get # ; + +: postgresql-type-hash* ( -- assoc ) + H{ + { SERIAL "serial" } + } ; + +: postgresql-type-hash ( -- assoc ) + H{ + { INTEGER "integer" } + { SERIAL "integer" } + { TEXT "text" } + { VARCHAR "varchar" } + { DOUBLE "real" } + } ; + +: enquote ( str -- newstr ) "(" swap ")" 3append ; + +: postgresql-type ( str n/str -- newstr ) + " " swap number>string* enquote 3append ; + +: >sql-type* ( obj -- str ) + dup pair? [ + first2 >r >sql-type* r> postgresql-type + ] [ + dup postgresql-type-hash* at* [ + nip + ] [ + drop >sql-type + ] if + ] if ; + +M: postgresql-db >sql-type ( hash obj -- str ) + dup pair? [ + first2 >r >sql-type r> postgresql-type + ] [ + postgresql-type-hash at* [ + no-sql-type + ] unless + ] if ; M: postgresql-db create-sql ( columns table -- sql ) [ + 2dup "create table " % % " (" % [ ", " % ] [ dup second % " " % - dup third >sql-type % " " % + dup third >sql-type* % " " % sql-modifiers " " join % - ] interleave ")" % - ] "" make ; + ] interleave "); " % -M: postgresql-db drop-sql ( table -- sql ) - [ - "drop table " % % - ] "" make ; + "create function add_" % dup % + "(" % + over [ "," % ] + [ third dup array? [ first ] when >sql-type % ] interleave + ")" % + " returns bigint as '" % -SYMBOL: postgresql-counter - -M: postgresql-db insert-sql* ( columns table -- sql ) - [ - postgresql-counter off - "insert into " % + 2dup "insert into " % % "(" % dup [ ", " % ] [ second % ] interleave ") " % " values (" % - [ ", " % ] [ - drop "$" % postgresql-counter [ inc ] keep get # - ] interleave + [ ", " % ] [ drop counter% ] interleave + "); " % + + "select currval(''" % % "_id_seq'');' language sql;" % + drop + ] make-postgresql-counter dup . ; + +M: postgresql-db drop-sql ( columns table -- sql ) + [ + dup "drop table " % % + "; drop function add_" % % + "(" % + [ "," % ] [ third >sql-type % ] interleave ")" % + ] "" make ; +! \ create-sql reset +! \ create-sql watch + +M: postgresql-db insert-sql* ( columns table -- sql ) + [ + "select add_" % % + "(" % + [ ", " % ] [ counter% ] interleave + ")" % + ] make-postgresql-counter ; + M: postgresql-db update-sql* ( columns table -- sql ) [ "update " % % " set " % dup remove-id - [ ", " % ] [ second dup % " = :" % % ] interleave + [ ", " % ] [ second % " = " % counter% ] interleave " where " % - [ primary-key? ] find nip second dup % " = :" % % - ] "" make ; + [ primary-key? ] find nip second dup % " = " % counter% + ] make-postgresql-counter ; M: postgresql-db delete-sql* ( columns table -- sql ) [ "delete from " % % " where " % - first second dup % " = :" % % - ] "" make ; + first second dup % " = " % counter% + ] make-postgresql-counter ; M: postgresql-db select-sql* ( columns table -- sql ) drop ; M: postgresql-db tuple>params ( columns tuple -- obj ) - [ - >r dup first r> get-slot-named swap third - ] curry { } map>assoc ; + [ >r dup third swap first r> get-slot-named swap ] + curry { } map>assoc ; M: postgresql-db last-id ( res -- id ) - pq-oid-value ; + drop f ; : postgresql-db-modifiers ( -- hashtable ) H{ - { +native-id+ "primary key" } + { +native-id+ "not null primary key" } { +assigned-id+ "primary key" } { +autoincrement+ "autoincrement" } { +unique+ "unique" } @@ -189,18 +257,3 @@ M: postgresql-db sql-modifiers* ( modifiers -- str ) swap at ] if ] with map [ ] subset ; - -: postgresql-type-hash ( -- assoc ) - H{ - { INTEGER "integer" } - { TEXT "text" } - { VARCHAR "text" } - { DOUBLE "real" } - } ; - -M: postgresql-db >sql-type ( obj -- str ) - dup pair? [ - first >sql-type - ] [ - postgresql-type-hash at* [ T{ no-sql-type } throw ] unless - ] if ; diff --git a/extra/db/sqlite/lib/lib.factor b/extra/db/sqlite/lib/lib.factor index e97dcf80c9..2c0f2ae130 100755 --- a/extra/db/sqlite/lib/lib.factor +++ b/extra/db/sqlite/lib/lib.factor @@ -74,10 +74,11 @@ IN: db.sqlite.lib dup array? [ first ] when { { INTEGER [ sqlite-bind-int-by-name ] } - { BIG_INTEGER [ sqlite-bind-int-by-name ] } + { BIG_INTEGER [ sqlite-bind-int64-by-name ] } { TEXT [ sqlite-bind-text-by-name ] } { VARCHAR [ sqlite-bind-text-by-name ] } { DOUBLE [ sqlite-bind-double-by-name ] } + { SERIAL [ sqlite-bind-int-by-name ] } ! { NULL [ sqlite-bind-null-by-name ] } [ no-sql-type ] } case ; diff --git a/extra/db/sqlite/sqlite.factor b/extra/db/sqlite/sqlite.factor index f58c669681..d83642bd8c 100755 --- a/extra/db/sqlite/sqlite.factor +++ b/extra/db/sqlite/sqlite.factor @@ -58,8 +58,8 @@ M: sqlite-statement bind-statement* ( triples statement -- ) M: sqlite-statement reset-statement ( statement -- ) statement-handle sqlite-reset ; -M: sqlite-statement execute-statement* ( statement -- obj ) - query-results ; +M: sqlite-statement insert-statement ( statement -- id ) + query-results [ last-id ] with-disposal ; M: sqlite-result-set #columns ( result-set -- n ) result-set-handle sqlite-#columns ; @@ -93,9 +93,10 @@ M: sqlite-db create-sql ( columns table -- sql ) ] interleave ")" % ] "" make ; -M: sqlite-db drop-sql ( table -- sql ) +M: sqlite-db drop-sql ( columns table -- sql ) [ "drop table " % % + drop ] "" make ; M: sqlite-db insert-sql* ( columns table -- sql ) @@ -175,6 +176,7 @@ M: sqlite-db sql-modifiers* ( modifiers -- str ) : sqlite-type-hash ( -- assoc ) H{ { INTEGER "integer" } + { SERIAL "integer" } { TEXT "text" } { VARCHAR "text" } { DOUBLE "real" } @@ -190,4 +192,3 @@ M: sqlite-db >sql-type ( obj -- str ) ! HOOK: get-column-value ( n result-set type -- ) ! M: sqlite get-column-value { { "TEXT" get-text-column } { ! "INTEGER" get-integer-column } ... } case ; - diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index 6945ccc722..cb4129965c 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: io.files kernel tools.test db db.sqlite db.tuples -db.types continuations namespaces db.postgresql math -tools.time ; +db.types continuations namespaces db.postgresql math ; +! tools.time ; IN: temporary TUPLE: person the-id the-name the-number real ; @@ -44,7 +44,7 @@ SYMBOL: the-person person "PERSON" { - { "the-id" "ROWID" INTEGER +native-id+ } + { "the-id" "ID" SERIAL +native-id+ } { "the-name" "NAME" { VARCHAR 256 } +not-null+ } { "the-number" "AGE" INTEGER { +default+ 0 } } { "real" "REAL" DOUBLE { +default+ 0.3 } } @@ -52,12 +52,12 @@ person "PERSON" "billy" 10 3.14 the-person set -test-sqlite + test-sqlite ! test-postgresql person "PERSON" { - { "the-id" "ROWID" INTEGER +assigned-id+ } + { "the-id" "ID" INTEGER +assigned-id+ } { "the-name" "NAME" { VARCHAR 256 } +not-null+ } { "the-number" "AGE" INTEGER { +default+ 0 } } { "real" "REAL" DOUBLE { +default+ 0.3 } } @@ -65,5 +65,5 @@ person "PERSON" 1 "billy" 20 6.28 the-person set -test-sqlite + test-sqlite ! test-postgresql diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index 783001f3f8..1697de83d3 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -39,7 +39,7 @@ TUPLE: no-slot-named ; [ ] 3compose cache nip ; inline HOOK: create-sql db ( columns table -- sql ) -HOOK: drop-sql db ( table -- sql ) +HOOK: drop-sql db ( columns table -- sql ) HOOK: insert-sql* db ( columns table -- sql ) HOOK: update-sql* db ( columns table -- sql ) HOOK: delete-sql* db ( columns table -- sql ) @@ -75,12 +75,12 @@ HOOK: tuple>params db ( columns tuple -- obj ) dup db-columns swap db-table create-sql sql-command ; : drop-table ( class -- ) - db-table drop-sql sql-command ; + dup db-columns swap db-table drop-sql sql-command ; : insert-tuple ( tuple -- ) [ [ maybe-remove-id ] [ insert-sql ] - make-tuple-statement execute-statement-last-id + make-tuple-statement insert-statement ] keep set-primary-key ; : update-tuple ( tuple -- ) diff --git a/extra/db/types/types.factor b/extra/db/types/types.factor index b8c82524a8..30c15682fa 100755 --- a/extra/db/types/types.factor +++ b/extra/db/types/types.factor @@ -22,6 +22,7 @@ SYMBOL: +not-null+ SYMBOL: +has-many+ +SYMBOL: SERIAL SYMBOL: INTEGER SYMBOL: DOUBLE SYMBOL: BOOLEAN From def53a07d8ab0882e91dddb7ebd4615249ae7737 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 14 Feb 2008 23:39:20 -0600 Subject: [PATCH 02/11] lose the bad codez in sqlite change the db api to more-rows? and advance-row instead of just advance-row sql-command takes a string or a seq of strings postgresql create-sql handles native/assigned ids --- extra/db/db.factor | 29 +++++---- extra/db/postgresql/postgresql.factor | 87 ++++++++++++++------------- extra/db/sqlite/lib/lib.factor | 8 +-- extra/db/sqlite/sqlite.factor | 31 ++++------ extra/db/tuples/tuples-tests.factor | 9 +-- extra/db/tuples/tuples.factor | 5 +- extra/db/types/types.factor | 6 ++ 7 files changed, 92 insertions(+), 83 deletions(-) diff --git a/extra/db/db.factor b/extra/db/db.factor index 365f0c009c..3595558dec 100755 --- a/extra/db/db.factor +++ b/extra/db/db.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: arrays assocs classes continuations kernel math -namespaces sequences sequences.lib tuples words ; +namespaces sequences sequences.lib tuples words strings ; IN: db TUPLE: db handle insert-statements update-statements delete-statements select-statements ; @@ -37,14 +37,14 @@ GENERIC: prepare-statement ( statement -- ) GENERIC: bind-statement* ( obj statement -- ) GENERIC: reset-statement ( statement -- ) GENERIC: insert-statement ( statement -- id ) -HOOK: last-id db ( res -- id ) TUPLE: result-set sql params handle n max ; GENERIC: query-results ( query -- result-set ) GENERIC: #rows ( result-set -- n ) GENERIC: #columns ( result-set -- n ) GENERIC# row-column 1 ( result-set n -- obj ) -GENERIC: advance-row ( result-set -- ? ) +GENERIC: advance-row ( result-set -- ) +GENERIC: more-rows? ( result-set -- ? ) : execute-statement ( statement -- ) query-results dispose ; @@ -56,7 +56,7 @@ GENERIC: advance-row ( result-set -- ? ) : init-result-set ( result-set -- ) dup #rows over set-result-set-max - -1 swap set-result-set-n ; + 0 swap set-result-set-n ; : ( query handle tuple -- result-set ) >r >r { statement-sql statement-params } get-slots r> @@ -70,10 +70,10 @@ GENERIC: advance-row ( result-set -- ? ) dup #columns [ row-column ] with map ; : query-each ( statement quot -- ) - over advance-row [ - 2drop + over more-rows? [ + [ call ] 2keep over advance-row query-each ] [ - [ call ] 2keep query-each + 2drop ] if ; inline : query-map ( statement quot -- seq ) @@ -94,11 +94,6 @@ GENERIC: advance-row ( result-set -- ? ) : do-bound-command ( obj query -- ) [ bind-statement ] keep execute-statement ; -: sql-query ( sql -- rows ) - [ do-query ] with-disposal ; - -: sql-command ( sql -- ) - [ execute-statement ] with-disposal ; SYMBOL: in-transaction HOOK: begin-transaction db ( -- ) @@ -112,3 +107,13 @@ HOOK: rollback-transaction db ( -- ) begin-transaction [ ] [ rollback-transaction ] cleanup commit-transaction ] with-variable ; + +: sql-query ( sql -- rows ) + [ do-query ] with-disposal ; + +: sql-command ( sql -- ) + dup string? [ + [ execute-statement ] with-disposal + ] [ + [ [ sql-command ] each ] with-transaction + ] if ; diff --git a/extra/db/postgresql/postgresql.factor b/extra/db/postgresql/postgresql.factor index 93c66708b4..f198a5c04c 100755 --- a/extra/db/postgresql/postgresql.factor +++ b/extra/db/postgresql/postgresql.factor @@ -3,7 +3,7 @@ USING: arrays assocs alien alien.syntax continuations io kernel math math.parser namespaces prettyprint quotations sequences debugger db db.postgresql.lib db.postgresql.ffi -db.tuples db.types tools.annotations ; +db.tuples db.types tools.annotations math.ranges ; IN: db.postgresql TUPLE: postgresql-db host port pgopts pgtty db user pass ; @@ -52,14 +52,8 @@ M: postgresql-result-set #columns ( result-set -- n ) M: postgresql-result-set row-column ( result-set n -- obj ) >r dup result-set-handle swap result-set-n r> PQgetvalue ; -M: postgresql-statement execute-statement ( statement -- obj ) - query-results dispose ; - M: postgresql-statement insert-statement ( statement -- id ) - query-results dispose ; - -: increment-n ( result-set -- n ) - dup result-set-n 1+ dup rot set-result-set-n ; + query-results [ break 0 row-column ] with-disposal ; M: postgresql-statement query-results ( query -- result-set ) dup statement-params [ @@ -71,8 +65,11 @@ M: postgresql-statement query-results ( query -- result-set ) postgresql-result-set dup init-result-set ; -M: postgresql-result-set advance-row ( result-set -- ? ) - dup increment-n swap result-set-max >= ; +M: postgresql-result-set advance-row ( result-set -- ) + dup result-set-n 1+ swap set-result-set-n ; + +M: postgresql-result-set more-rows? ( result-set -- ? ) + dup result-set-n swap result-set-max < ; M: postgresql-statement dispose ( query -- ) dup statement-handle PQclear @@ -108,15 +105,6 @@ M: postgresql-db commit-transaction ( -- ) M: postgresql-db rollback-transaction ( -- ) "ROLLBACK" sql-command ; -SYMBOL: postgresql-counter - -: make-postgresql-counter ( quot -- ) - [ postgresql-counter off ] swap compose "" make ; - -: counter% ( -- ) - CHAR: $ , - postgresql-counter [ inc ] keep get # ; - : postgresql-type-hash* ( -- assoc ) H{ { SERIAL "serial" } @@ -156,16 +144,9 @@ M: postgresql-db >sql-type ( hash obj -- str ) ] unless ] if ; -M: postgresql-db create-sql ( columns table -- sql ) +: insert-function ( columns table -- sql ) [ - 2dup - "create table " % % - " (" % [ ", " % ] [ - dup second % " " % - dup third >sql-type* % " " % - sql-modifiers " " join % - ] interleave "); " % - + >r remove-id r> "create function add_" % dup % "(" % over [ "," % ] @@ -179,33 +160,52 @@ M: postgresql-db create-sql ( columns table -- sql ) dup [ ", " % ] [ second % ] interleave ") " % " values (" % - [ ", " % ] [ drop counter% ] interleave + length [1,b] [ ", " % ] [ "$" % # ] interleave "); " % "select currval(''" % % "_id_seq'');' language sql;" % drop - ] make-postgresql-counter dup . ; + ] "" make ; -M: postgresql-db drop-sql ( columns table -- sql ) +: drop-function ( columns table -- sql ) [ - dup "drop table " % % - "; drop function add_" % % + >r remove-id r> + "drop function add_" % % "(" % [ "," % ] [ third >sql-type % ] interleave ")" % - ] "" make ; -! \ create-sql reset -! \ create-sql watch +M: postgresql-db create-sql ( columns table -- seq ) + [ + [ + 2dup + "create table " % % + " (" % [ ", " % ] [ + dup second % " " % + dup third >sql-type* % " " % + sql-modifiers " " join % + ] interleave "); " % + ] "" make , + + over native-id? [ insert-function , ] [ 2drop ] if + ] { } make ; + +M: postgresql-db drop-sql ( columns table -- seq ) + [ + [ + dup "drop table " % % ";" % + ] "" make , + over native-id? [ drop-function , ] [ 2drop ] if + ] { } make ; M: postgresql-db insert-sql* ( columns table -- sql ) [ "select add_" % % "(" % - [ ", " % ] [ counter% ] interleave + length [1,b] [ ", " % ] [ "$" % # ] interleave ")" % - ] make-postgresql-counter ; + ] "" make ; M: postgresql-db update-sql* ( columns table -- sql ) [ @@ -213,18 +213,19 @@ M: postgresql-db update-sql* ( columns table -- sql ) % " set " % dup remove-id - [ ", " % ] [ second % " = " % counter% ] interleave + dup length [1,b] swap 2array flip + [ ", " % ] [ first2 second % " = $" % # ] interleave " where " % - [ primary-key? ] find nip second dup % " = " % counter% - ] make-postgresql-counter ; + [ primary-key? ] find nip second dup % " = $" % length 2 + # + ] "" make ; M: postgresql-db delete-sql* ( columns table -- sql ) [ "delete from " % % " where " % - first second dup % " = " % counter% - ] make-postgresql-counter ; + first second % " = $1" % + ] "" make ; M: postgresql-db select-sql* ( columns table -- sql ) drop ; diff --git a/extra/db/sqlite/lib/lib.factor b/extra/db/sqlite/lib/lib.factor index 2c0f2ae130..dfa8a4b2dc 100755 --- a/extra/db/sqlite/lib/lib.factor +++ b/extra/db/sqlite/lib/lib.factor @@ -100,13 +100,13 @@ IN: db.sqlite.lib : sqlite-row ( handle -- seq ) dup sqlite-#columns [ sqlite-column ] with map ; -: step-complete? ( step-result -- bool ) +: sqlite-step-has-more-rows? ( step-result -- bool ) dup SQLITE_ROW = [ - drop f + drop t ] [ dup SQLITE_DONE = - [ drop ] [ sqlite-check-result ] if t + [ drop ] [ sqlite-check-result ] if f ] if ; : sqlite-next ( prepared -- ? ) - sqlite3_step step-complete? ; + sqlite3_step sqlite-step-has-more-rows? ; diff --git a/extra/db/sqlite/sqlite.factor b/extra/db/sqlite/sqlite.factor index d83642bd8c..298220b3ca 100755 --- a/extra/db/sqlite/sqlite.factor +++ b/extra/db/sqlite/sqlite.factor @@ -25,9 +25,7 @@ M: sqlite-db dispose ( db -- ) dispose-db ; TUPLE: sqlite-statement ; C: sqlite-statement -TUPLE: sqlite-result-set advanced? ; -: ( query -- sqlite-result-set ) - dup statement-handle sqlite-result-set ; +TUPLE: sqlite-result-set has-more? ; M: sqlite-db ( str -- obj ) ; @@ -40,13 +38,7 @@ M: sqlite-db ( str -- obj ) M: sqlite-statement dispose ( statement -- ) statement-handle sqlite-finalize ; -: maybe-advance-row ( result-set -- result-set ) - dup sqlite-result-set-advanced? [ - dup advance-row drop - ] unless ; - M: sqlite-result-set dispose ( result-set -- ) - maybe-advance-row f swap set-result-set-handle ; : sqlite-bind ( triples handle -- ) @@ -58,8 +50,12 @@ M: sqlite-statement bind-statement* ( triples statement -- ) M: sqlite-statement reset-statement ( statement -- ) statement-handle sqlite-reset ; +: last-insert-id ( -- id ) + db get db-handle sqlite3_last_insert_rowid + dup zero? [ "last-id failed" throw ] when ; + M: sqlite-statement insert-statement ( statement -- id ) - query-results [ last-id ] with-disposal ; + execute-statement last-insert-id ; M: sqlite-result-set #columns ( result-set -- n ) result-set-handle sqlite-#columns ; @@ -67,12 +63,16 @@ M: sqlite-result-set #columns ( result-set -- n ) M: sqlite-result-set row-column ( result-set n -- obj ) >r result-set-handle r> sqlite-column ; -M: sqlite-result-set advance-row ( result-set -- handle ? ) +M: sqlite-result-set advance-row ( result-set -- ) [ result-set-handle sqlite-next ] keep - t swap set-sqlite-result-set-advanced? ; + set-sqlite-result-set-has-more? ; + +M: sqlite-result-set more-rows? ( result-set -- ? ) + sqlite-result-set-has-more? ; M: sqlite-statement query-results ( query -- result-set ) - dup statement-handle sqlite-result-set ; + dup statement-handle sqlite-result-set + dup advance-row ; M: sqlite-db begin-transaction ( -- ) "BEGIN" sql-command ; @@ -145,11 +145,6 @@ M: sqlite-db tuple>params ( columns tuple -- obj ) dupd >r first r> get-slot-named swap third 3array ] curry map ; - -M: sqlite-db last-id ( result-set -- id ) - maybe-advance-row drop - db get db-handle sqlite3_last_insert_rowid - dup zero? [ "last-id failed" throw ] when ; : sqlite-db-modifiers ( -- hashtable ) H{ diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index cb4129965c..72fb6396b5 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -30,7 +30,8 @@ SYMBOL: the-person [ ] [ the-person get update-tuple ] unit-test - [ ] [ the-person get delete-tuple ] unit-test ; + [ ] [ the-person get delete-tuple ] unit-test + [ ] [ person drop-table ] unit-test ; : test-sqlite ( -- ) "tuples-test.db" resource-path [ @@ -52,8 +53,8 @@ person "PERSON" "billy" 10 3.14 the-person set - test-sqlite -! test-postgresql +! test-sqlite +test-postgresql person "PERSON" { @@ -65,5 +66,5 @@ person "PERSON" 1 "billy" 20 6.28 the-person set - test-sqlite +! test-sqlite ! test-postgresql diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index 1697de83d3..74726f12aa 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -38,8 +38,9 @@ TUPLE: no-slot-named ; [ db-table dupd ] swap [ ] 3compose cache nip ; inline -HOOK: create-sql db ( columns table -- sql ) -HOOK: drop-sql db ( columns table -- sql ) +HOOK: create-sql db ( columns table -- seq ) +HOOK: drop-sql db ( columns table -- seq ) + HOOK: insert-sql* db ( columns table -- sql ) HOOK: update-sql* db ( columns table -- sql ) HOOK: delete-sql* db ( columns table -- sql ) diff --git a/extra/db/types/types.factor b/extra/db/types/types.factor index 30c15682fa..7cacbcf861 100755 --- a/extra/db/types/types.factor +++ b/extra/db/types/types.factor @@ -11,6 +11,12 @@ SYMBOL: +assigned-id+ : primary-key? ( spec -- ? ) [ { +native-id+ +assigned-id+ } member? ] contains? ; +: contains-id? ( columns id -- ? ) + swap [ member? ] with contains? ; + +: assigned-id? ( columns -- ? ) +assigned-id+ contains-id? ; +: native-id? ( columns -- ? ) +native-id+ contains-id? ; + ! Same concept, SQLite has autoincrement, PostgreSQL has serial SYMBOL: +autoincrement+ SYMBOL: +serial+ From 3409aa670d17ffed5e89badeb7f01fcbb0ed82c0 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 02:21:01 -0600 Subject: [PATCH 03/11] builder.util: simpler cat and eval-file --- extra/builder/util/util.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/builder/util/util.factor b/extra/builder/util/util.factor index b3b88874b0..70f3083f57 100644 --- a/extra/builder/util/util.factor +++ b/extra/builder/util/util.factor @@ -69,9 +69,9 @@ TUPLE: process* arguments stdin stdout stderr timeout ; : milli-seconds>time ( n -- string ) 1000 /i 60 /mod >r 60 /mod r> 3array [ pad-00 ] map ":" join ; -: eval-file ( file -- obj ) contents eval ; +: eval-file ( file -- obj ) file-contents eval ; -: cat ( file -- ) contents print ; +: cat ( file -- ) file-contents print ; : run-or-bail ( desc quot -- ) [ [ try-process ] curry ] From 978a4e28ebad25adc76e5d145222b4bf3855535c Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 03:17:30 -0600 Subject: [PATCH 04/11] builder: minor tweaks --- extra/builder/builder.factor | 16 +++++++++++++--- extra/builder/util/util.factor | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index 00e39be2ba..572cd6d52c 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -69,13 +69,19 @@ VAR: stamp ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +SYMBOL: build-status + : (build) ( -- ) + build-status off + enter-build-dir "report" [ "Build machine: " write host-name print + "CPU: " write cpu print + "OS: " write os print "Build directory: " write cwd print git-clone [ "git clone failed" print ] run-or-bail @@ -88,7 +94,7 @@ VAR: stamp make-vm [ "vm compile error" print "../compile-log" cat ] run-or-bail - [ my-arch download-image ] [ "Image download error" print throw ] recover + [ retrieve-image ] [ "Image download error" print throw ] recover bootstrap [ "Bootstrap error" print "../boot-log" cat ] run-or-bail @@ -106,7 +112,9 @@ VAR: stamp "Benchmarks: " print "../benchmarks" [ stdio get contents eval ] with-file-in benchmarks. - ] with-file-out ; + ] with-file-out + + build-status on ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -114,12 +122,14 @@ SYMBOL: builder-recipients : tag-subject ( str -- str ) { "builder@" host-name* ": " , } bake to-string ; +: subject ( -- str ) build-status get [ "report" ] [ "error" ] if ; + : build ( -- ) [ (build) ] [ drop ] recover "ed@factorcode.org" >>from builder-recipients get >>to - "report" tag-subject >>subject + subject >>subject "../report" file>string >>body send ; diff --git a/extra/builder/util/util.factor b/extra/builder/util/util.factor index 70f3083f57..f9f432a8f6 100644 --- a/extra/builder/util/util.factor +++ b/extra/builder/util/util.factor @@ -81,3 +81,6 @@ TUPLE: process* arguments stdin stdout stderr timeout ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +USING: bootstrap.image bootstrap.image.download io.streams.null ; + +: retrieve-image ( -- ) [ my-arch download-image ] with-null-stream ; \ No newline at end of file From 50b38b0ae2e749fddd8390b34526464d688800d6 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 05:22:52 -0600 Subject: [PATCH 05/11] builder: builds-dir variable and prepare-build-machine --- extra/builder/builder.factor | 39 +++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index 572cd6d52c..d502d0dfbd 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -11,6 +11,28 @@ IN: builder ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +SYMBOL: builds-dir + +: builds ( -- path ) + builds-dir get + home "/builds" append + or ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +! User also needs to set smtp-host and builder-recipients + +: prepare-build-machine ( -- ) + builds make-directory + builds cd + { "git" "clone" "git://factorcode.org/git/factor.git" } run-process drop ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: builds-check ( -- ) builds exists? not [ prepare-build-machine ] when ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + : git-clone ( -- desc ) { "git" "clone" "../factor" } ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -19,7 +41,7 @@ VAR: stamp : enter-build-dir ( -- ) datestamp >stamp - "/builds" cd + builds cd stamp> make-directory stamp> cd ; @@ -75,6 +97,8 @@ SYMBOL: build-status build-status off + builds-check + enter-build-dir "report" [ @@ -118,21 +142,26 @@ SYMBOL: build-status ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +SYMBOL: builder-from + SYMBOL: builder-recipients : tag-subject ( str -- str ) { "builder@" host-name* ": " , } bake to-string ; -: subject ( -- str ) build-status get [ "report" ] [ "error" ] if ; +: subject ( -- str ) build-status get [ "report" ] [ "error" ] if tag-subject ; -: build ( -- ) - [ (build) ] [ drop ] recover +: send-builder-email ( -- ) - "ed@factorcode.org" >>from + builder-from get >>from builder-recipients get >>to subject >>subject "../report" file>string >>body send ; +: build ( -- ) + [ (build) ] [ drop ] recover + [ send-builder-email ] [ "not sending mail" . ] recover ; + ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : git-pull ( -- desc ) From 8d86b51e76a89971dbb50011aa7155b631dd7c37 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 05:54:19 -0600 Subject: [PATCH 06/11] builder: do builds-check in build-loop --- extra/builder/builder.factor | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index d502d0dfbd..e6e1c4d94f 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -97,8 +97,6 @@ SYMBOL: build-status build-status off - builds-check - enter-build-dir "report" [ @@ -160,7 +158,7 @@ SYMBOL: builder-recipients : build ( -- ) [ (build) ] [ drop ] recover - [ send-builder-email ] [ "not sending mail" . ] recover ; + [ send-builder-email ] [ drop "not sending mail" . ] recover ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -180,6 +178,7 @@ SYMBOL: builder-recipients = not ; : build-loop ( -- ) + builds-check [ "/builds/factor" cd updates-available? From da142685372f643d8669d4b6fae4f5387313971f Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 05:57:44 -0600 Subject: [PATCH 07/11] builder: minor fix --- extra/builder/builder.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index e6e1c4d94f..a13392699a 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -180,7 +180,7 @@ SYMBOL: builder-recipients : build-loop ( -- ) builds-check [ - "/builds/factor" cd + builds cd updates-available? [ build ] when From 9a66a8f87b43d9099cfa7da223d985aae77a20a4 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 06:04:53 -0600 Subject: [PATCH 08/11] builder: fix another bug --- extra/builder/builder.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index a13392699a..84a3d6d66e 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -180,7 +180,7 @@ SYMBOL: builder-recipients : build-loop ( -- ) builds-check [ - builds cd + builds "/factor" append cd updates-available? [ build ] when From bdbd6365324d04bf4ecbfce7a38e3fde35d75f42 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 15 Feb 2008 07:46:20 -0600 Subject: [PATCH 09/11] builder: fix report formatting --- extra/builder/builder.factor | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index 84a3d6d66e..d491e1650b 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -20,8 +20,6 @@ SYMBOL: builds-dir ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! User also needs to set smtp-host and builder-recipients - : prepare-build-machine ( -- ) builds make-directory builds cd @@ -104,7 +102,7 @@ SYMBOL: build-status "Build machine: " write host-name print "CPU: " write cpu print "OS: " write os print - "Build directory: " write cwd print + "Build directory: " write cwd print nl git-clone [ "git clone failed" print ] run-or-bail @@ -126,7 +124,7 @@ SYMBOL: build-status "Boot time: " write "../boot-time" eval-file milli-seconds>time print "Load time: " write "../load-time" eval-file milli-seconds>time print - "Test time: " write "../test-time" eval-file milli-seconds>time print + "Test time: " write "../test-time" eval-file milli-seconds>time print nl "Did not pass load-everything: " print "../load-everything-vocabs" cat "Did not pass test-all: " print "../test-all-vocabs" cat From 97fd5bee5fa1a66d42c638cac0b89ffc926e7483 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Sat, 16 Feb 2008 09:05:01 -0600 Subject: [PATCH 10/11] builder: (build) does builds-check --- extra/builder/builder.factor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extra/builder/builder.factor b/extra/builder/builder.factor index d491e1650b..cd17a32255 100644 --- a/extra/builder/builder.factor +++ b/extra/builder/builder.factor @@ -93,6 +93,8 @@ SYMBOL: build-status : (build) ( -- ) + builds-check + build-status off enter-build-dir From 46df9c16d19dcdbc315492051720ef17e29351c9 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 15 Feb 2008 12:16:31 -0600 Subject: [PATCH 11/11] fix load error --- extra/db/postgresql/postgresql.factor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extra/db/postgresql/postgresql.factor b/extra/db/postgresql/postgresql.factor index f198a5c04c..f0a008d065 100755 --- a/extra/db/postgresql/postgresql.factor +++ b/extra/db/postgresql/postgresql.factor @@ -52,6 +52,9 @@ M: postgresql-result-set #columns ( result-set -- n ) M: postgresql-result-set row-column ( result-set n -- obj ) >r dup result-set-handle swap result-set-n r> PQgetvalue ; +M: postgresql-result-set row-column ( result-set n -- obj ) + >r dup result-set-handle swap result-set-n r> PQgetvalue ; + M: postgresql-statement insert-statement ( statement -- id ) query-results [ break 0 row-column ] with-disposal ; @@ -234,9 +237,6 @@ M: postgresql-db tuple>params ( columns tuple -- obj ) [ >r dup third swap first r> get-slot-named swap ] curry { } map>assoc ; -M: postgresql-db last-id ( res -- id ) - drop f ; - : postgresql-db-modifiers ( -- hashtable ) H{ { +native-id+ "not null primary key" }