sqlite3-full 1.3.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/API_CHANGES.rdoc +50 -0
  4. data/CHANGELOG.rdoc +278 -0
  5. data/ChangeLog.cvs +88 -0
  6. data/Gemfile +15 -0
  7. data/LICENSE +34 -0
  8. data/Manifest.txt +52 -0
  9. data/README.rdoc +90 -0
  10. data/Rakefile +10 -0
  11. data/ext/sqlite3/backup.c +168 -0
  12. data/ext/sqlite3/backup.h +15 -0
  13. data/ext/sqlite3/database.c +825 -0
  14. data/ext/sqlite3/database.h +15 -0
  15. data/ext/sqlite3/exception.c +94 -0
  16. data/ext/sqlite3/exception.h +8 -0
  17. data/ext/sqlite3/extconf.rb +86 -0
  18. data/ext/sqlite3/sqlite3.c +97 -0
  19. data/ext/sqlite3/sqlite3_ruby.h +52 -0
  20. data/ext/sqlite3/sqlite3amalgamation.c +153367 -0
  21. data/ext/sqlite3/statement.c +447 -0
  22. data/ext/sqlite3/statement.h +16 -0
  23. data/faq/faq.rb +145 -0
  24. data/faq/faq.yml +426 -0
  25. data/lib/sqlite3/constants.rb +49 -0
  26. data/lib/sqlite3/database.rb +590 -0
  27. data/lib/sqlite3/errors.rb +44 -0
  28. data/lib/sqlite3/pragmas.rb +280 -0
  29. data/lib/sqlite3/resultset.rb +195 -0
  30. data/lib/sqlite3/statement.rb +144 -0
  31. data/lib/sqlite3/translator.rb +118 -0
  32. data/lib/sqlite3/value.rb +57 -0
  33. data/lib/sqlite3/version.rb +25 -0
  34. data/lib/sqlite3.rb +10 -0
  35. data/setup.rb +1333 -0
  36. data/tasks/faq.rake +9 -0
  37. data/tasks/gem.rake +38 -0
  38. data/tasks/native.rake +52 -0
  39. data/tasks/vendor_sqlite3.rake +91 -0
  40. data/test/helper.rb +18 -0
  41. data/test/test_backup.rb +33 -0
  42. data/test/test_collation.rb +82 -0
  43. data/test/test_database.rb +367 -0
  44. data/test/test_database_readonly.rb +29 -0
  45. data/test/test_deprecated.rb +44 -0
  46. data/test/test_encoding.rb +153 -0
  47. data/test/test_integration.rb +572 -0
  48. data/test/test_integration_open_close.rb +30 -0
  49. data/test/test_integration_pending.rb +115 -0
  50. data/test/test_integration_resultset.rb +159 -0
  51. data/test/test_integration_statement.rb +194 -0
  52. data/test/test_result_set.rb +37 -0
  53. data/test/test_sqlite3.rb +9 -0
  54. data/test/test_statement.rb +260 -0
  55. data/test/test_statement_execute.rb +35 -0
  56. metadata +205 -0
data/tasks/faq.rake ADDED
@@ -0,0 +1,9 @@
1
+ # Generate FAQ
2
+ desc "Generate the FAQ document"
3
+ task :faq => ['faq/faq.html']
4
+
5
+ file 'faq/faq.html' => ['faq/faq.rb', 'faq/faq.yml'] do
6
+ cd 'faq' do
7
+ ruby "faq.rb > faq.html"
8
+ end
9
+ end
data/tasks/gem.rake ADDED
@@ -0,0 +1,38 @@
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-full' do
12
+ developer 'Jamis Buck', 'jamis@37signals.com'
13
+ developer 'Luis Lavena', 'luislavena@gmail.com'
14
+ developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'
15
+ developer 'Eno Thierbach', 'eno@open-lab.org'
16
+
17
+ license "BSD-3"
18
+
19
+ self.readme_file = 'README.rdoc'
20
+ self.history_file = 'CHANGELOG.rdoc'
21
+ self.extra_rdoc_files = FileList['*.rdoc', 'ext/**/*.c']
22
+
23
+ require_ruby_version ">= 1.8.7"
24
+ require_rubygems_version ">= 1.3.5"
25
+
26
+ spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
27
+
28
+ extra_dev_deps << ['rake-compiler', "~> 0.9.3"]
29
+ extra_dev_deps << ["mini_portile", "~> 0.6.1"]
30
+ extra_dev_deps << ["minitest", "~> 5.0"]
31
+ extra_dev_deps << ["hoe-bundler", "~> 1.0"]
32
+
33
+ clean_globs.push('**/test.db')
34
+ end
35
+
36
+ Hoe.add_include_dirs '.'
37
+
38
+ # vim: syntax=ruby
data/tasks/native.rake ADDED
@@ -0,0 +1,52 @@
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.8.6"
9
+ URL_VERSION = "3080600"
10
+ URL_PATH = "/2014"
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
19
+
20
+ # build sqlite3_native C extension
21
+ RUBY_EXTENSION = Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
22
+ # where to locate the extension
23
+ ext.ext_dir = 'ext/sqlite3'
24
+
25
+ # where native extension will be copied (matches makefile)
26
+ ext.lib_dir = "lib/sqlite3"
27
+
28
+ # clean binary folders always
29
+ CLEAN.include("#{ext.lib_dir}/?.?")
30
+
31
+ # automatically add build options to avoid need of manual input
32
+ if RUBY_PLATFORM =~ /mswin|mingw/ then
33
+ # define target for extension (supporting fat binaries)
34
+ RUBY_VERSION =~ /(\d+\.\d+)/
35
+ ext.lib_dir = "lib/sqlite3/#{$1}"
36
+ else
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
46
+ end
47
+ end
48
+
49
+ # ensure things are compiled prior testing
50
+ task :test => [:compile]
51
+
52
+ # vim: syntax=ruby
@@ -0,0 +1,91 @@
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 && 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
+ recipe = define_sqlite_task(RUBY_PLATFORM, RbConfig::CONFIG["host"])
32
+
33
+ # force compilation of sqlite3 when working natively under MinGW
34
+ if RUBY_PLATFORM =~ /mingw/
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}"
40
+ end
41
+
42
+ # trick to test local compilation of sqlite3
43
+ if ENV["USE_MINI_PORTILE"] == "true"
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}"
52
+ end
53
+
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"
84
+ end
85
+ end
86
+
87
+ task :cross do
88
+ ["CC", "CXX", "LDFLAGS", "CPPFLAGS", "RUBYOPT"].each do |var|
89
+ ENV.delete(var)
90
+ end
91
+ 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
@@ -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,367 @@
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_batch_last_comment_is_processed
64
+ # FIXME: nil as a successful return value is kinda dumb
65
+ assert_nil @db.execute_batch <<-eosql
66
+ CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT);
67
+ -- omg
68
+ eosql
69
+ end
70
+
71
+ def test_new
72
+ db = SQLite3::Database.new(':memory:')
73
+ assert db
74
+ end
75
+
76
+ def test_new_yields_self
77
+ thing = nil
78
+ SQLite3::Database.new(':memory:') do |db|
79
+ thing = db
80
+ end
81
+ assert_instance_of(SQLite3::Database, thing)
82
+ end
83
+
84
+ def test_new_with_options
85
+ # determine if Ruby is running on Big Endian platform
86
+ utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
87
+
88
+ if RUBY_VERSION >= "1.9"
89
+ db = SQLite3::Database.new(':memory:'.encode(utf16), :utf16 => true)
90
+ else
91
+ db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
92
+ :utf16 => true)
93
+ end
94
+ assert db
95
+ end
96
+
97
+ def test_close
98
+ db = SQLite3::Database.new(':memory:')
99
+ db.close
100
+ assert db.closed?
101
+ end
102
+
103
+ def test_block_closes_self
104
+ thing = nil
105
+ SQLite3::Database.new(':memory:') do |db|
106
+ thing = db
107
+ assert !thing.closed?
108
+ end
109
+ assert thing.closed?
110
+ end
111
+
112
+ def test_prepare
113
+ db = SQLite3::Database.new(':memory:')
114
+ stmt = db.prepare('select "hello world"')
115
+ assert_instance_of(SQLite3::Statement, stmt)
116
+ end
117
+
118
+ def test_block_prepare_does_not_double_close
119
+ db = SQLite3::Database.new(':memory:')
120
+ r = db.prepare('select "hello world"') do |stmt|
121
+ stmt.close
122
+ :foo
123
+ end
124
+ assert_equal :foo, r
125
+ end
126
+
127
+ def test_total_changes
128
+ db = SQLite3::Database.new(':memory:')
129
+ db.execute("create table foo ( a integer primary key, b text )")
130
+ db.execute("insert into foo (b) values ('hello')")
131
+ assert_equal 1, db.total_changes
132
+ end
133
+
134
+ def test_execute_returns_list_of_hash
135
+ db = SQLite3::Database.new(':memory:', :results_as_hash => true)
136
+ db.execute("create table foo ( a integer primary key, b text )")
137
+ db.execute("insert into foo (b) values ('hello')")
138
+ rows = db.execute("select * from foo")
139
+ assert_equal [{0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}], rows
140
+ end
141
+
142
+ def test_execute_yields_hash
143
+ db = SQLite3::Database.new(':memory:', :results_as_hash => true)
144
+ db.execute("create table foo ( a integer primary key, b text )")
145
+ db.execute("insert into foo (b) values ('hello')")
146
+ db.execute("select * from foo") do |row|
147
+ assert_equal({0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}, row)
148
+ end
149
+ end
150
+
151
+ def test_table_info
152
+ db = SQLite3::Database.new(':memory:', :results_as_hash => true)
153
+ db.execute("create table foo ( a integer primary key, b text )")
154
+ info = [{
155
+ "name" => "a",
156
+ "pk" => 1,
157
+ "notnull" => 0,
158
+ "type" => "integer",
159
+ "dflt_value" => nil,
160
+ "cid" => 0
161
+ },
162
+ {
163
+ "name" => "b",
164
+ "pk" => 0,
165
+ "notnull" => 0,
166
+ "type" => "text",
167
+ "dflt_value" => nil,
168
+ "cid" => 1
169
+ }]
170
+ assert_equal info, db.table_info('foo')
171
+ end
172
+
173
+ def test_total_changes_closed
174
+ db = SQLite3::Database.new(':memory:')
175
+ db.close
176
+ assert_raise(SQLite3::Exception) do
177
+ db.total_changes
178
+ end
179
+ end
180
+
181
+ def test_trace_requires_opendb
182
+ @db.close
183
+ assert_raise(SQLite3::Exception) do
184
+ @db.trace { |x| }
185
+ end
186
+ end
187
+
188
+ def test_trace_with_block
189
+ result = nil
190
+ @db.trace { |sql| result = sql }
191
+ @db.execute "select 'foo'"
192
+ assert_equal "select 'foo'", result
193
+ end
194
+
195
+ def test_trace_with_object
196
+ obj = Class.new {
197
+ attr_accessor :result
198
+ def call sql; @result = sql end
199
+ }.new
200
+
201
+ @db.trace(obj)
202
+ @db.execute "select 'foo'"
203
+ assert_equal "select 'foo'", obj.result
204
+ end
205
+
206
+ def test_trace_takes_nil
207
+ @db.trace(nil)
208
+ @db.execute "select 'foo'"
209
+ end
210
+
211
+ def test_last_insert_row_id_closed
212
+ @db.close
213
+ assert_raise(SQLite3::Exception) do
214
+ @db.last_insert_row_id
215
+ end
216
+ end
217
+
218
+ def test_define_function
219
+ called_with = nil
220
+ @db.define_function("hello") do |value|
221
+ called_with = value
222
+ end
223
+ @db.execute("select hello(10)")
224
+ assert_equal 10, called_with
225
+ end
226
+
227
+ def test_call_func_arg_type
228
+ called_with = nil
229
+ @db.define_function("hello") do |b, c, d|
230
+ called_with = [b, c, d]
231
+ nil
232
+ end
233
+ @db.execute("select hello(2.2, 'foo', NULL)")
234
+ assert_equal [2.2, 'foo', nil], called_with
235
+ end
236
+
237
+ def test_define_varargs
238
+ called_with = nil
239
+ @db.define_function("hello") do |*args|
240
+ called_with = args
241
+ nil
242
+ end
243
+ @db.execute("select hello(2.2, 'foo', NULL)")
244
+ assert_equal [2.2, 'foo', nil], called_with
245
+ end
246
+
247
+ def test_call_func_blob
248
+ called_with = nil
249
+ @db.define_function("hello") do |a, b|
250
+ called_with = [a, b, a.length]
251
+ nil
252
+ end
253
+ blob = Blob.new("a\0fine\0kettle\0of\0fish")
254
+ @db.execute("select hello(?, length(?))", [blob, blob])
255
+ assert_equal [blob, blob.length, 21], called_with
256
+ end
257
+
258
+ def test_function_return
259
+ @db.define_function("hello") { |a| 10 }
260
+ assert_equal [10], @db.execute("select hello('world')").first
261
+ end
262
+
263
+ def test_function_return_types
264
+ [10, 2.2, nil, "foo"].each do |thing|
265
+ @db.define_function("hello") { |a| thing }
266
+ assert_equal [thing], @db.execute("select hello('world')").first
267
+ end
268
+ end
269
+
270
+ def test_define_function_closed
271
+ @db.close
272
+ assert_raise(SQLite3::Exception) do
273
+ @db.define_function('foo') { }
274
+ end
275
+ end
276
+
277
+ def test_inerrupt_closed
278
+ @db.close
279
+ assert_raise(SQLite3::Exception) do
280
+ @db.interrupt
281
+ end
282
+ end
283
+
284
+ def test_define_aggregate
285
+ @db.execute "create table foo ( a integer primary key, b text )"
286
+ @db.execute "insert into foo ( b ) values ( 'foo' )"
287
+ @db.execute "insert into foo ( b ) values ( 'bar' )"
288
+ @db.execute "insert into foo ( b ) values ( 'baz' )"
289
+
290
+ acc = Class.new {
291
+ attr_reader :sum
292
+ alias :finalize :sum
293
+ def initialize
294
+ @sum = 0
295
+ end
296
+
297
+ def step a
298
+ @sum += a
299
+ end
300
+ }.new
301
+
302
+ @db.define_aggregator("accumulate", acc)
303
+ value = @db.get_first_value( "select accumulate(a) from foo" )
304
+ assert_equal 6, value
305
+ end
306
+
307
+ def test_authorizer_ok
308
+ @db.authorizer = Class.new {
309
+ def call action, a, b, c, d; true end
310
+ }.new
311
+ @db.prepare("select 'fooooo'")
312
+
313
+ @db.authorizer = Class.new {
314
+ def call action, a, b, c, d; 0 end
315
+ }.new
316
+ @db.prepare("select 'fooooo'")
317
+ end
318
+
319
+ def test_authorizer_ignore
320
+ @db.authorizer = Class.new {
321
+ def call action, a, b, c, d; nil end
322
+ }.new
323
+ stmt = @db.prepare("select 'fooooo'")
324
+ assert_equal nil, stmt.step
325
+ end
326
+
327
+ def test_authorizer_fail
328
+ @db.authorizer = Class.new {
329
+ def call action, a, b, c, d; false end
330
+ }.new
331
+ assert_raises(SQLite3::AuthorizationException) do
332
+ @db.prepare("select 'fooooo'")
333
+ end
334
+ end
335
+
336
+ def test_remove_auth
337
+ @db.authorizer = Class.new {
338
+ def call action, a, b, c, d; false end
339
+ }.new
340
+ assert_raises(SQLite3::AuthorizationException) do
341
+ @db.prepare("select 'fooooo'")
342
+ end
343
+
344
+ @db.authorizer = nil
345
+ @db.prepare("select 'fooooo'")
346
+ end
347
+
348
+ def test_close_with_open_statements
349
+ @db.prepare("select 'foo'")
350
+ assert_raises(SQLite3::BusyException) do
351
+ @db.close
352
+ end
353
+ end
354
+
355
+ def test_execute_with_empty_bind_params
356
+ assert_equal [['foo']], @db.execute("select 'foo'", [])
357
+ end
358
+
359
+ def test_query_with_named_bind_params
360
+ assert_equal [['foo']], @db.query("select :n", {'n' => 'foo'}).to_a
361
+ end
362
+
363
+ def test_execute_with_named_bind_params
364
+ assert_equal [['foo']], @db.execute("select :n", {'n' => 'foo'})
365
+ end
366
+ end
367
+ end