sqlite3 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +7 -4
- data/VERSION +1 -1
- data/lib/sqlite3.rb +15 -0
- data/lib/sqlite3/database.rb +16 -339
- data/lib/sqlite3/driver/ffi/api.rb +65 -218
- data/lib/sqlite3/driver/ffi/driver.rb +141 -194
- data/lib/sqlite3/encoding.rb +43 -0
- data/lib/sqlite3/errors.rb +0 -2
- data/lib/sqlite3/pragmas.rb +0 -2
- data/lib/sqlite3/resultset.rb +8 -8
- data/lib/sqlite3/statement.rb +4 -18
- data/lib/sqlite3/translator.rb +0 -3
- data/lib/sqlite3/value.rb +0 -2
- data/test/fixtures/SQLite.gif +0 -0
- data/test/test_database_initialization.rb +25 -0
- data/test/test_database_queries_utf_16.rb +80 -0
- data/test/test_database_queries_utf_8.rb +80 -0
- metadata +18 -10
- data/test/test_database_queries.rb +0 -29
@@ -1,260 +1,107 @@
|
|
1
|
-
require "ffi"
|
2
|
-
|
3
1
|
module SQLite3
|
4
2
|
module Driver
|
5
3
|
module FFI
|
6
4
|
|
7
5
|
module API
|
8
|
-
|
9
6
|
extend ::FFI::Library
|
10
7
|
|
11
|
-
|
8
|
+
# TODO: cleanup
|
9
|
+
ffi_lib case RUBY_PLATFORM.downcase
|
10
|
+
when /darwin/
|
11
|
+
"libsqlite3.dylib"
|
12
|
+
when /linux|freebsd|netbsd|openbsd|dragonfly|solaris/
|
13
|
+
"libsqlite3.so"
|
14
|
+
when /win32/
|
15
|
+
"sqlite3.dll"
|
16
|
+
else
|
17
|
+
abort <<-EOF
|
18
|
+
==== UNSUPPORTED PLATFORM ======================================================
|
19
|
+
The platform '#{RUBY_PLATFORM}' is unsupported. Please help the author by
|
20
|
+
editing the following file to allow your sqlite3 library to be found, and
|
21
|
+
submitting a patch to qoobaa@gmail.com. Thanks!
|
22
|
+
|
23
|
+
#{__FILE__}
|
24
|
+
================================================================================
|
25
|
+
EOF
|
26
|
+
end
|
12
27
|
|
13
|
-
# extern "const char *sqlite3_libversion()"
|
14
28
|
attach_function :sqlite3_libversion, [], :string
|
15
|
-
|
16
|
-
# extern "int sqlite3_open(const char*,db*)"
|
17
29
|
attach_function :sqlite3_open, [:string, :pointer], :int
|
18
|
-
|
19
|
-
# extern "int sqlite3_open16(const void*,db*)"
|
20
30
|
attach_function :sqlite3_open16, [:pointer, :pointer], :int
|
21
|
-
|
22
|
-
# extern "int sqlite3_close(db)"
|
23
31
|
attach_function :sqlite3_close, [:pointer], :int
|
24
|
-
|
25
|
-
# extern "const char* sqlite3_errmsg(db)"
|
26
32
|
attach_function :sqlite3_errmsg, [:pointer], :string
|
27
|
-
|
28
|
-
# extern "void* sqlite3_errmsg16(db)"
|
29
33
|
attach_function :sqlite3_errmsg16, [:pointer], :pointer
|
30
|
-
|
31
|
-
# extern "int sqlite3_errcode(db)"
|
32
34
|
attach_function :sqlite3_errcode, [:pointer], :int
|
33
|
-
|
34
|
-
# extern "int sqlite3_prepare(db,const char*,int,stmt*,const char**)"
|
35
35
|
attach_function :sqlite3_prepare, [:pointer, :string, :int, :pointer, :pointer], :int
|
36
|
-
|
37
|
-
# extern "int sqlite3_prepare16(db,const void*,int,stmt*,const void**)"
|
38
|
-
attach_function :sqlite3_prepare16, [:pointer, :pointer, :int, :pointer, :pointer], :int
|
39
|
-
|
40
|
-
# extern "int sqlite3_finalize(stmt)"
|
36
|
+
# attach_function :sqlite3_prepare16, [:pointer, :pointer, :int, :pointer, :pointer], :int
|
41
37
|
attach_function :sqlite3_finalize, [:pointer], :int
|
42
|
-
|
43
|
-
# extern "int sqlite3_reset(stmt)"
|
44
|
-
attach_function :sqlite3_reset, [:pointer], :int
|
45
|
-
|
46
|
-
# extern "int sqlite3_step(stmt)"
|
38
|
+
# attach_function :sqlite3_reset, [:pointer], :int
|
47
39
|
attach_function :sqlite3_step, [:pointer], :int
|
48
|
-
|
49
|
-
# extern "int64 sqlite3_last_insert_rowid(db)"
|
50
40
|
attach_function :sqlite3_last_insert_rowid, [:pointer], :int64
|
51
|
-
|
52
|
-
#
|
53
|
-
attach_function :
|
54
|
-
|
55
|
-
#
|
56
|
-
attach_function :sqlite3_total_changes, [:pointer], :int
|
57
|
-
|
58
|
-
# extern "void sqlite3_interrupt(db)"
|
59
|
-
attach_function :sqlite3_interrupt, [:pointer], :void
|
60
|
-
|
61
|
-
# extern "ibool sqlite3_complete(const char*)"
|
62
|
-
attach_function :sqlite3_complete, [:string], :int
|
63
|
-
|
64
|
-
# extern "ibool sqlite3_complete16(const void*)"
|
65
|
-
attach_function :sqlite3_complete16, [:pointer], :int
|
66
|
-
|
67
|
-
# extern "int sqlite3_busy_handler(db,void*,void*)"
|
68
|
-
attach_function :sqlite3_busy_handler, [:pointer, :pointer, :pointer], :int
|
69
|
-
|
70
|
-
# extern "int sqlite3_busy_timeout(db,int)"
|
41
|
+
# attach_function :sqlite3_changes, [:pointer], :int
|
42
|
+
# attach_function :sqlite3_total_changes, [:pointer], :int
|
43
|
+
# attach_function :sqlite3_interrupt, [:pointer], :void
|
44
|
+
# attach_function :sqlite3_complete, [:string], :int
|
45
|
+
# attach_function :sqlite3_complete16, [:pointer], :int
|
71
46
|
attach_function :sqlite3_busy_timeout, [:pointer, :int], :int
|
72
|
-
|
73
|
-
# extern "int sqlite3_set_authorizer(db,void*,void*)"
|
74
|
-
attach_function :sqlite3_set_authorizer, [:pointer, :pointer, :pointer], :int
|
75
|
-
|
76
|
-
# extern "void* sqlite3_trace(db,void*,void*)"
|
77
|
-
attach_function :sqlite3_trace, [:pointer, :pointer, :pointer], :pointer
|
78
|
-
|
79
|
-
# extern "int sqlite3_bind_blob(stmt,int,const void*,int,void*)"
|
80
47
|
attach_function :sqlite3_bind_blob, [:pointer, :int, :pointer, :int, :pointer], :int
|
81
|
-
|
82
|
-
# extern "int sqlite3_bind_double(stmt,int,double)"
|
83
48
|
attach_function :sqlite3_bind_double, [:pointer, :int, :double], :int
|
84
|
-
|
85
|
-
# extern "int sqlite3_bind_int(stmt,int,int)"
|
86
49
|
attach_function :sqlite3_bind_int, [:pointer, :int, :int], :int
|
87
|
-
|
88
|
-
# extern "int sqlite3_bind_int64(stmt,int,int64)"
|
89
50
|
attach_function :sqlite3_bind_int64, [:pointer, :int, :int64], :int
|
90
|
-
|
91
|
-
# extern "int sqlite3_bind_null(stmt,int)"
|
92
51
|
attach_function :sqlite3_bind_null, [:pointer, :int], :int
|
93
|
-
|
94
|
-
# extern "int sqlite3_bind_text(stmt,int,const char*,int,void*)"
|
95
52
|
attach_function :sqlite3_bind_text, [:pointer, :int, :string, :int, :pointer], :int
|
96
|
-
|
97
|
-
# extern "int sqlite3_bind_text16(stmt,int,const void*,int,void*)"
|
98
53
|
attach_function :sqlite3_bind_text16, [:pointer, :int, :pointer, :int, :pointer], :int
|
99
|
-
|
100
|
-
#
|
101
|
-
attach_function :
|
102
|
-
|
103
|
-
# extern "int sqlite3_bind_parameter_count(stmt)"
|
104
|
-
attach_function :sqlite3_bind_parameter_count, [:pointer], :int
|
105
|
-
|
106
|
-
# extern "const char* sqlite3_bind_parameter_name(stmt,int)"
|
107
|
-
attach_function :sqlite3_bind_parameter_name, [:pointer, :int], :string
|
108
|
-
|
109
|
-
# extern "int sqlite3_bind_parameter_index(stmt,const char*)"
|
110
|
-
attach_function :sqlite3_bind_parameter_index, [:pointer, :string], :int
|
111
|
-
|
112
|
-
# extern "int sqlite3_column_count(stmt)"
|
54
|
+
# attach_function :sqlite3_bind_value, [:pointer, :int, :pointer], :int
|
55
|
+
# attach_function :sqlite3_bind_parameter_count, [:pointer], :int
|
56
|
+
# attach_function :sqlite3_bind_parameter_name, [:pointer, :int], :string
|
57
|
+
# attach_function :sqlite3_bind_parameter_index, [:pointer, :string], :int
|
113
58
|
attach_function :sqlite3_column_count, [:pointer], :int
|
114
|
-
|
115
|
-
# extern "int sqlite3_data_count(stmt)"
|
116
59
|
attach_function :sqlite3_data_count, [:pointer], :int
|
117
|
-
|
118
|
-
# extern "const void *sqlite3_column_blob(stmt,int)"
|
119
60
|
attach_function :sqlite3_column_blob, [:pointer, :int], :pointer
|
120
|
-
|
121
|
-
# extern "int sqlite3_column_bytes(stmt,int)"
|
122
61
|
attach_function :sqlite3_column_bytes, [:pointer, :int], :int
|
123
|
-
|
124
|
-
# extern "int sqlite3_column_bytes16(stmt,int)"
|
125
62
|
attach_function :sqlite3_column_bytes16, [:pointer, :int], :int
|
126
|
-
|
127
|
-
# extern "const char *sqlite3_column_decltype(stmt,int)"
|
128
63
|
attach_function :sqlite3_column_decltype, [:pointer, :int], :string
|
129
|
-
|
130
|
-
# extern "void *sqlite3_column_decltype16(stmt,int)"
|
131
|
-
attach_function :sqlite3_column_decltype16, [:pointer, :int], :pointer
|
132
|
-
|
133
|
-
# extern "double sqlite3_column_double(stmt,int)"
|
64
|
+
# attach_function :sqlite3_column_decltype16, [:pointer, :int], :pointer
|
134
65
|
attach_function :sqlite3_column_double, [:pointer, :int], :double
|
135
|
-
|
136
|
-
# extern "int sqlite3_column_int(stmt,int)"
|
137
|
-
attach_function :sqlite3_column_int, [:pointer, :int], :int
|
138
|
-
|
139
|
-
# extern "int64 sqlite3_column_int64(stmt,int)"
|
66
|
+
# attach_function :sqlite3_column_int, [:pointer, :int], :int
|
140
67
|
attach_function :sqlite3_column_int64, [:pointer, :int], :int64
|
141
|
-
|
142
|
-
# extern "const char *sqlite3_column_name(stmt,int)"
|
143
68
|
attach_function :sqlite3_column_name, [:pointer, :int], :string
|
144
|
-
|
145
|
-
# extern "const void *sqlite3_column_name16(stmt,int)"
|
146
|
-
attach_function :sqlite3_column_name16, [:pointer, :int], :pointer
|
147
|
-
|
148
|
-
# extern "const char *sqlite3_column_text(stmt,int)"
|
69
|
+
# attach_function :sqlite3_column_name16, [:pointer, :int], :pointer
|
149
70
|
attach_function :sqlite3_column_text, [:pointer, :int], :string
|
150
|
-
|
151
|
-
# extern "const void *sqlite3_column_text16(stmt,int)"
|
152
71
|
attach_function :sqlite3_column_text16, [:pointer, :int], :pointer
|
153
|
-
|
154
|
-
# extern "int sqlite3_column_type(stmt,int)"
|
155
72
|
attach_function :sqlite3_column_type, [:pointer, :int], :int
|
156
|
-
|
157
|
-
#
|
158
|
-
attach_function :
|
159
|
-
|
160
|
-
#
|
161
|
-
attach_function :
|
162
|
-
|
163
|
-
#
|
164
|
-
attach_function :
|
165
|
-
|
166
|
-
#
|
167
|
-
attach_function :
|
168
|
-
|
169
|
-
#
|
170
|
-
attach_function :
|
171
|
-
|
172
|
-
#
|
173
|
-
attach_function :
|
174
|
-
|
175
|
-
#
|
176
|
-
attach_function :
|
177
|
-
|
178
|
-
#
|
179
|
-
attach_function :
|
180
|
-
|
181
|
-
#
|
182
|
-
attach_function :
|
183
|
-
|
184
|
-
#
|
185
|
-
attach_function :
|
186
|
-
|
187
|
-
#
|
188
|
-
attach_function :sqlite3_value_text16, [:pointer], :pointer
|
189
|
-
|
190
|
-
# extern "const void* sqlite3_value_text16le(value)"
|
191
|
-
attach_function :sqlite3_value_text16le, [:pointer], :pointer
|
192
|
-
|
193
|
-
# extern "const void* sqlite3_value_text16be(value)"
|
194
|
-
attach_function :sqlite3_value_text16be, [:pointer], :pointer
|
195
|
-
|
196
|
-
# extern "int sqlite3_value_type(value)"
|
197
|
-
attach_function :sqlite3_value_type, [:pointer], :int
|
198
|
-
|
199
|
-
# extern "void *sqlite3_aggregate_context(context,int)"
|
200
|
-
attach_function :sqlite3_aggregate_context, [:pointer, :int], :pointer
|
201
|
-
|
202
|
-
# extern "void *sqlite3_user_data(context)"
|
203
|
-
attach_function :sqlite3_user_data, [:pointer], :pointer
|
204
|
-
|
205
|
-
# extern "void *sqlite3_get_auxdata(context,int)"
|
206
|
-
attach_function :sqlite3_get_auxdata, [:pointer, :int], :pointer
|
207
|
-
|
208
|
-
# extern "void sqlite3_set_auxdata(context,int,void*,void*)"
|
209
|
-
attach_function :sqlite3_set_auxdata, [:pointer, :int, :pointer, :pointer], :void
|
210
|
-
|
211
|
-
# extern "void sqlite3_result_blob(context,const void*,int,void*)"
|
212
|
-
attach_function :sqlite3_result_blob, [:pointer, :pointer, :int, :pointer], :void
|
213
|
-
|
214
|
-
# extern "void sqlite3_result_double(context,double)"
|
215
|
-
attach_function :sqlite3_result_double, [:pointer, :double], :void
|
216
|
-
|
217
|
-
# extern "void sqlite3_result_error(context,const char*,int)"
|
218
|
-
attach_function :sqlite3_result_error, [:pointer, :string, :int], :void
|
219
|
-
|
220
|
-
# extern "void sqlite3_result_error16(context,const void*,int)"
|
221
|
-
attach_function :sqlite3_result_error16, [:pointer, :pointer, :int], :void
|
222
|
-
|
223
|
-
# extern "void sqlite3_result_int(context,int)"
|
224
|
-
attach_function :sqlite3_result_int, [:pointer, :int], :void
|
225
|
-
|
226
|
-
# extern "void sqlite3_result_int64(context,int64)"
|
227
|
-
attach_function :sqlite3_result_int64, [:pointer, :int64], :void
|
228
|
-
|
229
|
-
# extern "void sqlite3_result_null(context)"
|
230
|
-
attach_function :sqlite3_result_null, [:pointer], :void
|
231
|
-
|
232
|
-
# extern "void sqlite3_result_text(context,const char*,int,void*)"
|
233
|
-
attach_function :sqlite3_result_text, [:pointer, :string, :int, :pointer], :void
|
234
|
-
|
235
|
-
# extern "void sqlite3_result_text16(context,const void*,int,void*)"
|
236
|
-
attach_function :sqlite3_result_text16, [:pointer, :pointer, :int, :pointer], :void
|
237
|
-
|
238
|
-
# extern "void sqlite3_result_text16le(context,const void*,int,void*)"
|
239
|
-
attach_function :sqlite3_result_text16le, [:pointer, :pointer, :int, :pointer], :void
|
240
|
-
|
241
|
-
# extern "void sqlite3_result_text16be(context,const void*,int,void*)"
|
242
|
-
attach_function :sqlite3_result_text16be, [:pointer, :pointer, :int, :pointer], :void
|
243
|
-
|
244
|
-
# extern "void sqlite3_result_value(context,value)"
|
245
|
-
attach_function :sqlite3_result_value, [:pointer, :pointer], :void
|
246
|
-
|
247
|
-
# extern "int sqlite3_create_collation(db,const char*,int,void*,void*)"
|
248
|
-
attach_function :sqlite3_create_collation, [:pointer, :string, :int, :pointer, :pointer], :int
|
249
|
-
|
250
|
-
# extern "int sqlite3_create_collation16(db,const char*,int,void*,void*)"
|
251
|
-
attach_function :sqlite3_create_collation16, [:pointer, :string, :int, :pointer, :pointer], :int
|
252
|
-
|
253
|
-
# extern "int sqlite3_collation_needed(db,void*,void*)"
|
254
|
-
attach_function :sqlite3_collation_needed, [:pointer, :pointer, :pointer], :int
|
255
|
-
|
256
|
-
# extern "int sqlite3_collation_needed16(db,void*,void*)"
|
257
|
-
attach_function :sqlite3_collation_needed16, [:pointer, :pointer, :pointer], :int
|
73
|
+
# attach_function :sqlite3_aggregate_count, [:pointer], :int
|
74
|
+
# attach_function :sqlite3_value_blob, [:pointer], :pointer
|
75
|
+
# attach_function :sqlite3_value_bytes, [:pointer], :int
|
76
|
+
# attach_function :sqlite3_value_bytes16, [:pointer], :int
|
77
|
+
# attach_function :sqlite3_value_double, [:pointer], :double
|
78
|
+
# attach_function :sqlite3_value_int, [:pointer], :int
|
79
|
+
# attach_function :sqlite3_value_int64, [:pointer], :int64
|
80
|
+
# attach_function :sqlite3_value_text, [:pointer], :string
|
81
|
+
# attach_function :sqlite3_value_text16, [:pointer], :pointer
|
82
|
+
# attach_function :sqlite3_value_text16le, [:pointer], :pointer
|
83
|
+
# attach_function :sqlite3_value_text16be, [:pointer], :pointer
|
84
|
+
# attach_function :sqlite3_value_type, [:pointer], :int
|
85
|
+
# attach_function :sqlite3_aggregate_context, [:pointer, :int], :pointer
|
86
|
+
# attach_function :sqlite3_user_data, [:pointer], :pointer
|
87
|
+
# attach_function :sqlite3_get_auxdata, [:pointer, :int], :pointer
|
88
|
+
# attach_function :sqlite3_set_auxdata, [:pointer, :int, :pointer, :pointer], :void
|
89
|
+
# attach_function :sqlite3_result_blob, [:pointer, :pointer, :int, :pointer], :void
|
90
|
+
# attach_function :sqlite3_result_double, [:pointer, :double], :void
|
91
|
+
# attach_function :sqlite3_result_error, [:pointer, :string, :int], :void
|
92
|
+
# attach_function :sqlite3_result_error16, [:pointer, :pointer, :int], :void
|
93
|
+
# attach_function :sqlite3_result_int, [:pointer, :int], :void
|
94
|
+
# attach_function :sqlite3_result_int64, [:pointer, :int64], :void
|
95
|
+
# attach_function :sqlite3_result_null, [:pointer], :void
|
96
|
+
# attach_function :sqlite3_result_text, [:pointer, :string, :int, :pointer], :void
|
97
|
+
# attach_function :sqlite3_result_text16, [:pointer, :pointer, :int, :pointer], :void
|
98
|
+
# attach_function :sqlite3_result_text16le, [:pointer, :pointer, :int, :pointer], :void
|
99
|
+
# attach_function :sqlite3_result_text16be, [:pointer, :pointer, :int, :pointer], :void
|
100
|
+
# attach_function :sqlite3_result_value, [:pointer, :pointer], :void
|
101
|
+
# attach_function :sqlite3_create_collation, [:pointer, :string, :int, :pointer, :pointer], :int
|
102
|
+
# attach_function :sqlite3_create_collation16, [:pointer, :string, :int, :pointer, :pointer], :int
|
103
|
+
# attach_function :sqlite3_collation_needed, [:pointer, :pointer, :pointer], :int
|
104
|
+
# attach_function :sqlite3_collation_needed16, [:pointer, :pointer, :pointer], :int
|
258
105
|
end
|
259
106
|
|
260
107
|
end
|
@@ -5,206 +5,140 @@ module SQLite3
|
|
5
5
|
module FFI
|
6
6
|
|
7
7
|
class Driver
|
8
|
-
|
9
|
-
TRANSIENT = -1
|
8
|
+
TRANSIENT = ::FFI::Pointer.new(-1)
|
10
9
|
|
11
|
-
def open(filename,
|
10
|
+
def open(filename, utf_16 = false)
|
12
11
|
handle = ::FFI::MemoryPointer.new(:pointer)
|
13
|
-
|
12
|
+
if utf_16
|
13
|
+
filename = filename.encode(Encoding.utf_16native)
|
14
|
+
result = API.sqlite3_open16(c_string(filename), handle)
|
15
|
+
else
|
16
|
+
filename = filename.encode(Encoding.utf_8)
|
17
|
+
result = API.sqlite3_open(filename, handle)
|
18
|
+
end
|
14
19
|
[result, handle.get_pointer(0)]
|
15
20
|
end
|
16
21
|
|
17
|
-
def errmsg(db,
|
18
|
-
if
|
19
|
-
|
20
|
-
|
21
|
-
msg.to_s(utf16_length(msg))
|
22
|
+
def errmsg(db, utf_16 = false)
|
23
|
+
if utf_16
|
24
|
+
ptr = API.sqlite3_errmsg16(db)
|
25
|
+
get_string_utf_16(ptr).force_encoding(Encoding.utf_16native)
|
22
26
|
else
|
23
|
-
API.sqlite3_errmsg(db)
|
27
|
+
API.sqlite3_errmsg(db).force_encoding(Encoding.utf_8)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
def prepare(db, sql
|
31
|
+
def prepare(db, sql)
|
28
32
|
handle = ::FFI::MemoryPointer.new(:pointer)
|
29
33
|
remainder = ::FFI::MemoryPointer.new(:pointer)
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def complete?(sql, utf16 = false)
|
41
|
-
API.send(utf16 ? :sqlite3_complete16 : :sqlite3_complete, sql)
|
42
|
-
end
|
43
|
-
|
44
|
-
def value_blob(value)
|
45
|
-
blob = API.sqlite3_value_blob(value)
|
46
|
-
blob.free = nil
|
47
|
-
blob.to_s(API.sqlite3_value_bytes(value))
|
48
|
-
end
|
49
|
-
|
50
|
-
def value_text(value, utf16 = false)
|
51
|
-
method = case utf16
|
52
|
-
when nil, false
|
53
|
-
:sqlite3_value_text
|
54
|
-
when :le
|
55
|
-
:sqlite3_value_text16le
|
56
|
-
when :be
|
57
|
-
:sqlite3_value_text16be
|
58
|
-
else
|
59
|
-
:sqlite3_value_text16
|
60
|
-
end
|
61
|
-
|
62
|
-
result = API.send(method, value)
|
63
|
-
if utf16
|
64
|
-
result.free = nil
|
65
|
-
size = API.sqlite3_value_bytes(value)
|
66
|
-
result = result.to_s(size)
|
35
|
+
if Encoding.utf_16?(sql)
|
36
|
+
str = c_string(sql)
|
37
|
+
result = API.sqlite3_prepare16(db, str, str.bytesize, handle, remainder)
|
38
|
+
remainder_string = get_string_utf_16(remainder.get_pointer(0))
|
39
|
+
else
|
40
|
+
result = API.sqlite3_prepare(db, sql, sql.bytesize, handle, remainder)
|
41
|
+
remainder_string = remainder.get_pointer(0).get_string(0)
|
67
42
|
end
|
68
43
|
|
69
|
-
result
|
44
|
+
[result, handle.get_pointer(0), remainder_string]
|
45
|
+
end
|
46
|
+
|
47
|
+
# def complete?(sql)
|
48
|
+
# API.send(utf16?(string) ? :sqlite3_complete16 : :sqlite3_complete, sql)
|
49
|
+
# end
|
50
|
+
|
51
|
+
# def value_blob(value)
|
52
|
+
# blob = API.sqlite3_value_blob(value)
|
53
|
+
# # blob.free = nil
|
54
|
+
# blob.to_s(API.sqlite3_value_bytes(value))
|
55
|
+
# end
|
56
|
+
|
57
|
+
# def value_text(value)
|
58
|
+
# method = case utf16
|
59
|
+
# when nil, false
|
60
|
+
# :sqlite3_value_text
|
61
|
+
# when :le
|
62
|
+
# :sqlite3_value_text16le
|
63
|
+
# when :be
|
64
|
+
# :sqlite3_value_text16be
|
65
|
+
# else
|
66
|
+
# :sqlite3_value_text16
|
67
|
+
# end
|
68
|
+
|
69
|
+
# result = API.send(method, value)
|
70
|
+
|
71
|
+
# if utf16
|
72
|
+
# # result.free = nil
|
73
|
+
# size = API.sqlite3_value_bytes(value)
|
74
|
+
# result = result.to_s(size)
|
75
|
+
# end
|
76
|
+
|
77
|
+
# result
|
78
|
+
# end
|
79
|
+
|
80
|
+
# def result_text(func, text)
|
81
|
+
# method = case utf16
|
82
|
+
# when false, nil
|
83
|
+
# :sqlite3_result_text
|
84
|
+
# when :le
|
85
|
+
# :sqlite3_result_text16le
|
86
|
+
# when :be
|
87
|
+
# :sqlite3_result_text16be
|
88
|
+
# else
|
89
|
+
# :sqlite3_result_text16
|
90
|
+
# end
|
91
|
+
|
92
|
+
# s = text.to_s
|
93
|
+
# API.send(method, func, s, s.length, TRANSIENT)
|
94
|
+
# end
|
95
|
+
|
96
|
+
# def aggregate_context(context)
|
97
|
+
# ptr = API.sqlite3_aggregate_context(context, 4)
|
98
|
+
# ptr.free = nil
|
99
|
+
# obj = (ptr ? ptr.to_object : nil)
|
100
|
+
# if obj.nil?
|
101
|
+
# obj = Hash.new
|
102
|
+
# ptr.set_object obj
|
103
|
+
# end
|
104
|
+
# obj
|
105
|
+
# end
|
106
|
+
|
107
|
+
def bind_string(stmt, index, value)
|
108
|
+
case value.encoding
|
109
|
+
when Encoding.utf_8, Encoding.us_ascii
|
110
|
+
API.sqlite3_bind_text(stmt, index, value, value.bytesize, TRANSIENT)
|
111
|
+
when Encoding.utf_16le, Encoding.utf_16be
|
112
|
+
value = add_byte_order_mask(value)
|
113
|
+
API.sqlite3_bind_text16(stmt, index, value, value.bytesize, TRANSIENT)
|
114
|
+
else
|
115
|
+
API.sqlite3_bind_blob(stmt, index, value, value.bytesize, TRANSIENT)
|
116
|
+
end
|
70
117
|
end
|
71
118
|
|
72
119
|
def column_blob(stmt, column)
|
73
120
|
blob = API.sqlite3_column_blob(stmt, column)
|
74
|
-
|
75
|
-
blob.
|
76
|
-
end
|
77
|
-
|
78
|
-
def result_text(func, text, utf16 = false)
|
79
|
-
method = case utf16
|
80
|
-
when false, nil
|
81
|
-
:sqlite3_result_text
|
82
|
-
when :le
|
83
|
-
:sqlite3_result_text16le
|
84
|
-
when :be
|
85
|
-
:sqlite3_result_text16be
|
86
|
-
else
|
87
|
-
:sqlite3_result_text16
|
88
|
-
end
|
89
|
-
|
90
|
-
s = text.to_s
|
91
|
-
API.send(method, func, s, s.length, TRANSIENT)
|
92
|
-
end
|
93
|
-
|
94
|
-
def busy_handler(db, data = nil, &block)
|
95
|
-
@busy_handler = block
|
96
|
-
|
97
|
-
unless @busy_handler_callback
|
98
|
-
@busy_handler_callback = ::DL.callback("IPI") do |cookie, timeout|
|
99
|
-
@busy_handler.call(cookie, timeout) || 0
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
API.sqlite3_busy_handler(db, block&&@busy_handler_callback, data)
|
104
|
-
end
|
105
|
-
|
106
|
-
def set_authorizer(db, data = nil, &block)
|
107
|
-
@authorizer_handler = block
|
108
|
-
|
109
|
-
unless @authorizer_handler_callback
|
110
|
-
@authorizer_handler_callback = ::DL.callback("IPIPPPP") do |cookie,mode,a,b,c,d|
|
111
|
-
@authorizer_handler.call(cookie, mode, a&&a.to_s, b&&b.to_s, c&&c.to_s, d&&d.to_s) || 0
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
API.sqlite3_set_authorizer(db, block&&@authorizer_handler_callback, data)
|
116
|
-
end
|
117
|
-
|
118
|
-
def trace(db, data = nil, &block)
|
119
|
-
@trace_handler = block
|
120
|
-
|
121
|
-
unless @trace_handler_callback
|
122
|
-
@trace_handler_callback = ::DL.callback("IPS") do |cookie,sql|
|
123
|
-
@trace_handler.call(cookie ? cookie.to_object : nil, sql) || 0
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
API.sqlite3_trace(db, block&&@trace_handler_callback, data)
|
121
|
+
length = API.sqlite3_column_bytes(stmt, column)
|
122
|
+
blob.get_bytes(0, length) # free?
|
128
123
|
end
|
129
124
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
if @step_handler_callback.nil? && step
|
141
|
-
@step_handler_callback = ::DL.callback("0PIP") do |context,nargs,args|
|
142
|
-
args = args.to_s(nargs*4).unpack("L*").map {|i| ::FFI::MemoryPointer.new(i)}
|
143
|
-
data = API.sqlite3_user_data(context).to_object
|
144
|
-
data[:step].call(context, *args)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
if @final_handler_callback.nil? && final
|
149
|
-
@final_handler_callback = ::DL.callback("0P") do |context|
|
150
|
-
data = API.sqlite3_user_data(context).to_object
|
151
|
-
data[:final].call(context)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
data = {
|
156
|
-
:cookie => cookie,
|
157
|
-
:name => name,
|
158
|
-
:func => func,
|
159
|
-
:step => step,
|
160
|
-
:final => final
|
161
|
-
}
|
162
|
-
|
163
|
-
API.sqlite3_create_function(db, name, args, text, data, (func ? @func_handler_callback : nil), (step ? @step_handler_callback : nil), (final ? @final_handler_callback : nil))
|
164
|
-
end
|
165
|
-
|
166
|
-
def aggregate_context(context)
|
167
|
-
ptr = API.sqlite3_aggregate_context(context, 4)
|
168
|
-
ptr.free = nil
|
169
|
-
obj = (ptr ? ptr.to_object : nil)
|
170
|
-
if obj.nil?
|
171
|
-
obj = Hash.new
|
172
|
-
ptr.set_object obj
|
125
|
+
def column_text(stmt, column, utf_16 = false)
|
126
|
+
if utf_16
|
127
|
+
ptr = API.sqlite3_column_text16(stmt, column)
|
128
|
+
length = API.sqlite3_column_bytes16(stmt, column)
|
129
|
+
ptr.get_bytes(0, length).force_encoding(Encoding.utf_16native) # free?
|
130
|
+
else
|
131
|
+
API.sqlite3_column_text(stmt, column).force_encoding(Encoding.utf_8)
|
173
132
|
end
|
174
|
-
obj
|
175
|
-
end
|
176
|
-
|
177
|
-
def bind_blob(stmt, index, value)
|
178
|
-
s = value.to_s
|
179
|
-
API.sqlite3_bind_blob(stmt, index, s, s.length, TRANSIENT)
|
180
|
-
end
|
181
|
-
|
182
|
-
def bind_text(stmt, index, value, utf16 = false)
|
183
|
-
s = value.to_s
|
184
|
-
method = (utf16 ? :sqlite3_bind_text16 : :sqlite3_bind_text)
|
185
|
-
API.send(method, stmt, index, s, s.length, TRANSIENT)
|
186
|
-
end
|
187
|
-
|
188
|
-
def column_text(stmt, column)
|
189
|
-
result = API.sqlite3_column_text(stmt, column)
|
190
|
-
result ? result.to_s : nil
|
191
|
-
end
|
192
|
-
|
193
|
-
def column_name(stmt, column)
|
194
|
-
result = API.sqlite3_column_name(stmt, column)
|
195
|
-
result ? result.to_s : nil
|
196
|
-
end
|
197
|
-
|
198
|
-
def column_decltype(stmt, column)
|
199
|
-
result = API.sqlite3_column_decltype(stmt, column)
|
200
|
-
result ? result.to_s : nil
|
201
133
|
end
|
202
134
|
|
203
135
|
def self.api_delegate(name)
|
204
136
|
define_method(name) { |*args| API.send("sqlite3_#{name}", *args) }
|
205
137
|
end
|
206
138
|
|
207
|
-
api_delegate :
|
139
|
+
api_delegate :column_name
|
140
|
+
api_delegate :column_decltype
|
141
|
+
# api_delegate :aggregate_count
|
208
142
|
api_delegate :bind_double
|
209
143
|
api_delegate :bind_int
|
210
144
|
api_delegate :bind_int64
|
@@ -212,44 +146,57 @@ module SQLite3
|
|
212
146
|
api_delegate :bind_parameter_index
|
213
147
|
api_delegate :bind_parameter_name
|
214
148
|
api_delegate :busy_timeout
|
215
|
-
api_delegate :changes
|
149
|
+
# api_delegate :changes
|
216
150
|
api_delegate :close
|
217
|
-
api_delegate :column_bytes
|
218
|
-
api_delegate :column_bytes16
|
151
|
+
# api_delegate :column_bytes
|
152
|
+
# api_delegate :column_bytes16
|
219
153
|
api_delegate :column_count
|
220
154
|
api_delegate :column_double
|
221
|
-
api_delegate :column_int
|
155
|
+
# api_delegate :column_int
|
222
156
|
api_delegate :column_int64
|
223
157
|
api_delegate :column_type
|
224
158
|
api_delegate :data_count
|
225
159
|
api_delegate :errcode
|
226
160
|
api_delegate :finalize
|
227
|
-
api_delegate :interrupt
|
161
|
+
# api_delegate :interrupt
|
228
162
|
api_delegate :last_insert_rowid
|
229
163
|
api_delegate :libversion
|
230
|
-
api_delegate :reset
|
231
|
-
api_delegate :result_error
|
164
|
+
# api_delegate :reset
|
165
|
+
# api_delegate :result_error
|
232
166
|
api_delegate :step
|
233
|
-
api_delegate :total_changes
|
234
|
-
api_delegate :value_bytes
|
235
|
-
api_delegate :value_bytes16
|
236
|
-
api_delegate :value_double
|
237
|
-
api_delegate :value_int
|
238
|
-
api_delegate :value_int64
|
239
|
-
api_delegate :value_type
|
167
|
+
# api_delegate :total_changes
|
168
|
+
# api_delegate :value_bytes
|
169
|
+
# api_delegate :value_bytes16
|
170
|
+
# api_delegate :value_double
|
171
|
+
# api_delegate :value_int
|
172
|
+
# api_delegate :value_int64
|
173
|
+
# api_delegate :value_type
|
240
174
|
|
241
175
|
private
|
242
176
|
|
243
|
-
def
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
177
|
+
def c_string(string)
|
178
|
+
if Encoding.utf_16?(string)
|
179
|
+
result = add_byte_order_mask(string)
|
180
|
+
terminate_string!(result)
|
181
|
+
else
|
182
|
+
string # FFI does the job
|
248
183
|
end
|
249
|
-
len
|
250
184
|
end
|
251
|
-
end
|
252
185
|
|
186
|
+
def add_byte_order_mask(string)
|
187
|
+
"\uFEFF".encode(string.encoding) + string
|
188
|
+
end
|
189
|
+
|
190
|
+
def terminate_string!(string)
|
191
|
+
string << "\0\0".force_encoding(string.encoding)
|
192
|
+
end
|
193
|
+
|
194
|
+
def get_string_utf_16(ptr)
|
195
|
+
length = 0
|
196
|
+
length += 2 until ptr.get_bytes(length, 2) == "\0\0"
|
197
|
+
ptr.get_bytes(0, length)
|
198
|
+
end
|
199
|
+
end
|
253
200
|
end
|
254
201
|
end
|
255
202
|
end
|