sqlite3-ruby 1.3.0.beta.2-x86-mswin32-60
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.
- data/API_CHANGES.rdoc +48 -0
- data/CHANGELOG.rdoc +108 -0
- data/ChangeLog.cvs +88 -0
- data/LICENSE +27 -0
- data/Manifest.txt +44 -0
- data/README.rdoc +54 -0
- data/Rakefile +10 -0
- data/ext/sqlite3/database.c +693 -0
- data/ext/sqlite3/database.h +15 -0
- data/ext/sqlite3/exception.c +94 -0
- data/ext/sqlite3/exception.h +8 -0
- data/ext/sqlite3/extconf.rb +39 -0
- data/ext/sqlite3/sqlite3.c +33 -0
- data/ext/sqlite3/sqlite3_ruby.h +43 -0
- data/ext/sqlite3/statement.c +419 -0
- data/ext/sqlite3/statement.h +16 -0
- data/faq/faq.rb +145 -0
- data/faq/faq.yml +426 -0
- data/lib/sqlite3.rb +10 -0
- data/lib/sqlite3/1.8/sqlite3_native.so +0 -0
- data/lib/sqlite3/1.9/sqlite3_native.so +0 -0
- data/lib/sqlite3/constants.rb +49 -0
- data/lib/sqlite3/database.rb +568 -0
- data/lib/sqlite3/errors.rb +44 -0
- data/lib/sqlite3/pragmas.rb +280 -0
- data/lib/sqlite3/resultset.rb +126 -0
- data/lib/sqlite3/statement.rb +146 -0
- data/lib/sqlite3/translator.rb +114 -0
- data/lib/sqlite3/value.rb +57 -0
- data/lib/sqlite3/version.rb +16 -0
- data/setup.rb +1333 -0
- data/tasks/faq.rake +9 -0
- data/tasks/gem.rake +31 -0
- data/tasks/native.rake +31 -0
- data/tasks/vendor_sqlite3.rake +107 -0
- data/test/helper.rb +3 -0
- data/test/test_database.rb +291 -0
- data/test/test_deprecated.rb +25 -0
- data/test/test_encoding.rb +115 -0
- data/test/test_integration.rb +545 -0
- data/test/test_integration_open_close.rb +30 -0
- data/test/test_integration_pending.rb +113 -0
- data/test/test_integration_resultset.rb +183 -0
- data/test/test_integration_statement.rb +194 -0
- data/test/test_sqlite3.rb +9 -0
- data/test/test_statement.rb +207 -0
- metadata +181 -0
data/tasks/faq.rake
ADDED
data/tasks/gem.rake
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
begin
|
2
|
+
require 'hoe'
|
3
|
+
rescue LoadError
|
4
|
+
# try with rubygems?
|
5
|
+
require 'rubygems'
|
6
|
+
require 'hoe'
|
7
|
+
end
|
8
|
+
|
9
|
+
Hoe.plugin :debugging, :doofus, :git
|
10
|
+
|
11
|
+
HOE = Hoe.spec 'sqlite3-ruby' do
|
12
|
+
developer 'Jamis Buck', 'jamis@37signals.com'
|
13
|
+
developer 'Luis Lavena', 'luislavena@gmail.com'
|
14
|
+
developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'
|
15
|
+
|
16
|
+
self.readme_file = 'README.rdoc'
|
17
|
+
self.history_file = 'CHANGELOG.rdoc'
|
18
|
+
self.extra_rdoc_files = FileList['*.rdoc', 'ext/**/*.c']
|
19
|
+
|
20
|
+
spec_extras[:required_ruby_version] = Gem::Requirement.new('>= 1.8.6')
|
21
|
+
spec_extras[:required_rubygems_version] = '>= 1.3.5'
|
22
|
+
spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
|
23
|
+
|
24
|
+
extra_dev_deps << ['rake-compiler', "~> 0.7.0"]
|
25
|
+
|
26
|
+
clean_globs.push('**/test.db')
|
27
|
+
end
|
28
|
+
|
29
|
+
Hoe.add_include_dirs '.'
|
30
|
+
|
31
|
+
# vim: syntax=ruby
|
data/tasks/native.rake
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# use rake-compiler for building the extension
|
2
|
+
require 'rake/extensiontask'
|
3
|
+
|
4
|
+
# build sqlite3_native C extension
|
5
|
+
Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
|
6
|
+
# where to locate the extension
|
7
|
+
ext.ext_dir = 'ext/sqlite3'
|
8
|
+
|
9
|
+
# where native extension will be copied (matches makefile)
|
10
|
+
ext.lib_dir = "lib/sqlite3"
|
11
|
+
|
12
|
+
# reference to the sqlite3 library
|
13
|
+
sqlite3_lib = File.expand_path(File.join(File.dirname(__FILE__), '..', 'vendor', 'sqlite3'))
|
14
|
+
|
15
|
+
# automatically add build options to avoid need of manual input
|
16
|
+
if RUBY_PLATFORM =~ /mswin|mingw/ then
|
17
|
+
# define target for extension (supporting fat binaries)
|
18
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
19
|
+
ext.lib_dir = "lib/sqlite3/#{$1}"
|
20
|
+
ext.config_options << "--with-sqlite3-dir=#{sqlite3_lib}"
|
21
|
+
else
|
22
|
+
ext.cross_compile = true
|
23
|
+
ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32']
|
24
|
+
ext.cross_config_options << "--with-sqlite3-dir=#{sqlite3_lib}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# ensure things are compiled prior testing
|
29
|
+
task :test => [:compile]
|
30
|
+
|
31
|
+
# vim: syntax=ruby
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rake/extensioncompiler'
|
3
|
+
|
4
|
+
# download sqlite3 library and headers
|
5
|
+
|
6
|
+
# only on Windows or cross platform compilation
|
7
|
+
def dlltool(dllname, deffile, libfile)
|
8
|
+
# define if we are using GCC or not
|
9
|
+
if Rake::ExtensionCompiler.mingw_gcc_executable then
|
10
|
+
dir = File.dirname(Rake::ExtensionCompiler.mingw_gcc_executable)
|
11
|
+
tool = case RUBY_PLATFORM
|
12
|
+
when /mingw/
|
13
|
+
File.join(dir, 'dlltool.exe')
|
14
|
+
when /linux|darwin/
|
15
|
+
File.join(dir, "#{Rake::ExtensionCompiler.mingw_host}-dlltool")
|
16
|
+
end
|
17
|
+
return "#{tool} --dllname #{dllname} --def #{deffile} --output-lib #{libfile}"
|
18
|
+
else
|
19
|
+
if RUBY_PLATFORM =~ /mswin/ then
|
20
|
+
tool = 'lib.exe'
|
21
|
+
else
|
22
|
+
fail "Unsupported platform for cross-compilation (please, contribute some patches)."
|
23
|
+
end
|
24
|
+
return "#{tool} /DEF:#{deffile} /OUT:#{libfile}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
SQLITE_VERSION = '3.6.22'
|
29
|
+
url_version = SQLITE_VERSION.gsub('.', '_')
|
30
|
+
|
31
|
+
# required folder structure for --with-sqlite3-dir (include + lib)
|
32
|
+
directory "vendor/sqlite3/lib"
|
33
|
+
directory "vendor/sqlite3/include"
|
34
|
+
|
35
|
+
# download amalgamation version (for include files)
|
36
|
+
file "vendor/sqlite-amalgamation-#{url_version}.zip" => ['vendor'] do |t|
|
37
|
+
url = "http://www.sqlite.org/#{File.basename(t.name)}"
|
38
|
+
when_writing "downloading #{t.name}" do
|
39
|
+
cd File.dirname(t.name) do
|
40
|
+
system "wget -c #{url} || curl -C - -O #{url}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# download dll binaries
|
46
|
+
file "vendor/sqlitedll-#{url_version}.zip" => ['vendor'] do |t|
|
47
|
+
url = "http://www.sqlite.org/#{File.basename(t.name)}"
|
48
|
+
when_writing "downloading #{t.name}" do
|
49
|
+
cd File.dirname(t.name) do
|
50
|
+
system "wget -c #{url} || curl -C - -O #{url}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# extract header files into include folder
|
56
|
+
file "vendor/sqlite3/include/sqlite3.h" => ['vendor/sqlite3/include', "vendor/sqlite-amalgamation-#{url_version}.zip"] do |t|
|
57
|
+
full_file = File.expand_path(t.prerequisites.last)
|
58
|
+
when_writing "creating #{t.name}" do
|
59
|
+
cd File.dirname(t.name) do
|
60
|
+
sh "unzip #{full_file}"
|
61
|
+
# update file timestamp to avoid Rake perform this extraction again.
|
62
|
+
touch File.basename(t.name)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# extract dll files into lib folder
|
68
|
+
file "vendor/sqlite3/lib/sqlite3.dll" => ['vendor/sqlite3/lib', "vendor/sqlitedll-#{url_version}.zip"] do |t|
|
69
|
+
full_file = File.expand_path(t.prerequisites.last)
|
70
|
+
when_writing "creating #{t.name}" do
|
71
|
+
cd File.dirname(t.name) do
|
72
|
+
sh "unzip #{full_file}"
|
73
|
+
# update file timestamp to avoid Rake perform this extraction again.
|
74
|
+
touch File.basename(t.name)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# generate import library from definition and dll file
|
80
|
+
file "vendor/sqlite3/lib/sqlite3.lib" => ["vendor/sqlite3/lib/sqlite3.dll"] do |t|
|
81
|
+
libfile = t.name
|
82
|
+
dllname = libfile.ext('dll')
|
83
|
+
deffile = libfile.ext('def')
|
84
|
+
|
85
|
+
when_writing "creating #{t.name}" do
|
86
|
+
sh dlltool(dllname, deffile, libfile)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# clean and clobber actions
|
91
|
+
# All the uncompressed files must be removed at clean
|
92
|
+
CLEAN.include('vendor/sqlite3')
|
93
|
+
|
94
|
+
# clobber vendored packages
|
95
|
+
CLOBBER.include('vendor')
|
96
|
+
|
97
|
+
# vendor:sqlite3
|
98
|
+
task 'vendor:sqlite3' => ["vendor/sqlite3/lib/sqlite3.lib", "vendor/sqlite3/include/sqlite3.h"]
|
99
|
+
|
100
|
+
# hook into cross compilation vendored sqlite3 dependency
|
101
|
+
if RUBY_PLATFORM =~ /mingw|mswin/ then
|
102
|
+
Rake::Task['compile'].prerequisites.unshift 'vendor:sqlite3'
|
103
|
+
else
|
104
|
+
if Rake::Task.task_defined?(:cross)
|
105
|
+
Rake::Task['cross'].prerequisites.unshift 'vendor:sqlite3'
|
106
|
+
end
|
107
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'iconv'
|
3
|
+
|
4
|
+
module SQLite3
|
5
|
+
class TestDatabase < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@db = SQLite3::Database.new(':memory:')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_changes
|
11
|
+
@db.execute("CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, number integer)")
|
12
|
+
assert_equal 0, @db.changes
|
13
|
+
@db.execute("INSERT INTO items (number) VALUES (10)")
|
14
|
+
assert_equal 1, @db.changes
|
15
|
+
@db.execute_batch(
|
16
|
+
"UPDATE items SET number = (number + :nn) WHERE (number = :n)",
|
17
|
+
{"nn" => 20, "n" => 10})
|
18
|
+
assert_equal 1, @db.changes
|
19
|
+
assert_equal [[30]], @db.execute("select number from items")
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_new
|
23
|
+
db = SQLite3::Database.new(':memory:')
|
24
|
+
assert db
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_new_yields_self
|
28
|
+
thing = nil
|
29
|
+
SQLite3::Database.new(':memory:') do |db|
|
30
|
+
thing = db
|
31
|
+
end
|
32
|
+
assert_instance_of(SQLite3::Database, thing)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_new_with_options
|
36
|
+
db = SQLite3::Database.new(Iconv.conv('UTF-16LE', 'UTF-8', ':memory:'),
|
37
|
+
:utf16 => true)
|
38
|
+
assert db
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_close
|
42
|
+
db = SQLite3::Database.new(':memory:')
|
43
|
+
db.close
|
44
|
+
assert db.closed?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_block_closes_self
|
48
|
+
thing = nil
|
49
|
+
SQLite3::Database.new(':memory:') do |db|
|
50
|
+
thing = db
|
51
|
+
assert !thing.closed?
|
52
|
+
end
|
53
|
+
assert thing.closed?
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_prepare
|
57
|
+
db = SQLite3::Database.new(':memory:')
|
58
|
+
stmt = db.prepare('select "hello world"')
|
59
|
+
assert_instance_of(SQLite3::Statement, stmt)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_total_changes
|
63
|
+
db = SQLite3::Database.new(':memory:')
|
64
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
65
|
+
db.execute("insert into foo (b) values ('hello')")
|
66
|
+
assert_equal 1, db.total_changes
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_execute_returns_list_of_hash
|
70
|
+
db = SQLite3::Database.new(':memory:', :results_as_hash => true)
|
71
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
72
|
+
db.execute("insert into foo (b) values ('hello')")
|
73
|
+
rows = db.execute("select * from foo")
|
74
|
+
assert_equal [{0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}], rows
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_execute_yields_hash
|
78
|
+
db = SQLite3::Database.new(':memory:', :results_as_hash => true)
|
79
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
80
|
+
db.execute("insert into foo (b) values ('hello')")
|
81
|
+
db.execute("select * from foo") do |row|
|
82
|
+
assert_equal({0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}, row)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_table_info
|
87
|
+
db = SQLite3::Database.new(':memory:', :results_as_hash => true)
|
88
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
89
|
+
info = [{
|
90
|
+
"name" => "a",
|
91
|
+
"pk" => 1,
|
92
|
+
"notnull" => 0,
|
93
|
+
"type" => "integer",
|
94
|
+
"dflt_value" => nil,
|
95
|
+
"cid" => 0
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"name" => "b",
|
99
|
+
"pk" => 0,
|
100
|
+
"notnull" => 0,
|
101
|
+
"type" => "text",
|
102
|
+
"dflt_value" => nil,
|
103
|
+
"cid" => 1
|
104
|
+
}]
|
105
|
+
assert_equal info, db.table_info('foo')
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_total_changes_closed
|
109
|
+
db = SQLite3::Database.new(':memory:')
|
110
|
+
db.close
|
111
|
+
assert_raise(SQLite3::Exception) do
|
112
|
+
db.total_changes
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_trace_requires_opendb
|
117
|
+
@db.close
|
118
|
+
assert_raise(SQLite3::Exception) do
|
119
|
+
@db.trace { |x| }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_trace_with_block
|
124
|
+
result = nil
|
125
|
+
@db.trace { |sql| result = sql }
|
126
|
+
@db.execute "select 'foo'"
|
127
|
+
assert_equal "select 'foo'", result
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_trace_with_object
|
131
|
+
obj = Class.new {
|
132
|
+
attr_accessor :result
|
133
|
+
def call sql; @result = sql end
|
134
|
+
}.new
|
135
|
+
|
136
|
+
@db.trace(obj)
|
137
|
+
@db.execute "select 'foo'"
|
138
|
+
assert_equal "select 'foo'", obj.result
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_trace_takes_nil
|
142
|
+
@db.trace(nil)
|
143
|
+
@db.execute "select 'foo'"
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_last_insert_row_id_closed
|
147
|
+
@db.close
|
148
|
+
assert_raise(SQLite3::Exception) do
|
149
|
+
@db.last_insert_row_id
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_define_function
|
154
|
+
called_with = nil
|
155
|
+
@db.define_function("hello") do |value|
|
156
|
+
called_with = value
|
157
|
+
end
|
158
|
+
@db.execute("select hello(10)")
|
159
|
+
assert_equal 10, called_with
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_call_func_arg_type
|
163
|
+
called_with = nil
|
164
|
+
@db.define_function("hello") do |b, c, d|
|
165
|
+
called_with = [b, c, d]
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
@db.execute("select hello(2.2, 'foo', NULL)")
|
169
|
+
assert_equal [2.2, 'foo', nil], called_with
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_define_varargs
|
173
|
+
called_with = nil
|
174
|
+
@db.define_function("hello") do |*args|
|
175
|
+
called_with = args
|
176
|
+
nil
|
177
|
+
end
|
178
|
+
@db.execute("select hello(2.2, 'foo', NULL)")
|
179
|
+
assert_equal [2.2, 'foo', nil], called_with
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_function_return
|
183
|
+
@db.define_function("hello") { |a| 10 }
|
184
|
+
assert_equal [10], @db.execute("select hello('world')").first
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_function_return_types
|
188
|
+
[10, 2.2, nil, "foo"].each do |thing|
|
189
|
+
@db.define_function("hello") { |a| thing }
|
190
|
+
assert_equal [thing], @db.execute("select hello('world')").first
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_define_function_closed
|
195
|
+
@db.close
|
196
|
+
assert_raise(SQLite3::Exception) do
|
197
|
+
@db.define_function('foo') { }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_inerrupt_closed
|
202
|
+
@db.close
|
203
|
+
assert_raise(SQLite3::Exception) do
|
204
|
+
@db.interrupt
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_define_aggregate
|
209
|
+
@db.execute "create table foo ( a integer primary key, b text )"
|
210
|
+
@db.execute "insert into foo ( b ) values ( 'foo' )"
|
211
|
+
@db.execute "insert into foo ( b ) values ( 'bar' )"
|
212
|
+
@db.execute "insert into foo ( b ) values ( 'baz' )"
|
213
|
+
|
214
|
+
acc = Class.new {
|
215
|
+
attr_reader :sum
|
216
|
+
alias :finalize :sum
|
217
|
+
def initialize
|
218
|
+
@sum = 0
|
219
|
+
end
|
220
|
+
|
221
|
+
def step a
|
222
|
+
@sum += a
|
223
|
+
end
|
224
|
+
}.new
|
225
|
+
|
226
|
+
@db.define_aggregator("accumulate", acc)
|
227
|
+
value = @db.get_first_value( "select accumulate(a) from foo" )
|
228
|
+
assert_equal 6, value
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_authorizer_ok
|
232
|
+
@db.authorizer = Class.new {
|
233
|
+
def call action, a, b, c, d; true end
|
234
|
+
}.new
|
235
|
+
@db.prepare("select 'fooooo'")
|
236
|
+
|
237
|
+
@db.authorizer = Class.new {
|
238
|
+
def call action, a, b, c, d; 0 end
|
239
|
+
}.new
|
240
|
+
@db.prepare("select 'fooooo'")
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_authorizer_ignore
|
244
|
+
@db.authorizer = Class.new {
|
245
|
+
def call action, a, b, c, d; nil end
|
246
|
+
}.new
|
247
|
+
stmt = @db.prepare("select 'fooooo'")
|
248
|
+
assert_equal nil, stmt.step
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_authorizer_fail
|
252
|
+
@db.authorizer = Class.new {
|
253
|
+
def call action, a, b, c, d; false end
|
254
|
+
}.new
|
255
|
+
assert_raises(SQLite3::AuthorizationException) do
|
256
|
+
@db.prepare("select 'fooooo'")
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_remove_auth
|
261
|
+
@db.authorizer = Class.new {
|
262
|
+
def call action, a, b, c, d; false end
|
263
|
+
}.new
|
264
|
+
assert_raises(SQLite3::AuthorizationException) do
|
265
|
+
@db.prepare("select 'fooooo'")
|
266
|
+
end
|
267
|
+
|
268
|
+
@db.authorizer = nil
|
269
|
+
@db.prepare("select 'fooooo'")
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_close_with_open_statements
|
273
|
+
stmt = @db.prepare("select 'foo'")
|
274
|
+
assert_raises(SQLite3::BusyException) do
|
275
|
+
@db.close
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_execute_with_empty_bind_params
|
280
|
+
assert_equal [['foo']], @db.execute("select 'foo'", [])
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_query_with_named_bind_params
|
284
|
+
assert_equal [['foo']], @db.query("select :n", {'n' => 'foo'}).to_a
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_execute_with_named_bind_params
|
288
|
+
assert_equal [['foo']], @db.execute("select :n", {'n' => 'foo'})
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|