| 
									
										
										
										
											2008-02-03 16:06:31 -05:00
										 |  |  | ! Copyright (C) 2008 Doug Coleman. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | USING: arrays continuations db io kernel math namespaces | 
					
						
							| 
									
										
										
										
											2008-02-14 02:27:54 -05:00
										 |  |  | quotations sequences db.postgresql.ffi alien alien.c-types | 
					
						
							| 
									
										
										
										
											2008-03-29 00:00:20 -04:00
										 |  |  | db.types tools.walker ascii splitting math.parser combinators | 
					
						
							|  |  |  | libc shuffle calendar.format byte-arrays destructors prettyprint | 
					
						
							| 
									
										
										
										
											2008-04-21 01:13:12 -04:00
										 |  |  | accessors strings serialize io.encodings.binary io.encodings.utf8 | 
					
						
							| 
									
										
										
										
											2008-07-02 01:20:01 -04:00
										 |  |  | alien.strings io.streams.byte-array summary present urls ;
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | IN: db.postgresql.lib | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : postgresql-result-error-message ( res -- str/f )
 | 
					
						
							|  |  |  |     dup zero? [ | 
					
						
							|  |  |  |         drop f
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-02-24 13:32:36 -05:00
										 |  |  |         PQresultErrorMessage [ blank? ] trim
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : postgres-result-error ( res -- )
 | 
					
						
							|  |  |  |     postgresql-result-error-message [ throw ] when* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-24 13:32:36 -05:00
										 |  |  | : (postgresql-error-message) ( handle -- str )
 | 
					
						
							|  |  |  |     PQerrorMessage | 
					
						
							|  |  |  |     "\n" split [ [ blank? ] trim ] map "\n" join ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | : postgresql-error-message ( -- str )
 | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |     db get handle>> (postgresql-error-message) ;
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : postgresql-error ( res -- res )
 | 
					
						
							|  |  |  |     dup [ postgresql-error-message throw ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 00:18:12 -04:00
										 |  |  | ERROR: postgresql-result-null ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: postgresql-result-null summary ( obj -- str )
 | 
					
						
							|  |  |  |     drop "PQexec returned f." ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : postgresql-result-ok? ( res -- ? )
 | 
					
						
							|  |  |  |     [ postgresql-result-null ] unless*
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  |     PQresultStatus | 
					
						
							|  |  |  |     PGRES_COMMAND_OK PGRES_TUPLES_OK 2array member? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-03 16:06:31 -05:00
										 |  |  | : connect-postgres ( host port pgopts pgtty db user pass -- conn )
 | 
					
						
							|  |  |  |     PQsetdbLogin | 
					
						
							| 
									
										
										
										
											2008-02-24 13:32:36 -05:00
										 |  |  |     dup PQstatus zero? [ (postgresql-error-message) throw ] unless ;
 | 
					
						
							| 
									
										
										
										
											2008-02-03 16:06:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | : do-postgresql-statement ( statement -- res )
 | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |     db get handle>> swap sql>> PQexec dup postgresql-result-ok? [ | 
					
						
							| 
									
										
										
										
											2008-04-20 00:48:07 -04:00
										 |  |  |         [ postgresql-result-error-message ] [ PQclear ] bi throw
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  |     ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | : type>oid ( symbol -- n )
 | 
					
						
							|  |  |  |     dup array? [ first ] when
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { BLOB [ BYTEA-OID ] } | 
					
						
							|  |  |  |         { FACTOR-BLOB [ BYTEA-OID ] } | 
					
						
							|  |  |  |         [ drop 0 ] | 
					
						
							|  |  |  |     } case ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : type>param-format ( symbol -- n )
 | 
					
						
							|  |  |  |     dup array? [ first ] when
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { BLOB [ 1 ] } | 
					
						
							|  |  |  |         { FACTOR-BLOB [ 1 ] } | 
					
						
							|  |  |  |         [ drop 0 ] | 
					
						
							|  |  |  |     } case ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : param-types ( statement -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |     in-params>> [ type>> type>oid ] map >c-uint-array ;
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | : malloc-byte-array/length ( byte-array -- alien length )
 | 
					
						
							| 
									
										
										
										
											2008-05-14 20:03:07 -04:00
										 |  |  |     [ malloc-byte-array &free ] [ length ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | : default-param-value ( obj -- alien n )
 | 
					
						
							| 
									
										
										
										
											2008-05-14 20:03:07 -04:00
										 |  |  |     number>string* dup [ utf8 malloc-string &free ] when 0 ;
 | 
					
						
							| 
									
										
										
										
											2008-04-23 23:23:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | : param-values ( statement -- seq seq2 )
 | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |     [ bind-params>> ] [ in-params>> ] bi
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-04-21 14:11:19 -04:00
										 |  |  |         >r value>> r> type>> { | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |             { FACTOR-BLOB [ | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |                 dup [ object>bytes malloc-byte-array/length ] [ 0 ] if
 | 
					
						
							|  |  |  |             ] } | 
					
						
							|  |  |  |             { BLOB [ dup [ malloc-byte-array/length ] [ 0 ] if ] } | 
					
						
							| 
									
										
										
										
											2008-04-23 23:23:22 -04:00
										 |  |  |             { DATE [ dup [ timestamp>ymd ] when default-param-value ] } | 
					
						
							|  |  |  |             { TIME [ dup [ timestamp>hms ] when default-param-value ] } | 
					
						
							|  |  |  |             { DATETIME [ dup [ timestamp>ymdhms ] when default-param-value ] } | 
					
						
							|  |  |  |             { TIMESTAMP [ dup [ timestamp>ymdhms ] when default-param-value ] } | 
					
						
							| 
									
										
										
										
											2008-06-12 19:04:01 -04:00
										 |  |  |             { URL [ dup [ present ] when default-param-value ] } | 
					
						
							| 
									
										
										
										
											2008-04-23 23:23:22 -04:00
										 |  |  |             [ drop default-param-value ] | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |         } case 2array
 | 
					
						
							| 
									
										
										
										
											2008-09-06 20:13:59 -04:00
										 |  |  |     ] 2map flip [ | 
					
						
							|  |  |  |         f f
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         first2 [ >c-void*-array ] [ >c-uint-array ] bi*
 | 
					
						
							| 
									
										
										
										
											2008-09-06 20:13:59 -04:00
										 |  |  |     ] if-empty ;
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : param-formats ( statement -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |     in-params>> [ type>> type>param-format ] map >c-uint-array ;
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-03 16:06:31 -05:00
										 |  |  | : do-postgresql-bound-statement ( statement -- res )
 | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |         >r db get handle>> r> | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |             [ sql>> ] | 
					
						
							|  |  |  |             [ bind-params>> length ] | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |             [ param-types ] | 
					
						
							|  |  |  |             [ param-values ] | 
					
						
							|  |  |  |             [ param-formats ] | 
					
						
							|  |  |  |         } cleave
 | 
					
						
							|  |  |  |         0 PQexecParams dup postgresql-result-ok? [ | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |             [ postgresql-result-error-message ] [ PQclear ] bi throw
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |         ] unless
 | 
					
						
							|  |  |  |     ] with-destructors ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : pq-get-is-null ( handle row column -- ? )
 | 
					
						
							|  |  |  |     PQgetisnull 1 = ;
 | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : pq-get-string ( handle row column -- obj )
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:13:12 -04:00
										 |  |  |     3dup PQgetvalue utf8 alien>string | 
					
						
							| 
									
										
										
										
											2008-04-20 00:41:48 -04:00
										 |  |  |     dup empty? [ >r pq-get-is-null f r> ? ] [ 3nip ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : pq-get-number ( handle row column -- obj )
 | 
					
						
							|  |  |  |     pq-get-string dup [ string>number ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | TUPLE: postgresql-malloc-destructor alien ;
 | 
					
						
							|  |  |  | C: <postgresql-malloc-destructor> postgresql-malloc-destructor | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: postgresql-malloc-destructor dispose ( obj -- )
 | 
					
						
							|  |  |  |     alien>> PQfreemem ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-14 20:03:07 -04:00
										 |  |  | : &postgresql-free ( alien -- alien )
 | 
					
						
							| 
									
										
										
										
											2008-05-14 20:41:39 -04:00
										 |  |  |     dup <postgresql-malloc-destructor> &dispose drop ; inline
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  | : pq-get-blob ( handle row column -- obj/f )
 | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |     [ PQgetvalue ] 3keep 3dup PQgetlength | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  |     dup 0 > [ | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |         3nip | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             memory>byte-array >string
 | 
					
						
							|  |  |  |             0 <uint> | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 PQunescapeBytea dup zero? [ | 
					
						
							|  |  |  |                     postgresql-result-error-message throw
 | 
					
						
							|  |  |  |                 ] [ | 
					
						
							| 
									
										
										
										
											2008-05-14 20:03:07 -04:00
										 |  |  |                     &postgresql-free | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |                 ] if
 | 
					
						
							|  |  |  |             ] keep
 | 
					
						
							|  |  |  |             *uint memory>byte-array | 
					
						
							|  |  |  |         ] with-destructors  | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |         drop pq-get-is-null nip [ f ] [ B{ } clone ] if
 | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-03-10 14:56:58 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : postgresql-column-typed ( handle row column type -- obj )
 | 
					
						
							|  |  |  |     dup array? [ first ] when
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-04-28 17:48:55 -04:00
										 |  |  |         { +db-assigned-id+ [ pq-get-number ] } | 
					
						
							| 
									
										
										
										
											2008-04-21 14:11:19 -04:00
										 |  |  |         { +random-id+ [ pq-get-number ] } | 
					
						
							| 
									
										
										
										
											2008-03-10 18:00:28 -04:00
										 |  |  |         { INTEGER [ pq-get-number ] } | 
					
						
							|  |  |  |         { BIG-INTEGER [ pq-get-number ] } | 
					
						
							|  |  |  |         { DOUBLE [ pq-get-number ] } | 
					
						
							|  |  |  |         { TEXT [ pq-get-string ] } | 
					
						
							|  |  |  |         { VARCHAR [ pq-get-string ] } | 
					
						
							|  |  |  |         { DATE [ pq-get-string dup [ ymd>timestamp ] when ] } | 
					
						
							|  |  |  |         { TIME [ pq-get-string dup [ hms>timestamp ] when ] } | 
					
						
							|  |  |  |         { TIMESTAMP [ pq-get-string dup [ ymdhms>timestamp ] when ] } | 
					
						
							|  |  |  |         { DATETIME [ pq-get-string dup [ ymdhms>timestamp ] when ] } | 
					
						
							|  |  |  |         { BLOB [ pq-get-blob ] } | 
					
						
							| 
									
										
										
										
											2008-06-12 19:04:01 -04:00
										 |  |  |         { URL [ pq-get-string dup [ >url ] when ] } | 
					
						
							| 
									
										
										
										
											2008-03-11 01:05:22 -04:00
										 |  |  |         { FACTOR-BLOB [ | 
					
						
							|  |  |  |             pq-get-blob | 
					
						
							| 
									
										
										
										
											2008-03-17 00:41:26 -04:00
										 |  |  |             dup [ bytes>object ] when ] } | 
					
						
							| 
									
										
										
										
											2008-03-10 14:56:58 -04:00
										 |  |  |         [ no-sql-type ] | 
					
						
							|  |  |  |     } case ;
 |