sqlite3 1.3.13-x64-mingw32 → 1.5.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sqlite3 might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.gemtest +0 -0
- data/{API_CHANGES.rdoc → API_CHANGES.md} +3 -4
- data/CHANGELOG.md +425 -0
- data/CONTRIBUTING.md +24 -0
- data/Gemfile +2 -14
- data/LICENSE-DEPENDENCIES +20 -0
- data/README.md +233 -0
- data/ext/sqlite3/aggregator.c +274 -0
- data/ext/sqlite3/aggregator.h +12 -0
- data/ext/sqlite3/database.c +171 -206
- data/ext/sqlite3/database.h +2 -0
- data/ext/sqlite3/exception.c +6 -2
- data/ext/sqlite3/extconf.rb +236 -55
- data/ext/sqlite3/sqlite3.c +12 -1
- data/ext/sqlite3/sqlite3_ruby.h +3 -7
- data/ext/sqlite3/statement.c +15 -20
- data/faq/faq.md +431 -0
- data/faq/faq.yml +1 -1
- data/lib/sqlite3/2.6/sqlite3_native.so +0 -0
- data/lib/sqlite3/2.7/sqlite3_native.so +0 -0
- data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
- data/lib/sqlite3/constants.rb +2 -1
- data/lib/sqlite3/database.rb +202 -52
- data/lib/sqlite3/errors.rb +1 -10
- data/lib/sqlite3/pragmas.rb +17 -10
- data/lib/sqlite3/resultset.rb +2 -10
- data/lib/sqlite3/statement.rb +2 -1
- data/lib/sqlite3/translator.rb +1 -1
- data/lib/sqlite3/version.rb +3 -5
- data/test/helper.rb +9 -0
- data/test/test_database.rb +126 -11
- data/test/test_database_flags.rb +95 -0
- data/test/test_database_readwrite.rb +41 -0
- data/test/test_integration.rb +12 -81
- data/test/test_integration_aggregate.rb +336 -0
- data/test/test_integration_resultset.rb +0 -17
- data/test/test_sqlite3.rb +9 -0
- data/test/test_statement.rb +11 -8
- metadata +54 -85
- data/CHANGELOG.rdoc +0 -292
- data/Manifest.txt +0 -52
- data/README.rdoc +0 -118
- data/Rakefile +0 -10
- data/lib/sqlite3/2.0/sqlite3_native.so +0 -0
- data/lib/sqlite3/2.1/sqlite3_native.so +0 -0
- data/lib/sqlite3/2.2/sqlite3_native.so +0 -0
- data/lib/sqlite3/2.3/sqlite3_native.so +0 -0
- data/lib/sqlite3/2.4/sqlite3_native.so +0 -0
- data/setup.rb +0 -1333
- data/tasks/faq.rake +0 -9
- data/tasks/gem.rake +0 -38
- data/tasks/native.rake +0 -52
- data/tasks/vendor_sqlite3.rake +0 -97
data/lib/sqlite3/database.rb
CHANGED
@@ -54,12 +54,73 @@ module SQLite3
|
|
54
54
|
# as hashes or not. By default, rows are returned as arrays.
|
55
55
|
attr_accessor :results_as_hash
|
56
56
|
|
57
|
+
# call-seq: SQLite3::Database.new(file, options = {})
|
58
|
+
#
|
59
|
+
# Create a new Database object that opens the given file. If utf16
|
60
|
+
# is +true+, the filename is interpreted as a UTF-16 encoded string.
|
61
|
+
#
|
62
|
+
# By default, the new database will return result rows as arrays
|
63
|
+
# (#results_as_hash) and has type translation disabled (#type_translation=).
|
64
|
+
|
65
|
+
def initialize file, options = {}, zvfs = nil
|
66
|
+
mode = Constants::Open::READWRITE | Constants::Open::CREATE
|
67
|
+
|
68
|
+
file = file.to_path if file.respond_to? :to_path
|
69
|
+
if file.encoding == ::Encoding::UTF_16LE || file.encoding == ::Encoding::UTF_16BE || options[:utf16]
|
70
|
+
open16 file
|
71
|
+
else
|
72
|
+
# The three primary flag values for sqlite3_open_v2 are:
|
73
|
+
# SQLITE_OPEN_READONLY
|
74
|
+
# SQLITE_OPEN_READWRITE
|
75
|
+
# SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE -- always used for sqlite3_open and sqlite3_open16
|
76
|
+
mode = Constants::Open::READONLY if options[:readonly]
|
77
|
+
|
78
|
+
if options[:readwrite]
|
79
|
+
raise "conflicting options: readonly and readwrite" if options[:readonly]
|
80
|
+
mode = Constants::Open::READWRITE
|
81
|
+
end
|
82
|
+
|
83
|
+
if options[:flags]
|
84
|
+
if options[:readonly] || options[:readwrite]
|
85
|
+
raise "conflicting options: flags with readonly and/or readwrite"
|
86
|
+
end
|
87
|
+
mode = options[:flags]
|
88
|
+
end
|
89
|
+
|
90
|
+
open_v2 file.encode("utf-8"), mode, zvfs
|
91
|
+
|
92
|
+
if options[:strict]
|
93
|
+
disable_quirk_mode
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
@tracefunc = nil
|
98
|
+
@authorizer = nil
|
99
|
+
@encoding = nil
|
100
|
+
@busy_handler = nil
|
101
|
+
@collations = {}
|
102
|
+
@functions = {}
|
103
|
+
@results_as_hash = options[:results_as_hash]
|
104
|
+
@type_translation = options[:type_translation]
|
105
|
+
@type_translator = make_type_translator @type_translation
|
106
|
+
@readonly = mode & Constants::Open::READONLY != 0
|
107
|
+
|
108
|
+
if block_given?
|
109
|
+
begin
|
110
|
+
yield self
|
111
|
+
ensure
|
112
|
+
close
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
57
117
|
def type_translation= value # :nodoc:
|
58
118
|
warn(<<-eowarn) if $VERBOSE
|
59
119
|
#{caller[0]} is calling SQLite3::Database#type_translation=
|
60
120
|
SQLite3::Database#type_translation= is deprecated and will be removed
|
61
121
|
in version 2.0.0.
|
62
122
|
eowarn
|
123
|
+
@type_translator = make_type_translator value
|
63
124
|
@type_translation = value
|
64
125
|
end
|
65
126
|
attr_reader :type_translation # :nodoc:
|
@@ -136,25 +197,14 @@ Support for bind parameters as *args will be removed in 2.0.0.
|
|
136
197
|
|
137
198
|
prepare( sql ) do |stmt|
|
138
199
|
stmt.bind_params(bind_vars)
|
139
|
-
|
140
|
-
stmt = ResultSet.new(self, stmt).to_a if type_translation
|
200
|
+
stmt = ResultSet.new self, stmt
|
141
201
|
|
142
202
|
if block_given?
|
143
203
|
stmt.each do |row|
|
144
|
-
|
145
|
-
yield type_translation ? row : ordered_map_for(columns, row)
|
146
|
-
else
|
147
|
-
yield row
|
148
|
-
end
|
204
|
+
yield row
|
149
205
|
end
|
150
206
|
else
|
151
|
-
|
152
|
-
stmt.map { |row|
|
153
|
-
type_translation ? row : ordered_map_for(columns, row)
|
154
|
-
}
|
155
|
-
else
|
156
|
-
stmt.to_a
|
157
|
-
end
|
207
|
+
stmt.to_a
|
158
208
|
end
|
159
209
|
end
|
160
210
|
end
|
@@ -190,6 +240,9 @@ Support for bind parameters as *args will be removed in 2.0.0.
|
|
190
240
|
#
|
191
241
|
# This always returns +nil+, making it unsuitable for queries that return
|
192
242
|
# rows.
|
243
|
+
#
|
244
|
+
# See also #execute_batch2 for additional ways of
|
245
|
+
# executing statements.
|
193
246
|
def execute_batch( sql, bind_vars = [], *args )
|
194
247
|
# FIXME: remove this stuff later
|
195
248
|
unless [Array, Hash].include?(bind_vars.class)
|
@@ -234,8 +287,32 @@ Support for this behavior will be removed in version 2.0.0.
|
|
234
287
|
nil
|
235
288
|
end
|
236
289
|
|
290
|
+
# Executes all SQL statements in the given string. By contrast, the other
|
291
|
+
# means of executing queries will only execute the first statement in the
|
292
|
+
# string, ignoring all subsequent statements. This will execute each one
|
293
|
+
# in turn. Bind parameters cannot be passed to #execute_batch2.
|
294
|
+
#
|
295
|
+
# If a query is made, all values will be returned as strings.
|
296
|
+
# If no query is made, an empty array will be returned.
|
297
|
+
#
|
298
|
+
# Because all values except for 'NULL' are returned as strings,
|
299
|
+
# a block can be passed to parse the values accordingly.
|
300
|
+
#
|
301
|
+
# See also #execute_batch for additional ways of
|
302
|
+
# executing statements.
|
303
|
+
def execute_batch2(sql, &block)
|
304
|
+
if block_given?
|
305
|
+
result = exec_batch(sql, @results_as_hash)
|
306
|
+
result.map do |val|
|
307
|
+
yield val
|
308
|
+
end
|
309
|
+
else
|
310
|
+
exec_batch(sql, @results_as_hash)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
237
314
|
# This is a convenience method for creating a statement, binding
|
238
|
-
#
|
315
|
+
# parameters to it, and calling execute:
|
239
316
|
#
|
240
317
|
# result = db.query( "select * from foo where a=?", [5])
|
241
318
|
# # is the same as
|
@@ -287,7 +364,11 @@ Support for this will be removed in version 2.0.0.
|
|
287
364
|
#
|
288
365
|
# See also #get_first_row.
|
289
366
|
def get_first_value( sql, *bind_vars )
|
290
|
-
|
367
|
+
query( sql, bind_vars ) do |rs|
|
368
|
+
if (row = rs.next)
|
369
|
+
return @results_as_hash ? row[rs.columns[0]] : row[0]
|
370
|
+
end
|
371
|
+
end
|
291
372
|
nil
|
292
373
|
end
|
293
374
|
|
@@ -316,8 +397,8 @@ Support for this will be removed in version 2.0.0.
|
|
316
397
|
# end
|
317
398
|
#
|
318
399
|
# puts db.get_first_value( "select maim(name) from table" )
|
319
|
-
def create_function name, arity, text_rep=Constants::TextRep::
|
320
|
-
|
400
|
+
def create_function name, arity, text_rep=Constants::TextRep::UTF8, &block
|
401
|
+
define_function_with_flags(name, text_rep) do |*args|
|
321
402
|
fp = FunctionProxy.new
|
322
403
|
block.call(fp, *args)
|
323
404
|
fp.result
|
@@ -364,42 +445,52 @@ Support for this will be removed in version 2.0.0.
|
|
364
445
|
def create_aggregate( name, arity, step=nil, finalize=nil,
|
365
446
|
text_rep=Constants::TextRep::ANY, &block )
|
366
447
|
|
367
|
-
|
448
|
+
proxy = Class.new do
|
368
449
|
def self.step( &block )
|
369
|
-
define_method(:
|
450
|
+
define_method(:step_with_ctx, &block)
|
370
451
|
end
|
371
452
|
|
372
453
|
def self.finalize( &block )
|
373
|
-
define_method(:
|
454
|
+
define_method(:finalize_with_ctx, &block)
|
374
455
|
end
|
375
456
|
end
|
376
457
|
|
377
458
|
if block_given?
|
378
|
-
|
459
|
+
proxy.instance_eval(&block)
|
379
460
|
else
|
380
|
-
|
381
|
-
define_method(:
|
382
|
-
define_method(:
|
461
|
+
proxy.class_eval do
|
462
|
+
define_method(:step_with_ctx, step)
|
463
|
+
define_method(:finalize_with_ctx, finalize)
|
383
464
|
end
|
384
465
|
end
|
385
466
|
|
386
|
-
proxy
|
387
|
-
|
388
|
-
|
467
|
+
proxy.class_eval do
|
468
|
+
# class instance variables
|
469
|
+
@name = name
|
470
|
+
@arity = arity
|
471
|
+
|
472
|
+
def self.name
|
473
|
+
@name
|
474
|
+
end
|
475
|
+
|
476
|
+
def self.arity
|
477
|
+
@arity
|
478
|
+
end
|
479
|
+
|
480
|
+
def initialize
|
481
|
+
@ctx = FunctionProxy.new
|
482
|
+
end
|
389
483
|
|
390
484
|
def step( *args )
|
391
|
-
|
485
|
+
step_with_ctx(@ctx, *args)
|
392
486
|
end
|
393
487
|
|
394
488
|
def finalize
|
395
|
-
|
396
|
-
|
397
|
-
@ctx = FunctionProxy.new
|
398
|
-
result
|
489
|
+
finalize_with_ctx(@ctx)
|
490
|
+
@ctx.result
|
399
491
|
end
|
400
|
-
|
401
|
-
proxy
|
402
|
-
define_aggregator(name, proxy)
|
492
|
+
end
|
493
|
+
define_aggregator2(proxy, name)
|
403
494
|
end
|
404
495
|
|
405
496
|
# This is another approach to creating an aggregate function (see
|
@@ -450,29 +541,75 @@ Support for this will be removed in version 2.0.0.
|
|
450
541
|
# db.create_aggregate_handler( LengthsAggregateHandler )
|
451
542
|
# puts db.get_first_value( "select lengths(name) from A" )
|
452
543
|
def create_aggregate_handler( handler )
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
544
|
+
# This is a compatibility shim so the (basically pointless) FunctionProxy
|
545
|
+
# "ctx" object is passed as first argument to both step() and finalize().
|
546
|
+
# Now its up to the library user whether he prefers to store his
|
547
|
+
# temporaries as instance variables or fields in the FunctionProxy.
|
548
|
+
# The library user still must set the result value with
|
549
|
+
# FunctionProxy.result= as there is no backwards compatible way to
|
550
|
+
# change this.
|
551
|
+
proxy = Class.new(handler) do
|
552
|
+
def initialize
|
553
|
+
super
|
554
|
+
@fp = FunctionProxy.new
|
457
555
|
end
|
458
556
|
|
459
557
|
def step( *args )
|
460
|
-
|
558
|
+
super(@fp, *args)
|
461
559
|
end
|
462
560
|
|
463
561
|
def finalize
|
464
|
-
|
465
|
-
@instance = nil
|
562
|
+
super(@fp)
|
466
563
|
@fp.result
|
467
564
|
end
|
565
|
+
end
|
566
|
+
define_aggregator2(proxy, proxy.name)
|
567
|
+
self
|
568
|
+
end
|
468
569
|
|
469
|
-
|
570
|
+
# Define an aggregate function named +name+ using a object template
|
571
|
+
# object +aggregator+. +aggregator+ must respond to +step+ and +finalize+.
|
572
|
+
# +step+ will be called with row information and +finalize+ must return the
|
573
|
+
# return value for the aggregator function.
|
574
|
+
#
|
575
|
+
# _API Change:_ +aggregator+ must also implement +clone+. The provided
|
576
|
+
# +aggregator+ object will serve as template that is cloned to provide the
|
577
|
+
# individual instances of the aggregate function. Regular ruby objects
|
578
|
+
# already provide a suitable +clone+.
|
579
|
+
# The functions arity is the arity of the +step+ method.
|
580
|
+
def define_aggregator( name, aggregator )
|
581
|
+
# Previously, this has been implemented in C. Now this is just yet
|
582
|
+
# another compatibility shim
|
583
|
+
proxy = Class.new do
|
584
|
+
@template = aggregator
|
585
|
+
@name = name
|
586
|
+
|
587
|
+
def self.template
|
588
|
+
@template
|
589
|
+
end
|
590
|
+
|
591
|
+
def self.name
|
592
|
+
@name
|
593
|
+
end
|
594
|
+
|
595
|
+
def self.arity
|
596
|
+
# this is what sqlite3_obj_method_arity did before
|
597
|
+
@template.method(:step).arity
|
598
|
+
end
|
599
|
+
|
600
|
+
def initialize
|
601
|
+
@klass = self.class.template.clone
|
602
|
+
end
|
470
603
|
|
471
|
-
def
|
472
|
-
@
|
604
|
+
def step(*args)
|
605
|
+
@klass.step(*args)
|
606
|
+
end
|
607
|
+
|
608
|
+
def finalize
|
609
|
+
@klass.finalize
|
473
610
|
end
|
474
611
|
end
|
475
|
-
|
612
|
+
define_aggregator2(proxy, name)
|
476
613
|
self
|
477
614
|
end
|
478
615
|
|
@@ -499,7 +636,7 @@ Support for this will be removed in version 2.0.0.
|
|
499
636
|
abort = false
|
500
637
|
begin
|
501
638
|
yield self
|
502
|
-
rescue
|
639
|
+
rescue
|
503
640
|
abort = true
|
504
641
|
raise
|
505
642
|
ensure
|
@@ -580,12 +717,25 @@ Support for this will be removed in version 2.0.0.
|
|
580
717
|
end
|
581
718
|
end
|
582
719
|
|
720
|
+
# Translates a +row+ of data from the database with the given +types+
|
721
|
+
def translate_from_db types, row
|
722
|
+
@type_translator.call types, row
|
723
|
+
end
|
724
|
+
|
583
725
|
private
|
584
726
|
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
727
|
+
NULL_TRANSLATOR = lambda { |_, row| row }
|
728
|
+
|
729
|
+
def make_type_translator should_translate
|
730
|
+
if should_translate
|
731
|
+
lambda { |types, row|
|
732
|
+
types.zip(row).map do |type, value|
|
733
|
+
translator.translate( type, value )
|
734
|
+
end
|
735
|
+
}
|
736
|
+
else
|
737
|
+
NULL_TRANSLATOR
|
738
|
+
end
|
589
739
|
end
|
590
740
|
end
|
591
741
|
end
|
data/lib/sqlite3/errors.rb
CHANGED
@@ -2,17 +2,8 @@ require 'sqlite3/constants'
|
|
2
2
|
|
3
3
|
module SQLite3
|
4
4
|
class Exception < ::StandardError
|
5
|
-
@code = 0
|
6
|
-
|
7
|
-
# The numeric error code that this exception represents.
|
8
|
-
def self.code
|
9
|
-
@code
|
10
|
-
end
|
11
|
-
|
12
5
|
# A convenience for accessing the error code for this exception.
|
13
|
-
|
14
|
-
self.class.code
|
15
|
-
end
|
6
|
+
attr_reader :code
|
16
7
|
end
|
17
8
|
|
18
9
|
class SQLException < Exception; end
|
data/lib/sqlite3/pragmas.rb
CHANGED
@@ -19,19 +19,19 @@ module SQLite3
|
|
19
19
|
# integer that represents truth.
|
20
20
|
def set_boolean_pragma( name, mode )
|
21
21
|
case mode
|
22
|
-
|
22
|
+
when String
|
23
23
|
case mode.downcase
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
when "on", "yes", "true", "y", "t"; mode = "'ON'"
|
25
|
+
when "off", "no", "false", "n", "f"; mode = "'OFF'"
|
26
|
+
else
|
27
27
|
raise Exception,
|
28
28
|
"unrecognized pragma parameter #{mode.inspect}"
|
29
29
|
end
|
30
|
-
|
30
|
+
when true, 1
|
31
31
|
mode = "ON"
|
32
|
-
|
32
|
+
when false, 0, nil
|
33
33
|
mode = "OFF"
|
34
|
-
|
34
|
+
else
|
35
35
|
raise Exception,
|
36
36
|
"unrecognized pragma parameter #{mode.inspect}"
|
37
37
|
end
|
@@ -42,11 +42,11 @@ module SQLite3
|
|
42
42
|
# Requests the given pragma (and parameters), and if the block is given,
|
43
43
|
# each row of the result set will be yielded to it. Otherwise, the results
|
44
44
|
# are returned as an array.
|
45
|
-
def get_query_pragma( name, *
|
46
|
-
if
|
45
|
+
def get_query_pragma( name, *params, &block ) # :yields: row
|
46
|
+
if params.empty?
|
47
47
|
execute( "PRAGMA #{name}", &block )
|
48
48
|
else
|
49
|
-
args = "'" +
|
49
|
+
args = "'" + params.join("','") + "'"
|
50
50
|
execute( "PRAGMA #{name}( #{args} )", &block )
|
51
51
|
end
|
52
52
|
end
|
@@ -543,6 +543,13 @@ module SQLite3
|
|
543
543
|
|
544
544
|
tweak_default(new_row) if needs_tweak_default
|
545
545
|
|
546
|
+
# Ensure the type value is downcased. On Mac and Windows
|
547
|
+
# platforms this value is now being returned as all upper
|
548
|
+
# case.
|
549
|
+
if new_row['type']
|
550
|
+
new_row['type'] = new_row['type'].downcase
|
551
|
+
end
|
552
|
+
|
546
553
|
if block_given?
|
547
554
|
yield new_row
|
548
555
|
else
|
data/lib/sqlite3/resultset.rb
CHANGED
@@ -108,11 +108,7 @@ object that created this object
|
|
108
108
|
row = @stmt.step
|
109
109
|
return nil if @stmt.done?
|
110
110
|
|
111
|
-
|
112
|
-
row = @stmt.types.zip(row).map do |type, value|
|
113
|
-
@db.translator.translate( type, value )
|
114
|
-
end
|
115
|
-
end
|
111
|
+
row = @db.translate_from_db @stmt.types, row
|
116
112
|
|
117
113
|
if row.respond_to?(:fields)
|
118
114
|
# FIXME: this can only happen if the translator returns something
|
@@ -176,11 +172,7 @@ object that created this object
|
|
176
172
|
|
177
173
|
# FIXME: type translation is deprecated, so this can be removed
|
178
174
|
# in 2.0
|
179
|
-
|
180
|
-
row = @stmt.types.zip(row).map do |type, value|
|
181
|
-
@db.translator.translate( type, value )
|
182
|
-
end
|
183
|
-
end
|
175
|
+
row = @db.translate_from_db @stmt.types, row
|
184
176
|
|
185
177
|
# FIXME: this can be switched to a regular hash in 2.0
|
186
178
|
row = HashWithTypesAndFields[*@stmt.columns.zip(row).flatten]
|
data/lib/sqlite3/statement.rb
CHANGED
data/lib/sqlite3/translator.rb
CHANGED
@@ -43,7 +43,7 @@ Built in translators are deprecated and will be removed in version 2.0.0
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# Translate the given string value to a value of the given type. In the
|
46
|
-
#
|
46
|
+
# absence of an installed translator block for the given type, the value
|
47
47
|
# itself is always returned. Further, +nil+ values are never translated,
|
48
48
|
# and are always passed straight through regardless of the type parameter.
|
49
49
|
def translate( type, value )
|
data/lib/sqlite3/version.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
module SQLite3
|
2
2
|
|
3
|
-
VERSION =
|
3
|
+
VERSION = "1.5.0"
|
4
4
|
|
5
5
|
module VersionProxy
|
6
|
-
|
7
6
|
MAJOR = 1
|
8
|
-
MINOR =
|
9
|
-
TINY =
|
7
|
+
MINOR = 5
|
8
|
+
TINY = 0
|
10
9
|
BUILD = nil
|
11
10
|
|
12
11
|
STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." )
|
13
|
-
#:beta-tag:
|
14
12
|
|
15
13
|
VERSION = ::SQLite3::VERSION
|
16
14
|
end
|
data/test/helper.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'sqlite3'
|
2
2
|
require 'minitest/autorun'
|
3
3
|
|
4
|
+
if ENV['GITHUB_ACTIONS'] == 'true' || ENV['CI']
|
5
|
+
$VERBOSE = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
puts "info: sqlite3-ruby version: #{SQLite3::VERSION}/#{SQLite3::VersionProxy::STRING}"
|
9
|
+
puts "info: sqlite3 version: #{SQLite3::SQLITE_VERSION}/#{SQLite3::SQLITE_LOADED_VERSION}"
|
10
|
+
puts "info: sqlcipher?: #{SQLite3.sqlcipher?}"
|
11
|
+
puts "info: threadsafe?: #{SQLite3.threadsafe?}"
|
12
|
+
|
4
13
|
unless RUBY_VERSION >= "1.9"
|
5
14
|
require 'iconv'
|
6
15
|
end
|