amalgalite 0.10.1-x86-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/HISTORY +201 -0
- data/LICENSE +29 -0
- data/README +51 -0
- data/bin/amalgalite-pack +126 -0
- data/examples/a.rb +9 -0
- data/examples/blob.rb +88 -0
- data/examples/bootstrap.rb +36 -0
- data/examples/define_aggregate.rb +75 -0
- data/examples/define_function.rb +104 -0
- data/examples/gem-db.rb +94 -0
- data/examples/gems.db +0 -0
- data/examples/require_me.rb +11 -0
- data/examples/requires.rb +42 -0
- data/examples/schema-info.rb +34 -0
- data/ext/amalgalite/amalgalite3.c +290 -0
- data/ext/amalgalite/amalgalite3.h +151 -0
- data/ext/amalgalite/amalgalite3_blob.c +240 -0
- data/ext/amalgalite/amalgalite3_constants.c +221 -0
- data/ext/amalgalite/amalgalite3_database.c +1148 -0
- data/ext/amalgalite/amalgalite3_requires_bootstrap.c +210 -0
- data/ext/amalgalite/amalgalite3_statement.c +639 -0
- data/ext/amalgalite/extconf.rb +36 -0
- data/ext/amalgalite/gen_constants.rb +130 -0
- data/ext/amalgalite/sqlite3.c +106729 -0
- data/ext/amalgalite/sqlite3.h +5626 -0
- data/ext/amalgalite/sqlite3_options.h +4 -0
- data/ext/amalgalite/sqlite3ext.h +380 -0
- data/gemspec.rb +60 -0
- data/lib/amalgalite.rb +43 -0
- data/lib/amalgalite/1.8/amalgalite3.so +0 -0
- data/lib/amalgalite/1.9/amalgalite3.so +0 -0
- data/lib/amalgalite/aggregate.rb +67 -0
- data/lib/amalgalite/blob.rb +186 -0
- data/lib/amalgalite/boolean.rb +42 -0
- data/lib/amalgalite/busy_timeout.rb +47 -0
- data/lib/amalgalite/column.rb +97 -0
- data/lib/amalgalite/core_ext/kernel/require.rb +21 -0
- data/lib/amalgalite/database.rb +947 -0
- data/lib/amalgalite/function.rb +61 -0
- data/lib/amalgalite/index.rb +43 -0
- data/lib/amalgalite/packer.rb +226 -0
- data/lib/amalgalite/paths.rb +70 -0
- data/lib/amalgalite/profile_tap.rb +131 -0
- data/lib/amalgalite/progress_handler.rb +21 -0
- data/lib/amalgalite/requires.rb +120 -0
- data/lib/amalgalite/schema.rb +191 -0
- data/lib/amalgalite/sqlite3.rb +6 -0
- data/lib/amalgalite/sqlite3/constants.rb +80 -0
- data/lib/amalgalite/sqlite3/database/function.rb +48 -0
- data/lib/amalgalite/sqlite3/database/status.rb +68 -0
- data/lib/amalgalite/sqlite3/status.rb +60 -0
- data/lib/amalgalite/sqlite3/version.rb +37 -0
- data/lib/amalgalite/statement.rb +414 -0
- data/lib/amalgalite/table.rb +90 -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 +40 -0
- data/lib/amalgalite/type_maps/text_map.rb +22 -0
- data/lib/amalgalite/version.rb +37 -0
- data/lib/amalgalite/view.rb +26 -0
- data/spec/aggregate_spec.rb +169 -0
- data/spec/amalgalite_spec.rb +4 -0
- data/spec/blob_spec.rb +81 -0
- data/spec/boolean_spec.rb +23 -0
- data/spec/busy_handler.rb +165 -0
- data/spec/database_spec.rb +494 -0
- data/spec/default_map_spec.rb +87 -0
- data/spec/function_spec.rb +94 -0
- data/spec/integeration_spec.rb +111 -0
- data/spec/packer_spec.rb +60 -0
- data/spec/paths_spec.rb +28 -0
- data/spec/progress_handler_spec.rb +105 -0
- data/spec/requires_spec.rb +23 -0
- data/spec/rtree_spec.rb +71 -0
- data/spec/schema_spec.rb +120 -0
- data/spec/spec_helper.rb +27 -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 +53 -0
- data/spec/statement_spec.rb +161 -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 +15 -0
- data/tasks/announce.rake +43 -0
- data/tasks/config.rb +107 -0
- data/tasks/distribution.rake +77 -0
- data/tasks/documentation.rake +32 -0
- data/tasks/extension.rake +141 -0
- data/tasks/rspec.rake +33 -0
- data/tasks/rubyforge.rake +59 -0
- data/tasks/utils.rb +80 -0
- metadata +237 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
5
|
+
#require 'amalgalite/requires'
|
6
|
+
|
7
|
+
#describe Amalgalite::Requires do
|
8
|
+
# it "#require_order has all files in 'lib' and no more" do
|
9
|
+
# dir_files = Dir.glob( File.join( Amalgalite::Paths.lib_path , "**", "*.rb" ) )
|
10
|
+
# require_files = Amalgalite::Requires.require_order.collect { |r| Amalgalite::Paths.lib_path r }
|
11
|
+
# dir_files.size.should == require_files.size
|
12
|
+
# (dir_files - require_files).size.should == 0
|
13
|
+
# (require_files - dir_files).size.should == 0
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# it "can compress and uncompress data" do
|
17
|
+
# s = IO.read( __FILE__ )
|
18
|
+
# s_gz = Amalgalite::Requires.gzip( s )
|
19
|
+
# s.should == Amalgalite::Requires.gunzip( s_gz )
|
20
|
+
# end
|
21
|
+
#end
|
22
|
+
|
23
|
+
|
data/spec/rtree_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
require File.expand_path( File.join( File.dirname(__FILE__), 'spec_helper'))
|
4
|
+
|
5
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
6
|
+
require 'amalgalite'
|
7
|
+
require 'amalgalite/database'
|
8
|
+
|
9
|
+
# Example from http://sqlite.org/rtree.html
|
10
|
+
#
|
11
|
+
describe "SQLite3 R*Tree extension" do
|
12
|
+
before( :each ) do
|
13
|
+
@db = Amalgalite::Database.new( ":memory:" )
|
14
|
+
x = @db.execute_batch <<-sql
|
15
|
+
CREATE VIRTUAL TABLE demo_index USING rtree(
|
16
|
+
id, -- Integer primary key
|
17
|
+
minX, maxX, -- Minimum and maximum X coordinate
|
18
|
+
minY, maxY -- Minimum and maximum Y coordinate
|
19
|
+
);
|
20
|
+
--
|
21
|
+
INSERT INTO demo_index VALUES(
|
22
|
+
1, -- Primary key
|
23
|
+
-80.7749, -80.7747, -- Longitude range
|
24
|
+
30.3776, 30.3778 -- Latitude range
|
25
|
+
);
|
26
|
+
INSERT INTO demo_index VALUES(
|
27
|
+
2,
|
28
|
+
-81.0, -79.6,
|
29
|
+
35.0, 36.2
|
30
|
+
);
|
31
|
+
sql
|
32
|
+
x.should == 3
|
33
|
+
end
|
34
|
+
|
35
|
+
after( :each ) do
|
36
|
+
@db.close
|
37
|
+
end
|
38
|
+
|
39
|
+
it "has 2 rows" do
|
40
|
+
r = @db.first_value_from( "SELECT count(*) FROM demo_index")
|
41
|
+
r.should == 2
|
42
|
+
end
|
43
|
+
|
44
|
+
it "queries normally" do
|
45
|
+
r = @db.execute "SELECT * FROM demo_index WHERE id=1;"
|
46
|
+
r.size.should == 1
|
47
|
+
row = r.first
|
48
|
+
row['id'].should == 1
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does a 'contained within' query" do
|
52
|
+
r = @db.execute <<-sql
|
53
|
+
SELECT id FROM demo_index
|
54
|
+
WHERE minX>=-81.08 AND maxX<=-80.58
|
55
|
+
AND minY>=30.00 AND maxY<=30.44;
|
56
|
+
sql
|
57
|
+
|
58
|
+
r.size.should == 1
|
59
|
+
r.first['id'].should == 1
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does an 'overlapping' query" do
|
63
|
+
r = @db.execute <<-sql
|
64
|
+
SELECT id FROM demo_index
|
65
|
+
WHERE maxX>=-81.08 AND minX<=-80.58
|
66
|
+
AND maxY>=30.00 AND minY<=35.44;
|
67
|
+
sql
|
68
|
+
r.size.should == 2
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
data/spec/schema_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
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.load_tables
|
24
|
+
schema.tables.size.should eql(2)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "lazily loads new table schema" do
|
28
|
+
@iso_db.schema.tables.size.should eql(2)
|
29
|
+
sql = "CREATE TABLE t1 ( a, b, c )"
|
30
|
+
@iso_db.execute( sql )
|
31
|
+
@iso_db.schema.tables.size.should eql(2)
|
32
|
+
@iso_db.schema.dirty!
|
33
|
+
@iso_db.schema.tables['t1'].column_names.should eql(%w[ a b c ])
|
34
|
+
@iso_db.schema.tables.size.should eql(3)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "loads the views in the database" do
|
38
|
+
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"
|
39
|
+
@iso_db.execute( sql )
|
40
|
+
@iso_db.schema.load_views
|
41
|
+
@iso_db.schema.views.size.should eql(1)
|
42
|
+
@iso_db.schema.views["v1"].sql.should eql(sql)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "removes quotes from around default values in columns" do
|
46
|
+
sql = "CREATE TABLE t1( d1 default 't' )"
|
47
|
+
@iso_db.execute( sql )
|
48
|
+
@iso_db.schema.dirty!
|
49
|
+
tt = @iso_db.schema.tables['t1']
|
50
|
+
tt.columns['d1'].default_value.should == "t"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "loads the tables and columns" do
|
54
|
+
ct = @iso_db.schema.tables['country']
|
55
|
+
ct.name.should eql("country")
|
56
|
+
ct.columns.size.should eql(3)
|
57
|
+
ct.indexes.size.should eql(2)
|
58
|
+
ct.column_names.should eql(%w[ name two_letter id ])
|
59
|
+
@iso_db.schema.tables.size.should eql(2)
|
60
|
+
|
61
|
+
|
62
|
+
ct.columns['two_letter'].should be_primary_key
|
63
|
+
ct.columns['two_letter'].declared_data_type.should eql("TEXT")
|
64
|
+
ct.columns['name'].should_not be_nullable
|
65
|
+
ct.columns['name'].should be_not_null_constraint
|
66
|
+
ct.columns['name'].should_not be_has_default_value
|
67
|
+
ct.columns['id'].should_not be_auto_increment
|
68
|
+
end
|
69
|
+
|
70
|
+
it "knows what the primary key of a table is" do
|
71
|
+
ct = @iso_db.schema.tables['country']
|
72
|
+
ct.primary_key.should == [ ct.columns['two_letter'] ]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "knows the primary key of a table even without an explicity unique index" do
|
76
|
+
sql = "CREATE TABLE u( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , other text )"
|
77
|
+
@iso_db.execute( sql )
|
78
|
+
@iso_db.schema.dirty!
|
79
|
+
ut = @iso_db.schema.tables['u']
|
80
|
+
ut.primary_key.should == [ ut.columns['id'] ]
|
81
|
+
end
|
82
|
+
|
83
|
+
it "knows the primary key of a temporary table" do
|
84
|
+
@iso_db.execute "CREATE TEMPORARY TABLE tt( a, b INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, c )"
|
85
|
+
@iso_db.schema.dirty!
|
86
|
+
tt = @iso_db.schema.load_table( 'tt' )
|
87
|
+
tt.primary_key.should == [ tt.columns['b'] ]
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
it "knows what the primary key of a table is when it is a multiple column primary key" do
|
92
|
+
sql = "CREATE TABLE m ( id1, id2, PRIMARY KEY (id2, id1) )"
|
93
|
+
@iso_db.execute( sql )
|
94
|
+
@iso_db.schema.dirty!
|
95
|
+
mt = @iso_db.schema.tables['m']
|
96
|
+
mt.primary_key.should == [ mt.columns['id2'], mt.columns['id1'] ]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "loads the indexes" do
|
100
|
+
c = @iso_db.schema.tables['country']
|
101
|
+
c.indexes.size.should eql(2)
|
102
|
+
c.indexes['country_name'].columns.size.should eql(1)
|
103
|
+
c.indexes['country_name'].should_not be_unique
|
104
|
+
c.indexes['country_name'].sequence_number.should eql(0)
|
105
|
+
c.indexes['country_name'].columns.first.should eql(@iso_db.schema.tables['country'].columns['name'])
|
106
|
+
c.indexes['sqlite_autoindex_country_1'].should be_unique
|
107
|
+
|
108
|
+
subc = @iso_db.schema.tables['subcountry']
|
109
|
+
subc.indexes.size.should eql(3)
|
110
|
+
subc.indexes['subcountry_country'].columns.first.should eql(@iso_db.schema.tables['subcountry'].columns['country'])
|
111
|
+
end
|
112
|
+
|
113
|
+
it "can load the schema of a temporary table" do
|
114
|
+
@iso_db.execute "CREATE TEMPORARY TABLE tt( a, b, c )"
|
115
|
+
@iso_db.schema.dirty!
|
116
|
+
@iso_db.schema.tables['tt'].should be_nil
|
117
|
+
@iso_db.schema.load_table('tt').should_not be_nil
|
118
|
+
@iso_db.schema.tables['tt'].should be_temporary
|
119
|
+
end
|
120
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
|
5
|
+
|
6
|
+
require 'amalgalite'
|
7
|
+
|
8
|
+
class SpecInfo
|
9
|
+
class << self
|
10
|
+
def test_db
|
11
|
+
@test_db ||= File.expand_path(File.join(File.dirname(__FILE__), "test.db"))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_schema_file
|
15
|
+
@test_schema_file ||= File.expand_path(File.join(File.dirname(__FILE__),"iso-3166-schema.sql"))
|
16
|
+
end
|
17
|
+
|
18
|
+
def make_iso_db
|
19
|
+
@iso_db ||= File.expand_path(File.join(File.dirname(__FILE__), "iso-3166.db"))
|
20
|
+
@new_is_db = File.expand_path(File.join(File.dirname(__FILE__), "iso-3166-testing.db"))
|
21
|
+
FileUtils.cp @iso_db, @new_is_db
|
22
|
+
return @new_is_db
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -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 eql(0)
|
34
|
+
after.should_not eql(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 eql(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 eql(3006016)
|
9
|
+
Amalgalite::SQLite3::Version::MAJOR.should eql(3)
|
10
|
+
Amalgalite::SQLite3::Version::MINOR.should eql(6)
|
11
|
+
Amalgalite::SQLite3::Version::RELEASE.should eql(16)
|
12
|
+
Amalgalite::SQLite3::Version.to_a.should have(3).items
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,53 @@
|
|
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 eql(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 eql(true)
|
12
|
+
#Amalgalite::SQLite3.complete?("SELECT * FROM sometable;", :utf16 => true).should eql(true)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "knows if an SQL statement is not complete" do
|
16
|
+
Amalgalite::SQLite3.complete?("SELECT * FROM sometable ").should eql(false)
|
17
|
+
#Amalgalite::SQLite3.complete?("SELECT * FROM sometable WHERE ", :utf16 => true).should eql(false)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can produce random data" do
|
21
|
+
Amalgalite::SQLite3.randomness( 42 ).size.should eql(42)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has nil for the default sqlite temporary directory" do
|
25
|
+
Amalgalite::SQLite3.temp_directory.should eql(nil)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can set the temporary directory" do
|
29
|
+
Amalgalite::SQLite3.temp_directory.should eql(nil)
|
30
|
+
Amalgalite::SQLite3.temp_directory = "/tmp/testing"
|
31
|
+
Amalgalite::SQLite3.temp_directory.should eql("/tmp/testing")
|
32
|
+
Amalgalite::SQLite3.temp_directory = nil
|
33
|
+
Amalgalite::SQLite3.temp_directory.should eql(nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can escape quoted strings" do
|
37
|
+
Amalgalite::SQLite3.escape( "It's a happy day!" ).should eql("It''s a happy day!")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can escape a symble into a string" do
|
41
|
+
Amalgalite::SQLite3.escape( :stuff ).should eql("stuff")
|
42
|
+
Amalgalite::SQLite3.escape( :"stuff'n" ).should eql("stuff''n")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can quote and escape single quoted strings" do
|
46
|
+
Amalgalite::SQLite3.quote( "It's a happy day!" ).should eql("'It''s a happy day!'")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can quote and escape symbols" do
|
50
|
+
Amalgalite::SQLite3.quote( :stuff ).should eql("'stuff'")
|
51
|
+
Amalgalite::SQLite3.quote( :"stuff'n" ).should eql("'stuff''n'")
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
|
5
|
+
|
6
|
+
require 'amalgalite'
|
7
|
+
|
8
|
+
describe Amalgalite::Statement do
|
9
|
+
before(:each) do
|
10
|
+
@db = Amalgalite::Database.new( SpecInfo.test_db )
|
11
|
+
@schema_sql = 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
|
+
@db.close
|
18
|
+
File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
|
19
|
+
|
20
|
+
@iso_db.close
|
21
|
+
File.unlink @iso_db_file if File.exist?( @iso_db_file )
|
22
|
+
end
|
23
|
+
|
24
|
+
it "a statement has a copy of the sql it was prepared with" do
|
25
|
+
stmt = @db.prepare( "SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
|
26
|
+
stmt.sql.should eql("SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
|
27
|
+
stmt.close
|
28
|
+
end
|
29
|
+
|
30
|
+
it "steps through results" do
|
31
|
+
now = Time.new.utc.strftime("%Y-%m-%d %H:%M")
|
32
|
+
@db.prepare( "SELECT strftime('%Y-%m-%d %H:%M', 'now') as now") do |stmt|
|
33
|
+
stmt.should_not eql(nil)
|
34
|
+
stmt.each do |row|
|
35
|
+
row['now'].should eql(now)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can prepare a statement without a block" do
|
41
|
+
stmt = @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two")
|
42
|
+
rs = stmt.execute( ":two" => "JP" )
|
43
|
+
rs.size.should eql(1)
|
44
|
+
stmt.close
|
45
|
+
end
|
46
|
+
|
47
|
+
it "knows how many parameters are in the statement" do
|
48
|
+
@iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
|
49
|
+
stmt.check_parameter_count!( 1 ).should eql(1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "raises an error if there are not enough parameters are passed in a statement" do
|
54
|
+
@iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
|
55
|
+
lambda{ stmt.execute }.should raise_error( Amalgalite::Error )
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
it "can run a query with a named parameter" do
|
61
|
+
@iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
|
62
|
+
all_rows = stmt.execute( ":two" => "JP" )
|
63
|
+
all_rows.size.should eql(1)
|
64
|
+
all_rows.first['name'].should eql("Japan")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "it can execute a query with a named parameter and yield the rows" do
|
69
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = @id ORDER BY name") do |stmt|
|
70
|
+
rows = []
|
71
|
+
stmt.execute( "@id" => 891 ) do |row|
|
72
|
+
rows << row
|
73
|
+
end
|
74
|
+
rows.size.should eql(2)
|
75
|
+
rows.last['name'].should eql("Yugoslavia")
|
76
|
+
rows.first['two_letter'].should eql("CS")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "can execute the same prepared statement multiple times" do
|
81
|
+
@db.execute(" CREATE TABLE t(x,y); ")
|
82
|
+
values = {}
|
83
|
+
@db.prepare("INSERT INTO t( x, y ) VALUES( $x, $y )" ) do |stmt|
|
84
|
+
20.times do |x|
|
85
|
+
y = rand( x )
|
86
|
+
stmt.execute( { "$x" => x, "$y" => y } )
|
87
|
+
values[x] = y
|
88
|
+
end
|
89
|
+
end
|
90
|
+
c = 0
|
91
|
+
@db.execute("SELECT * from t") do |row|
|
92
|
+
c += 1
|
93
|
+
values[ row['x'] ].should eql(row['y'])
|
94
|
+
end
|
95
|
+
c.should eql(20)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "binds a integer variable correctly" do
|
99
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
|
100
|
+
all_rows = stmt.execute( 891 )
|
101
|
+
all_rows.size.should eql(2)
|
102
|
+
all_rows.last['name'].should eql("Yugoslavia")
|
103
|
+
all_rows.first['two_letter'].should eql("CS")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "raises and error if an invaliding binding is attempted" do
|
108
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ") do |stmt|
|
109
|
+
lambda{ stmt.execute( "blah" => 42 ) }.should raise_error(Amalgalite::Error)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "can reset the statement to the state it was before executing" do
|
114
|
+
stmt = @iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ")
|
115
|
+
stmt.reset_and_clear_bindings!
|
116
|
+
stmt.close
|
117
|
+
end
|
118
|
+
|
119
|
+
it "can execute a single sql command and say if there is remaining sql to execute" do
|
120
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
121
|
+
stmt = @db.prepare( @schema_sql )
|
122
|
+
stmt.execute
|
123
|
+
stmt.remaining_sql.size.should > 0
|
124
|
+
stmt.close
|
125
|
+
end
|
126
|
+
|
127
|
+
it "can select the rowid from the table" do
|
128
|
+
db = Amalgalite::Database.new( ":memory:" )
|
129
|
+
db.execute( "create table t1(c1,c2,c3)" )
|
130
|
+
db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
|
131
|
+
rows = db.execute( "select rowid,* from t1")
|
132
|
+
rows.size.should eql(1)
|
133
|
+
rows.first['rowid'].should eql(1)
|
134
|
+
rows.first['c1'].should eql(1 )
|
135
|
+
rows.first['c3'].should eql('abc')
|
136
|
+
end
|
137
|
+
|
138
|
+
it "shows that the rowid column is rowid column" do
|
139
|
+
db = Amalgalite::Database.new( ":memory:" )
|
140
|
+
db.execute( "create table t1(c1,c2,c3)" )
|
141
|
+
db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
|
142
|
+
db.prepare( "select oid,* from t1" ) do |stmt|
|
143
|
+
rows = stmt.execute
|
144
|
+
stmt.should be_using_rowid_column
|
145
|
+
end
|
146
|
+
|
147
|
+
db.prepare( "select * from t1" ) do |stmt|
|
148
|
+
stmt.execute
|
149
|
+
stmt.should_not be_using_rowid_column
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it "has index based access to the result set" do
|
154
|
+
@iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
|
155
|
+
all_rows = stmt.execute( 891 )
|
156
|
+
all_rows.size.should eql(2)
|
157
|
+
all_rows.last.first.should eql("Yugoslavia")
|
158
|
+
all_rows.first[1].should eql("CS")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|