amalgalite 0.4.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/HISTORY +81 -0
- data/LICENSE +29 -0
- data/README +40 -0
- data/bin/amalgalite-pack-into-db +155 -0
- data/examples/a.rb +9 -0
- data/examples/blob.rb +105 -0
- data/examples/bootstrap.rb +36 -0
- data/examples/gem-db.rb +94 -0
- data/examples/requires.rb +54 -0
- data/examples/schema-info.rb +34 -0
- data/ext/amalgalite3.c +201 -0
- data/ext/amalgalite3.h +121 -0
- data/ext/amalgalite3_blob.c +241 -0
- data/ext/amalgalite3_constants.c +221 -0
- data/ext/amalgalite3_database.c +550 -0
- data/ext/amalgalite3_requires_bootstrap.c +210 -0
- data/ext/amalgalite3_statement.c +628 -0
- data/ext/extconf.rb +19 -0
- data/ext/gen_constants.rb +130 -0
- data/ext/rbconfig-mingw.rb +178 -0
- data/ext/sqlite3.c +97092 -0
- data/ext/sqlite3.h +6364 -0
- data/ext/sqlite3_options.h +4 -0
- data/ext/sqlite3ext.h +372 -0
- data/gemspec.rb +55 -0
- data/lib/amalgalite.rb +33 -0
- data/lib/amalgalite/blob.rb +186 -0
- data/lib/amalgalite/boolean.rb +42 -0
- data/lib/amalgalite/column.rb +86 -0
- data/lib/amalgalite/core_ext/kernel/require.rb +14 -0
- data/lib/amalgalite/database.rb +514 -0
- data/lib/amalgalite/index.rb +43 -0
- data/lib/amalgalite/paths.rb +70 -0
- data/lib/amalgalite/profile_tap.rb +130 -0
- data/lib/amalgalite/requires.rb +112 -0
- data/lib/amalgalite/schema.rb +115 -0
- data/lib/amalgalite/sqlite3.rb +6 -0
- data/lib/amalgalite/sqlite3/constants.rb +82 -0
- data/lib/amalgalite/sqlite3/database/status.rb +69 -0
- data/lib/amalgalite/sqlite3/status.rb +61 -0
- data/lib/amalgalite/sqlite3/version.rb +38 -0
- data/lib/amalgalite/statement.rb +394 -0
- data/lib/amalgalite/table.rb +36 -0
- data/lib/amalgalite/taps.rb +2 -0
- data/lib/amalgalite/taps/console.rb +27 -0
- data/lib/amalgalite/taps/io.rb +71 -0
- data/lib/amalgalite/trace_tap.rb +35 -0
- data/lib/amalgalite/type_map.rb +63 -0
- data/lib/amalgalite/type_maps/default_map.rb +167 -0
- data/lib/amalgalite/type_maps/storage_map.rb +41 -0
- data/lib/amalgalite/type_maps/text_map.rb +23 -0
- data/lib/amalgalite/version.rb +37 -0
- data/lib/amalgalite/view.rb +26 -0
- data/lib/amalgalite3.so +0 -0
- data/spec/amalgalite_spec.rb +4 -0
- data/spec/blob_spec.rb +81 -0
- data/spec/boolean_spec.rb +23 -0
- data/spec/database_spec.rb +238 -0
- data/spec/default_map_spec.rb +87 -0
- data/spec/integeration_spec.rb +111 -0
- data/spec/paths_spec.rb +28 -0
- data/spec/schema_spec.rb +60 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/sqlite3/constants_spec.rb +65 -0
- data/spec/sqlite3/database_status_spec.rb +36 -0
- data/spec/sqlite3/status_spec.rb +18 -0
- data/spec/sqlite3/version_spec.rb +14 -0
- data/spec/sqlite3_spec.rb +23 -0
- data/spec/statement_spec.rb +134 -0
- data/spec/storage_map_spec.rb +41 -0
- data/spec/tap_spec.rb +59 -0
- data/spec/text_map_spec.rb +23 -0
- data/spec/type_map_spec.rb +17 -0
- data/spec/version_spec.rb +9 -0
- data/tasks/announce.rake +39 -0
- data/tasks/config.rb +110 -0
- data/tasks/distribution.rake +53 -0
- data/tasks/documentation.rake +33 -0
- data/tasks/extension.rake +100 -0
- data/tasks/rspec.rake +32 -0
- data/tasks/rubyforge.rake +59 -0
- data/tasks/utils.rb +80 -0
- metadata +192 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
require 'date'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
7
|
+
require 'amalgalite'
|
8
|
+
|
9
|
+
describe "Integration specifications" do
|
10
|
+
before(:each) do
|
11
|
+
@schema = IO.read( SpecInfo.test_schema_file )
|
12
|
+
@iso_db_file = SpecInfo.make_iso_db
|
13
|
+
@iso_db = Amalgalite::Database.new( SpecInfo.make_iso_db )
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
|
18
|
+
@iso_db.close
|
19
|
+
File.unlink @iso_db_file if File.exist?( @iso_db_file )
|
20
|
+
end
|
21
|
+
|
22
|
+
describe " - invalid queries" do
|
23
|
+
it "raises error with an invalid syntax" do
|
24
|
+
lambda{ @iso_db.prepare "SELECT from country" }.should raise_error( ::Amalgalite::SQLite3::Error )
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises error with invalid table" do
|
28
|
+
lambda{ @iso_db.prepare "SELECT * FROM foo" }.should raise_error( ::Amalgalite::SQLite3::Error )
|
29
|
+
end
|
30
|
+
|
31
|
+
it "raises error with invalid column" do
|
32
|
+
lambda{ @iso_db.prepare "SELECT foo FROM country" }.should raise_error( ::Amalgalite::SQLite3::Error )
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe " - default types conversion" do
|
37
|
+
|
38
|
+
{
|
39
|
+
"datetime" => { :value => DateTime.now, :klass => DateTime },
|
40
|
+
"timestamp" => { :value => Time.now, :klass => Time } ,
|
41
|
+
"date" => { :value => Date.today, :klass => Date },
|
42
|
+
"integer" => { :value => 42, :klass => Fixnum } ,
|
43
|
+
"double" => { :value => 3.14, :klass => Float },
|
44
|
+
"varchar" => { :value => "foobarbaz", :klass => String },
|
45
|
+
"boolean" => { :value => true, :klass => TrueClass },
|
46
|
+
"varchar(2)"=> { :value => nil, :klass => NilClass }
|
47
|
+
}.each_pair do |sql_type, ruby_info|
|
48
|
+
it "converts a ruby obj (#{ruby_info[:value].to_s}) of #{ruby_info[:klass]} to an SQL type of #{sql_type} and back again " do
|
49
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
50
|
+
db.execute "CREATE TABLE t( c #{sql_type} )"
|
51
|
+
db.execute "insert into t (c) values ( ? )", ruby_info[:value]
|
52
|
+
rows = db.execute "select * from t"
|
53
|
+
rows.first['c'].class.should == ruby_info[:klass]
|
54
|
+
|
55
|
+
if [ DateTime, Time ].include?( ruby_info[:klass] ) then
|
56
|
+
rows.first['c'].strftime("%Y-%m-%d %H:%M:%S").should == ruby_info[:value].strftime("%Y-%m-%d %H:%M:%S")
|
57
|
+
else
|
58
|
+
rows.first['c'].should == ruby_info[:value]
|
59
|
+
end
|
60
|
+
db.close
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe " - storage type conversion" do
|
66
|
+
{
|
67
|
+
"datetime" => { :value => DateTime.now, :result => DateTime.now.strftime("%Y-%m-%dT%H:%M:%S%Z") } ,
|
68
|
+
"timestamp" => { :value => Time.now, :result => Time.now.to_s },
|
69
|
+
"date" => { :value => Date.today, :result => Date.today.to_s },
|
70
|
+
"integer" => { :value => 42, :result => 42 } ,
|
71
|
+
"double" => { :value => 3.14, :result => 3.14 } ,
|
72
|
+
"varchar" => { :value => "foobarbaz", :result => "foobarbaz" },
|
73
|
+
"boolean" => { :value => true, :result => "true" },
|
74
|
+
"varchar(2)"=> { :value => nil, :result => nil }
|
75
|
+
}.each_pair do |sql_type, ruby_info|
|
76
|
+
it "converts a ruby obj (#{ruby_info[:value].to_s}) of class #{ruby_info[:value].class.name} to an SQL type of #{sql_type} and back to a storage type" do
|
77
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
78
|
+
db.type_map = Amalgalite::TypeMaps::StorageMap.new
|
79
|
+
db.execute "CREATE TABLE t( c #{sql_type} )"
|
80
|
+
db.execute "insert into t (c) values ( ? )", ruby_info[:value]
|
81
|
+
rows = db.execute "select * from t"
|
82
|
+
rows.first['c'].should == ruby_info[:result]
|
83
|
+
db.close
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe " - text type conversion" do
|
89
|
+
{
|
90
|
+
"datetime" => { :value => DateTime.now, :result => DateTime.now.strftime("%Y-%m-%dT%H:%M:%S%Z") } ,
|
91
|
+
"timestamp" => { :value => Time.now, :result => Time.now.to_s },
|
92
|
+
"date" => { :value => Date.today, :result => Date.today.to_s },
|
93
|
+
"integer" => { :value => 42, :result => "42" } ,
|
94
|
+
"double" => { :value => 3.14, :result => "3.14" } ,
|
95
|
+
"varchar" => { :value => "foobarbaz", :result => "foobarbaz" },
|
96
|
+
"boolean" => { :value => true, :result => "true" },
|
97
|
+
"varchar(2)"=> { :value => nil, :result => "" }
|
98
|
+
}.each_pair do |sql_type, ruby_info|
|
99
|
+
it "converts a ruby obj (#{ruby_info[:value].to_s}) of class #{ruby_info[:value].class.name} to an SQL type of #{sql_type} and back to text" do
|
100
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
101
|
+
db.type_map = Amalgalite::TypeMaps::TextMap.new
|
102
|
+
db.execute "CREATE TABLE t( c #{sql_type} )"
|
103
|
+
db.execute "insert into t (c) values ( ? )", ruby_info[:value]
|
104
|
+
rows = db.execute "select * from t"
|
105
|
+
rows.first['c'].should == ruby_info[:result]
|
106
|
+
db.close
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
data/spec/paths_spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
|
2
|
+
|
3
|
+
describe Amalgalite::Paths do
|
4
|
+
before(:each) do
|
5
|
+
@root_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
6
|
+
@root_dir += "/"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "root dir should be correct" do
|
10
|
+
Amalgalite::Paths.root_dir.should == @root_dir
|
11
|
+
end
|
12
|
+
|
13
|
+
it "config_path should be correct" do
|
14
|
+
Amalgalite::Paths.config_path.should == File.join(@root_dir, "config/")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "data path should be correct" do
|
18
|
+
Amalgalite::Paths.data_path.should == File.join(@root_dir, "data/")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "lib path should be correct" do
|
22
|
+
Amalgalite::Paths.lib_path.should == File.join(@root_dir, "lib/")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "ext path should be correct" do
|
26
|
+
Amalgalite::Paths.ext_path.should == File.join(@root_dir, "ext/")
|
27
|
+
end
|
28
|
+
end
|
data/spec/schema_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
5
|
+
require 'amalgalite'
|
6
|
+
require 'amalgalite/schema'
|
7
|
+
|
8
|
+
describe Amalgalite::Schema do
|
9
|
+
before(:each) do
|
10
|
+
@schema = IO.read( SpecInfo.test_schema_file )
|
11
|
+
@iso_db_file = SpecInfo.make_iso_db
|
12
|
+
@iso_db = Amalgalite::Database.new( SpecInfo.make_iso_db )
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
|
17
|
+
@iso_db.close
|
18
|
+
File.unlink @iso_db_file if File.exist?( @iso_db_file )
|
19
|
+
end
|
20
|
+
|
21
|
+
it "loads the schema of a database" do
|
22
|
+
schema = @iso_db.schema
|
23
|
+
schema.tables.size.should == 2
|
24
|
+
end
|
25
|
+
|
26
|
+
it "loads the views in the database" do
|
27
|
+
sql = "CREATE VIEW v1 AS SELECT c.name, c.two_letter, s.name, s.subdivision FROM country AS c JOIN subcountry AS s ON c.two_letter = s.country"
|
28
|
+
@iso_db.execute( sql )
|
29
|
+
@iso_db.schema.views.size.should == 1
|
30
|
+
@iso_db.schema.views["v1"].sql.should == sql
|
31
|
+
end
|
32
|
+
|
33
|
+
it "loads the tables and columns" do
|
34
|
+
@iso_db.schema.tables.size.should == 2
|
35
|
+
ct = @iso_db.schema.tables['country']
|
36
|
+
ct.name.should == "country"
|
37
|
+
ct.columns.size.should == 3
|
38
|
+
ct.indexes.size.should == 2
|
39
|
+
|
40
|
+
ct.columns['two_letter'].should be_primary_key
|
41
|
+
ct.columns['name'].should_not be_nullable
|
42
|
+
ct.columns['name'].should be_not_null_constraint
|
43
|
+
ct.columns['name'].should_not be_has_default_value
|
44
|
+
ct.columns['id'].should_not be_auto_increment
|
45
|
+
end
|
46
|
+
|
47
|
+
it "loads the indexes" do
|
48
|
+
c = @iso_db.schema.tables['country']
|
49
|
+
c.indexes.size.should == 2
|
50
|
+
c.indexes['country_name'].columns.size.should == 1
|
51
|
+
c.indexes['country_name'].should_not be_unique
|
52
|
+
c.indexes['country_name'].sequence_number.should == 0
|
53
|
+
c.indexes['country_name'].columns.first.should == @iso_db.schema.tables['country'].columns['name']
|
54
|
+
c.indexes['sqlite_autoindex_country_1'].should be_unique
|
55
|
+
|
56
|
+
subc = @iso_db.schema.tables['subcountry']
|
57
|
+
subc.indexes.size.should == 3
|
58
|
+
subc.indexes['subcountry_country'].columns.first.should == @iso_db.schema.tables['subcountry'].columns['country']
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
5
|
+
require 'amalgalite'
|
6
|
+
|
7
|
+
class SpecInfo
|
8
|
+
class << self
|
9
|
+
def test_db
|
10
|
+
@test_db ||= File.expand_path(File.join(File.dirname(__FILE__), "test.db"))
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_schema_file
|
14
|
+
@test_schema_file ||= File.expand_path(File.join(File.dirname(__FILE__),"iso-3166-schema.sql"))
|
15
|
+
end
|
16
|
+
|
17
|
+
def make_iso_db
|
18
|
+
@iso_db ||= File.expand_path(File.join(File.dirname(__FILE__), "iso-3166.db"))
|
19
|
+
@new_is_db = File.expand_path(File.join(File.dirname(__FILE__), "iso-3166-testing.db"))
|
20
|
+
FileUtils.cp @iso_db, @new_is_db
|
21
|
+
return @new_is_db
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),%w[ .. spec_helper.rb ]))
|
2
|
+
|
3
|
+
require 'amalgalite/sqlite3/constants'
|
4
|
+
|
5
|
+
describe Amalgalite::SQLite3::Constants do
|
6
|
+
|
7
|
+
it "has Open constants" do
|
8
|
+
Amalgalite::SQLite3::Constants::Open::READONLY.should > 0
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has DataType constants" do
|
12
|
+
Amalgalite::SQLite3::Constants::DataType::BLOB.should > 0
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has ResultCode constants" do
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'ResultCode' do
|
19
|
+
it "has constants" do
|
20
|
+
Amalgalite::SQLite3::Constants::ResultCode::OK.should == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can return the constant from a number" do
|
24
|
+
c = Amalgalite::SQLite3::Constants::ResultCode.name_from_value( 21 )
|
25
|
+
c.should == "MISUSE"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can return the number from a name" do
|
29
|
+
v = Amalgalite::SQLite3::Constants::ResultCode.value_from_name( "MISUSE" )
|
30
|
+
v.should == 21
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'Status' do
|
35
|
+
it "has constants" do
|
36
|
+
Amalgalite::SQLite3::Constants::Status::MEMORY_USED.should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can return the constant from a number" do
|
40
|
+
c = Amalgalite::SQLite3::Constants::Status.name_from_value( 3 )
|
41
|
+
c.should == "SCRATCH_USED"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can return the number from a name" do
|
45
|
+
v = Amalgalite::SQLite3::Constants::Status.value_from_name( "memory_used" )
|
46
|
+
v.should == 0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'DBStatus' do
|
51
|
+
it "has constants" do
|
52
|
+
Amalgalite::SQLite3::Constants::DBStatus::LOOKASIDE_USED.should == 0
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can return the constant from a number" do
|
56
|
+
c = Amalgalite::SQLite3::Constants::DBStatus.name_from_value( 0 )
|
57
|
+
c.should == "LOOKASIDE_USED"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can return the number from a name" do
|
61
|
+
v = Amalgalite::SQLite3::Constants::DBStatus.value_from_name( "lookaside_used" )
|
62
|
+
v.should == 0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper.rb"))
|
2
|
+
require 'amalgalite/sqlite3'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
describe "Amalgalite::SQLite3::Database::Status" do
|
6
|
+
before(:each) do
|
7
|
+
@db = Amalgalite::Database.new( "lookaside-test.db" )
|
8
|
+
@db.execute(" create table t(a, b)")
|
9
|
+
20.times do |x|
|
10
|
+
@db.execute("insert into t(a, b) values (?,?);", x, x+1)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:each) do
|
15
|
+
@db.close
|
16
|
+
FileUtils.rm_f "lookaside-test.db"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
it "knows how much lookaside memory it has used" do
|
21
|
+
@db.api.status.lookaside_used.highwater.should > 0
|
22
|
+
@db.api.status.lookaside_used.current.should >= 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can reset the highwater value" do
|
26
|
+
stat = @db.api.status.lookaside_used
|
27
|
+
before = stat.highwater
|
28
|
+
before.should > 0
|
29
|
+
|
30
|
+
stat.reset!
|
31
|
+
after = stat.highwater
|
32
|
+
|
33
|
+
after.should == 0
|
34
|
+
after.should_not == before
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper.rb"))
|
2
|
+
require 'amalgalite/sqlite3'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
describe "Amalgalite::SQLite3::Status" do
|
6
|
+
it "knows how much memory it has used" do
|
7
|
+
Amalgalite::SQLite3.status.memory_used.current.should >= 0
|
8
|
+
Amalgalite::SQLite3.status.memory_used.highwater.should >= 0
|
9
|
+
end
|
10
|
+
|
11
|
+
it "can reset the highwater value" do
|
12
|
+
before = Amalgalite::SQLite3.status.memory_used.highwater
|
13
|
+
Amalgalite::SQLite3.status.memory_used.reset!
|
14
|
+
Amalgalite::SQLite3.status.memory_used.highwater.should > 0
|
15
|
+
after = Amalgalite::SQLite3.status.memory_used.highwater
|
16
|
+
after.should_not == before
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),"..","spec_helper.rb"))
|
2
|
+
require 'amalgalite/sqlite3/version'
|
3
|
+
|
4
|
+
describe "Amalgalite::SQLite3::Version" do
|
5
|
+
it "should have the sqlite3 version" do
|
6
|
+
Amalgalite::SQLite3::VERSION.should =~ /\d\.\d\.\d/
|
7
|
+
Amalgalite::SQLite3::Version.to_s.should =~ /\d\.\d\.\d/
|
8
|
+
Amalgalite::SQLite3::Version.to_i.should == 3006003
|
9
|
+
Amalgalite::SQLite3::Version::MAJOR.should == 3
|
10
|
+
Amalgalite::SQLite3::Version::MINOR.should == 6
|
11
|
+
Amalgalite::SQLite3::Version::RELEASE.should == 3
|
12
|
+
Amalgalite::SQLite3::Version.to_a.should have(3).items
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
|
2
|
+
require 'amalgalite/sqlite3'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
describe "Amalgalite::SQLite3" do
|
6
|
+
it "is threadsafe is ruby is compiled with pthread support, in this case that is (#{Config::CONFIG['configure_args'].include?( "--enable-pthread" )})" do
|
7
|
+
Amalgalite::SQLite3.threadsafe?.should == Config::CONFIG['configure_args'].include?( "--enable-pthread" )
|
8
|
+
end
|
9
|
+
|
10
|
+
it "knows if an SQL statement is complete" do
|
11
|
+
Amalgalite::SQLite3.complete?("SELECT * FROM sometable;").should == true
|
12
|
+
Amalgalite::SQLite3.complete?("SELECT * FROM sometable;", :utf16 => true).should == true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "knows if an SQL statement is not complete" do
|
16
|
+
Amalgalite::SQLite3.complete?("SELECT * FROM sometable ").should == false
|
17
|
+
Amalgalite::SQLite3.complete?("SELECT * FROM sometable WHERE ", :utf16 => true).should == false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can produce random data" do
|
21
|
+
Amalgalite::SQLite3.randomness( 42 ).size.should == 42
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
5
|
+
require 'amalgalite'
|
6
|
+
|
7
|
+
describe Amalgalite::Statement do
|
8
|
+
before(:each) do
|
9
|
+
@db = Amalgalite::Database.new( SpecInfo.test_db )
|
10
|
+
@schema_sql = IO.read( SpecInfo.test_schema_file )
|
11
|
+
@iso_db_file = SpecInfo.make_iso_db
|
12
|
+
@iso_db = Amalgalite::Database.new( SpecInfo.make_iso_db )
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
@db.close
|
17
|
+
File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
|
18
|
+
|
19
|
+
@iso_db.close
|
20
|
+
File.unlink @iso_db_file if File.exist?( @iso_db_file )
|
21
|
+
end
|
22
|
+
|
23
|
+
it "a statement has a copy of the sql it was prepared with" do
|
24
|
+
stmt = @db.prepare( "SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
|
25
|
+
stmt.sql.should == "SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')"
|
26
|
+
stmt.close
|
27
|
+
end
|
28
|
+
|
29
|
+
it "steps through results" do
|
30
|
+
now = Time.new.utc.strftime("%Y-%m-%d %H:%M")
|
31
|
+
@db.prepare( "SELECT strftime('%Y-%m-%d %H:%M', 'now') as now") do |stmt|
|
32
|
+
stmt.should_not == nil
|
33
|
+
stmt.each do |row|
|
34
|
+
row['now'].should == now
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can prepare a statement without a block" do
|
40
|
+
stmt = @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two")
|
41
|
+
rs = stmt.execute( ":two" => "JP" )
|
42
|
+
rs.size.should == 1
|
43
|
+
stmt.close
|
44
|
+
end
|
45
|
+
|
46
|
+
it "knows how many parameters are in the statement" do
|
47
|
+
@iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
|
48
|
+
stmt.check_parameter_count!( 1 ).should == 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "raises an error if there are not enough parameters are passed in a statement" do
|
53
|
+
@iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
|
54
|
+
lambda{ stmt.execute }.should raise_error( Amalgalite::Error )
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
it "can run a query with a named parameter" do
|
60
|
+
@iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
|
61
|
+
all_rows = stmt.execute( ":two" => "JP" )
|
62
|
+
all_rows.size.should == 1
|
63
|
+
all_rows.first['name'].should == "Japan"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "it can execute a query with a named parameter and yield the rows" do
|
68
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = @id ORDER BY name") do |stmt|
|
69
|
+
rows = []
|
70
|
+
stmt.execute( "@id" => 891 ) do |row|
|
71
|
+
rows << row
|
72
|
+
end
|
73
|
+
rows.size.should == 2
|
74
|
+
rows.last['name'].should == "Yugoslavia"
|
75
|
+
rows.first['two_letter'].should == "CS"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "can execute the same prepared statement multiple times" do
|
80
|
+
@db.execute(" CREATE TABLE t(x,y); ")
|
81
|
+
values = {}
|
82
|
+
@db.prepare("INSERT INTO t( x, y ) VALUES( $x, $y )" ) do |stmt|
|
83
|
+
20.times do |x|
|
84
|
+
y = rand( x )
|
85
|
+
stmt.execute( { "$x" => x, "$y" => y } )
|
86
|
+
values[x] = y
|
87
|
+
end
|
88
|
+
end
|
89
|
+
c = 0
|
90
|
+
@db.execute("SELECT * from t") do |row|
|
91
|
+
c += 1
|
92
|
+
values[ row['x'] ].should == row['y']
|
93
|
+
end
|
94
|
+
c.should == 20
|
95
|
+
end
|
96
|
+
|
97
|
+
it "binds a integer variable correctly" do
|
98
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
|
99
|
+
all_rows = stmt.execute( 891 )
|
100
|
+
all_rows.size.should == 2
|
101
|
+
all_rows.last['name'].should == "Yugoslavia"
|
102
|
+
all_rows.first['two_letter'].should == "CS"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "raises and error if an invaliding binding is attempted" do
|
107
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ") do |stmt|
|
108
|
+
lambda{ stmt.execute( "blah" => 42 ) }.should raise_error(Amalgalite::Error)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it "can reset the statement to the state it was before executing" do
|
113
|
+
stmt = @iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ")
|
114
|
+
stmt.reset_and_clear_bindings!
|
115
|
+
stmt.close
|
116
|
+
end
|
117
|
+
|
118
|
+
it "can execute a single sql command and say if there is remaining sql to execute" do
|
119
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
120
|
+
stmt = @db.prepare( @schema_sql )
|
121
|
+
stmt.execute
|
122
|
+
stmt.remaining_sql.size.should > 0
|
123
|
+
stmt.close
|
124
|
+
end
|
125
|
+
|
126
|
+
it "has index based access to the result set" do
|
127
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
|
128
|
+
all_rows = stmt.execute( 891 )
|
129
|
+
all_rows.size.should == 2
|
130
|
+
all_rows.last.first.should == "Yugoslavia"
|
131
|
+
all_rows.first[1].should == "CS"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|