sqlite3 0.0.0 → 0.0.1
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/.gitignore +2 -0
- data/README.rdoc +1 -1
- data/Rakefile +11 -3
- data/VERSION +1 -0
- data/lib/sqlite3.rb +1 -0
- data/lib/sqlite3/constants.rb +51 -0
- data/lib/sqlite3/database.rb +703 -0
- data/lib/sqlite3/driver/ffi/api.rb +262 -0
- data/lib/sqlite3/driver/ffi/driver.rb +255 -0
- data/lib/sqlite3/errors.rb +68 -0
- data/lib/sqlite3/pragmas.rb +272 -0
- data/lib/sqlite3/resultset.rb +176 -0
- data/lib/sqlite3/statement.rb +231 -0
- data/lib/sqlite3/translator.rb +109 -0
- data/lib/sqlite3/value.rb +62 -0
- data/lib/sqlite3/version.rb +14 -0
- data/test/helper.rb +6 -5
- data/test/test_database_initialization.rb +26 -0
- data/test/test_database_queries.rb +29 -0
- metadata +29 -9
- data/test/test_sqlite3.rb +0 -7
@@ -0,0 +1,262 @@
|
|
1
|
+
require "ffi"
|
2
|
+
|
3
|
+
module SQLite3
|
4
|
+
module Driver
|
5
|
+
module FFI
|
6
|
+
|
7
|
+
module API
|
8
|
+
|
9
|
+
extend ::FFI::Library
|
10
|
+
|
11
|
+
ffi_lib "libsqlite3.so"
|
12
|
+
|
13
|
+
# extern "const char *sqlite3_libversion()"
|
14
|
+
attach_function :sqlite3_libversion, [], :string
|
15
|
+
|
16
|
+
# extern "int sqlite3_open(const char*,db*)"
|
17
|
+
attach_function :sqlite3_open, [:string, :pointer], :int
|
18
|
+
|
19
|
+
# extern "int sqlite3_open16(const void*,db*)"
|
20
|
+
attach_function :sqlite3_open16, [:pointer, :pointer], :int
|
21
|
+
|
22
|
+
# extern "int sqlite3_close(db)"
|
23
|
+
attach_function :sqlite3_close, [:pointer], :int
|
24
|
+
|
25
|
+
# extern "const char* sqlite3_errmsg(db)"
|
26
|
+
attach_function :sqlite3_errmsg, [:pointer], :string
|
27
|
+
|
28
|
+
# extern "void* sqlite3_errmsg16(db)"
|
29
|
+
attach_function :sqlite3_errmsg16, [:pointer], :pointer
|
30
|
+
|
31
|
+
# extern "int sqlite3_errcode(db)"
|
32
|
+
attach_function :sqlite3_errcode, [:pointer], :int
|
33
|
+
|
34
|
+
# extern "int sqlite3_prepare(db,const char*,int,stmt*,const char**)"
|
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)"
|
41
|
+
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)"
|
47
|
+
attach_function :sqlite3_step, [:pointer], :int
|
48
|
+
|
49
|
+
# extern "int64 sqlite3_last_insert_rowid(db)"
|
50
|
+
attach_function :sqlite3_last_insert_rowid, [:pointer], :int64
|
51
|
+
|
52
|
+
# extern "int sqlite3_changes(db)"
|
53
|
+
attach_function :sqlite3_changes, [:pointer], :int
|
54
|
+
|
55
|
+
# extern "int sqlite3_total_changes(db)"
|
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)"
|
71
|
+
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
|
+
attach_function :sqlite3_bind_blob, [:pointer, :int, :pointer, :int, :pointer], :int
|
81
|
+
|
82
|
+
# extern "int sqlite3_bind_double(stmt,int,double)"
|
83
|
+
attach_function :sqlite3_bind_double, [:pointer, :int, :double], :int
|
84
|
+
|
85
|
+
# extern "int sqlite3_bind_int(stmt,int,int)"
|
86
|
+
attach_function :sqlite3_bind_int, [:pointer, :int, :int], :int
|
87
|
+
|
88
|
+
# extern "int sqlite3_bind_int64(stmt,int,int64)"
|
89
|
+
attach_function :sqlite3_bind_int64, [:pointer, :int, :int64], :int
|
90
|
+
|
91
|
+
# extern "int sqlite3_bind_null(stmt,int)"
|
92
|
+
attach_function :sqlite3_bind_null, [:pointer, :int], :int
|
93
|
+
|
94
|
+
# extern "int sqlite3_bind_text(stmt,int,const char*,int,void*)"
|
95
|
+
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
|
+
attach_function :sqlite3_bind_text16, [:pointer, :int, :pointer, :int, :pointer], :int
|
99
|
+
|
100
|
+
# #extern "int sqlite3_bind_value(stmt,int,value)"
|
101
|
+
attach_function :sqlite3_bind_value, [:pointer, :int, :pointer], :int
|
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)"
|
113
|
+
attach_function :sqlite3_column_count, [:pointer], :int
|
114
|
+
|
115
|
+
# extern "int sqlite3_data_count(stmt)"
|
116
|
+
attach_function :sqlite3_data_count, [:pointer], :int
|
117
|
+
|
118
|
+
# extern "const void *sqlite3_column_blob(stmt,int)"
|
119
|
+
attach_function :sqlite3_column_blob, [:pointer, :int], :pointer
|
120
|
+
|
121
|
+
# extern "int sqlite3_column_bytes(stmt,int)"
|
122
|
+
attach_function :sqlite3_column_bytes, [:pointer, :int], :int
|
123
|
+
|
124
|
+
# extern "int sqlite3_column_bytes16(stmt,int)"
|
125
|
+
attach_function :sqlite3_column_bytes16, [:pointer, :int], :int
|
126
|
+
|
127
|
+
# extern "const char *sqlite3_column_decltype(stmt,int)"
|
128
|
+
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)"
|
134
|
+
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)"
|
140
|
+
attach_function :sqlite3_column_int64, [:pointer, :int], :int64
|
141
|
+
|
142
|
+
# extern "const char *sqlite3_column_name(stmt,int)"
|
143
|
+
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)"
|
149
|
+
attach_function :sqlite3_column_text, [:pointer, :int], :string
|
150
|
+
|
151
|
+
# extern "const void *sqlite3_column_text16(stmt,int)"
|
152
|
+
attach_function :sqlite3_column_text16, [:pointer, :int], :pointer
|
153
|
+
|
154
|
+
# extern "int sqlite3_column_type(stmt,int)"
|
155
|
+
attach_function :sqlite3_column_type, [:pointer, :int], :int
|
156
|
+
|
157
|
+
# extern "int sqlite3_create_function(db,const char*,int,int,void*,void*,void*,void*)"
|
158
|
+
attach_function :sqlite3_create_function, [:pointer, :string, :int, :int, :pointer, :pointer, :pointer, :pointer], :int
|
159
|
+
|
160
|
+
# extern "int sqlite3_create_function16(db,const void*,int,int,void*,void*,void*,void*)"
|
161
|
+
attach_function :sqlite3_create_function16, [:pointer, :pointer, :int, :int, :pointer, :pointer, :pointer, :pointer], :int
|
162
|
+
|
163
|
+
# extern "int sqlite3_aggregate_count(context)"
|
164
|
+
attach_function :sqlite3_aggregate_count, [:pointer], :int
|
165
|
+
|
166
|
+
# extern "const void *sqlite3_value_blob(value)"
|
167
|
+
attach_function :sqlite3_value_blob, [:pointer], :pointer
|
168
|
+
|
169
|
+
# extern "int sqlite3_value_bytes(value)"
|
170
|
+
attach_function :sqlite3_value_bytes, [:pointer], :int
|
171
|
+
|
172
|
+
# extern "int sqlite3_value_bytes16(value)"
|
173
|
+
attach_function :sqlite3_value_bytes16, [:pointer], :int
|
174
|
+
|
175
|
+
# extern "double sqlite3_value_double(value)"
|
176
|
+
attach_function :sqlite3_value_double, [:pointer], :double
|
177
|
+
|
178
|
+
# extern "int sqlite3_value_int(value)"
|
179
|
+
attach_function :sqlite3_value_int, [:pointer], :int
|
180
|
+
|
181
|
+
# extern "int64 sqlite3_value_int64(value)"
|
182
|
+
attach_function :sqlite3_value_int64, [:pointer], :int64
|
183
|
+
|
184
|
+
# extern "const char* sqlite3_value_text(value)"
|
185
|
+
attach_function :sqlite3_value_text, [:pointer], :string
|
186
|
+
|
187
|
+
# extern "const void* sqlite3_value_text16(value)"
|
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
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require 'sqlite3/driver/ffi/api'
|
2
|
+
|
3
|
+
module SQLite3
|
4
|
+
module Driver
|
5
|
+
module FFI
|
6
|
+
|
7
|
+
class Driver
|
8
|
+
STATIC = 0
|
9
|
+
TRANSIENT = -1
|
10
|
+
|
11
|
+
def open(filename, utf16 = false)
|
12
|
+
handle = ::FFI::MemoryPointer.new(:pointer)
|
13
|
+
result = API.send((utf16 ? :sqlite3_open16 : :sqlite3_open), filename, handle)
|
14
|
+
[result, handle.get_pointer(0)]
|
15
|
+
end
|
16
|
+
|
17
|
+
def errmsg(db, utf16 = false)
|
18
|
+
if utf16
|
19
|
+
msg = API.sqlite3_errmsg16(db)
|
20
|
+
msg.free = nil
|
21
|
+
msg.to_s(utf16_length(msg))
|
22
|
+
else
|
23
|
+
API.sqlite3_errmsg(db)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def prepare(db, sql, utf16 = false)
|
28
|
+
handle = ::FFI::MemoryPointer.new(:pointer)
|
29
|
+
remainder = ::FFI::MemoryPointer.new(:pointer)
|
30
|
+
|
31
|
+
result = API.send((utf16 ? :sqlite3_prepare16 : :sqlite3_prepare), db, sql, sql.length, handle, remainder)
|
32
|
+
|
33
|
+
# TODO: UTF-16
|
34
|
+
# args = utf16 ? [utf16_length(remainder)] : []
|
35
|
+
# remainder = remainder.to_s(*args)
|
36
|
+
|
37
|
+
[result, handle.get_pointer(0), remainder.get_pointer(0).get_string(0)]
|
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)
|
67
|
+
end
|
68
|
+
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def column_blob(stmt, column)
|
73
|
+
blob = API.sqlite3_column_blob(stmt, column)
|
74
|
+
blob.free = nil
|
75
|
+
blob.to_s(API.sqlite3_column_bytes(stmt, column))
|
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)
|
128
|
+
end
|
129
|
+
|
130
|
+
def create_function(db, name, args, text, cookie, func, step, final)
|
131
|
+
# begin
|
132
|
+
if @func_handler_callback.nil? && func
|
133
|
+
@func_handler_callback = ::DL.callback("0PIP") do |context,nargs,args|
|
134
|
+
args = args.to_s(nargs*4).unpack("L*").map {|i| ::FFI::MemoryPointer.new(i)}
|
135
|
+
data = API.sqlite3_user_data(context).to_object
|
136
|
+
data[:func].call(context, *args)
|
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
|
173
|
+
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
|
+
end
|
202
|
+
|
203
|
+
def self.api_delegate(name)
|
204
|
+
define_method(name) { |*args| API.send("sqlite3_#{name}", *args) }
|
205
|
+
end
|
206
|
+
|
207
|
+
api_delegate :aggregate_count
|
208
|
+
api_delegate :bind_double
|
209
|
+
api_delegate :bind_int
|
210
|
+
api_delegate :bind_int64
|
211
|
+
api_delegate :bind_null
|
212
|
+
api_delegate :bind_parameter_index
|
213
|
+
api_delegate :bind_parameter_name
|
214
|
+
api_delegate :busy_timeout
|
215
|
+
api_delegate :changes
|
216
|
+
api_delegate :close
|
217
|
+
api_delegate :column_bytes
|
218
|
+
api_delegate :column_bytes16
|
219
|
+
api_delegate :column_count
|
220
|
+
api_delegate :column_double
|
221
|
+
api_delegate :column_int
|
222
|
+
api_delegate :column_int64
|
223
|
+
api_delegate :column_type
|
224
|
+
api_delegate :data_count
|
225
|
+
api_delegate :errcode
|
226
|
+
api_delegate :finalize
|
227
|
+
api_delegate :interrupt
|
228
|
+
api_delegate :last_insert_rowid
|
229
|
+
api_delegate :libversion
|
230
|
+
api_delegate :reset
|
231
|
+
api_delegate :result_error
|
232
|
+
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
|
240
|
+
|
241
|
+
private
|
242
|
+
|
243
|
+
def utf16_length(ptr)
|
244
|
+
len = 0
|
245
|
+
loop do
|
246
|
+
break if ptr[len,1] == "\0"
|
247
|
+
len += 2
|
248
|
+
end
|
249
|
+
len
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|