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.
Files changed (54) 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 +419 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +2 -15
  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 +210 -182
  12. data/ext/sqlite3/database.h +2 -0
  13. data/ext/sqlite3/exception.c +6 -2
  14. data/ext/sqlite3/extconf.rb +148 -39
  15. data/ext/sqlite3/sqlite3.c +67 -1
  16. data/ext/sqlite3/sqlite3_ruby.h +0 -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 +209 -58
  25. data/lib/sqlite3/errors.rb +1 -10
  26. data/lib/sqlite3/pragmas.rb +372 -57
  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/lib/sqlite3.rb +5 -0
  32. data/test/helper.rb +9 -0
  33. data/test/test_database.rb +180 -9
  34. data/test/test_database_flags.rb +95 -0
  35. data/test/test_database_readonly.rb +9 -2
  36. data/test/test_database_readwrite.rb +41 -0
  37. data/test/test_integration.rb +12 -77
  38. data/test/test_integration_aggregate.rb +336 -0
  39. data/test/test_integration_resultset.rb +0 -17
  40. data/test/test_sqlite3.rb +16 -0
  41. data/test/test_statement.rb +12 -9
  42. metadata +55 -84
  43. data/CHANGELOG.rdoc +0 -287
  44. data/Manifest.txt +0 -52
  45. data/README.rdoc +0 -101
  46. data/Rakefile +0 -10
  47. data/lib/sqlite3/2.0/sqlite3_native.so +0 -0
  48. data/lib/sqlite3/2.1/sqlite3_native.so +0 -0
  49. data/lib/sqlite3/2.2/sqlite3_native.so +0 -0
  50. data/setup.rb +0 -1333
  51. data/tasks/faq.rake +0 -9
  52. data/tasks/gem.rake +0 -38
  53. data/tasks/native.rake +0 -52
  54. 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:
@@ -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
- columns = stmt.columns
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
- if @results_as_hash
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
- if @results_as_hash
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
- # paramters to it, and calling execute:
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
- 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
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::ANY, &block
322
- 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|
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
- factory = Class.new do
448
+ proxy = Class.new do
370
449
  def self.step( &block )
371
- define_method(:step, &block)
450
+ define_method(:step_with_ctx, &block)
372
451
  end
373
452
 
374
453
  def self.finalize( &block )
375
- define_method(:finalize, &block)
454
+ define_method(:finalize_with_ctx, &block)
376
455
  end
377
456
  end
378
457
 
379
458
  if block_given?
380
- factory.instance_eval(&block)
459
+ proxy.instance_eval(&block)
381
460
  else
382
- factory.class_eval do
383
- define_method(:step, step)
384
- define_method(:finalize, finalize)
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 = factory.new
389
- proxy.extend(Module.new {
390
- 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
391
483
 
392
484
  def step( *args )
393
- super(@ctx, *args)
485
+ step_with_ctx(@ctx, *args)
394
486
  end
395
487
 
396
488
  def finalize
397
- super(@ctx)
489
+ finalize_with_ctx(@ctx)
490
+ @ctx.result
398
491
  end
399
- })
400
- proxy.ctx = FunctionProxy.new
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
- proxy = Class.new do
453
- def initialize klass
454
- @klass = klass
455
- @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
456
555
  end
457
556
 
458
557
  def step( *args )
459
- instance.step(@fp, *args)
558
+ super(@fp, *args)
460
559
  end
461
560
 
462
561
  def finalize
463
- instance.finalize @fp
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
- private
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 instance
471
- @instance ||= @klass.new
604
+ def step(*args)
605
+ @klass.step(*args)
606
+ end
607
+
608
+ def finalize
609
+ @klass.finalize
472
610
  end
473
611
  end
474
- define_aggregator(handler.name, proxy.new(handler))
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 ::Object
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
- def ordered_map_for columns, row
585
- h = Hash[*columns.zip(row).flatten]
586
- row.each_with_index { |r, i| h[i] = r }
587
- 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
588
739
  end
589
740
  end
590
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