sqlite3 1.3.12-x64-mingw32 → 1.5.0.rc2-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.gemtest +0 -0
  3. data/{API_CHANGES.rdoc → API_CHANGES.md} +3 -4
  4. data/CHANGELOG.md +425 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +2 -14
  7. data/LICENSE-DEPENDENCIES +20 -0
  8. data/README.md +233 -0
  9. data/ext/sqlite3/aggregator.c +273 -0
  10. data/ext/sqlite3/aggregator.h +12 -0
  11. data/ext/sqlite3/database.c +171 -206
  12. data/ext/sqlite3/database.h +2 -0
  13. data/ext/sqlite3/exception.c +6 -2
  14. data/ext/sqlite3/extconf.rb +236 -55
  15. data/ext/sqlite3/sqlite3.c +12 -1
  16. data/ext/sqlite3/sqlite3_ruby.h +3 -7
  17. data/ext/sqlite3/statement.c +15 -20
  18. data/faq/faq.md +431 -0
  19. data/faq/faq.yml +1 -1
  20. data/lib/sqlite3/2.6/sqlite3_native.so +0 -0
  21. data/lib/sqlite3/2.7/sqlite3_native.so +0 -0
  22. data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
  23. data/lib/sqlite3/constants.rb +2 -1
  24. data/lib/sqlite3/database.rb +202 -52
  25. data/lib/sqlite3/errors.rb +1 -10
  26. data/lib/sqlite3/pragmas.rb +17 -19
  27. data/lib/sqlite3/resultset.rb +2 -10
  28. data/lib/sqlite3/statement.rb +2 -1
  29. data/lib/sqlite3/translator.rb +1 -1
  30. data/lib/sqlite3/version.rb +4 -4
  31. data/test/helper.rb +9 -0
  32. data/test/test_database.rb +127 -11
  33. data/test/test_database_flags.rb +95 -0
  34. data/test/test_database_readwrite.rb +41 -0
  35. data/test/test_integration.rb +12 -81
  36. data/test/test_integration_aggregate.rb +336 -0
  37. data/test/test_integration_resultset.rb +0 -17
  38. data/test/test_sqlite3.rb +9 -0
  39. data/test/test_statement.rb +12 -9
  40. metadata +55 -85
  41. data/CHANGELOG.rdoc +0 -292
  42. data/Manifest.txt +0 -52
  43. data/README.rdoc +0 -118
  44. data/Rakefile +0 -10
  45. data/lib/sqlite3/2.0/sqlite3_native.so +0 -0
  46. data/lib/sqlite3/2.1/sqlite3_native.so +0 -0
  47. data/lib/sqlite3/2.2/sqlite3_native.so +0 -0
  48. data/lib/sqlite3/2.3/sqlite3_native.so +0 -0
  49. data/setup.rb +0 -1333
  50. data/tasks/faq.rake +0 -9
  51. data/tasks/gem.rake +0 -38
  52. data/tasks/native.rake +0 -52
  53. data/tasks/vendor_sqlite3.rake +0 -97
@@ -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
- columns = stmt.columns
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
- if @results_as_hash
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
- if @results_as_hash
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
- # paramters to it, and calling execute:
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
- execute( sql, *bind_vars ) { |row| return row[0] }
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::ANY, &block
320
- define_function(name) do |*args|
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
- factory = Class.new do
448
+ proxy = Class.new do
368
449
  def self.step( &block )
369
- define_method(:step, &block)
450
+ define_method(:step_with_ctx, &block)
370
451
  end
371
452
 
372
453
  def self.finalize( &block )
373
- define_method(:finalize, &block)
454
+ define_method(:finalize_with_ctx, &block)
374
455
  end
375
456
  end
376
457
 
377
458
  if block_given?
378
- factory.instance_eval(&block)
459
+ proxy.instance_eval(&block)
379
460
  else
380
- factory.class_eval do
381
- define_method(:step, step)
382
- define_method(:finalize, finalize)
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 = factory.new
387
- proxy.extend(Module.new {
388
- attr_accessor :ctx
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
- super(@ctx, *args)
485
+ step_with_ctx(@ctx, *args)
392
486
  end
393
487
 
394
488
  def finalize
395
- super(@ctx)
396
- result = @ctx.result
397
- @ctx = FunctionProxy.new
398
- result
489
+ finalize_with_ctx(@ctx)
490
+ @ctx.result
399
491
  end
400
- })
401
- proxy.ctx = FunctionProxy.new
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
- proxy = Class.new do
454
- def initialize klass
455
- @klass = klass
456
- @fp = FunctionProxy.new
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
- instance.step(@fp, *args)
558
+ super(@fp, *args)
461
559
  end
462
560
 
463
561
  def finalize
464
- instance.finalize @fp
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
- private
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 instance
472
- @instance ||= @klass.new
604
+ def step(*args)
605
+ @klass.step(*args)
606
+ end
607
+
608
+ def finalize
609
+ @klass.finalize
473
610
  end
474
611
  end
475
- define_aggregator(handler.name, proxy.new(handler))
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 ::Object
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
- def ordered_map_for columns, row
586
- h = Hash[*columns.zip(row).flatten]
587
- row.each_with_index { |r, i| h[i] = r }
588
- h
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
@@ -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
- def code
14
- self.class.code
15
- end
6
+ attr_reader :code
16
7
  end
17
8
 
18
9
  class SQLException < Exception; end
@@ -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
- when String
22
+ when String
23
23
  case mode.downcase
24
- when "on", "yes", "true", "y", "t"; mode = "'ON'"
25
- when "off", "no", "false", "n", "f"; mode = "'OFF'"
26
- else
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
- when true, 1
30
+ when true, 1
31
31
  mode = "ON"
32
- when false, 0, nil
32
+ when false, 0, nil
33
33
  mode = "OFF"
34
- else
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, *parms, &block ) # :yields: row
46
- if parms.empty?
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 = "'" + parms.join("','") + "'"
49
+ args = "'" + params.join("','") + "'"
50
50
  execute( "PRAGMA #{name}( #{args} )", &block )
51
51
  end
52
52
  end
@@ -101,15 +101,6 @@ module SQLite3
101
101
  # The list of valid WAL checkpoints.
102
102
  WAL_CHECKPOINTS = [ [ 'passive' ], [ 'full' ], [ 'restart' ], [ 'truncate' ] ]
103
103
 
104
- # Does an integrity check on the database. If the check fails, a
105
- # SQLite3::Exception will be raised. Otherwise it
106
- # returns silently.
107
- def integrity_check
108
- execute( "PRAGMA integrity_check" ) do |row|
109
- raise Exception, row[0] if row[0] != "ok"
110
- end
111
- end
112
-
113
104
  def application_id
114
105
  get_int_pragma "application_id"
115
106
  end
@@ -552,6 +543,13 @@ module SQLite3
552
543
 
553
544
  tweak_default(new_row) if needs_tweak_default
554
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
+
555
553
  if block_given?
556
554
  yield new_row
557
555
  else
@@ -108,11 +108,7 @@ object that created this object
108
108
  row = @stmt.step
109
109
  return nil if @stmt.done?
110
110
 
111
- if @db.type_translation
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
- if @db.type_translation
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]
@@ -137,7 +137,8 @@ module SQLite3
137
137
  column_name column
138
138
  end
139
139
  @types = Array.new(column_count) do |column|
140
- column_decltype column
140
+ val = column_decltype(column)
141
+ val.nil? ? nil : val.downcase
141
142
  end
142
143
  end
143
144
  end
@@ -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
- # absense of an installed translator block for the given type, the value
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 )
@@ -1,13 +1,13 @@
1
1
  module SQLite3
2
2
 
3
- VERSION = '1.3.12'
3
+ VERSION = "1.5.0.rc2"
4
4
 
5
5
  module VersionProxy
6
6
 
7
7
  MAJOR = 1
8
- MINOR = 3
9
- TINY = 12
10
- BUILD = nil
8
+ MINOR = 5
9
+ TINY = 0
10
+ BUILD = "rc2"
11
11
 
12
12
  STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." )
13
13
  #:beta-tag:
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