]> gitweb.factorcode.org Git - factor.git/blob - basis/db/sqlite/lib/lib.factor
Fix permission bits
[factor.git] / basis / db / sqlite / lib / lib.factor
1 ! Copyright (C) 2008 Chris Double, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien.c-types arrays assocs kernel math math.parser
4 namespaces sequences db.sqlite.ffi db combinators
5 continuations db.types calendar.format serialize
6 io.streams.byte-array byte-arrays io.encodings.binary
7 io.backend db.errors present urls io.encodings.utf8
8 io.encodings.string accessors ;
9 IN: db.sqlite.lib
10
11 ERROR: sqlite-error < db-error n string ;
12 ERROR: sqlite-sql-error < sql-error n string ;
13
14 : throw-sqlite-error ( n -- * )
15     dup sqlite-error-messages nth sqlite-error ;
16
17 : sqlite-statement-error ( -- * )
18     SQLITE_ERROR
19     db get handle>> sqlite3_errmsg sqlite-sql-error ;
20
21 : sqlite-check-result ( n -- )
22     {
23         { SQLITE_OK [ ] }
24         { SQLITE_ERROR [ sqlite-statement-error ] }
25         [ throw-sqlite-error ]
26     } case ;
27
28 : sqlite-open ( path -- db )
29     normalize-path
30     "void*" <c-object>
31     [ sqlite3_open sqlite-check-result ] keep *void* ;
32
33 : sqlite-close ( db -- )
34     sqlite3_close sqlite-check-result ;
35
36 : sqlite-prepare ( db sql -- handle )
37     utf8 encode dup length "void*" <c-object> "void*" <c-object>
38     [ sqlite3_prepare_v2 sqlite-check-result ] 2keep
39     drop *void* ;
40
41 : sqlite-bind-parameter-index ( handle name -- index )
42     sqlite3_bind_parameter_index ;
43
44 : parameter-index ( handle name text -- handle name text )
45     >r dupd sqlite-bind-parameter-index r> ;
46
47 : sqlite-bind-text ( handle index text -- )
48     utf8 encode dup length SQLITE_TRANSIENT
49     sqlite3_bind_text sqlite-check-result ;
50
51 : sqlite-bind-int ( handle i n -- )
52     sqlite3_bind_int sqlite-check-result ;
53
54 : sqlite-bind-int64 ( handle i n -- )
55     sqlite3_bind_int64 sqlite-check-result ;
56
57 : sqlite-bind-uint64 ( handle i n -- )
58     sqlite3-bind-uint64 sqlite-check-result ;
59
60 : sqlite-bind-double ( handle i x -- )
61     sqlite3_bind_double sqlite-check-result ;
62
63 : sqlite-bind-null ( handle i -- )
64     sqlite3_bind_null sqlite-check-result ;
65
66 : sqlite-bind-blob ( handle i byte-array -- )
67     dup length SQLITE_TRANSIENT
68     sqlite3_bind_blob sqlite-check-result ;
69
70 : sqlite-bind-text-by-name ( handle name text -- )
71     parameter-index sqlite-bind-text ;
72
73 : sqlite-bind-int-by-name ( handle name int -- )
74     parameter-index sqlite-bind-int ;
75
76 : sqlite-bind-int64-by-name ( handle name int64 -- )
77     parameter-index sqlite-bind-int64 ;
78
79 : sqlite-bind-uint64-by-name ( handle name int64 -- )
80     parameter-index sqlite-bind-uint64 ;
81
82 : sqlite-bind-double-by-name ( handle name double -- )
83     parameter-index sqlite-bind-double ;
84
85 : sqlite-bind-blob-by-name ( handle name blob -- )
86     parameter-index sqlite-bind-blob ;
87
88 : sqlite-bind-null-by-name ( handle name obj -- )
89     parameter-index drop sqlite-bind-null ;
90
91 : sqlite-bind-type ( handle key value type -- )
92     over [ drop NULL ] unless
93     dup array? [ first ] when
94     {
95         { INTEGER [ sqlite-bind-int-by-name ] }
96         { BIG-INTEGER [ sqlite-bind-int64-by-name ] }
97         { SIGNED-BIG-INTEGER [ sqlite-bind-int64-by-name ] }
98         { UNSIGNED-BIG-INTEGER [ sqlite-bind-uint64-by-name ] }
99         { TEXT [ sqlite-bind-text-by-name ] }
100         { VARCHAR [ sqlite-bind-text-by-name ] }
101         { DOUBLE [ sqlite-bind-double-by-name ] }
102         { DATE [ timestamp>ymd sqlite-bind-text-by-name ] }
103         { TIME [ timestamp>hms sqlite-bind-text-by-name ] }
104         { DATETIME [ timestamp>ymdhms sqlite-bind-text-by-name ] }
105         { TIMESTAMP [ timestamp>ymdhms sqlite-bind-text-by-name ] }
106         { BLOB [ sqlite-bind-blob-by-name ] }
107         { FACTOR-BLOB [
108             object>bytes
109             sqlite-bind-blob-by-name
110         ] }
111         { URL [ present sqlite-bind-text-by-name ] }
112         { +db-assigned-id+ [ sqlite-bind-int-by-name ] }
113         { +random-id+ [ sqlite-bind-int64-by-name ] }
114         { NULL [ sqlite-bind-null-by-name ] }
115         [ no-sql-type ]
116     } case ;
117
118 : sqlite-finalize ( handle -- ) sqlite3_finalize sqlite-check-result ;
119 : sqlite-reset ( handle -- ) sqlite3_reset sqlite-check-result ;
120 : sqlite-clear-bindings ( handle -- )
121     sqlite3_clear_bindings sqlite-check-result ;
122 : sqlite-#columns ( query -- int ) sqlite3_column_count ;
123 : sqlite-column ( handle index -- string ) sqlite3_column_text ;
124 : sqlite-column-name ( handle index -- string ) sqlite3_column_name ;
125 : sqlite-column-type ( handle index -- string ) sqlite3_column_type ;
126
127 : sqlite-column-blob ( handle index -- byte-array/f )
128     [ sqlite3_column_bytes ] 2keep
129     pick zero? [
130         3drop f
131     ] [
132         sqlite3_column_blob swap memory>byte-array
133     ] if ;
134
135 : sqlite-column-typed ( handle index type -- obj )
136     dup array? [ first ] when
137     {
138         { +db-assigned-id+ [ sqlite3_column_int64  ] }
139         { +random-id+ [ sqlite3-column-uint64 ] }
140         { INTEGER [ sqlite3_column_int ] }
141         { BIG-INTEGER [ sqlite3_column_int64 ] }
142         { SIGNED-BIG-INTEGER [ sqlite3_column_int64 ] }
143         { UNSIGNED-BIG-INTEGER [ sqlite3-column-uint64 ] }
144         { DOUBLE [ sqlite3_column_double ] }
145         { TEXT [ sqlite3_column_text ] }
146         { VARCHAR [ sqlite3_column_text ] }
147         { DATE [ sqlite3_column_text dup [ ymd>timestamp ] when ] }
148         { TIME [ sqlite3_column_text dup [ hms>timestamp ] when ] }
149         { TIMESTAMP [ sqlite3_column_text dup [ ymdhms>timestamp ] when ] }
150         { DATETIME [ sqlite3_column_text dup [ ymdhms>timestamp ] when ] }
151         { BLOB [ sqlite-column-blob ] }
152         { URL [ sqlite3_column_text dup [ >url ] when ] }
153         { FACTOR-BLOB [
154             sqlite-column-blob
155             dup [ bytes>object ] when
156         ] }
157         ! { NULL [ 2drop f ] }
158         [ no-sql-type ]
159     } case ;
160
161 : sqlite-row ( handle -- seq )
162     dup sqlite-#columns [ sqlite-column ] with map ;
163
164 : sqlite-step-has-more-rows? ( prepared -- bool )
165     {
166         { SQLITE_ROW [ t ] }
167         { SQLITE_DONE [ f ] }
168         [ sqlite-check-result f ]
169     } case ;
170
171 : sqlite-next ( prepared -- ? )
172     sqlite3_step sqlite-step-has-more-rows? ;