amalgalite 0.10.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|