sqlite3 1.7.3-x64-mingw32 → 2.0.0-x64-mingw32

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +152 -0
  3. data/CONTRIBUTING.md +23 -1
  4. data/FAQ.md +0 -43
  5. data/INSTALLATION.md +13 -5
  6. data/LICENSE +18 -22
  7. data/README.md +75 -4
  8. data/dependencies.yml +10 -11
  9. data/ext/sqlite3/aggregator.c +142 -145
  10. data/ext/sqlite3/aggregator.h +2 -4
  11. data/ext/sqlite3/backup.c +74 -65
  12. data/ext/sqlite3/backup.h +2 -2
  13. data/ext/sqlite3/database.c +535 -482
  14. data/ext/sqlite3/database.h +7 -4
  15. data/ext/sqlite3/exception.c +111 -92
  16. data/ext/sqlite3/exception.h +3 -1
  17. data/ext/sqlite3/extconf.rb +21 -22
  18. data/ext/sqlite3/sqlite3.c +159 -115
  19. data/ext/sqlite3/sqlite3_ruby.h +2 -2
  20. data/ext/sqlite3/statement.c +516 -300
  21. data/ext/sqlite3/statement.h +3 -3
  22. data/ext/sqlite3/timespec.h +20 -0
  23. data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
  24. data/lib/sqlite3/constants.rb +171 -47
  25. data/lib/sqlite3/database.rb +105 -165
  26. data/lib/sqlite3/errors.rb +26 -1
  27. data/lib/sqlite3/pragmas.rb +126 -136
  28. data/lib/sqlite3/resultset.rb +14 -97
  29. data/lib/sqlite3/statement.rb +58 -13
  30. data/lib/sqlite3/value.rb +17 -20
  31. data/lib/sqlite3/version.rb +1 -21
  32. data/lib/sqlite3.rb +6 -4
  33. metadata +3 -28
  34. data/API_CHANGES.md +0 -49
  35. data/ChangeLog.cvs +0 -88
  36. data/Gemfile +0 -10
  37. data/LICENSE-DEPENDENCIES +0 -20
  38. data/lib/sqlite3/translator.rb +0 -117
  39. data/test/helper.rb +0 -27
  40. data/test/test_backup.rb +0 -33
  41. data/test/test_collation.rb +0 -82
  42. data/test/test_database.rb +0 -668
  43. data/test/test_database_flags.rb +0 -95
  44. data/test/test_database_readonly.rb +0 -36
  45. data/test/test_database_readwrite.rb +0 -41
  46. data/test/test_deprecated.rb +0 -49
  47. data/test/test_encoding.rb +0 -165
  48. data/test/test_integration.rb +0 -507
  49. data/test/test_integration_aggregate.rb +0 -336
  50. data/test/test_integration_open_close.rb +0 -30
  51. data/test/test_integration_pending.rb +0 -115
  52. data/test/test_integration_resultset.rb +0 -142
  53. data/test/test_integration_statement.rb +0 -194
  54. data/test/test_pragmas.rb +0 -22
  55. data/test/test_result_set.rb +0 -47
  56. data/test/test_sqlite3.rb +0 -30
  57. data/test/test_statement.rb +0 -290
  58. data/test/test_statement_execute.rb +0 -39
@@ -1,12 +1,10 @@
1
- require 'sqlite3/constants'
2
- require 'sqlite3/errors'
3
- require 'sqlite3/pragmas'
4
- require 'sqlite3/statement'
5
- require 'sqlite3/translator'
6
- require 'sqlite3/value'
1
+ require "sqlite3/constants"
2
+ require "sqlite3/errors"
3
+ require "sqlite3/pragmas"
4
+ require "sqlite3/statement"
5
+ require "sqlite3/value"
7
6
 
8
7
  module SQLite3
9
-
10
8
  # The Database class encapsulates a single connection to a SQLite3 database.
11
9
  # Its usage is very straightforward:
12
10
  #
@@ -32,17 +30,24 @@ module SQLite3
32
30
  # ArrayFields module from Ara Howard. If you require the ArrayFields
33
31
  # module before performing a query, and if you have not enabled results as
34
32
  # hashes, then the results will all be indexible by field name.
33
+ #
34
+ # Thread safety:
35
+ #
36
+ # When `SQLite3.threadsafe?` returns true, it is safe to share instances of
37
+ # the database class among threads without adding specific locking. Other
38
+ # object instances may require applications to provide their own locks if
39
+ # they are to be shared among threads. Please see the README.md for more
40
+ # information.
35
41
  class Database
36
42
  attr_reader :collations
37
43
 
38
44
  include Pragmas
39
45
 
40
46
  class << self
41
-
42
47
  # Without block works exactly as new.
43
48
  # With block, like new closes the database at the end, but unlike new
44
49
  # returns the result of the block instead of the database instance.
45
- def open( *args )
50
+ def open(*args)
46
51
  database = new(*args)
47
52
 
48
53
  if block_given?
@@ -59,10 +64,9 @@ module SQLite3
59
64
  # Quotes the given string, making it safe to use in an SQL statement.
60
65
  # It replaces all instances of the single-quote character with two
61
66
  # single-quote characters. The modified string is returned.
62
- def quote( string )
63
- string.gsub( /'/, "''" )
67
+ def quote(string)
68
+ string.gsub("'", "''")
64
69
  end
65
-
66
70
  end
67
71
 
68
72
  # A boolean that indicates whether rows in result sets should be returned
@@ -85,7 +89,6 @@ module SQLite3
85
89
  # Other supported +options+:
86
90
  # - +:strict+: boolean (default false), disallow the use of double-quoted string literals (see https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted)
87
91
  # - +:results_as_hash+: boolean (default false), return rows as hashes instead of arrays
88
- # - +:type_translation+: boolean (default false), enable type translation
89
92
  # - +:default_transaction_mode+: one of +:deferred+ (default), +:immediate+, or +:exclusive+. If a mode is not specified in a call to #transaction, this will be the default transaction mode.
90
93
  #
91
94
  def initialize file, options = {}, zvfs = nil
@@ -120,16 +123,14 @@ module SQLite3
120
123
  end
121
124
  end
122
125
 
123
- @tracefunc = nil
124
- @authorizer = nil
125
- @encoding = nil
126
- @busy_handler = nil
127
- @collations = {}
128
- @functions = {}
129
- @results_as_hash = options[:results_as_hash]
130
- @type_translation = options[:type_translation]
131
- @type_translator = make_type_translator @type_translation
132
- @readonly = mode & Constants::Open::READONLY != 0
126
+ @tracefunc = nil
127
+ @authorizer = nil
128
+ @busy_handler = nil
129
+ @progress_handler = nil
130
+ @collations = {}
131
+ @functions = {}
132
+ @results_as_hash = options[:results_as_hash]
133
+ @readonly = mode & Constants::Open::READONLY != 0
133
134
  @default_transaction_mode = options[:default_transaction_mode] || :deferred
134
135
 
135
136
  if block_given?
@@ -141,30 +142,18 @@ module SQLite3
141
142
  end
142
143
  end
143
144
 
144
- def type_translation= value # :nodoc:
145
- warn(<<-eowarn) if $VERBOSE
146
- #{caller[0]} is calling `SQLite3::Database#type_translation=` which is deprecated and will be removed in version 2.0.0.
147
- eowarn
148
- @type_translator = make_type_translator value
149
- @type_translation = value
150
- end
151
- attr_reader :type_translation # :nodoc:
152
-
153
- # Return the type translator employed by this database instance. Each
154
- # database instance has its own type translator; this allows for different
155
- # type handlers to be installed in each instance without affecting other
156
- # instances. Furthermore, the translators are instantiated lazily, so that
157
- # if a database does not use type translation, it will not be burdened by
158
- # the overhead of a useless type translator. (See the Translator class.)
159
- def translator
160
- @translator ||= Translator.new
145
+ # call-seq: db.encoding
146
+ #
147
+ # Fetch the encoding set on this database
148
+ def encoding
149
+ prepare("PRAGMA encoding") { |stmt| Encoding.find(stmt.first.first) }
161
150
  end
162
151
 
163
152
  # Installs (or removes) a block that will be invoked for every access
164
153
  # to the database. If the block returns 0 (or +nil+), the statement
165
154
  # is allowed to proceed. Returning 1 causes an authorization error to
166
155
  # occur, and returning 2 causes the access to be silently denied.
167
- def authorizer( &block )
156
+ def authorizer(&block)
168
157
  self.authorizer = block
169
158
  end
170
159
 
@@ -174,7 +163,7 @@ module SQLite3
174
163
  # The Statement can then be executed using Statement#execute.
175
164
  #
176
165
  def prepare sql
177
- stmt = SQLite3::Statement.new( self, sql )
166
+ stmt = SQLite3::Statement.new(self, sql)
178
167
  return stmt unless block_given?
179
168
 
180
169
  begin
@@ -187,7 +176,7 @@ module SQLite3
187
176
  # Returns the filename for the database named +db_name+. +db_name+ defaults
188
177
  # to "main". Main return `nil` or an empty string if the database is
189
178
  # temporary or in-memory.
190
- def filename db_name = 'main'
179
+ def filename db_name = "main"
191
180
  db_filename db_name
192
181
  end
193
182
 
@@ -206,28 +195,16 @@ module SQLite3
206
195
  # See also #execute2, #query, and #execute_batch for additional ways of
207
196
  # executing statements.
208
197
  def execute sql, bind_vars = [], *args, &block
209
- if bind_vars.nil? || !args.empty?
210
- if args.empty?
211
- bind_vars = []
212
- else
213
- bind_vars = [bind_vars] + args
214
- end
215
-
216
- warn(<<-eowarn) if $VERBOSE
217
- #{caller[0]} is calling `SQLite3::Database#execute` with nil or multiple bind params without using an array. Please switch to passing bind parameters as an array. Support for bind parameters as *args will be removed in 2.0.0.
218
- eowarn
219
- end
220
-
221
- prepare( sql ) do |stmt|
198
+ prepare(sql) do |stmt|
222
199
  stmt.bind_params(bind_vars)
223
- stmt = ResultSet.new self, stmt
200
+ stmt = build_result_set stmt
224
201
 
225
- if block_given?
202
+ if block
226
203
  stmt.each do |row|
227
204
  yield row
228
205
  end
229
206
  else
230
- stmt.to_a
207
+ stmt.to_a.freeze
231
208
  end
232
209
  end
233
210
  end
@@ -242,15 +219,16 @@ module SQLite3
242
219
  #
243
220
  # See also #execute, #query, and #execute_batch for additional ways of
244
221
  # executing statements.
245
- def execute2( sql, *bind_vars )
246
- prepare( sql ) do |stmt|
247
- result = stmt.execute( *bind_vars )
222
+ def execute2(sql, *bind_vars)
223
+ prepare(sql) do |stmt|
224
+ result = stmt.execute(*bind_vars)
248
225
  if block_given?
249
226
  yield stmt.columns
250
227
  result.each { |row| yield row }
251
228
  else
252
- return result.inject( [ stmt.columns ] ) { |arr,row|
253
- arr << row; arr }
229
+ return result.each_with_object([stmt.columns]) { |row, arr|
230
+ arr << row
231
+ }
254
232
  end
255
233
  end
256
234
  end
@@ -261,49 +239,28 @@ module SQLite3
261
239
  # in turn. The same bind parameters, if given, will be applied to each
262
240
  # statement.
263
241
  #
264
- # This always returns +nil+, making it unsuitable for queries that return
265
- # rows.
242
+ # This always returns the result of the last statement.
266
243
  #
267
244
  # See also #execute_batch2 for additional ways of
268
245
  # executing statements.
269
- def execute_batch( sql, bind_vars = [], *args )
270
- # FIXME: remove this stuff later
271
- unless [Array, Hash].include?(bind_vars.class)
272
- bind_vars = [bind_vars]
273
- warn(<<-eowarn) if $VERBOSE
274
- #{caller[0]} is calling `SQLite3::Database#execute_batch` with bind parameters that are not a list of a hash. Please switch to passing bind parameters as an array or hash. Support for this behavior will be removed in version 2.0.0.
275
- eowarn
276
- end
277
-
278
- # FIXME: remove this stuff later
279
- if bind_vars.nil? || !args.empty?
280
- if args.empty?
281
- bind_vars = []
282
- else
283
- bind_vars = [nil] + args
284
- end
285
-
286
- warn(<<-eowarn) if $VERBOSE
287
- #{caller[0]} is calling `SQLite3::Database#execute_batch` with nil or multiple bind params without using an array. Please switch to passing bind parameters as an array. Support for this behavior will be removed in version 2.0.0.
288
- eowarn
289
- end
290
-
246
+ def execute_batch(sql, bind_vars = [], *args)
291
247
  sql = sql.strip
292
- until sql.empty? do
293
- prepare( sql ) do |stmt|
248
+ result = nil
249
+ until sql.empty?
250
+ prepare(sql) do |stmt|
294
251
  unless stmt.closed?
295
252
  # FIXME: this should probably use sqlite3's api for batch execution
296
253
  # This implementation requires stepping over the results.
297
254
  if bind_vars.length == stmt.bind_parameter_count
298
255
  stmt.bind_params(bind_vars)
299
256
  end
300
- stmt.step
257
+ result = stmt.step
301
258
  end
302
259
  sql = stmt.remainder.strip
303
260
  end
304
261
  end
305
- # FIXME: we should not return `nil` as a success return value
306
- nil
262
+
263
+ result
307
264
  end
308
265
 
309
266
  # Executes all SQL statements in the given string. By contrast, the other
@@ -320,7 +277,7 @@ module SQLite3
320
277
  # See also #execute_batch for additional ways of
321
278
  # executing statements.
322
279
  def execute_batch2(sql, &block)
323
- if block_given?
280
+ if block
324
281
  result = exec_batch(sql, @results_as_hash)
325
282
  result.map do |val|
326
283
  yield val
@@ -341,21 +298,8 @@ module SQLite3
341
298
  # returned, or you could have problems with locks on the table. If called
342
299
  # with a block, +close+ will be invoked implicitly when the block
343
300
  # terminates.
344
- def query( sql, bind_vars = [], *args )
345
-
346
- if bind_vars.nil? || !args.empty?
347
- if args.empty?
348
- bind_vars = []
349
- else
350
- bind_vars = [bind_vars] + args
351
- end
352
-
353
- warn(<<-eowarn) if $VERBOSE
354
- #{caller[0]} is calling `SQLite3::Database#query` with nil or multiple bind params without using an array. Please switch to passing bind parameters as an array. Support for this will be removed in version 2.0.0.
355
- eowarn
356
- end
357
-
358
- result = prepare( sql ).execute( bind_vars )
301
+ def query(sql, bind_vars = [], *args)
302
+ result = prepare(sql).execute(bind_vars)
359
303
  if block_given?
360
304
  begin
361
305
  yield result
@@ -363,7 +307,7 @@ module SQLite3
363
307
  result.close
364
308
  end
365
309
  else
366
- return result
310
+ result
367
311
  end
368
312
  end
369
313
 
@@ -371,8 +315,8 @@ module SQLite3
371
315
  # discarding all others. It is otherwise identical to #execute.
372
316
  #
373
317
  # See also #get_first_value.
374
- def get_first_row( sql, *bind_vars )
375
- execute( sql, *bind_vars ).first
318
+ def get_first_row(sql, *bind_vars)
319
+ execute(sql, *bind_vars).first
376
320
  end
377
321
 
378
322
  # A convenience method for obtaining the first value of the first row of a
@@ -380,8 +324,8 @@ module SQLite3
380
324
  # identical to #execute.
381
325
  #
382
326
  # See also #get_first_row.
383
- def get_first_value( sql, *bind_vars )
384
- query( sql, bind_vars ) do |rs|
327
+ def get_first_value(sql, *bind_vars)
328
+ query(sql, bind_vars) do |rs|
385
329
  if (row = rs.next)
386
330
  return @results_as_hash ? row[rs.columns[0]] : row[0]
387
331
  end
@@ -389,7 +333,7 @@ module SQLite3
389
333
  nil
390
334
  end
391
335
 
392
- alias :busy_timeout :busy_timeout=
336
+ alias_method :busy_timeout, :busy_timeout=
393
337
 
394
338
  # Creates a new function for use in SQL statements. It will be added as
395
339
  # +name+, with the given +arity+. (For variable arity functions, use
@@ -414,7 +358,7 @@ module SQLite3
414
358
  # end
415
359
  #
416
360
  # puts db.get_first_value( "select maim(name) from table" )
417
- def create_function name, arity, text_rep=Constants::TextRep::UTF8, &block
361
+ def create_function name, arity, text_rep = Constants::TextRep::UTF8, &block
418
362
  define_function_with_flags(name, text_rep) do |*args|
419
363
  fp = FunctionProxy.new
420
364
  block.call(fp, *args)
@@ -459,20 +403,20 @@ module SQLite3
459
403
  #
460
404
  # See also #create_aggregate_handler for a more object-oriented approach to
461
405
  # aggregate functions.
462
- def create_aggregate( name, arity, step=nil, finalize=nil,
463
- text_rep=Constants::TextRep::ANY, &block )
406
+ def create_aggregate(name, arity, step = nil, finalize = nil,
407
+ text_rep = Constants::TextRep::ANY, &block)
464
408
 
465
409
  proxy = Class.new do
466
- def self.step( &block )
410
+ def self.step(&block)
467
411
  define_method(:step_with_ctx, &block)
468
412
  end
469
413
 
470
- def self.finalize( &block )
414
+ def self.finalize(&block)
471
415
  define_method(:finalize_with_ctx, &block)
472
416
  end
473
417
  end
474
418
 
475
- if block_given?
419
+ if block
476
420
  proxy.instance_eval(&block)
477
421
  else
478
422
  proxy.class_eval do
@@ -498,7 +442,7 @@ module SQLite3
498
442
  @ctx = FunctionProxy.new
499
443
  end
500
444
 
501
- def step( *args )
445
+ def step(*args)
502
446
  step_with_ctx(@ctx, *args)
503
447
  end
504
448
 
@@ -557,7 +501,7 @@ module SQLite3
557
501
  #
558
502
  # db.create_aggregate_handler( LengthsAggregateHandler )
559
503
  # puts db.get_first_value( "select lengths(name) from A" )
560
- def create_aggregate_handler( handler )
504
+ def create_aggregate_handler(handler)
561
505
  # This is a compatibility shim so the (basically pointless) FunctionProxy
562
506
  # "ctx" object is passed as first argument to both step() and finalize().
563
507
  # Now its up to the library user whether he prefers to store his
@@ -571,7 +515,7 @@ module SQLite3
571
515
  @fp = FunctionProxy.new
572
516
  end
573
517
 
574
- def step( *args )
518
+ def step(*args)
575
519
  super(@fp, *args)
576
520
  end
577
521
 
@@ -594,7 +538,7 @@ module SQLite3
594
538
  # individual instances of the aggregate function. Regular ruby objects
595
539
  # already provide a suitable +clone+.
596
540
  # The functions arity is the arity of the +step+ method.
597
- def define_aggregator( name, aggregator )
541
+ def define_aggregator(name, aggregator)
598
542
  # Previously, this has been implemented in C. Now this is just yet
599
543
  # another compatibility shim
600
544
  proxy = Class.new do
@@ -648,9 +592,9 @@ module SQLite3
648
592
  # If a block is not given, it is the caller's responsibility to end the
649
593
  # transaction explicitly, either by calling #commit, or by calling
650
594
  # #rollback.
651
- def transaction( mode = nil )
595
+ def transaction(mode = nil)
652
596
  mode = @default_transaction_mode if mode.nil?
653
- execute "begin #{mode.to_s} transaction"
597
+ execute "begin #{mode} transaction"
654
598
 
655
599
  if block_given?
656
600
  abort = false
@@ -662,9 +606,9 @@ module SQLite3
662
606
  ensure
663
607
  abort and rollback or commit
664
608
  end
609
+ else
610
+ true
665
611
  end
666
-
667
- true
668
612
  end
669
613
 
670
614
  # Commits the current transaction. If there is no current transaction,
@@ -691,6 +635,25 @@ module SQLite3
691
635
  @readonly
692
636
  end
693
637
 
638
+ # Sets a #busy_handler that releases the GVL between retries,
639
+ # but only retries up to the indicated number of +milliseconds+.
640
+ # This is an alternative to #busy_timeout, which holds the GVL
641
+ # while SQLite sleeps and retries.
642
+ def busy_handler_timeout=(milliseconds)
643
+ timeout_seconds = milliseconds.fdiv(1000)
644
+
645
+ busy_handler do |count|
646
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
647
+ if count.zero?
648
+ @timeout_deadline = now + timeout_seconds
649
+ elsif now > @timeout_deadline
650
+ next false
651
+ else
652
+ sleep(0.001)
653
+ end
654
+ end
655
+ end
656
+
694
657
  # A helper class for dealing with custom functions (see #create_function,
695
658
  # #create_aggregate, and #create_aggregate_handler). It encapsulates the
696
659
  # opaque function object that represents the current invocation. It also
@@ -707,54 +670,31 @@ module SQLite3
707
670
  # it is non-nil, it must quack like a Hash. If it is nil, then none of
708
671
  # the context functions will be available.
709
672
  def initialize
710
- @result = nil
711
- @context = {}
712
- end
713
-
714
- # Set the result of the function to the given error message.
715
- # The function will then return that error.
716
- def set_error( error )
717
- @driver.result_error( @func, error.to_s, -1 )
718
- end
719
-
720
- # (Only available to aggregate functions.) Returns the number of rows
721
- # that the aggregate has processed so far. This will include the current
722
- # row, and so will always return at least 1.
723
- def count
724
- @driver.aggregate_count( @func )
673
+ @result = nil
674
+ @context = {}
725
675
  end
726
676
 
727
677
  # Returns the value with the given key from the context. This is only
728
678
  # available to aggregate functions.
729
- def []( key )
730
- @context[ key ]
679
+ def [](key)
680
+ @context[key]
731
681
  end
732
682
 
733
683
  # Sets the value with the given key in the context. This is only
734
684
  # available to aggregate functions.
735
- def []=( key, value )
736
- @context[ key ] = value
685
+ def []=(key, value)
686
+ @context[key] = value
737
687
  end
738
688
  end
739
689
 
740
- # Translates a +row+ of data from the database with the given +types+
741
- def translate_from_db types, row
742
- @type_translator.call types, row
743
- end
744
-
745
- private
746
-
747
- NULL_TRANSLATOR = lambda { |_, row| row }
748
-
749
- def make_type_translator should_translate
750
- if should_translate
751
- lambda { |types, row|
752
- types.zip(row).map do |type, value|
753
- translator.translate( type, value )
754
- end
755
- }
690
+ # Given a statement, return a result set.
691
+ # This is not intended for general consumption
692
+ # :nodoc:
693
+ def build_result_set stmt
694
+ if results_as_hash
695
+ HashResultSet.new(self, stmt)
756
696
  else
757
- NULL_TRANSLATOR
697
+ ResultSet.new(self, stmt)
758
698
  end
759
699
  end
760
700
  end
@@ -1,4 +1,4 @@
1
- require 'sqlite3/constants'
1
+ require "sqlite3/constants"
2
2
 
3
3
  module SQLite3
4
4
  class Exception < ::StandardError
@@ -7,29 +7,54 @@ module SQLite3
7
7
  end
8
8
 
9
9
  class SQLException < Exception; end
10
+
10
11
  class InternalException < Exception; end
12
+
11
13
  class PermissionException < Exception; end
14
+
12
15
  class AbortException < Exception; end
16
+
13
17
  class BusyException < Exception; end
18
+
14
19
  class LockedException < Exception; end
20
+
15
21
  class MemoryException < Exception; end
22
+
16
23
  class ReadOnlyException < Exception; end
24
+
17
25
  class InterruptException < Exception; end
26
+
18
27
  class IOException < Exception; end
28
+
19
29
  class CorruptException < Exception; end
30
+
20
31
  class NotFoundException < Exception; end
32
+
21
33
  class FullException < Exception; end
34
+
22
35
  class CantOpenException < Exception; end
36
+
23
37
  class ProtocolException < Exception; end
38
+
24
39
  class EmptyException < Exception; end
40
+
25
41
  class SchemaChangedException < Exception; end
42
+
26
43
  class TooBigException < Exception; end
44
+
27
45
  class ConstraintException < Exception; end
46
+
28
47
  class MismatchException < Exception; end
48
+
29
49
  class MisuseException < Exception; end
50
+
30
51
  class UnsupportedException < Exception; end
52
+
31
53
  class AuthorizationException < Exception; end
54
+
32
55
  class FormatException < Exception; end
56
+
33
57
  class RangeException < Exception; end
58
+
34
59
  class NotADatabaseException < Exception; end
35
60
  end