sqlite3 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|