sqlite3 1.7.3-arm64-darwin → 2.0.0-arm64-darwin
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +152 -0
- data/CONTRIBUTING.md +23 -1
- data/FAQ.md +0 -43
- data/INSTALLATION.md +13 -5
- data/LICENSE +18 -22
- data/README.md +75 -4
- data/dependencies.yml +10 -11
- data/ext/sqlite3/aggregator.c +142 -145
- data/ext/sqlite3/aggregator.h +2 -4
- data/ext/sqlite3/backup.c +74 -65
- data/ext/sqlite3/backup.h +2 -2
- data/ext/sqlite3/database.c +535 -482
- data/ext/sqlite3/database.h +7 -4
- data/ext/sqlite3/exception.c +111 -92
- data/ext/sqlite3/exception.h +3 -1
- data/ext/sqlite3/extconf.rb +21 -22
- data/ext/sqlite3/sqlite3.c +159 -115
- data/ext/sqlite3/sqlite3_ruby.h +2 -2
- data/ext/sqlite3/statement.c +516 -300
- data/ext/sqlite3/statement.h +3 -3
- data/ext/sqlite3/timespec.h +20 -0
- data/lib/sqlite3/3.0/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.1/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.2/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.3/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/constants.rb +171 -47
- data/lib/sqlite3/database.rb +105 -165
- data/lib/sqlite3/errors.rb +26 -1
- data/lib/sqlite3/pragmas.rb +126 -136
- data/lib/sqlite3/resultset.rb +14 -97
- data/lib/sqlite3/statement.rb +58 -13
- data/lib/sqlite3/value.rb +17 -20
- data/lib/sqlite3/version.rb +1 -21
- data/lib/sqlite3.rb +6 -4
- metadata +3 -28
- data/API_CHANGES.md +0 -49
- data/ChangeLog.cvs +0 -88
- data/Gemfile +0 -10
- data/LICENSE-DEPENDENCIES +0 -20
- data/lib/sqlite3/translator.rb +0 -117
- data/test/helper.rb +0 -27
- data/test/test_backup.rb +0 -33
- data/test/test_collation.rb +0 -82
- data/test/test_database.rb +0 -668
- data/test/test_database_flags.rb +0 -95
- data/test/test_database_readonly.rb +0 -36
- data/test/test_database_readwrite.rb +0 -41
- data/test/test_deprecated.rb +0 -49
- data/test/test_encoding.rb +0 -165
- data/test/test_integration.rb +0 -507
- data/test/test_integration_aggregate.rb +0 -336
- data/test/test_integration_open_close.rb +0 -30
- data/test/test_integration_pending.rb +0 -115
- data/test/test_integration_resultset.rb +0 -142
- data/test/test_integration_statement.rb +0 -194
- data/test/test_pragmas.rb +0 -22
- data/test/test_result_set.rb +0 -47
- data/test/test_sqlite3.rb +0 -30
- data/test/test_statement.rb +0 -290
- data/test/test_statement_execute.rb +0 -39
    
        data/lib/sqlite3/database.rb
    CHANGED
    
    | @@ -1,12 +1,10 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 5 | 
            -
            require  | 
| 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( | 
| 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( | 
| 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 | 
| 124 | 
            -
                  @authorizer | 
| 125 | 
            -
                  @ | 
| 126 | 
            -
                  @ | 
| 127 | 
            -
                  @collations | 
| 128 | 
            -
                  @functions | 
| 129 | 
            -
                  @results_as_hash | 
| 130 | 
            -
                  @ | 
| 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 | 
            -
                 | 
| 145 | 
            -
             | 
| 146 | 
            -
            # | 
| 147 | 
            -
             | 
| 148 | 
            -
                   | 
| 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( | 
| 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( | 
| 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 =  | 
| 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 | 
            -
                   | 
| 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 | 
| 200 | 
            +
                    stmt = build_result_set stmt
         | 
| 224 201 |  | 
| 225 | 
            -
                    if  | 
| 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( | 
| 246 | 
            -
                  prepare( | 
| 247 | 
            -
                    result = stmt.execute( | 
| 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. | 
| 253 | 
            -
             | 
| 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  | 
| 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( | 
| 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 | 
            -
                   | 
| 293 | 
            -
             | 
| 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 | 
            -
             | 
| 306 | 
            -
                   | 
| 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  | 
| 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( | 
| 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 | 
            -
                     | 
| 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( | 
| 375 | 
            -
                  execute( | 
| 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( | 
| 384 | 
            -
                  query( | 
| 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 | 
            -
                 | 
| 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( | 
| 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( | 
| 410 | 
            +
                    def self.step(&block)
         | 
| 467 411 | 
             
                      define_method(:step_with_ctx, &block)
         | 
| 468 412 | 
             
                    end
         | 
| 469 413 |  | 
| 470 | 
            -
                    def self.finalize( | 
| 414 | 
            +
                    def self.finalize(&block)
         | 
| 471 415 | 
             
                      define_method(:finalize_with_ctx, &block)
         | 
| 472 416 | 
             
                    end
         | 
| 473 417 | 
             
                  end
         | 
| 474 418 |  | 
| 475 | 
            -
                  if  | 
| 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( | 
| 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( | 
| 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( | 
| 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( | 
| 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( | 
| 595 | 
            +
                def transaction(mode = nil)
         | 
| 652 596 | 
             
                  mode = @default_transaction_mode if mode.nil?
         | 
| 653 | 
            -
                  execute "begin #{mode | 
| 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 | 
| 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 []( | 
| 730 | 
            -
                    @context[ | 
| 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 []=( | 
| 736 | 
            -
                    @context[ | 
| 685 | 
            +
                  def []=(key, value)
         | 
| 686 | 
            +
                    @context[key] = value
         | 
| 737 687 | 
             
                  end
         | 
| 738 688 | 
             
                end
         | 
| 739 689 |  | 
| 740 | 
            -
                #  | 
| 741 | 
            -
                 | 
| 742 | 
            -
             | 
| 743 | 
            -
                 | 
| 744 | 
            -
             | 
| 745 | 
            -
             | 
| 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 | 
            -
                     | 
| 697 | 
            +
                    ResultSet.new(self, stmt)
         | 
| 758 698 | 
             
                  end
         | 
| 759 699 | 
             
                end
         | 
| 760 700 | 
             
              end
         | 
    
        data/lib/sqlite3/errors.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 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
         |