sqlite3 1.3.11-x64-mingw32 → 1.5.0.rc1-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gemtest +0 -0
- data/{API_CHANGES.rdoc → API_CHANGES.md} +3 -4
- data/CHANGELOG.md +419 -0
- data/CONTRIBUTING.md +24 -0
- data/Gemfile +2 -15
- data/LICENSE-DEPENDENCIES +20 -0
- data/README.md +233 -0
- data/ext/sqlite3/aggregator.c +273 -0
- data/ext/sqlite3/aggregator.h +12 -0
- data/ext/sqlite3/database.c +210 -182
- data/ext/sqlite3/database.h +2 -0
- data/ext/sqlite3/exception.c +6 -2
- data/ext/sqlite3/extconf.rb +148 -39
- data/ext/sqlite3/sqlite3.c +67 -1
- data/ext/sqlite3/sqlite3_ruby.h +0 -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 +209 -58
- data/lib/sqlite3/errors.rb +1 -10
- data/lib/sqlite3/pragmas.rb +372 -57
- 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 +4 -4
- data/lib/sqlite3.rb +5 -0
- data/test/helper.rb +9 -0
- data/test/test_database.rb +180 -9
- data/test/test_database_flags.rb +95 -0
- data/test/test_database_readonly.rb +9 -2
- data/test/test_database_readwrite.rb +41 -0
- data/test/test_integration.rb +12 -77
- data/test/test_integration_aggregate.rb +336 -0
- data/test/test_integration_resultset.rb +0 -17
- data/test/test_sqlite3.rb +16 -0
- data/test/test_statement.rb +12 -9
- metadata +55 -84
- data/CHANGELOG.rdoc +0 -287
- data/Manifest.txt +0 -52
- data/README.rdoc +0 -101
- 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/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:
|
@@ -98,6 +159,13 @@ in version 2.0.0.
|
|
98
159
|
end
|
99
160
|
end
|
100
161
|
|
162
|
+
# Returns the filename for the database named +db_name+. +db_name+ defaults
|
163
|
+
# to "main". Main return `nil` or an empty string if the database is
|
164
|
+
# temporary or in-memory.
|
165
|
+
def filename db_name = 'main'
|
166
|
+
db_filename db_name
|
167
|
+
end
|
168
|
+
|
101
169
|
# Executes the given SQL statement. If additional parameters are given,
|
102
170
|
# they are treated as bind variables, and are bound to the placeholders in
|
103
171
|
# the query.
|
@@ -113,10 +181,6 @@ in version 2.0.0.
|
|
113
181
|
# See also #execute2, #query, and #execute_batch for additional ways of
|
114
182
|
# executing statements.
|
115
183
|
def execute sql, bind_vars = [], *args, &block
|
116
|
-
# FIXME: This is a terrible hack and should be removed but is required
|
117
|
-
# for older versions of rails
|
118
|
-
hack = Object.const_defined?(:ActiveRecord) && sql =~ /^PRAGMA index_list/
|
119
|
-
|
120
184
|
if bind_vars.nil? || !args.empty?
|
121
185
|
if args.empty?
|
122
186
|
bind_vars = []
|
@@ -133,30 +197,14 @@ Support for bind parameters as *args will be removed in 2.0.0.
|
|
133
197
|
|
134
198
|
prepare( sql ) do |stmt|
|
135
199
|
stmt.bind_params(bind_vars)
|
136
|
-
|
137
|
-
stmt = ResultSet.new(self, stmt).to_a if type_translation
|
200
|
+
stmt = ResultSet.new self, stmt
|
138
201
|
|
139
202
|
if block_given?
|
140
203
|
stmt.each do |row|
|
141
|
-
|
142
|
-
yield type_translation ? row : ordered_map_for(columns, row)
|
143
|
-
else
|
144
|
-
yield row
|
145
|
-
end
|
204
|
+
yield row
|
146
205
|
end
|
147
206
|
else
|
148
|
-
|
149
|
-
stmt.map { |row|
|
150
|
-
h = type_translation ? row : ordered_map_for(columns, row)
|
151
|
-
|
152
|
-
# FIXME UGH TERRIBLE HACK!
|
153
|
-
h['unique'] = h['unique'].to_s if hack
|
154
|
-
|
155
|
-
h
|
156
|
-
}
|
157
|
-
else
|
158
|
-
stmt.to_a
|
159
|
-
end
|
207
|
+
stmt.to_a
|
160
208
|
end
|
161
209
|
end
|
162
210
|
end
|
@@ -192,6 +240,9 @@ Support for bind parameters as *args will be removed in 2.0.0.
|
|
192
240
|
#
|
193
241
|
# This always returns +nil+, making it unsuitable for queries that return
|
194
242
|
# rows.
|
243
|
+
#
|
244
|
+
# See also #execute_batch2 for additional ways of
|
245
|
+
# executing statements.
|
195
246
|
def execute_batch( sql, bind_vars = [], *args )
|
196
247
|
# FIXME: remove this stuff later
|
197
248
|
unless [Array, Hash].include?(bind_vars.class)
|
@@ -236,8 +287,32 @@ Support for this behavior will be removed in version 2.0.0.
|
|
236
287
|
nil
|
237
288
|
end
|
238
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
|
+
|
239
314
|
# This is a convenience method for creating a statement, binding
|
240
|
-
#
|
315
|
+
# parameters to it, and calling execute:
|
241
316
|
#
|
242
317
|
# result = db.query( "select * from foo where a=?", [5])
|
243
318
|
# # is the same as
|
@@ -289,7 +364,11 @@ Support for this will be removed in version 2.0.0.
|
|
289
364
|
#
|
290
365
|
# See also #get_first_row.
|
291
366
|
def get_first_value( sql, *bind_vars )
|
292
|
-
|
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
|
293
372
|
nil
|
294
373
|
end
|
295
374
|
|
@@ -318,8 +397,8 @@ Support for this will be removed in version 2.0.0.
|
|
318
397
|
# end
|
319
398
|
#
|
320
399
|
# puts db.get_first_value( "select maim(name) from table" )
|
321
|
-
def create_function name, arity, text_rep=Constants::TextRep::
|
322
|
-
|
400
|
+
def create_function name, arity, text_rep=Constants::TextRep::UTF8, &block
|
401
|
+
define_function_with_flags(name, text_rep) do |*args|
|
323
402
|
fp = FunctionProxy.new
|
324
403
|
block.call(fp, *args)
|
325
404
|
fp.result
|
@@ -366,39 +445,52 @@ Support for this will be removed in version 2.0.0.
|
|
366
445
|
def create_aggregate( name, arity, step=nil, finalize=nil,
|
367
446
|
text_rep=Constants::TextRep::ANY, &block )
|
368
447
|
|
369
|
-
|
448
|
+
proxy = Class.new do
|
370
449
|
def self.step( &block )
|
371
|
-
define_method(:
|
450
|
+
define_method(:step_with_ctx, &block)
|
372
451
|
end
|
373
452
|
|
374
453
|
def self.finalize( &block )
|
375
|
-
define_method(:
|
454
|
+
define_method(:finalize_with_ctx, &block)
|
376
455
|
end
|
377
456
|
end
|
378
457
|
|
379
458
|
if block_given?
|
380
|
-
|
459
|
+
proxy.instance_eval(&block)
|
381
460
|
else
|
382
|
-
|
383
|
-
define_method(:
|
384
|
-
define_method(:
|
461
|
+
proxy.class_eval do
|
462
|
+
define_method(:step_with_ctx, step)
|
463
|
+
define_method(:finalize_with_ctx, finalize)
|
385
464
|
end
|
386
465
|
end
|
387
466
|
|
388
|
-
proxy
|
389
|
-
|
390
|
-
|
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
|
391
483
|
|
392
484
|
def step( *args )
|
393
|
-
|
485
|
+
step_with_ctx(@ctx, *args)
|
394
486
|
end
|
395
487
|
|
396
488
|
def finalize
|
397
|
-
|
489
|
+
finalize_with_ctx(@ctx)
|
490
|
+
@ctx.result
|
398
491
|
end
|
399
|
-
|
400
|
-
proxy
|
401
|
-
define_aggregator(name, proxy)
|
492
|
+
end
|
493
|
+
define_aggregator2(proxy, name)
|
402
494
|
end
|
403
495
|
|
404
496
|
# This is another approach to creating an aggregate function (see
|
@@ -449,29 +541,75 @@ Support for this will be removed in version 2.0.0.
|
|
449
541
|
# db.create_aggregate_handler( LengthsAggregateHandler )
|
450
542
|
# puts db.get_first_value( "select lengths(name) from A" )
|
451
543
|
def create_aggregate_handler( handler )
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
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
|
456
555
|
end
|
457
556
|
|
458
557
|
def step( *args )
|
459
|
-
|
558
|
+
super(@fp, *args)
|
460
559
|
end
|
461
560
|
|
462
561
|
def finalize
|
463
|
-
|
464
|
-
@instance = nil
|
562
|
+
super(@fp)
|
465
563
|
@fp.result
|
466
564
|
end
|
565
|
+
end
|
566
|
+
define_aggregator2(proxy, proxy.name)
|
567
|
+
self
|
568
|
+
end
|
569
|
+
|
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
|
467
590
|
|
468
|
-
|
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
|
469
603
|
|
470
|
-
def
|
471
|
-
@
|
604
|
+
def step(*args)
|
605
|
+
@klass.step(*args)
|
606
|
+
end
|
607
|
+
|
608
|
+
def finalize
|
609
|
+
@klass.finalize
|
472
610
|
end
|
473
611
|
end
|
474
|
-
|
612
|
+
define_aggregator2(proxy, name)
|
475
613
|
self
|
476
614
|
end
|
477
615
|
|
@@ -498,7 +636,7 @@ Support for this will be removed in version 2.0.0.
|
|
498
636
|
abort = false
|
499
637
|
begin
|
500
638
|
yield self
|
501
|
-
rescue
|
639
|
+
rescue
|
502
640
|
abort = true
|
503
641
|
raise
|
504
642
|
ensure
|
@@ -579,12 +717,25 @@ Support for this will be removed in version 2.0.0.
|
|
579
717
|
end
|
580
718
|
end
|
581
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
|
+
|
582
725
|
private
|
583
726
|
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
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
|
588
739
|
end
|
589
740
|
end
|
590
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
|