sqlite3 1.3.5 → 1.3.13
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 +7 -0
- data/CHANGELOG.rdoc +84 -0
- data/Gemfile +15 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +29 -6
- data/ext/sqlite3/database.c +131 -27
- data/ext/sqlite3/extconf.rb +31 -7
- data/ext/sqlite3/sqlite3.c +112 -0
- data/ext/sqlite3/sqlite3_ruby.h +12 -4
- data/ext/sqlite3/statement.c +33 -22
- data/faq/faq.yml +1 -1
- data/lib/sqlite3.rb +6 -1
- data/lib/sqlite3/database.rb +36 -24
- data/lib/sqlite3/pragmas.rb +357 -49
- data/lib/sqlite3/resultset.rb +94 -25
- data/lib/sqlite3/statement.rb +13 -17
- data/lib/sqlite3/version.rb +2 -2
- data/setup.rb +2 -2
- data/tasks/gem.rake +12 -6
- data/tasks/native.rake +22 -7
- data/tasks/vendor_sqlite3.rake +69 -20
- data/test/helper.rb +17 -2
- data/test/test_backup.rb +2 -2
- data/test/test_collation.rb +1 -1
- data/test/test_database.rb +102 -7
- data/test/test_database_readonly.rb +10 -3
- data/test/test_deprecated.rb +8 -1
- data/test/test_encoding.rb +35 -1
- data/test/test_integration.rb +36 -15
- data/test/test_integration_open_close.rb +1 -1
- data/test/test_integration_pending.rb +2 -2
- data/test/test_integration_resultset.rb +6 -3
- data/test/test_integration_statement.rb +2 -2
- data/test/test_result_set.rb +37 -0
- data/test/test_sqlite3.rb +13 -1
- data/test/test_statement.rb +26 -4
- data/test/test_statement_execute.rb +1 -1
- metadata +125 -121
- data/.gemtest +0 -0
data/lib/sqlite3/resultset.rb
CHANGED
@@ -5,28 +5,66 @@ module SQLite3
|
|
5
5
|
|
6
6
|
# The ResultSet object encapsulates the enumerability of a query's output.
|
7
7
|
# It is a simple cursor over the data that the query returns. It will
|
8
|
-
# very rarely (if ever) be instantiated directly. Instead,
|
8
|
+
# very rarely (if ever) be instantiated directly. Instead, clients should
|
9
9
|
# obtain a ResultSet instance via Statement#execute.
|
10
10
|
class ResultSet
|
11
11
|
include Enumerable
|
12
12
|
|
13
|
-
|
14
|
-
# result. (ArrayFields is installed.)
|
15
|
-
class ArrayWithTypes < Array
|
13
|
+
class ArrayWithTypes < Array # :nodoc:
|
16
14
|
attr_accessor :types
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
class ArrayWithTypesAndFields < Array # :nodoc:
|
18
|
+
attr_writer :types
|
19
|
+
attr_writer :fields
|
20
|
+
|
21
|
+
def types
|
22
|
+
warn(<<-eowarn) if $VERBOSE
|
23
|
+
#{caller[0]} is calling #{self.class}#types. This method will be removed in
|
24
|
+
sqlite3 version 2.0.0, please call the `types` method on the SQLite3::ResultSet
|
25
|
+
object that created this object
|
26
|
+
eowarn
|
27
|
+
@types
|
28
|
+
end
|
29
|
+
|
30
|
+
def fields
|
31
|
+
warn(<<-eowarn) if $VERBOSE
|
32
|
+
#{caller[0]} is calling #{self.class}#fields. This method will be removed in
|
33
|
+
sqlite3 version 2.0.0, please call the `columns` method on the SQLite3::ResultSet
|
34
|
+
object that created this object
|
35
|
+
eowarn
|
36
|
+
@fields
|
37
|
+
end
|
24
38
|
end
|
25
39
|
|
26
40
|
# The class of which we return an object in case we want a Hash as
|
27
41
|
# result.
|
28
|
-
class
|
29
|
-
|
42
|
+
class HashWithTypesAndFields < Hash # :nodoc:
|
43
|
+
attr_writer :types
|
44
|
+
attr_writer :fields
|
45
|
+
|
46
|
+
def types
|
47
|
+
warn(<<-eowarn) if $VERBOSE
|
48
|
+
#{caller[0]} is calling #{self.class}#types. This method will be removed in
|
49
|
+
sqlite3 version 2.0.0, please call the `types` method on the SQLite3::ResultSet
|
50
|
+
object that created this object
|
51
|
+
eowarn
|
52
|
+
@types
|
53
|
+
end
|
54
|
+
|
55
|
+
def fields
|
56
|
+
warn(<<-eowarn) if $VERBOSE
|
57
|
+
#{caller[0]} is calling #{self.class}#fields. This method will be removed in
|
58
|
+
sqlite3 version 2.0.0, please call the `columns` method on the SQLite3::ResultSet
|
59
|
+
object that created this object
|
60
|
+
eowarn
|
61
|
+
@fields
|
62
|
+
end
|
63
|
+
|
64
|
+
def [] key
|
65
|
+
key = fields[key] if key.is_a? Numeric
|
66
|
+
super key
|
67
|
+
end
|
30
68
|
end
|
31
69
|
|
32
70
|
# Create a new ResultSet attached to the given database, using the
|
@@ -63,6 +101,10 @@ module SQLite3
|
|
63
101
|
# For hashes, the column names are the keys of the hash, and the column
|
64
102
|
# types are accessible via the +types+ property.
|
65
103
|
def next
|
104
|
+
if @db.results_as_hash
|
105
|
+
return next_hash
|
106
|
+
end
|
107
|
+
|
66
108
|
row = @stmt.step
|
67
109
|
return nil if @stmt.done?
|
68
110
|
|
@@ -72,33 +114,39 @@ module SQLite3
|
|
72
114
|
end
|
73
115
|
end
|
74
116
|
|
75
|
-
if
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
row = new_row
|
117
|
+
if row.respond_to?(:fields)
|
118
|
+
# FIXME: this can only happen if the translator returns something
|
119
|
+
# that responds to `fields`. Since we're removing the translator
|
120
|
+
# in 2.0, we can remove this branch in 2.0.
|
121
|
+
row = ArrayWithTypes.new(row)
|
81
122
|
else
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
row.fields = @stmt.columns
|
123
|
+
# FIXME: the `fields` and `types` methods are deprecated on this
|
124
|
+
# object for version 2.0, so we can safely remove this branch
|
125
|
+
# as well.
|
126
|
+
row = ArrayWithTypesAndFields.new(row)
|
88
127
|
end
|
89
128
|
|
129
|
+
row.fields = @stmt.columns
|
90
130
|
row.types = @stmt.types
|
91
131
|
row
|
92
132
|
end
|
93
133
|
|
94
134
|
# Required by the Enumerable mixin. Provides an internal iterator over the
|
95
135
|
# rows of the result set.
|
96
|
-
def each
|
136
|
+
def each
|
97
137
|
while node = self.next
|
98
138
|
yield node
|
99
139
|
end
|
100
140
|
end
|
101
141
|
|
142
|
+
# Provides an internal iterator over the rows of the result set where
|
143
|
+
# each row is yielded as a hash.
|
144
|
+
def each_hash
|
145
|
+
while node = next_hash
|
146
|
+
yield node
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
102
150
|
# Closes the statement that spawned this result set.
|
103
151
|
# <em>Use with caution!</em> Closing a result set will automatically
|
104
152
|
# close any other result sets that were spawned from the same statement.
|
@@ -121,6 +169,27 @@ module SQLite3
|
|
121
169
|
@stmt.columns
|
122
170
|
end
|
123
171
|
|
124
|
-
|
172
|
+
# Return the next row as a hash
|
173
|
+
def next_hash
|
174
|
+
row = @stmt.step
|
175
|
+
return nil if @stmt.done?
|
176
|
+
|
177
|
+
# FIXME: type translation is deprecated, so this can be removed
|
178
|
+
# 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
|
184
|
+
|
185
|
+
# FIXME: this can be switched to a regular hash in 2.0
|
186
|
+
row = HashWithTypesAndFields[*@stmt.columns.zip(row).flatten]
|
125
187
|
|
188
|
+
# FIXME: these methods are deprecated for version 2.0, so we can remove
|
189
|
+
# this code in 2.0
|
190
|
+
row.fields = @stmt.columns
|
191
|
+
row.types = @stmt.types
|
192
|
+
row
|
193
|
+
end
|
194
|
+
end
|
126
195
|
end
|
data/lib/sqlite3/statement.rb
CHANGED
@@ -120,23 +120,6 @@ module SQLite3
|
|
120
120
|
@types
|
121
121
|
end
|
122
122
|
|
123
|
-
# A convenience method for obtaining the metadata about the query. Note
|
124
|
-
# that this will actually execute the SQL, which means it can be a
|
125
|
-
# (potentially) expensive operation.
|
126
|
-
def get_metadata
|
127
|
-
@columns = []
|
128
|
-
@types = []
|
129
|
-
|
130
|
-
column_count.times do |column|
|
131
|
-
@columns << column_name(column)
|
132
|
-
@types << column_decltype(column)
|
133
|
-
end
|
134
|
-
|
135
|
-
@columns.freeze
|
136
|
-
@types.freeze
|
137
|
-
end
|
138
|
-
private :get_metadata
|
139
|
-
|
140
123
|
# Performs a sanity check to ensure that the statement is not
|
141
124
|
# closed. If it is, an exception is raised.
|
142
125
|
def must_be_open! # :nodoc:
|
@@ -144,5 +127,18 @@ module SQLite3
|
|
144
127
|
raise SQLite3::Exception, "cannot use a closed statement"
|
145
128
|
end
|
146
129
|
end
|
130
|
+
|
131
|
+
private
|
132
|
+
# A convenience method for obtaining the metadata about the query. Note
|
133
|
+
# that this will actually execute the SQL, which means it can be a
|
134
|
+
# (potentially) expensive operation.
|
135
|
+
def get_metadata
|
136
|
+
@columns = Array.new(column_count) do |column|
|
137
|
+
column_name column
|
138
|
+
end
|
139
|
+
@types = Array.new(column_count) do |column|
|
140
|
+
column_decltype column
|
141
|
+
end
|
142
|
+
end
|
147
143
|
end
|
148
144
|
end
|
data/lib/sqlite3/version.rb
CHANGED
data/setup.rb
CHANGED
@@ -102,7 +102,7 @@ end
|
|
102
102
|
|
103
103
|
class ConfigTable
|
104
104
|
|
105
|
-
c = ::
|
105
|
+
c = ::RbConfig::CONFIG
|
106
106
|
|
107
107
|
rubypath = c['bindir'] + '/' + c['ruby_install_name']
|
108
108
|
|
@@ -1219,7 +1219,7 @@ class Installer
|
|
1219
1219
|
raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first"
|
1220
1220
|
end
|
1221
1221
|
|
1222
|
-
DLEXT = /\.#{ ::
|
1222
|
+
DLEXT = /\.#{ ::RbConfig::CONFIG['DLEXT'] }\z/
|
1223
1223
|
|
1224
1224
|
def _ruby_extentions(dir)
|
1225
1225
|
Dir.open(dir) {|d|
|
data/tasks/gem.rake
CHANGED
@@ -6,23 +6,29 @@ rescue LoadError
|
|
6
6
|
require 'hoe'
|
7
7
|
end
|
8
8
|
|
9
|
-
Hoe.plugin :debugging, :doofus, :git
|
9
|
+
Hoe.plugin :debugging, :doofus, :git, :minitest, :bundler
|
10
10
|
|
11
11
|
HOE = Hoe.spec 'sqlite3' do
|
12
12
|
developer 'Jamis Buck', 'jamis@37signals.com'
|
13
13
|
developer 'Luis Lavena', 'luislavena@gmail.com'
|
14
14
|
developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'
|
15
15
|
|
16
|
+
license "BSD-3"
|
17
|
+
|
16
18
|
self.readme_file = 'README.rdoc'
|
17
19
|
self.history_file = 'CHANGELOG.rdoc'
|
18
20
|
self.extra_rdoc_files = FileList['*.rdoc', 'ext/**/*.c']
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
require_ruby_version ">= 1.8.7"
|
23
|
+
require_rubygems_version ">= 1.3.5"
|
24
|
+
|
25
|
+
spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
|
23
26
|
|
24
|
-
extra_dev_deps << ['rake-compiler', "~> 0.
|
25
|
-
extra_dev_deps << [
|
27
|
+
extra_dev_deps << ['rake-compiler', "~> 0.9.3"]
|
28
|
+
extra_dev_deps << ['rake-compiler-dock', "~> 0.5.2"]
|
29
|
+
extra_dev_deps << ["mini_portile", "~> 0.6.2"]
|
30
|
+
extra_dev_deps << ["minitest", "~> 5.0"]
|
31
|
+
extra_dev_deps << ["hoe-bundler", "~> 1.0"]
|
26
32
|
|
27
33
|
clean_globs.push('**/test.db')
|
28
34
|
end
|
data/tasks/native.rake
CHANGED
@@ -1,14 +1,24 @@
|
|
1
1
|
# use rake-compiler for building the extension
|
2
2
|
require 'rake/extensiontask'
|
3
|
+
require 'rake/extensioncompiler'
|
3
4
|
|
4
5
|
# NOTE: version used by cross compilation of Windows native extension
|
5
6
|
# It do not affect compilation under other operating systems
|
6
7
|
# The version indicated is the minimum DLL suggested for correct functionality
|
7
|
-
BINARY_VERSION = "3.
|
8
|
-
URL_VERSION = "
|
8
|
+
BINARY_VERSION = "3.8.11.1"
|
9
|
+
URL_VERSION = "3081101"
|
10
|
+
URL_PATH = "/2015"
|
11
|
+
|
12
|
+
task :devkit do
|
13
|
+
begin
|
14
|
+
require "devkit"
|
15
|
+
rescue LoadError => e
|
16
|
+
abort "Failed to activate RubyInstaller's DevKit required for compilation."
|
17
|
+
end
|
18
|
+
end
|
9
19
|
|
10
20
|
# build sqlite3_native C extension
|
11
|
-
Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
|
21
|
+
RUBY_EXTENSION = Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
|
12
22
|
# where to locate the extension
|
13
23
|
ext.ext_dir = 'ext/sqlite3'
|
14
24
|
|
@@ -23,11 +33,16 @@ Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
|
|
23
33
|
# define target for extension (supporting fat binaries)
|
24
34
|
RUBY_VERSION =~ /(\d+\.\d+)/
|
25
35
|
ext.lib_dir = "lib/sqlite3/#{$1}"
|
26
|
-
ext.config_options << "--enable-local"
|
27
36
|
else
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
|
38
|
+
# detect cross-compiler available
|
39
|
+
begin
|
40
|
+
Rake::ExtensionCompiler.mingw_host
|
41
|
+
ext.cross_compile = true
|
42
|
+
ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32', 'x64-mingw32']
|
43
|
+
rescue RuntimeError
|
44
|
+
# noop
|
45
|
+
end
|
31
46
|
end
|
32
47
|
end
|
33
48
|
|
data/tasks/vendor_sqlite3.rake
CHANGED
@@ -2,47 +2,96 @@ require "rake/clean"
|
|
2
2
|
require "rake/extensioncompiler"
|
3
3
|
require "mini_portile"
|
4
4
|
|
5
|
-
|
5
|
+
CLOBBER.include("ports")
|
6
6
|
|
7
|
-
|
8
|
-
$recipes[:sqlite3].files << "http://sqlite.org/sqlite-autoconf-#{URL_VERSION}.tar.gz"
|
7
|
+
directory "ports"
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
def define_sqlite_task(platform, host)
|
10
|
+
recipe = MiniPortile.new "sqlite3", BINARY_VERSION
|
11
|
+
recipe.files << "http://sqlite.org#{URL_PATH}/sqlite-autoconf-#{URL_VERSION}.tar.gz"
|
12
|
+
recipe.host = host
|
12
13
|
|
13
|
-
desc "
|
14
|
-
task :sqlite3 => ["ports"] do |t|
|
15
|
-
recipe = $recipes[:sqlite3]
|
14
|
+
desc "Compile sqlite3 for #{platform} (#{host})"
|
15
|
+
task "ports:sqlite3:#{platform}" => ["ports"] do |t|
|
16
16
|
checkpoint = "ports/.#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
|
17
17
|
|
18
18
|
unless File.exist?(checkpoint)
|
19
19
|
cflags = "-O2 -DSQLITE_ENABLE_COLUMN_METADATA"
|
20
|
-
cflags << " -fPIC" if recipe.host.include?("x86_64")
|
20
|
+
cflags << " -fPIC" if recipe.host && recipe.host.include?("x86_64")
|
21
21
|
recipe.configure_options << "CFLAGS='#{cflags}'"
|
22
22
|
recipe.cook
|
23
23
|
touch checkpoint
|
24
24
|
end
|
25
|
-
|
26
|
-
recipe.activate
|
27
25
|
end
|
26
|
+
|
27
|
+
recipe
|
28
28
|
end
|
29
29
|
|
30
|
+
# native sqlite3 compilation
|
31
|
+
recipe = define_sqlite_task(RUBY_PLATFORM, RbConfig::CONFIG["host"])
|
32
|
+
|
33
|
+
# force compilation of sqlite3 when working natively under MinGW
|
30
34
|
if RUBY_PLATFORM =~ /mingw/
|
31
|
-
|
35
|
+
RUBY_EXTENSION.config_options << "--with-opt-dir=#{recipe.path}"
|
36
|
+
|
37
|
+
# also prepend DevKit into compilation phase
|
38
|
+
Rake::Task["compile"].prerequisites.unshift "devkit", "ports:sqlite3:#{RUBY_PLATFORM}"
|
39
|
+
Rake::Task["native"].prerequisites.unshift "devkit", "ports:sqlite3:#{RUBY_PLATFORM}"
|
32
40
|
end
|
33
41
|
|
42
|
+
# trick to test local compilation of sqlite3
|
34
43
|
if ENV["USE_MINI_PORTILE"] == "true"
|
35
|
-
|
44
|
+
# fake recipe so we can build a directory to it
|
45
|
+
recipe = MiniPortile.new "sqlite3", BINARY_VERSION
|
46
|
+
recipe.host = RbConfig::CONFIG["host"]
|
47
|
+
|
48
|
+
RUBY_EXTENSION.config_options << "--with-opt-dir=#{recipe.path}"
|
49
|
+
|
50
|
+
# compile sqlite3 first
|
51
|
+
Rake::Task["compile"].prerequisites.unshift "ports:sqlite3:#{RUBY_PLATFORM}"
|
36
52
|
end
|
37
53
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
54
|
+
# iterate over all cross-compilation platforms and define the proper
|
55
|
+
# sqlite3 recipe for it.
|
56
|
+
if RUBY_EXTENSION.cross_compile
|
57
|
+
config_path = File.expand_path("~/.rake-compiler/config.yml")
|
58
|
+
if File.exist?(config_path)
|
59
|
+
# obtains platforms from rake-compiler's config.yml
|
60
|
+
config_file = YAML.load_file(config_path)
|
61
|
+
|
62
|
+
Array(RUBY_EXTENSION.cross_platform).each do |platform|
|
63
|
+
# obtain platform from rbconfig file
|
64
|
+
config_key = config_file.keys.sort.find { |key|
|
65
|
+
key.start_with?("rbconfig-#{platform}-")
|
66
|
+
}
|
67
|
+
rbfile = config_file[config_key]
|
68
|
+
|
69
|
+
# skip if rbconfig cannot be read
|
70
|
+
next unless File.exist?(rbfile)
|
71
|
+
|
72
|
+
host = IO.read(rbfile).match(/CONFIG\["CC"\] = "(.*)"/)[1].sub(/\-gcc/, '')
|
73
|
+
recipe = define_sqlite_task(platform, host)
|
74
|
+
|
75
|
+
RUBY_EXTENSION.cross_config_options << {
|
76
|
+
platform => "--with-opt-dir=#{recipe.path}"
|
77
|
+
}
|
78
|
+
|
79
|
+
# pre-compile sqlite3 port when cross-compiling
|
80
|
+
task :cross => "ports:sqlite3:#{platform}"
|
81
|
+
end
|
82
|
+
else
|
83
|
+
warn "rake-compiler configuration doesn't exist, but is required for ports"
|
42
84
|
end
|
85
|
+
end
|
43
86
|
|
44
|
-
|
45
|
-
|
87
|
+
task :cross do
|
88
|
+
["CC", "CXX", "LDFLAGS", "CPPFLAGS", "RUBYOPT"].each do |var|
|
89
|
+
ENV.delete(var)
|
90
|
+
end
|
46
91
|
end
|
47
92
|
|
48
|
-
|
93
|
+
desc "Build windows binary gems per rake-compiler-dock."
|
94
|
+
task "gem:windows" do
|
95
|
+
require "rake_compiler_dock"
|
96
|
+
RakeCompilerDock.sh "bundle && rake cross native gem MAKE='nice make -j`nproc`'"
|
97
|
+
end
|