sqlite3-ruby 1.2.3-x86-mingw32
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.
Potentially problematic release.
This version of sqlite3-ruby might be problematic. Click here for more details.
- data/README.rdoc +51 -0
- data/doc/faq/faq.html +408 -0
- data/doc/faq/faq.rb +145 -0
- data/doc/faq/faq.yml +426 -0
- data/ext/sqlite3_api/MANIFEST +4 -0
- data/ext/sqlite3_api/Makefile +142 -0
- data/ext/sqlite3_api/extconf.rb +16 -0
- data/ext/sqlite3_api/mkmf.log +66 -0
- data/ext/sqlite3_api/sqlite3_api.i +358 -0
- data/ext/sqlite3_api/sqlite3_api.so +0 -0
- data/ext/sqlite3_api/sqlite3_api_wrap.c +3094 -0
- data/ext/sqlite3_api/sqlite3_api_wrap.o +0 -0
- data/ext/sqlite3_api/win32/build.bat +7 -0
- data/lib/sqlite3.rb +1 -0
- data/lib/sqlite3/constants.rb +49 -0
- data/lib/sqlite3/database.rb +715 -0
- data/lib/sqlite3/driver/dl/api.rb +152 -0
- data/lib/sqlite3/driver/dl/driver.rb +307 -0
- data/lib/sqlite3/driver/native/driver.rb +211 -0
- data/lib/sqlite3/errors.rb +68 -0
- data/lib/sqlite3/pragmas.rb +271 -0
- data/lib/sqlite3/resultset.rb +176 -0
- data/lib/sqlite3/statement.rb +230 -0
- data/lib/sqlite3/translator.rb +109 -0
- data/lib/sqlite3/value.rb +57 -0
- data/lib/sqlite3/version.rb +14 -0
- data/test/bm.rb +140 -0
- data/test/driver/dl/tc_driver.rb +292 -0
- data/test/mocks.rb +45 -0
- data/test/native-vs-dl.rb +126 -0
- data/test/tc_database.rb +198 -0
- data/test/tc_errors.rb +21 -0
- data/test/tc_integration.rb +1044 -0
- data/test/tests.rb +6 -0
- metadata +96 -0
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'dl/import'
|
2
|
+
|
3
|
+
module SQLite3 ; module Driver; module DL;
|
4
|
+
|
5
|
+
module API
|
6
|
+
extend ::DL::Importable
|
7
|
+
|
8
|
+
library_name = case RUBY_PLATFORM.downcase
|
9
|
+
when /darwin/
|
10
|
+
"libsqlite3.dylib"
|
11
|
+
when /linux/, /freebsd|netbsd|openbsd|dragonfly/, /solaris/
|
12
|
+
"libsqlite3.so"
|
13
|
+
when /win32/
|
14
|
+
"sqlite3.dll"
|
15
|
+
else
|
16
|
+
abort <<-EOF
|
17
|
+
== * UNSUPPORTED PLATFORM ======================================================
|
18
|
+
The platform '#{RUBY_PLATFORM}' is unsupported. Please help the author by
|
19
|
+
editing the following file to allow your sqlite3 library to be found, and
|
20
|
+
submitting a patch to jamis_buck@byu.edu. Thanks!
|
21
|
+
|
22
|
+
#{__FILE__}
|
23
|
+
=========================================================================== * ==
|
24
|
+
EOF
|
25
|
+
end
|
26
|
+
|
27
|
+
if defined? SQLITE3_LIB_PATH
|
28
|
+
library_name = File.join( SQLITE3_LIB_PATH, library_name )
|
29
|
+
end
|
30
|
+
|
31
|
+
dlload library_name
|
32
|
+
|
33
|
+
typealias "db", "void*"
|
34
|
+
typealias "stmt", "void*"
|
35
|
+
typealias "value", "void*"
|
36
|
+
typealias "context", "void*"
|
37
|
+
|
38
|
+
# until Ruby/DL supports 64-bit ints, we'll just treat them as 32-bit ints
|
39
|
+
typealias "int64", "unsigned long"
|
40
|
+
|
41
|
+
extern "const char *sqlite3_libversion()"
|
42
|
+
|
43
|
+
extern "int sqlite3_open(const char*,db*)"
|
44
|
+
extern "int sqlite3_open16(const void*,db*)"
|
45
|
+
extern "int sqlite3_close(db)"
|
46
|
+
extern "const char* sqlite3_errmsg(db)"
|
47
|
+
extern "void* sqlite3_errmsg16(db)"
|
48
|
+
extern "int sqlite3_errcode(db)"
|
49
|
+
|
50
|
+
extern "int sqlite3_prepare(db,const char*,int,stmt*,const char**)"
|
51
|
+
extern "int sqlite3_prepare16(db,const void*,int,stmt*,const void**)"
|
52
|
+
extern "int sqlite3_finalize(stmt)"
|
53
|
+
extern "int sqlite3_reset(stmt)"
|
54
|
+
extern "int sqlite3_step(stmt)"
|
55
|
+
|
56
|
+
extern "int64 sqlite3_last_insert_rowid(db)"
|
57
|
+
extern "int sqlite3_changes(db)"
|
58
|
+
extern "int sqlite3_total_changes(db)"
|
59
|
+
extern "void sqlite3_interrupt(db)"
|
60
|
+
extern "ibool sqlite3_complete(const char*)"
|
61
|
+
extern "ibool sqlite3_complete16(const void*)"
|
62
|
+
|
63
|
+
extern "int sqlite3_busy_handler(db,void*,void*)"
|
64
|
+
extern "int sqlite3_busy_timeout(db,int)"
|
65
|
+
|
66
|
+
extern "int sqlite3_set_authorizer(db,void*,void*)"
|
67
|
+
extern "void* sqlite3_trace(db,void*,void*)"
|
68
|
+
|
69
|
+
extern "int sqlite3_bind_blob(stmt,int,const void*,int,void*)"
|
70
|
+
extern "int sqlite3_bind_double(stmt,int,double)"
|
71
|
+
extern "int sqlite3_bind_int(stmt,int,int)"
|
72
|
+
extern "int sqlite3_bind_int64(stmt,int,int64)"
|
73
|
+
extern "int sqlite3_bind_null(stmt,int)"
|
74
|
+
extern "int sqlite3_bind_text(stmt,int,const char*,int,void*)"
|
75
|
+
extern "int sqlite3_bind_text16(stmt,int,const void*,int,void*)"
|
76
|
+
#extern "int sqlite3_bind_value(stmt,int,value)"
|
77
|
+
|
78
|
+
extern "int sqlite3_bind_parameter_count(stmt)"
|
79
|
+
extern "const char* sqlite3_bind_parameter_name(stmt,int)"
|
80
|
+
extern "int sqlite3_bind_parameter_index(stmt,const char*)"
|
81
|
+
|
82
|
+
extern "int sqlite3_column_count(stmt)"
|
83
|
+
extern "int sqlite3_data_count(stmt)"
|
84
|
+
|
85
|
+
extern "const void *sqlite3_column_blob(stmt,int)"
|
86
|
+
extern "int sqlite3_column_bytes(stmt,int)"
|
87
|
+
extern "int sqlite3_column_bytes16(stmt,int)"
|
88
|
+
extern "const char *sqlite3_column_decltype(stmt,int)"
|
89
|
+
extern "void *sqlite3_column_decltype16(stmt,int)"
|
90
|
+
extern "double sqlite3_column_double(stmt,int)"
|
91
|
+
extern "int sqlite3_column_int(stmt,int)"
|
92
|
+
extern "int64 sqlite3_column_int64(stmt,int)"
|
93
|
+
extern "const char *sqlite3_column_name(stmt,int)"
|
94
|
+
extern "const void *sqlite3_column_name16(stmt,int)"
|
95
|
+
extern "const char *sqlite3_column_text(stmt,int)"
|
96
|
+
extern "const void *sqlite3_column_text16(stmt,int)"
|
97
|
+
extern "int sqlite3_column_type(stmt,int)"
|
98
|
+
|
99
|
+
extern "int sqlite3_create_function(db,const char*,int,int,void*,void*,void*,void*)"
|
100
|
+
extern "int sqlite3_create_function16(db,const void*,int,int,void*,void*,void*,void*)"
|
101
|
+
extern "int sqlite3_aggregate_count(context)"
|
102
|
+
|
103
|
+
extern "const void *sqlite3_value_blob(value)"
|
104
|
+
extern "int sqlite3_value_bytes(value)"
|
105
|
+
extern "int sqlite3_value_bytes16(value)"
|
106
|
+
extern "double sqlite3_value_double(value)"
|
107
|
+
extern "int sqlite3_value_int(value)"
|
108
|
+
extern "int64 sqlite3_value_int64(value)"
|
109
|
+
extern "const char* sqlite3_value_text(value)"
|
110
|
+
extern "const void* sqlite3_value_text16(value)"
|
111
|
+
extern "const void* sqlite3_value_text16le(value)"
|
112
|
+
extern "const void* sqlite3_value_text16be(value)"
|
113
|
+
extern "int sqlite3_value_type(value)"
|
114
|
+
|
115
|
+
extern "void *sqlite3_aggregate_context(context,int)"
|
116
|
+
extern "void *sqlite3_user_data(context)"
|
117
|
+
extern "void *sqlite3_get_auxdata(context,int)"
|
118
|
+
extern "void sqlite3_set_auxdata(context,int,void*,void*)"
|
119
|
+
|
120
|
+
extern "void sqlite3_result_blob(context,const void*,int,void*)"
|
121
|
+
extern "void sqlite3_result_double(context,double)"
|
122
|
+
extern "void sqlite3_result_error(context,const char*,int)"
|
123
|
+
extern "void sqlite3_result_error16(context,const void*,int)"
|
124
|
+
extern "void sqlite3_result_int(context,int)"
|
125
|
+
extern "void sqlite3_result_int64(context,int64)"
|
126
|
+
extern "void sqlite3_result_null(context)"
|
127
|
+
extern "void sqlite3_result_text(context,const char*,int,void*)"
|
128
|
+
extern "void sqlite3_result_text16(context,const void*,int,void*)"
|
129
|
+
extern "void sqlite3_result_text16le(context,const void*,int,void*)"
|
130
|
+
extern "void sqlite3_result_text16be(context,const void*,int,void*)"
|
131
|
+
extern "void sqlite3_result_value(context,value)"
|
132
|
+
|
133
|
+
extern "int sqlite3_create_collation(db,const char*,int,void*,void*)"
|
134
|
+
extern "int sqlite3_create_collation16(db,const char*,int,void*,void*)"
|
135
|
+
extern "int sqlite3_collation_needed(db,void*,void*)"
|
136
|
+
extern "int sqlite3_collation_needed16(db,void*,void*)"
|
137
|
+
|
138
|
+
# ==== CRYPTO (NOT IN PUBLIC RELEASE) ====
|
139
|
+
if defined?( CRYPTO_API ) && CRYPTO_API
|
140
|
+
extern "int sqlite3_key(db,void*,int)"
|
141
|
+
extern "int sqlite3_rekey(db,void*,int)"
|
142
|
+
end
|
143
|
+
|
144
|
+
# ==== EXPERIMENTAL ====
|
145
|
+
if defined?( EXPERIMENTAL_API ) && EXPERIMENTAL_API
|
146
|
+
extern "int sqlite3_progress_handler(db,int,void*,void*)"
|
147
|
+
extern "int sqlite3_commit_hook(db,void*,void*)"
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
end ; end ; end
|
@@ -0,0 +1,307 @@
|
|
1
|
+
require 'sqlite3/driver/dl/api'
|
2
|
+
|
3
|
+
warn "The DL driver for sqlite3-ruby is deprecated and will be removed"
|
4
|
+
warn "in a future release. Please update your installation to use the"
|
5
|
+
warn "Native driver."
|
6
|
+
|
7
|
+
module Kernel
|
8
|
+
# Allows arbitrary objects to be passed as a pointer to functions.
|
9
|
+
# (Probably not very GC safe, but by encapsulating it like this we
|
10
|
+
# can change the implementation later.)
|
11
|
+
def to_ptr
|
12
|
+
ptr = DL.malloc(DL.sizeof("L"))
|
13
|
+
ptr.set_object self
|
14
|
+
ptr
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class DL::PtrData
|
19
|
+
# The inverse of the Kernel#to_ptr operation.
|
20
|
+
def to_object
|
21
|
+
n = to_s(4).unpack("L").first
|
22
|
+
return nil if n < 1
|
23
|
+
ObjectSpace._id2ref(n) rescue self.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_object(obj)
|
27
|
+
self[0] = [obj.object_id].pack("L")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module SQLite3 ; module Driver ; module DL
|
32
|
+
|
33
|
+
class Driver
|
34
|
+
STATIC = ::DL::PtrData.new(0)
|
35
|
+
TRANSIENT = ::DL::PtrData.new(-1)
|
36
|
+
|
37
|
+
def open( filename, utf16=false )
|
38
|
+
handle = ::DL::PtrData.new(0)
|
39
|
+
result = API.send( ( utf16 ? :sqlite3_open16 : :sqlite3_open ),
|
40
|
+
filename+"\0", handle.ref )
|
41
|
+
[ result, handle ]
|
42
|
+
end
|
43
|
+
|
44
|
+
def errmsg( db, utf16=false )
|
45
|
+
if utf16
|
46
|
+
msg = API.sqlite3_errmsg16( db )
|
47
|
+
msg.free = nil
|
48
|
+
msg.to_s(utf16_length(msg))
|
49
|
+
else
|
50
|
+
API.sqlite3_errmsg( db )
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def prepare( db, sql, utf16=false )
|
55
|
+
handle = ::DL::PtrData.new(0)
|
56
|
+
remainder = ::DL::PtrData.new(0)
|
57
|
+
|
58
|
+
result = API.send( ( utf16 ? :sqlite3_prepare16 : :sqlite3_prepare ),
|
59
|
+
db, sql+"\0", sql.length, handle.ref, remainder.ref )
|
60
|
+
|
61
|
+
args = utf16 ? [ utf16_length(remainder) ] : []
|
62
|
+
remainder = remainder.to_s( *args )
|
63
|
+
|
64
|
+
[ result, handle, remainder ]
|
65
|
+
end
|
66
|
+
|
67
|
+
def complete?( sql, utf16=false )
|
68
|
+
API.send( utf16 ? :sqlite3_complete16 : :sqlite3_complete, sql+"\0" )
|
69
|
+
end
|
70
|
+
|
71
|
+
def value_blob( value )
|
72
|
+
blob = API.sqlite3_value_blob( value )
|
73
|
+
blob.free = nil
|
74
|
+
blob.to_s( API.sqlite3_value_bytes( value ) )
|
75
|
+
end
|
76
|
+
|
77
|
+
def value_text( value, utf16=false )
|
78
|
+
method = case utf16
|
79
|
+
when nil, false then :sqlite3_value_text
|
80
|
+
when :le then :sqlite3_value_text16le
|
81
|
+
when :be then :sqlite3_value_text16be
|
82
|
+
else :sqlite3_value_text16
|
83
|
+
end
|
84
|
+
|
85
|
+
result = API.send( method, value )
|
86
|
+
if utf16
|
87
|
+
result.free = nil
|
88
|
+
size = API.sqlite3_value_bytes( value )
|
89
|
+
result = result.to_s( size )
|
90
|
+
end
|
91
|
+
|
92
|
+
result
|
93
|
+
end
|
94
|
+
|
95
|
+
def column_blob( stmt, column )
|
96
|
+
blob = API.sqlite3_column_blob( stmt, column )
|
97
|
+
blob.free = nil
|
98
|
+
blob.to_s( API.sqlite3_column_bytes( stmt, column ) )
|
99
|
+
end
|
100
|
+
|
101
|
+
def result_text( func, text, utf16=false )
|
102
|
+
method = case utf16
|
103
|
+
when false, nil then :sqlite3_result_text
|
104
|
+
when :le then :sqlite3_result_text16le
|
105
|
+
when :be then :sqlite3_result_text16be
|
106
|
+
else :sqlite3_result_text16
|
107
|
+
end
|
108
|
+
|
109
|
+
s = text.to_s
|
110
|
+
API.send( method, func, s, s.length, TRANSIENT )
|
111
|
+
end
|
112
|
+
|
113
|
+
def busy_handler( db, data=nil, &block )
|
114
|
+
@busy_handler = block
|
115
|
+
|
116
|
+
unless @busy_handler_callback
|
117
|
+
@busy_handler_callback = ::DL.callback( "IPI" ) do |cookie, timeout|
|
118
|
+
@busy_handler.call( cookie, timeout ) || 0
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
API.sqlite3_busy_handler( db, block&&@busy_handler_callback, data )
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_authorizer( db, data=nil, &block )
|
126
|
+
@authorizer_handler = block
|
127
|
+
|
128
|
+
unless @authorizer_handler_callback
|
129
|
+
@authorizer_handler_callback = ::DL.callback( "IPIPPPP"
|
130
|
+
) do |cookie,mode,a,b,c,d|
|
131
|
+
@authorizer_handler.call( cookie, mode,
|
132
|
+
a&&a.to_s, b&&b.to_s, c&&c.to_s, d&&d.to_s ) || 0
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
API.sqlite3_set_authorizer( db, block&&@authorizer_handler_callback,
|
137
|
+
data )
|
138
|
+
end
|
139
|
+
|
140
|
+
def trace( db, data=nil, &block )
|
141
|
+
@trace_handler = block
|
142
|
+
|
143
|
+
unless @trace_handler_callback
|
144
|
+
@trace_handler_callback = ::DL.callback( "IPS" ) do |cookie,sql|
|
145
|
+
@trace_handler.call( cookie ? cookie.to_object : nil, sql ) || 0
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
API.sqlite3_trace( db, block&&@trace_handler_callback, data )
|
150
|
+
end
|
151
|
+
|
152
|
+
def create_function( db, name, args, text, cookie,
|
153
|
+
func, step, final )
|
154
|
+
# begin
|
155
|
+
if @func_handler_callback.nil? && func
|
156
|
+
@func_handler_callback = ::DL.callback( "0PIP" ) do |context,nargs,args|
|
157
|
+
args = args.to_s(nargs*4).unpack("L*").map {|i| ::DL::PtrData.new(i)}
|
158
|
+
data = API.sqlite3_user_data( context ).to_object
|
159
|
+
data[:func].call( context, *args )
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
if @step_handler_callback.nil? && step
|
164
|
+
@step_handler_callback = ::DL.callback( "0PIP" ) do |context,nargs,args|
|
165
|
+
args = args.to_s(nargs*4).unpack("L*").map {|i| ::DL::PtrData.new(i)}
|
166
|
+
data = API.sqlite3_user_data( context ).to_object
|
167
|
+
data[:step].call( context, *args )
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
if @final_handler_callback.nil? && final
|
172
|
+
@final_handler_callback = ::DL.callback( "0P" ) do |context|
|
173
|
+
data = API.sqlite3_user_data( context ).to_object
|
174
|
+
data[:final].call( context )
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
data = { :cookie => cookie,
|
179
|
+
:name => name,
|
180
|
+
:func => func,
|
181
|
+
:step => step,
|
182
|
+
:final => final }
|
183
|
+
|
184
|
+
API.sqlite3_create_function( db, name, args, text, data,
|
185
|
+
( func ? @func_handler_callback : nil ),
|
186
|
+
( step ? @step_handler_callback : nil ),
|
187
|
+
( final ? @final_handler_callback : nil ) )
|
188
|
+
end
|
189
|
+
|
190
|
+
def aggregate_context( context )
|
191
|
+
ptr = API.sqlite3_aggregate_context( context, 4 )
|
192
|
+
ptr.free = nil
|
193
|
+
obj = ( ptr ? ptr.to_object : nil )
|
194
|
+
if obj.nil?
|
195
|
+
obj = Hash.new
|
196
|
+
ptr.set_object obj
|
197
|
+
end
|
198
|
+
obj
|
199
|
+
end
|
200
|
+
|
201
|
+
def bind_blob( stmt, index, value )
|
202
|
+
s = value.to_s
|
203
|
+
API.sqlite3_bind_blob( stmt, index, s, s.length, TRANSIENT )
|
204
|
+
end
|
205
|
+
|
206
|
+
def bind_text( stmt, index, value, utf16=false )
|
207
|
+
s = value.to_s
|
208
|
+
method = ( utf16 ? :sqlite3_bind_text16 : :sqlite3_bind_text )
|
209
|
+
API.send( method, stmt, index, s, s.length, TRANSIENT )
|
210
|
+
end
|
211
|
+
|
212
|
+
def column_text( stmt, column )
|
213
|
+
result = API.sqlite3_column_text( stmt, column )
|
214
|
+
result ? result.to_s : nil
|
215
|
+
end
|
216
|
+
|
217
|
+
def column_name( stmt, column )
|
218
|
+
result = API.sqlite3_column_name( stmt, column )
|
219
|
+
result ? result.to_s : nil
|
220
|
+
end
|
221
|
+
|
222
|
+
def column_decltype( stmt, column )
|
223
|
+
result = API.sqlite3_column_decltype( stmt, column )
|
224
|
+
result ? result.to_s : nil
|
225
|
+
end
|
226
|
+
|
227
|
+
def self.api_delegate( name )
|
228
|
+
define_method( name ) { |*args| API.send( "sqlite3_#{name}", *args ) }
|
229
|
+
end
|
230
|
+
|
231
|
+
api_delegate :aggregate_count
|
232
|
+
api_delegate :bind_double
|
233
|
+
api_delegate :bind_int
|
234
|
+
api_delegate :bind_int64
|
235
|
+
api_delegate :bind_null
|
236
|
+
api_delegate :bind_parameter_index
|
237
|
+
api_delegate :bind_parameter_name
|
238
|
+
api_delegate :busy_timeout
|
239
|
+
api_delegate :changes
|
240
|
+
api_delegate :close
|
241
|
+
api_delegate :column_bytes
|
242
|
+
api_delegate :column_bytes16
|
243
|
+
api_delegate :column_count
|
244
|
+
api_delegate :column_double
|
245
|
+
api_delegate :column_int
|
246
|
+
api_delegate :column_int64
|
247
|
+
api_delegate :column_type
|
248
|
+
api_delegate :data_count
|
249
|
+
api_delegate :errcode
|
250
|
+
api_delegate :finalize
|
251
|
+
api_delegate :interrupt
|
252
|
+
api_delegate :last_insert_rowid
|
253
|
+
api_delegate :libversion
|
254
|
+
api_delegate :reset
|
255
|
+
api_delegate :result_error
|
256
|
+
api_delegate :step
|
257
|
+
api_delegate :total_changes
|
258
|
+
api_delegate :value_bytes
|
259
|
+
api_delegate :value_bytes16
|
260
|
+
api_delegate :value_double
|
261
|
+
api_delegate :value_int
|
262
|
+
api_delegate :value_int64
|
263
|
+
api_delegate :value_type
|
264
|
+
|
265
|
+
# ==== EXPERIMENTAL ====
|
266
|
+
if defined?( EXPERIMENTAL_API ) && EXPERIMENTAL_API
|
267
|
+
def progress_handler( db, n, data=nil, &block )
|
268
|
+
@progress_handler = block
|
269
|
+
|
270
|
+
unless @progress_handler_callback
|
271
|
+
@progress_handler_callback = ::DL.callback( "IP" ) do |cookie|
|
272
|
+
@progress_handler.call( cookie )
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
API.sqlite3_progress_handler( db, n, block&&@progress_handler_callback,
|
277
|
+
data )
|
278
|
+
end
|
279
|
+
|
280
|
+
def commit_hook( db, data=nil, &block )
|
281
|
+
@commit_hook_handler = block
|
282
|
+
|
283
|
+
unless @commit_hook_handler_callback
|
284
|
+
@commit_hook_handler_callback = ::DL.callback( "IP" ) do |cookie|
|
285
|
+
@commit_hook_handler.call( cookie )
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
API.sqlite3_commit_hook( db, block&&@commit_hook_handler_callback,
|
290
|
+
data )
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
private
|
295
|
+
|
296
|
+
def utf16_length(ptr)
|
297
|
+
len = 0
|
298
|
+
loop do
|
299
|
+
break if ptr[len,1] == "\0"
|
300
|
+
len += 2
|
301
|
+
end
|
302
|
+
len
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
end ; end ; end
|