parent
9f2c032b2f
commit
eb75685031
|
@ -15,7 +15,8 @@ TUPLE: db handle insert-statements update-statements delete-statements select-st
|
|||
GENERIC: db-open ( db -- )
|
||||
HOOK: db-close db ( handle -- )
|
||||
|
||||
: dispose-statements [ dispose drop ] assoc-each ;
|
||||
: dispose-statements ( seq -- )
|
||||
[ dispose drop ] assoc-each ;
|
||||
|
||||
: dispose-db ( db -- )
|
||||
dup db [
|
||||
|
@ -35,7 +36,13 @@ HOOK: <prepared-statement> db ( str -- statement )
|
|||
GENERIC: prepare-statement ( statement -- )
|
||||
GENERIC: bind-statement* ( obj statement -- )
|
||||
GENERIC: reset-statement ( statement -- )
|
||||
GENERIC: execute-statement ( statement -- )
|
||||
GENERIC: execute-statement* ( statement -- result-set )
|
||||
HOOK: last-id db ( res -- id )
|
||||
: execute-statement ( statement -- )
|
||||
execute-statement* dispose ;
|
||||
|
||||
: execute-statement-last-id ( statement -- id )
|
||||
execute-statement* [ last-id ] with-disposal ;
|
||||
|
||||
: bind-statement ( obj statement -- )
|
||||
dup statement-bound? [ dup reset-statement ] when
|
||||
|
@ -51,8 +58,6 @@ GENERIC: #columns ( result-set -- n )
|
|||
GENERIC# row-column 1 ( result-set n -- obj )
|
||||
GENERIC: advance-row ( result-set -- ? )
|
||||
|
||||
HOOK: last-id db ( -- id )
|
||||
|
||||
: init-result-set ( result-set -- )
|
||||
dup #rows over set-result-set-max
|
||||
-1 swap set-result-set-n ;
|
||||
|
|
|
@ -50,6 +50,8 @@ IN: db.postgresql.ffi
|
|||
: PQERRORS_DEFAULT HEX: 1 ; inline
|
||||
: PQERRORS_VERBOSE HEX: 2 ; inline
|
||||
|
||||
: InvalidOid 0 ; inline
|
||||
|
||||
TYPEDEF: int size_t
|
||||
TYPEDEF: int ConnStatusType
|
||||
TYPEDEF: int ExecStatusType
|
||||
|
|
|
@ -37,8 +37,13 @@ IN: db.postgresql.lib
|
|||
>r db get db-handle r>
|
||||
[ statement-sql ] keep
|
||||
[ statement-params length f ] keep
|
||||
statement-params [ malloc-char-string ] map >c-void*-array
|
||||
statement-params [ second 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 ;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
! Copyright (C) 2007, 2008 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: arrays assocs alien alien.syntax continuations io
|
||||
kernel math namespaces prettyprint quotations
|
||||
sequences debugger db db.postgresql.lib db.postgresql.ffi ;
|
||||
kernel math math.parser namespaces prettyprint quotations
|
||||
sequences debugger db db.postgresql.lib db.postgresql.ffi
|
||||
db.tuples db.types ;
|
||||
IN: db.postgresql
|
||||
|
||||
TUPLE: postgresql-db host port pgopts pgtty db user pass ;
|
||||
|
@ -51,8 +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 -- )
|
||||
query-results dispose ;
|
||||
M: postgresql-statement execute-statement* ( statement -- obj )
|
||||
query-results ;
|
||||
|
||||
: increment-n ( result-set -- n )
|
||||
dup result-set-n 1+ dup rot set-result-set-n ;
|
||||
|
@ -103,3 +104,103 @@ M: postgresql-db commit-transaction ( -- )
|
|||
|
||||
M: postgresql-db rollback-transaction ( -- )
|
||||
"ROLLBACK" sql-command ;
|
||||
|
||||
|
||||
M: postgresql-db create-sql ( columns table -- sql )
|
||||
[
|
||||
"create table " % %
|
||||
" (" % [ ", " % ] [
|
||||
dup second % " " %
|
||||
dup third >sql-type % " " %
|
||||
sql-modifiers " " join %
|
||||
] interleave ")" %
|
||||
] "" make ;
|
||||
|
||||
M: postgresql-db drop-sql ( table -- sql )
|
||||
[
|
||||
"drop table " % %
|
||||
] "" make ;
|
||||
|
||||
SYMBOL: postgresql-counter
|
||||
|
||||
M: postgresql-db insert-sql* ( columns table -- sql )
|
||||
[
|
||||
postgresql-counter off
|
||||
"insert into " %
|
||||
%
|
||||
"(" %
|
||||
dup [ ", " % ] [ second % ] interleave
|
||||
") " %
|
||||
" values (" %
|
||||
[ ", " % ] [
|
||||
drop "$" % postgresql-counter [ inc ] keep get #
|
||||
] interleave
|
||||
")" %
|
||||
] "" make ;
|
||||
|
||||
M: postgresql-db update-sql* ( columns table -- sql )
|
||||
[
|
||||
"update " %
|
||||
%
|
||||
" set " %
|
||||
dup remove-id
|
||||
[ ", " % ] [ second dup % " = :" % % ] interleave
|
||||
" where " %
|
||||
[ primary-key? ] find nip second dup % " = :" % %
|
||||
] "" make ;
|
||||
|
||||
M: postgresql-db delete-sql* ( columns table -- sql )
|
||||
[
|
||||
"delete from " %
|
||||
%
|
||||
" where " %
|
||||
first second dup % " = :" % %
|
||||
] "" make ;
|
||||
|
||||
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 ;
|
||||
|
||||
M: postgresql-db last-id ( res -- id )
|
||||
pq-oid-value ;
|
||||
|
||||
: postgresql-db-modifiers ( -- hashtable )
|
||||
H{
|
||||
{ +native-id+ "primary key" }
|
||||
{ +assigned-id+ "primary key" }
|
||||
{ +autoincrement+ "autoincrement" }
|
||||
{ +unique+ "unique" }
|
||||
{ +default+ "default" }
|
||||
{ +null+ "null" }
|
||||
{ +not-null+ "not null" }
|
||||
} ;
|
||||
|
||||
M: postgresql-db sql-modifiers* ( modifiers -- str )
|
||||
postgresql-db-modifiers swap [
|
||||
dup array? [
|
||||
first2
|
||||
>r swap at r> number>string*
|
||||
" " swap 3append
|
||||
] [
|
||||
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 ;
|
||||
|
|
|
@ -108,7 +108,7 @@ LIBRARY: sqlite
|
|||
FUNCTION: int sqlite3_open ( char* filename, void* ppDb ) ;
|
||||
FUNCTION: int sqlite3_close ( sqlite3* pDb ) ;
|
||||
FUNCTION: char* sqlite3_errmsg ( sqlite3* pDb ) ;
|
||||
FUNCTION: int sqlite3_prepare_v2 ( sqlite3* pDb, char* zSql, int nBytes, void* ppStmt, void* pzTail ) ;
|
||||
FUNCTION: int sqlite3_prepare ( sqlite3* pDb, char* zSql, int nBytes, void* ppStmt, void* pzTail ) ;
|
||||
FUNCTION: int sqlite3_finalize ( sqlite3_stmt* pStmt ) ;
|
||||
FUNCTION: int sqlite3_reset ( sqlite3_stmt* pStmt ) ;
|
||||
FUNCTION: int sqlite3_step ( sqlite3_stmt* pStmt ) ;
|
||||
|
|
|
@ -30,7 +30,7 @@ IN: db.sqlite.lib
|
|||
|
||||
: sqlite-prepare ( db sql -- handle )
|
||||
dup length "void*" <c-object> "void*" <c-object>
|
||||
[ sqlite3_prepare_v2 sqlite-check-result ] 2keep
|
||||
[ sqlite3_prepare sqlite-check-result ] 2keep
|
||||
drop *void* ;
|
||||
|
||||
: sqlite-bind-parameter-index ( handle name -- index )
|
||||
|
|
|
@ -25,7 +25,7 @@ M: sqlite-db dispose ( db -- ) dispose-db ;
|
|||
TUPLE: sqlite-statement ;
|
||||
C: <sqlite-statement> sqlite-statement
|
||||
|
||||
TUPLE: sqlite-result-set ;
|
||||
TUPLE: sqlite-result-set advanced? ;
|
||||
: <sqlite-result-set> ( query -- sqlite-result-set )
|
||||
dup statement-handle sqlite-result-set <result-set> ;
|
||||
|
||||
|
@ -40,7 +40,13 @@ M: sqlite-db <prepared-statement> ( 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 -- )
|
||||
|
@ -52,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 -- )
|
||||
statement-handle sqlite-next drop ;
|
||||
M: sqlite-statement execute-statement* ( statement -- obj )
|
||||
query-results ;
|
||||
|
||||
M: sqlite-result-set #columns ( result-set -- n )
|
||||
result-set-handle sqlite-#columns ;
|
||||
|
@ -62,7 +68,8 @@ 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 ? )
|
||||
result-set-handle sqlite-next ;
|
||||
[ result-set-handle sqlite-next ] keep
|
||||
t swap set-sqlite-result-set-advanced? ;
|
||||
|
||||
M: sqlite-statement query-results ( query -- result-set )
|
||||
dup statement-handle sqlite-result-set <result-set> ;
|
||||
|
@ -138,9 +145,10 @@ M: sqlite-db tuple>params ( columns tuple -- obj )
|
|||
third 3array
|
||||
] curry map ;
|
||||
|
||||
M: sqlite-db last-id ( -- id )
|
||||
db get db-handle sqlite3_last_insert_rowid ;
|
||||
|
||||
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{
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
! 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.types continuations namespaces db.postgresql math
|
||||
tools.time ;
|
||||
IN: temporary
|
||||
|
||||
TUPLE: person the-id the-name the-number real ;
|
||||
: <person> ( name age -- person )
|
||||
: <person> ( name age real -- person )
|
||||
{
|
||||
set-person-the-name
|
||||
set-person-the-number
|
||||
|
@ -36,10 +37,10 @@ SYMBOL: the-person
|
|||
test-tuples
|
||||
] with-db ;
|
||||
|
||||
! : test-postgres ( -- )
|
||||
! resource-path <postgresql-db> [
|
||||
! test-tuples
|
||||
! ] with-db ;
|
||||
: test-postgresql ( -- )
|
||||
"localhost" "postgres" "" "factor-test" <postgresql-db> [
|
||||
test-tuples
|
||||
] with-db ;
|
||||
|
||||
person "PERSON"
|
||||
{
|
||||
|
@ -52,7 +53,7 @@ person "PERSON"
|
|||
"billy" 10 3.14 <person> the-person set
|
||||
|
||||
test-sqlite
|
||||
! test-postgres
|
||||
! test-postgresql
|
||||
|
||||
person "PERSON"
|
||||
{
|
||||
|
@ -65,4 +66,4 @@ person "PERSON"
|
|||
1 "billy" 20 6.28 <assigned-person> the-person set
|
||||
|
||||
test-sqlite
|
||||
! test-postgres
|
||||
! test-postgresql
|
||||
|
|
|
@ -64,9 +64,12 @@ HOOK: tuple>params db ( columns tuple -- obj )
|
|||
2dup . .
|
||||
[ bind-statement ] keep ;
|
||||
|
||||
: do-tuple-statement ( tuple columns-quot statement-quot -- )
|
||||
: make-tuple-statement ( tuple columns-quot statement-quot -- statement )
|
||||
>r [ class db-columns ] swap compose keep
|
||||
r> tuple-statement execute-statement ;
|
||||
r> tuple-statement ;
|
||||
|
||||
: do-tuple-statement ( tuple columns-quot statement-quot -- )
|
||||
make-tuple-statement execute-statement ;
|
||||
|
||||
: create-table ( class -- )
|
||||
dup db-columns swap db-table create-sql sql-command ;
|
||||
|
@ -76,8 +79,8 @@ HOOK: tuple>params db ( columns tuple -- obj )
|
|||
|
||||
: insert-tuple ( tuple -- )
|
||||
[
|
||||
[ maybe-remove-id ] [ insert-sql ] do-tuple-statement
|
||||
last-id
|
||||
[ maybe-remove-id ] [ insert-sql ]
|
||||
make-tuple-statement execute-statement-last-id
|
||||
] keep set-primary-key ;
|
||||
|
||||
: update-tuple ( tuple -- )
|
||||
|
|
Loading…
Reference in New Issue