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.
@@ -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
- ffi_lib "libsqlite3.so"
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
- # 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)"
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
- # #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)"
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
- # 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
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
- STATIC = 0
9
- TRANSIENT = -1
8
+ TRANSIENT = ::FFI::Pointer.new(-1)
10
9
 
11
- def open(filename, utf16 = false)
10
+ def open(filename, utf_16 = false)
12
11
  handle = ::FFI::MemoryPointer.new(:pointer)
13
- result = API.send((utf16 ? :sqlite3_open16 : :sqlite3_open), filename, handle)
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, utf16 = false)
18
- if utf16
19
- msg = API.sqlite3_errmsg16(db)
20
- msg.free = nil
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, utf16 = false)
31
+ def prepare(db, sql)
28
32
  handle = ::FFI::MemoryPointer.new(:pointer)
29
33
  remainder = ::FFI::MemoryPointer.new(:pointer)
30
34
 
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)
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
- 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)
121
+ length = API.sqlite3_column_bytes(stmt, column)
122
+ blob.get_bytes(0, length) # free?
128
123
  end
129
124
 
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
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 :aggregate_count
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 utf16_length(ptr)
244
- len = 0
245
- loop do
246
- break if ptr[len,1] == "\0"
247
- len += 2
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