sqlite3 1.3.8-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.
- data/.gemtest +0 -0
- data/API_CHANGES.rdoc +50 -0
- data/CHANGELOG.rdoc +265 -0
- data/ChangeLog.cvs +88 -0
- data/Gemfile +15 -0
- data/LICENSE +27 -0
- data/Manifest.txt +52 -0
- data/README.rdoc +95 -0
- data/Rakefile +10 -0
- data/ext/sqlite3/backup.c +168 -0
- data/ext/sqlite3/backup.h +15 -0
- data/ext/sqlite3/database.c +822 -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 +51 -0
- data/ext/sqlite3/sqlite3.c +40 -0
- data/ext/sqlite3/sqlite3_ruby.h +53 -0
- data/ext/sqlite3/statement.c +439 -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/2.0/sqlite3_native.so +0 -0
- data/lib/sqlite3/constants.rb +49 -0
- data/lib/sqlite3/database.rb +579 -0
- data/lib/sqlite3/errors.rb +44 -0
- data/lib/sqlite3/pragmas.rb +280 -0
- data/lib/sqlite3/resultset.rb +195 -0
- data/lib/sqlite3/statement.rb +144 -0
- data/lib/sqlite3/translator.rb +118 -0
- data/lib/sqlite3/value.rb +57 -0
- data/lib/sqlite3/version.rb +25 -0
- data/setup.rb +1333 -0
- data/tasks/faq.rake +9 -0
- data/tasks/gem.rake +37 -0
- data/tasks/native.rake +45 -0
- data/tasks/vendor_sqlite3.rake +87 -0
- data/test/helper.rb +18 -0
- data/test/test_backup.rb +33 -0
- data/test/test_collation.rb +82 -0
- data/test/test_database.rb +350 -0
- data/test/test_database_readonly.rb +29 -0
- data/test/test_deprecated.rb +44 -0
- data/test/test_encoding.rb +121 -0
- data/test/test_integration.rb +555 -0
- data/test/test_integration_open_close.rb +30 -0
- data/test/test_integration_pending.rb +115 -0
- data/test/test_integration_resultset.rb +159 -0
- data/test/test_integration_statement.rb +194 -0
- data/test/test_result_set.rb +37 -0
- data/test/test_sqlite3.rb +9 -0
- data/test/test_statement.rb +256 -0
- data/test/test_statement_execute.rb +35 -0
- metadata +246 -0
data/tasks/faq.rake
ADDED
data/tasks/gem.rake
ADDED
@@ -0,0 +1,37 @@
|
|
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, :minitest, :bundler
|
10
|
+
|
11
|
+
HOE = Hoe.spec 'sqlite3' do
|
12
|
+
developer 'Jamis Buck', 'jamis@37signals.com'
|
13
|
+
developer 'Luis Lavena', 'luislavena@gmail.com'
|
14
|
+
developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'
|
15
|
+
|
16
|
+
license "MIT"
|
17
|
+
|
18
|
+
self.readme_file = 'README.rdoc'
|
19
|
+
self.history_file = 'CHANGELOG.rdoc'
|
20
|
+
self.extra_rdoc_files = FileList['*.rdoc', 'ext/**/*.c']
|
21
|
+
|
22
|
+
require_ruby_version ">= 1.8.7"
|
23
|
+
require_rubygems_version ">= 1.3.5"
|
24
|
+
|
25
|
+
spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
|
26
|
+
|
27
|
+
extra_dev_deps << ['rake-compiler', "~> 0.9.1"]
|
28
|
+
extra_dev_deps << ["mini_portile", "~> 0.5.1"]
|
29
|
+
extra_dev_deps << ["minitest", "~> 5.0"]
|
30
|
+
extra_dev_deps << ["hoe-bundler", "~> 1.0"]
|
31
|
+
|
32
|
+
clean_globs.push('**/test.db')
|
33
|
+
end
|
34
|
+
|
35
|
+
Hoe.add_include_dirs '.'
|
36
|
+
|
37
|
+
# vim: syntax=ruby
|
data/tasks/native.rake
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# use rake-compiler for building the extension
|
2
|
+
require 'rake/extensiontask'
|
3
|
+
require 'rake/extensioncompiler'
|
4
|
+
|
5
|
+
# NOTE: version used by cross compilation of Windows native extension
|
6
|
+
# It do not affect compilation under other operating systems
|
7
|
+
# The version indicated is the minimum DLL suggested for correct functionality
|
8
|
+
BINARY_VERSION = "3.7.17"
|
9
|
+
URL_VERSION = "3071700"
|
10
|
+
URL_PATH = "/2013"
|
11
|
+
|
12
|
+
# build sqlite3_native C extension
|
13
|
+
RUBY_EXTENSION = Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
|
14
|
+
# where to locate the extension
|
15
|
+
ext.ext_dir = 'ext/sqlite3'
|
16
|
+
|
17
|
+
# where native extension will be copied (matches makefile)
|
18
|
+
ext.lib_dir = "lib/sqlite3"
|
19
|
+
|
20
|
+
# clean binary folders always
|
21
|
+
CLEAN.include("#{ext.lib_dir}/?.?")
|
22
|
+
|
23
|
+
# automatically add build options to avoid need of manual input
|
24
|
+
if RUBY_PLATFORM =~ /mswin|mingw/ then
|
25
|
+
# define target for extension (supporting fat binaries)
|
26
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
27
|
+
ext.lib_dir = "lib/sqlite3/#{$1}"
|
28
|
+
ext.config_options << "--enable-local"
|
29
|
+
else
|
30
|
+
|
31
|
+
# detect cross-compiler available
|
32
|
+
begin
|
33
|
+
Rake::ExtensionCompiler.mingw_host
|
34
|
+
ext.cross_compile = true
|
35
|
+
ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32', 'x64-mingw32']
|
36
|
+
rescue RuntimeError
|
37
|
+
# noop
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# ensure things are compiled prior testing
|
43
|
+
task :test => [:compile]
|
44
|
+
|
45
|
+
# vim: syntax=ruby
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "rake/clean"
|
2
|
+
require "rake/extensioncompiler"
|
3
|
+
require "mini_portile"
|
4
|
+
|
5
|
+
CLOBBER.include("ports")
|
6
|
+
|
7
|
+
directory "ports"
|
8
|
+
|
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
|
13
|
+
|
14
|
+
desc "Compile sqlite3 for #{platform} (#{host})"
|
15
|
+
task "ports:sqlite3:#{platform}" => ["ports"] do |t|
|
16
|
+
checkpoint = "ports/.#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
|
17
|
+
|
18
|
+
unless File.exist?(checkpoint)
|
19
|
+
cflags = "-O2 -DSQLITE_ENABLE_COLUMN_METADATA"
|
20
|
+
cflags << " -fPIC" if recipe.host.include?("x86_64")
|
21
|
+
recipe.configure_options << "CFLAGS='#{cflags}'"
|
22
|
+
recipe.cook
|
23
|
+
touch checkpoint
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
recipe
|
28
|
+
end
|
29
|
+
|
30
|
+
# native sqlite3 compilation
|
31
|
+
define_sqlite_task RUBY_PLATFORM, RbConfig::CONFIG["host"]
|
32
|
+
|
33
|
+
# trick to test local compilation of sqlite3
|
34
|
+
if ENV["USE_MINI_PORTILE"] == "true"
|
35
|
+
# fake recipe so we can build a directory to it
|
36
|
+
recipe = MiniPortile.new "sqlite3", BINARY_VERSION
|
37
|
+
recipe.host = RbConfig::CONFIG["host"]
|
38
|
+
|
39
|
+
RUBY_EXTENSION.config_options << "--with-opt-dir=#{recipe.path}"
|
40
|
+
|
41
|
+
# compile sqlite3 first
|
42
|
+
Rake::Task["compile"].prerequisites.unshift "ports:sqlite3:#{RUBY_PLATFORM}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# force compilation of sqlite3 when working natively under MinGW
|
46
|
+
if RUBY_PLATFORM =~ /mingw/
|
47
|
+
Rake::Task['compile'].prerequisites.unshift "ports:sqlite3:#{RUBY_PLATFORM}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# iterate over all cross-compilation platforms and define the proper
|
51
|
+
# sqlite3 recipe for it.
|
52
|
+
if RUBY_EXTENSION.cross_compile
|
53
|
+
config_path = File.expand_path("~/.rake-compiler/config.yml")
|
54
|
+
if File.exist?(config_path)
|
55
|
+
# obtains platforms from rake-compiler's config.yml
|
56
|
+
config_file = YAML.load_file(config_path)
|
57
|
+
|
58
|
+
Array(RUBY_EXTENSION.cross_platform).each do |platform|
|
59
|
+
# obtain platform from rbconfig file
|
60
|
+
config_key = config_file.keys.sort.find { |key|
|
61
|
+
key.start_with?("rbconfig-#{platform}-")
|
62
|
+
}
|
63
|
+
rbfile = config_file[config_key]
|
64
|
+
|
65
|
+
# skip if rbconfig cannot be read
|
66
|
+
next unless File.exist?(rbfile)
|
67
|
+
|
68
|
+
host = IO.read(rbfile).match(/CONFIG\["CC"\] = "(.*)"/)[1].sub(/\-gcc/, '')
|
69
|
+
recipe = define_sqlite_task(platform, host)
|
70
|
+
|
71
|
+
RUBY_EXTENSION.cross_config_options << {
|
72
|
+
platform => "--with-opt-dir=#{recipe.path}"
|
73
|
+
}
|
74
|
+
|
75
|
+
# pre-compile sqlite3 port when cross-compiling
|
76
|
+
task :cross => "ports:sqlite3:#{platform}"
|
77
|
+
end
|
78
|
+
else
|
79
|
+
warn "rake-compiler configuration doesn't exist, but is required for ports"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
task :cross do
|
84
|
+
["CC", "CXX", "LDFLAGS", "CPPFLAGS", "RUBYOPT"].each do |var|
|
85
|
+
ENV.delete(var)
|
86
|
+
end
|
87
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
unless RUBY_VERSION >= "1.9"
|
5
|
+
require 'iconv'
|
6
|
+
end
|
7
|
+
|
8
|
+
module SQLite3
|
9
|
+
class TestCase < Minitest::Test
|
10
|
+
alias :assert_not_equal :refute_equal
|
11
|
+
alias :assert_not_nil :refute_nil
|
12
|
+
alias :assert_raise :assert_raises
|
13
|
+
|
14
|
+
def assert_nothing_raised
|
15
|
+
yield
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/test_backup.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module SQLite3
|
4
|
+
class TestBackup < SQLite3::TestCase
|
5
|
+
def setup
|
6
|
+
@sdb = SQLite3::Database.new(':memory:')
|
7
|
+
@ddb = SQLite3::Database.new(':memory:')
|
8
|
+
@sdb.execute('CREATE TABLE foo (idx, val);');
|
9
|
+
@data = ('A'..'Z').map{|x|x * 40}
|
10
|
+
@data.each_with_index do |v, i|
|
11
|
+
@sdb.execute('INSERT INTO foo (idx, val) VALUES (?, ?);', [i, v])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_backup_step
|
16
|
+
b = SQLite3::Backup.new(@ddb, 'main', @sdb, 'main')
|
17
|
+
while b.step(1) == SQLite3::Constants::ErrorCode::OK
|
18
|
+
assert_not_equal(0, b.remaining)
|
19
|
+
end
|
20
|
+
assert_equal(0, b.remaining)
|
21
|
+
b.finish
|
22
|
+
assert_equal(@data.length, @ddb.execute('SELECT * FROM foo;').length)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_backup_all
|
26
|
+
b = SQLite3::Backup.new(@ddb, 'main', @sdb, 'main')
|
27
|
+
assert_equal(SQLite3::Constants::ErrorCode::DONE, b.step(-1))
|
28
|
+
assert_equal(0, b.remaining)
|
29
|
+
b.finish
|
30
|
+
assert_equal(@data.length, @ddb.execute('SELECT * FROM foo;').length)
|
31
|
+
end
|
32
|
+
end if defined?(SQLite3::Backup)
|
33
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
module SQLite3
|
6
|
+
class TestCollation < SQLite3::TestCase
|
7
|
+
class Comparator
|
8
|
+
attr_reader :calls
|
9
|
+
def initialize
|
10
|
+
@calls = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def compare left, right
|
14
|
+
@calls << [left, right]
|
15
|
+
left <=> right
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@db = SQLite3::Database.new(':memory:')
|
21
|
+
@create = "create table ex(id int, data string)"
|
22
|
+
@db.execute(@create);
|
23
|
+
[ [1, 'hello'], [2, 'world'] ].each do |vals|
|
24
|
+
@db.execute('insert into ex (id, data) VALUES (?, ?)', vals)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_custom_collation
|
29
|
+
comparator = Comparator.new
|
30
|
+
|
31
|
+
@db.collation 'foo', comparator
|
32
|
+
|
33
|
+
assert_equal comparator, @db.collations['foo']
|
34
|
+
@db.execute('select data from ex order by 1 collate foo')
|
35
|
+
assert_equal 1, comparator.calls.length
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_remove_collation
|
39
|
+
comparator = Comparator.new
|
40
|
+
|
41
|
+
@db.collation 'foo', comparator
|
42
|
+
@db.collation 'foo', nil
|
43
|
+
|
44
|
+
assert_nil @db.collations['foo']
|
45
|
+
assert_raises(SQLite3::SQLException) do
|
46
|
+
@db.execute('select data from ex order by 1 collate foo')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if RUBY_VERSION >= '1.9.1'
|
51
|
+
def test_encoding
|
52
|
+
comparator = Comparator.new
|
53
|
+
@db.collation 'foo', comparator
|
54
|
+
@db.execute('select data from ex order by 1 collate foo')
|
55
|
+
|
56
|
+
a, b = *comparator.calls.first
|
57
|
+
|
58
|
+
assert_equal Encoding.find('UTF-8'), a.encoding
|
59
|
+
assert_equal Encoding.find('UTF-8'), b.encoding
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_encoding_default_internal
|
63
|
+
warn_before = $-w
|
64
|
+
$-w = false
|
65
|
+
before_enc = Encoding.default_internal
|
66
|
+
|
67
|
+
Encoding.default_internal = 'EUC-JP'
|
68
|
+
comparator = Comparator.new
|
69
|
+
@db.collation 'foo', comparator
|
70
|
+
@db.execute('select data from ex order by 1 collate foo')
|
71
|
+
|
72
|
+
a, b = *comparator.calls.first
|
73
|
+
|
74
|
+
assert_equal Encoding.find('EUC-JP'), a.encoding
|
75
|
+
assert_equal Encoding.find('EUC-JP'), b.encoding
|
76
|
+
ensure
|
77
|
+
Encoding.default_internal = before_enc
|
78
|
+
$-w = warn_before
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,350 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module SQLite3
|
4
|
+
class TestDatabase < SQLite3::TestCase
|
5
|
+
attr_reader :db
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@db = SQLite3::Database.new(':memory:')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_segv
|
12
|
+
assert_raises(TypeError) { SQLite3::Database.new 1 }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_bignum
|
16
|
+
num = 4907021672125087844
|
17
|
+
db.execute 'CREATE TABLE "employees" ("token" integer(8), "name" varchar(20) NOT NULL)'
|
18
|
+
db.execute "INSERT INTO employees(name, token) VALUES('employee-1', ?)", [num]
|
19
|
+
rows = db.execute 'select token from employees'
|
20
|
+
assert_equal num, rows.first.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_blob
|
24
|
+
@db.execute("CREATE TABLE blobs ( id INTEGER, hash BLOB(10) )")
|
25
|
+
blob = Blob.new("foo\0bar")
|
26
|
+
@db.execute("INSERT INTO blobs VALUES (0, ?)", [blob])
|
27
|
+
assert_equal [[0, blob, blob.length, blob.length*2]], @db.execute("SELECT id, hash, length(hash), length(hex(hash)) FROM blobs")
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_get_first_row
|
31
|
+
assert_equal [1], @db.get_first_row('SELECT 1')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_get_first_row_with_type_translation_and_hash_results
|
35
|
+
@db.results_as_hash = true
|
36
|
+
assert_equal({0=>1, "1"=>1}, @db.get_first_row('SELECT 1'))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_execute_with_type_translation_and_hash
|
40
|
+
@db.results_as_hash = true
|
41
|
+
rows = []
|
42
|
+
@db.execute('SELECT 1') { |row| rows << row }
|
43
|
+
|
44
|
+
assert_equal({0=>1, "1"=>1}, rows.first)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_encoding
|
48
|
+
assert @db.encoding, 'database has encoding'
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_changes
|
52
|
+
@db.execute("CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, number integer)")
|
53
|
+
assert_equal 0, @db.changes
|
54
|
+
@db.execute("INSERT INTO items (number) VALUES (10)")
|
55
|
+
assert_equal 1, @db.changes
|
56
|
+
@db.execute_batch(
|
57
|
+
"UPDATE items SET number = (number + :nn) WHERE (number = :n)",
|
58
|
+
{"nn" => 20, "n" => 10})
|
59
|
+
assert_equal 1, @db.changes
|
60
|
+
assert_equal [[30]], @db.execute("select number from items")
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_new
|
64
|
+
db = SQLite3::Database.new(':memory:')
|
65
|
+
assert db
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_new_yields_self
|
69
|
+
thing = nil
|
70
|
+
SQLite3::Database.new(':memory:') do |db|
|
71
|
+
thing = db
|
72
|
+
end
|
73
|
+
assert_instance_of(SQLite3::Database, thing)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_new_with_options
|
77
|
+
# determine if Ruby is running on Big Endian platform
|
78
|
+
utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
|
79
|
+
|
80
|
+
if RUBY_VERSION >= "1.9"
|
81
|
+
db = SQLite3::Database.new(':memory:'.encode(utf16), :utf16 => true)
|
82
|
+
else
|
83
|
+
db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
|
84
|
+
:utf16 => true)
|
85
|
+
end
|
86
|
+
assert db
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_close
|
90
|
+
db = SQLite3::Database.new(':memory:')
|
91
|
+
db.close
|
92
|
+
assert db.closed?
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_block_closes_self
|
96
|
+
thing = nil
|
97
|
+
SQLite3::Database.new(':memory:') do |db|
|
98
|
+
thing = db
|
99
|
+
assert !thing.closed?
|
100
|
+
end
|
101
|
+
assert thing.closed?
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_prepare
|
105
|
+
db = SQLite3::Database.new(':memory:')
|
106
|
+
stmt = db.prepare('select "hello world"')
|
107
|
+
assert_instance_of(SQLite3::Statement, stmt)
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_total_changes
|
111
|
+
db = SQLite3::Database.new(':memory:')
|
112
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
113
|
+
db.execute("insert into foo (b) values ('hello')")
|
114
|
+
assert_equal 1, db.total_changes
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_execute_returns_list_of_hash
|
118
|
+
db = SQLite3::Database.new(':memory:', :results_as_hash => true)
|
119
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
120
|
+
db.execute("insert into foo (b) values ('hello')")
|
121
|
+
rows = db.execute("select * from foo")
|
122
|
+
assert_equal [{0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}], rows
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_execute_yields_hash
|
126
|
+
db = SQLite3::Database.new(':memory:', :results_as_hash => true)
|
127
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
128
|
+
db.execute("insert into foo (b) values ('hello')")
|
129
|
+
db.execute("select * from foo") do |row|
|
130
|
+
assert_equal({0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}, row)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_table_info
|
135
|
+
db = SQLite3::Database.new(':memory:', :results_as_hash => true)
|
136
|
+
db.execute("create table foo ( a integer primary key, b text )")
|
137
|
+
info = [{
|
138
|
+
"name" => "a",
|
139
|
+
"pk" => 1,
|
140
|
+
"notnull" => 0,
|
141
|
+
"type" => "integer",
|
142
|
+
"dflt_value" => nil,
|
143
|
+
"cid" => 0
|
144
|
+
},
|
145
|
+
{
|
146
|
+
"name" => "b",
|
147
|
+
"pk" => 0,
|
148
|
+
"notnull" => 0,
|
149
|
+
"type" => "text",
|
150
|
+
"dflt_value" => nil,
|
151
|
+
"cid" => 1
|
152
|
+
}]
|
153
|
+
assert_equal info, db.table_info('foo')
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_total_changes_closed
|
157
|
+
db = SQLite3::Database.new(':memory:')
|
158
|
+
db.close
|
159
|
+
assert_raise(SQLite3::Exception) do
|
160
|
+
db.total_changes
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_trace_requires_opendb
|
165
|
+
@db.close
|
166
|
+
assert_raise(SQLite3::Exception) do
|
167
|
+
@db.trace { |x| }
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_trace_with_block
|
172
|
+
result = nil
|
173
|
+
@db.trace { |sql| result = sql }
|
174
|
+
@db.execute "select 'foo'"
|
175
|
+
assert_equal "select 'foo'", result
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_trace_with_object
|
179
|
+
obj = Class.new {
|
180
|
+
attr_accessor :result
|
181
|
+
def call sql; @result = sql end
|
182
|
+
}.new
|
183
|
+
|
184
|
+
@db.trace(obj)
|
185
|
+
@db.execute "select 'foo'"
|
186
|
+
assert_equal "select 'foo'", obj.result
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_trace_takes_nil
|
190
|
+
@db.trace(nil)
|
191
|
+
@db.execute "select 'foo'"
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_last_insert_row_id_closed
|
195
|
+
@db.close
|
196
|
+
assert_raise(SQLite3::Exception) do
|
197
|
+
@db.last_insert_row_id
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_define_function
|
202
|
+
called_with = nil
|
203
|
+
@db.define_function("hello") do |value|
|
204
|
+
called_with = value
|
205
|
+
end
|
206
|
+
@db.execute("select hello(10)")
|
207
|
+
assert_equal 10, called_with
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_call_func_arg_type
|
211
|
+
called_with = nil
|
212
|
+
@db.define_function("hello") do |b, c, d|
|
213
|
+
called_with = [b, c, d]
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
@db.execute("select hello(2.2, 'foo', NULL)")
|
217
|
+
assert_equal [2.2, 'foo', nil], called_with
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_define_varargs
|
221
|
+
called_with = nil
|
222
|
+
@db.define_function("hello") do |*args|
|
223
|
+
called_with = args
|
224
|
+
nil
|
225
|
+
end
|
226
|
+
@db.execute("select hello(2.2, 'foo', NULL)")
|
227
|
+
assert_equal [2.2, 'foo', nil], called_with
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_call_func_blob
|
231
|
+
called_with = nil
|
232
|
+
@db.define_function("hello") do |a, b|
|
233
|
+
called_with = [a, b, a.length]
|
234
|
+
nil
|
235
|
+
end
|
236
|
+
blob = Blob.new("a\0fine\0kettle\0of\0fish")
|
237
|
+
@db.execute("select hello(?, length(?))", [blob, blob])
|
238
|
+
assert_equal [blob, blob.length, 21], called_with
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_function_return
|
242
|
+
@db.define_function("hello") { |a| 10 }
|
243
|
+
assert_equal [10], @db.execute("select hello('world')").first
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_function_return_types
|
247
|
+
[10, 2.2, nil, "foo"].each do |thing|
|
248
|
+
@db.define_function("hello") { |a| thing }
|
249
|
+
assert_equal [thing], @db.execute("select hello('world')").first
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_define_function_closed
|
254
|
+
@db.close
|
255
|
+
assert_raise(SQLite3::Exception) do
|
256
|
+
@db.define_function('foo') { }
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_inerrupt_closed
|
261
|
+
@db.close
|
262
|
+
assert_raise(SQLite3::Exception) do
|
263
|
+
@db.interrupt
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_define_aggregate
|
268
|
+
@db.execute "create table foo ( a integer primary key, b text )"
|
269
|
+
@db.execute "insert into foo ( b ) values ( 'foo' )"
|
270
|
+
@db.execute "insert into foo ( b ) values ( 'bar' )"
|
271
|
+
@db.execute "insert into foo ( b ) values ( 'baz' )"
|
272
|
+
|
273
|
+
acc = Class.new {
|
274
|
+
attr_reader :sum
|
275
|
+
alias :finalize :sum
|
276
|
+
def initialize
|
277
|
+
@sum = 0
|
278
|
+
end
|
279
|
+
|
280
|
+
def step a
|
281
|
+
@sum += a
|
282
|
+
end
|
283
|
+
}.new
|
284
|
+
|
285
|
+
@db.define_aggregator("accumulate", acc)
|
286
|
+
value = @db.get_first_value( "select accumulate(a) from foo" )
|
287
|
+
assert_equal 6, value
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_authorizer_ok
|
291
|
+
@db.authorizer = Class.new {
|
292
|
+
def call action, a, b, c, d; true end
|
293
|
+
}.new
|
294
|
+
@db.prepare("select 'fooooo'")
|
295
|
+
|
296
|
+
@db.authorizer = Class.new {
|
297
|
+
def call action, a, b, c, d; 0 end
|
298
|
+
}.new
|
299
|
+
@db.prepare("select 'fooooo'")
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_authorizer_ignore
|
303
|
+
@db.authorizer = Class.new {
|
304
|
+
def call action, a, b, c, d; nil end
|
305
|
+
}.new
|
306
|
+
stmt = @db.prepare("select 'fooooo'")
|
307
|
+
assert_equal nil, stmt.step
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_authorizer_fail
|
311
|
+
@db.authorizer = Class.new {
|
312
|
+
def call action, a, b, c, d; false end
|
313
|
+
}.new
|
314
|
+
assert_raises(SQLite3::AuthorizationException) do
|
315
|
+
@db.prepare("select 'fooooo'")
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_remove_auth
|
320
|
+
@db.authorizer = Class.new {
|
321
|
+
def call action, a, b, c, d; false end
|
322
|
+
}.new
|
323
|
+
assert_raises(SQLite3::AuthorizationException) do
|
324
|
+
@db.prepare("select 'fooooo'")
|
325
|
+
end
|
326
|
+
|
327
|
+
@db.authorizer = nil
|
328
|
+
@db.prepare("select 'fooooo'")
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_close_with_open_statements
|
332
|
+
@db.prepare("select 'foo'")
|
333
|
+
assert_raises(SQLite3::BusyException) do
|
334
|
+
@db.close
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_execute_with_empty_bind_params
|
339
|
+
assert_equal [['foo']], @db.execute("select 'foo'", [])
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_query_with_named_bind_params
|
343
|
+
assert_equal [['foo']], @db.query("select :n", {'n' => 'foo'}).to_a
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_execute_with_named_bind_params
|
347
|
+
assert_equal [['foo']], @db.execute("select :n", {'n' => 'foo'})
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|