amalgalite 1.6.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +49 -0
- data/HISTORY.md +346 -0
- data/LICENSE +31 -0
- data/Manifest.txt +104 -0
- data/README.md +65 -0
- data/Rakefile +26 -0
- data/TODO.md +57 -0
- data/bin/amalgalite-pack +147 -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/fts5.rb +152 -0
- data/examples/gem-db.rb +94 -0
- data/examples/require_me.rb +11 -0
- data/examples/requires.rb +42 -0
- data/examples/schema-info.rb +34 -0
- data/ext/amalgalite/c/amalgalite.c +355 -0
- data/ext/amalgalite/c/amalgalite.h +151 -0
- data/ext/amalgalite/c/amalgalite_blob.c +240 -0
- data/ext/amalgalite/c/amalgalite_constants.c +1226 -0
- data/ext/amalgalite/c/amalgalite_database.c +1178 -0
- data/ext/amalgalite/c/amalgalite_requires_bootstrap.c +282 -0
- data/ext/amalgalite/c/amalgalite_statement.c +649 -0
- data/ext/amalgalite/c/extconf.rb +62 -0
- data/ext/amalgalite/c/gen_constants.rb +330 -0
- data/ext/amalgalite/c/notes.txt +134 -0
- data/ext/amalgalite/c/sqlite3.c +205352 -0
- data/ext/amalgalite/c/sqlite3.h +10727 -0
- data/ext/amalgalite/c/sqlite3_options.h +4 -0
- data/ext/amalgalite/c/sqlite3ext.h +578 -0
- data/lib/amalgalite.rb +51 -0
- data/lib/amalgalite/2.0/amalgalite.so +0 -0
- data/lib/amalgalite/2.1/amalgalite.so +0 -0
- data/lib/amalgalite/2.2/amalgalite.so +0 -0
- data/lib/amalgalite/2.3/amalgalite.so +0 -0
- data/lib/amalgalite/2.4/amalgalite.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 +99 -0
- data/lib/amalgalite/core_ext/kernel/require.rb +21 -0
- data/lib/amalgalite/csv_table_importer.rb +74 -0
- data/lib/amalgalite/database.rb +984 -0
- data/lib/amalgalite/function.rb +61 -0
- data/lib/amalgalite/index.rb +43 -0
- data/lib/amalgalite/memory_database.rb +15 -0
- data/lib/amalgalite/packer.rb +231 -0
- data/lib/amalgalite/paths.rb +80 -0
- data/lib/amalgalite/profile_tap.rb +131 -0
- data/lib/amalgalite/progress_handler.rb +21 -0
- data/lib/amalgalite/requires.rb +151 -0
- data/lib/amalgalite/schema.rb +225 -0
- data/lib/amalgalite/sqlite3.rb +6 -0
- data/lib/amalgalite/sqlite3/constants.rb +95 -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 +55 -0
- data/lib/amalgalite/statement.rb +418 -0
- data/lib/amalgalite/table.rb +91 -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 +166 -0
- data/lib/amalgalite/type_maps/storage_map.rb +38 -0
- data/lib/amalgalite/type_maps/text_map.rb +21 -0
- data/lib/amalgalite/version.rb +8 -0
- data/lib/amalgalite/view.rb +26 -0
- data/spec/aggregate_spec.rb +154 -0
- data/spec/amalgalite_spec.rb +4 -0
- data/spec/blob_spec.rb +78 -0
- data/spec/boolean_spec.rb +24 -0
- data/spec/busy_handler.rb +157 -0
- data/spec/data/iso-3166-country.txt +242 -0
- data/spec/data/iso-3166-schema.sql +22 -0
- data/spec/data/iso-3166-subcountry.txt +3995 -0
- data/spec/data/make-iso-db.sh +12 -0
- data/spec/database_spec.rb +508 -0
- data/spec/default_map_spec.rb +92 -0
- data/spec/function_spec.rb +78 -0
- data/spec/integeration_spec.rb +97 -0
- data/spec/iso_3166_database.rb +58 -0
- data/spec/packer_spec.rb +60 -0
- data/spec/paths_spec.rb +28 -0
- data/spec/progress_handler_spec.rb +91 -0
- data/spec/requires_spec.rb +54 -0
- data/spec/rtree_spec.rb +66 -0
- data/spec/schema_spec.rb +131 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/sqlite3/constants_spec.rb +108 -0
- data/spec/sqlite3/database_status_spec.rb +36 -0
- data/spec/sqlite3/status_spec.rb +22 -0
- data/spec/sqlite3/version_spec.rb +28 -0
- data/spec/sqlite3_spec.rb +53 -0
- data/spec/statement_spec.rb +168 -0
- data/spec/storage_map_spec.rb +38 -0
- data/spec/tap_spec.rb +57 -0
- data/spec/text_map_spec.rb +20 -0
- data/spec/type_map_spec.rb +14 -0
- data/spec/version_spec.rb +8 -0
- data/tasks/custom.rake +102 -0
- data/tasks/default.rake +240 -0
- data/tasks/extension.rake +38 -0
- data/tasks/this.rb +208 -0
- metadata +318 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'amalgalite/type_maps/default_map'
|
3
|
+
|
4
|
+
describe Amalgalite::TypeMaps::DefaultMap do
|
5
|
+
before(:each) do
|
6
|
+
@map = Amalgalite::TypeMaps::DefaultMap.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#bind_type_of" do
|
10
|
+
|
11
|
+
it "Float is bound to DataType::FLOAT" do
|
12
|
+
@map.bind_type_of( 3.14 ).should == ::Amalgalite::SQLite3::Constants::DataType::FLOAT
|
13
|
+
end
|
14
|
+
|
15
|
+
it "Integer is bound to DataType::INTGER" do
|
16
|
+
@map.bind_type_of( 42 ).should == ::Amalgalite::SQLite3::Constants::DataType::INTEGER
|
17
|
+
end
|
18
|
+
|
19
|
+
it "nil is bound to DataType::NULL" do
|
20
|
+
@map.bind_type_of( nil ).should == ::Amalgalite::SQLite3::Constants::DataType::NULL
|
21
|
+
end
|
22
|
+
|
23
|
+
it "::Amalgalite::Blob is bound to DataType::BLOB" do
|
24
|
+
@map.bind_type_of( ::Amalgalite::Blob.new( :column => true, :string => "just a test" ) ).should == ::Amalgalite::SQLite3::Constants::DataType::BLOB
|
25
|
+
end
|
26
|
+
|
27
|
+
it "everything else is bound to DataType::TEXT" do
|
28
|
+
@map.bind_type_of( "everything else" ).should == ::Amalgalite::SQLite3::Constants::DataType::TEXT
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe "#result_value_of" do
|
35
|
+
|
36
|
+
it "Numeric's are returned" do
|
37
|
+
y = 42
|
38
|
+
x = @map.result_value_of( "INT", 42 )
|
39
|
+
x.object_id.should == y.object_id
|
40
|
+
end
|
41
|
+
|
42
|
+
it "Nil is returned" do
|
43
|
+
@map.result_value_of( "NULL", nil ).should == nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "DateTime is returned for delcared types of 'datetime'" do
|
47
|
+
@map.result_value_of( "DaTeTiME", "2008-04-01 23:23:23" ).should be_kind_of(DateTime)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "Date is returned for declared types of 'date'" do
|
51
|
+
@map.result_value_of( "date", "2008-04-01 23:42:42" ).should be_kind_of(Date)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "Time is returned for declared types of 'time'" do
|
55
|
+
@map.result_value_of( "timestamp", "2008-04-01T23:42:42" ).should be_kind_of(Time)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "Float is returned for declared types of 'double'" do
|
59
|
+
@map.result_value_of( "double", "3.14" ).should be_kind_of(Float)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "Float is returned for declared types of 'float'" do
|
63
|
+
@map.result_value_of( "float", "3.14" ).should be_kind_of(Float)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "Integer is returned for declared types of 'int'" do
|
67
|
+
@map.result_value_of( "int", "42" ).should be_kind_of(Integer)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "boolean is returned for declared types of 'bool'" do
|
71
|
+
@map.result_value_of( "bool", "True" ).should == true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "Blob is returned for declared types of 'blob'" do
|
75
|
+
blob = @map.result_value_of( "blob", "stuff")
|
76
|
+
blob.to_s.should == "stuff"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "String is returned for delcared types of 'string'" do
|
80
|
+
@map.result_value_of( "string", "stuff").should == "stuff"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "raises and error if an unknown sql type is returned" do
|
84
|
+
x = nil
|
85
|
+
lambda{ x = @map.result_value_of( "footype", "foo" ) }.should raise_error( ::Amalgalite::Error )
|
86
|
+
end
|
87
|
+
|
88
|
+
it "raises and error if an ruby class is attempted to be mapped" do
|
89
|
+
lambda{ @map.result_value_of( "footype", 1..3 ) }.should raise_error( ::Amalgalite::Error )
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Scalar SQL Functions" do
|
4
|
+
|
5
|
+
it "can define a custom SQL function as a block with 0 params" do
|
6
|
+
@iso_db.define_function("foo") do
|
7
|
+
"foo"
|
8
|
+
end
|
9
|
+
r = @iso_db.execute("SELECT foo() AS f");
|
10
|
+
r.first['f'].should == "foo"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has a signature" do
|
14
|
+
::Amalgalite::Function.new( "testing_name", 42 ).signature.should == "testing_name/42"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can define a custom SQL function as a lambda with 2 param" do
|
18
|
+
@iso_db.define_function("foo2", lambda{ |x,y| "foo2 -> #{x} #{y}" } )
|
19
|
+
r = @iso_db.execute("SELECT foo2( 'bar', 'baz' ) as f")
|
20
|
+
r.first['f'].should == "foo2 -> bar baz"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can define a custom SQL function as a class with N params" do
|
24
|
+
class FunctionTest1 < ::Amalgalite::Function
|
25
|
+
def initialize
|
26
|
+
super('ftest', -1)
|
27
|
+
end
|
28
|
+
def call( *args )
|
29
|
+
"#{args.length} args #{args.join(', ')}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
@iso_db.define_function("ftest1", FunctionTest1.new )
|
34
|
+
r = @iso_db.execute("SELECT ftest1(1,2,3,'baz') as f")
|
35
|
+
r.first['f'].should == "4 args 1, 2, 3, baz"
|
36
|
+
end
|
37
|
+
|
38
|
+
[ [ 1, lambda { true } ],
|
39
|
+
[ 0, lambda { false } ],
|
40
|
+
[ nil, lambda { nil } ],
|
41
|
+
[ "foo", lambda { "foo" } ],
|
42
|
+
[ 42, lambda { 42 } ],
|
43
|
+
[ 42.2 , lambda { 42.2 } ], ].each do |expected, func|
|
44
|
+
it "returns the appropriate class #{expected.class} " do
|
45
|
+
@iso_db.define_function("ctest", func )
|
46
|
+
r = @iso_db.execute( "SELECT ctest() AS c" )
|
47
|
+
r.first['c'].should == expected
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does not allow outrageous arity" do
|
52
|
+
class FunctionTest3 < ::Amalgalite::Function
|
53
|
+
def initialize
|
54
|
+
super( 'ftest3', 128)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
lambda { @iso_db.define_function("ftest3", FunctionTest3.new) }.should raise_error( ::Amalgalite::SQLite3::Error, /SQLITE_ERROR .* Library used incorrectly/ )
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raises an error if the function returns a complex Ruby object" do
|
61
|
+
l = lambda { Hash.new }
|
62
|
+
@iso_db.define_function("htest", l)
|
63
|
+
begin
|
64
|
+
@iso_db.execute( "SELECT htest() AS h" )
|
65
|
+
rescue => e
|
66
|
+
e.should be_instance_of( ::Amalgalite::SQLite3::Error )
|
67
|
+
e.message.should =~ /Unable to convert ruby object to an SQL function result/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "an error raised during the sql function is handled correctly" do
|
72
|
+
@iso_db.define_function( "etest" ) do
|
73
|
+
raise "error from within an sql function"
|
74
|
+
end
|
75
|
+
lambda { @iso_db.execute( "SELECT etest() AS e" ) }.should raise_error( ::Amalgalite::SQLite3::Error, /error from within an sql function/ )
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
describe "Integration specifications" do
|
7
|
+
|
8
|
+
describe " - invalid queries" do
|
9
|
+
it "raises error with an invalid syntax" do
|
10
|
+
lambda{ @iso_db.prepare "SELECT from country" }.should raise_error( ::Amalgalite::SQLite3::Error )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "raises error with invalid table" do
|
14
|
+
lambda{ @iso_db.prepare "SELECT * FROM foo" }.should raise_error( ::Amalgalite::SQLite3::Error )
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises error with invalid column" do
|
18
|
+
lambda{ @iso_db.prepare "SELECT foo FROM country" }.should raise_error( ::Amalgalite::SQLite3::Error )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe " - default types conversion" do
|
23
|
+
|
24
|
+
{
|
25
|
+
"datetime" => { :value => DateTime.now, :klass => DateTime },
|
26
|
+
"timestamp" => { :value => Time.now, :klass => Time } ,
|
27
|
+
"date" => { :value => Date.today, :klass => Date },
|
28
|
+
"integer" => { :value => 42, :klass => Integer },
|
29
|
+
"double" => { :value => 3.14, :klass => Float },
|
30
|
+
"varchar" => { :value => "foobarbaz", :klass => String },
|
31
|
+
"boolean" => { :value => true, :klass => TrueClass },
|
32
|
+
"varchar(2)"=> { :value => nil, :klass => NilClass }
|
33
|
+
}.each_pair do |sql_type, ruby_info|
|
34
|
+
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
|
35
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
36
|
+
db.execute "CREATE TABLE t( c #{sql_type} )"
|
37
|
+
db.execute "insert into t (c) values ( ? )", ruby_info[:value]
|
38
|
+
rows = db.execute "select * from t"
|
39
|
+
rows.first['c'].should be_kind_of(ruby_info[:klass])
|
40
|
+
|
41
|
+
if [ DateTime, Time ].include?( ruby_info[:klass] ) then
|
42
|
+
rows.first['c'].strftime("%Y-%m-%d %H:%M:%S").should eql(ruby_info[:value].strftime("%Y-%m-%d %H:%M:%S"))
|
43
|
+
else
|
44
|
+
rows.first['c'].should eql(ruby_info[:value])
|
45
|
+
end
|
46
|
+
db.close
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe " - storage type conversion" do
|
52
|
+
{
|
53
|
+
"datetime" => { :value => DateTime.now, :result => DateTime.now.strftime("%Y-%m-%dT%H:%M:%S%Z") } ,
|
54
|
+
"timestamp" => { :value => Time.now, :result => Time.now.to_s },
|
55
|
+
"date" => { :value => Date.today, :result => Date.today.to_s },
|
56
|
+
"integer" => { :value => 42, :result => 42 } ,
|
57
|
+
"double" => { :value => 3.14, :result => 3.14 } ,
|
58
|
+
"varchar" => { :value => "foobarbaz", :result => "foobarbaz" },
|
59
|
+
"boolean" => { :value => true, :result => "true" },
|
60
|
+
"varchar(2)"=> { :value => nil, :result => nil }
|
61
|
+
}.each_pair do |sql_type, ruby_info|
|
62
|
+
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
|
63
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
64
|
+
db.type_map = Amalgalite::TypeMaps::StorageMap.new
|
65
|
+
db.execute "CREATE TABLE t( c #{sql_type} )"
|
66
|
+
db.execute "insert into t (c) values ( ? )", ruby_info[:value]
|
67
|
+
rows = db.execute "select * from t"
|
68
|
+
rows.first['c'].should eql(ruby_info[:result])
|
69
|
+
db.close
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe " - text type conversion" do
|
75
|
+
{
|
76
|
+
"datetime" => { :value => DateTime.now, :result => DateTime.now.strftime("%Y-%m-%dT%H:%M:%S%Z") } ,
|
77
|
+
"timestamp" => { :value => Time.now, :result => Time.now.to_s },
|
78
|
+
"date" => { :value => Date.today, :result => Date.today.to_s },
|
79
|
+
"integer" => { :value => 42, :result => "42" } ,
|
80
|
+
"double" => { :value => 3.14, :result => "3.14" } ,
|
81
|
+
"varchar" => { :value => "foobarbaz", :result => "foobarbaz" },
|
82
|
+
"boolean" => { :value => true, :result => "true" },
|
83
|
+
"varchar(2)"=> { :value => nil, :result => "" }
|
84
|
+
}.each_pair do |sql_type, ruby_info|
|
85
|
+
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
|
86
|
+
db = Amalgalite::Database.new( SpecInfo.test_db )
|
87
|
+
db.type_map = Amalgalite::TypeMaps::TextMap.new
|
88
|
+
db.execute "CREATE TABLE t( c #{sql_type} )"
|
89
|
+
db.execute "insert into t (c) values ( ? )", ruby_info[:value]
|
90
|
+
rows = db.execute "select * from t"
|
91
|
+
rows.first['c'].should eql(ruby_info[:result])
|
92
|
+
db.close
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'amalgalite'
|
2
|
+
|
3
|
+
module Amalgalite
|
4
|
+
class Iso3166Database < Database
|
5
|
+
def self.country_data_file
|
6
|
+
@country_data_file ||= File.expand_path( File.join( File.dirname(__FILE__), "data", "iso-3166-country.txt" ) )
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.subcountry_data_file
|
10
|
+
@subcountry_data_file ||= File.expand_path( File.join( File.dirname(__FILE__), "data", "iso-3166-subcountry.txt" ) )
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.schema_file
|
14
|
+
@schema_file ||= File.expand_path(File.join(File.dirname(__FILE__), "data", "iso-3166-schema.sql"))
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.default_db_file
|
18
|
+
@db_file ||= File.expand_path(File.join(File.dirname(__FILE__), "data", "iso-3166.db"))
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.memory
|
23
|
+
Iso3166Database.new( ":memory:" )
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize( path = Iso3166Database.default_db_file )
|
27
|
+
@path = path
|
28
|
+
super( @path )
|
29
|
+
install_schema( self )
|
30
|
+
populate( self )
|
31
|
+
end
|
32
|
+
|
33
|
+
def duplicate( slug )
|
34
|
+
dirname = File.dirname( @path )
|
35
|
+
bname = File.basename( @path, ".db" )
|
36
|
+
new_name = File.join( dirname, "#{bname}_#{slug}.db" )
|
37
|
+
File.unlink( new_name ) if File.exist?( new_name )
|
38
|
+
new_db = replicate_to( new_name )
|
39
|
+
new_db.close
|
40
|
+
return new_name
|
41
|
+
end
|
42
|
+
|
43
|
+
def install_schema( db )
|
44
|
+
db.execute_batch( IO.read( Iso3166Database.schema_file ) );
|
45
|
+
end
|
46
|
+
|
47
|
+
def populate( db )
|
48
|
+
db.import_csv_to_table( Iso3166Database.country_data_file, "country", :col_sep => "|" )
|
49
|
+
db.import_csv_to_table( Iso3166Database.subcountry_data_file, "subcountry", :col_sep => "|" )
|
50
|
+
end
|
51
|
+
|
52
|
+
def remove
|
53
|
+
File.unlink( @path ) if File.exist?( @path )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
data/spec/packer_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'amalgalite/packer'
|
4
|
+
|
5
|
+
describe "Amalgalite::Packer" do
|
6
|
+
before( :each ) do
|
7
|
+
@table = Amalgalite::Requires::Bootstrap::DEFAULT_BOOTSTRAP_TABLE
|
8
|
+
@packer = Amalgalite::Packer.new( :table_name => @table )
|
9
|
+
end
|
10
|
+
|
11
|
+
after( :each ) do
|
12
|
+
FileUtils.rm_f Amalgalite::Requires::Bootstrap::DEFAULT_DB
|
13
|
+
end
|
14
|
+
|
15
|
+
it "does not load the amalgalite/requires file" do
|
16
|
+
$LOADED_FEATURES.should_not be_include("amalgalite/requires")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "packs amalgalite into a bootstrap database" do
|
20
|
+
@packer.pack( Amalgalite::Packer.amalgalite_require_order )
|
21
|
+
db = Amalgalite::Database.new( @packer.dbfile )
|
22
|
+
db.schema.tables[ @table ].should_not be_nil
|
23
|
+
count = db.execute("SELECT count(1) FROM #{@table}").first
|
24
|
+
count.first.should eql(Amalgalite::Packer.amalgalite_require_order.size)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "recreates the table if :drop_table option is given " do
|
28
|
+
@packer.pack( Amalgalite::Packer.amalgalite_require_order )
|
29
|
+
db = Amalgalite::Database.new( @packer.dbfile )
|
30
|
+
db.schema.tables[ @table ].should_not be_nil
|
31
|
+
count = db.execute("SELECT count(1) FROM #{@table}").first
|
32
|
+
count.first.should eql(Amalgalite::Packer.amalgalite_require_order.size)
|
33
|
+
|
34
|
+
np = Amalgalite::Packer.new( :drop_table => true, :table_name => @table )
|
35
|
+
np.options[ :drop_table ].should eql(true)
|
36
|
+
np.check_db( db )
|
37
|
+
count = db.execute("SELECT count(1) FROM #{@table}").first
|
38
|
+
count.first.should eql(0)
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
it "compresses the content if told too" do
|
43
|
+
@packer.options[ :compressed ] = true
|
44
|
+
@packer.pack( Amalgalite::Packer.amalgalite_require_order )
|
45
|
+
db = Amalgalite::Database.new( @packer.dbfile )
|
46
|
+
orig = IO.read( File.join( File.dirname( __FILE__ ), "..", "lib", "amalgalite.rb" ) )
|
47
|
+
zipped = db.execute("SELECT contents FROM #{@table} WHERE filename = 'amalgalite'")
|
48
|
+
expanded = Amalgalite::Packer.gunzip( zipped.first['contents'].to_s )
|
49
|
+
expanded.should eql(orig)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "has all the lib files in the amalgalite gem" do
|
53
|
+
ro = Amalgalite::Packer.amalgalite_require_order
|
54
|
+
glist = IO.readlines("Manifest.txt").select { |l| l.index("lib/amalgalite") == 0 }
|
55
|
+
glist.map! { |l| l.strip.sub("lib/","") }
|
56
|
+
(glist - ro).each do |l|
|
57
|
+
l.should_not =~ /amalgalite/
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/paths_spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
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
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class PH < ::Amalgalite::ProgressHandler
|
4
|
+
attr_reader :call_count
|
5
|
+
def initialize( max = nil )
|
6
|
+
@call_count = 0
|
7
|
+
@max = max
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
@call_count += 1
|
12
|
+
if @max && ( @call_count >= @max ) then
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def query_thread( database )
|
20
|
+
Thread.new( database ) do |db|
|
21
|
+
begin
|
22
|
+
db.execute("select count(id) from country")
|
23
|
+
rescue => e
|
24
|
+
Thread.current[:exception] = e
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Progress Handlers" do
|
30
|
+
|
31
|
+
it "raises NotImplemented if #call is not overwritten" do
|
32
|
+
bh = ::Amalgalite::ProgressHandler.new
|
33
|
+
lambda { bh.call }.should raise_error( ::NotImplementedError, /The progress handler call\(\) method must be implemented/ )
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can be registered as block" do
|
37
|
+
call_count = 0
|
38
|
+
@iso_db.progress_handler( 50 ) do ||
|
39
|
+
call_count += 1
|
40
|
+
true
|
41
|
+
end
|
42
|
+
qt = query_thread( @iso_db )
|
43
|
+
qt.join
|
44
|
+
call_count.should > 10
|
45
|
+
end
|
46
|
+
|
47
|
+
it "can be registered as lambda" do
|
48
|
+
call_count = 0
|
49
|
+
callable = lambda { || call_count += 1; true }
|
50
|
+
@iso_db.progress_handler( 42, callable )
|
51
|
+
qt = query_thread( @iso_db )
|
52
|
+
qt.join
|
53
|
+
call_count.should > 10
|
54
|
+
end
|
55
|
+
|
56
|
+
it "can be registered as a class" do
|
57
|
+
ph = PH.new
|
58
|
+
@iso_db.progress_handler( 5, ph )
|
59
|
+
qt = query_thread( @iso_db )
|
60
|
+
qt.join
|
61
|
+
ph.call_count.should > 100
|
62
|
+
end
|
63
|
+
|
64
|
+
it "behaves like #interrupt! if returning a false value" do
|
65
|
+
ph = PH.new( 25 )
|
66
|
+
@iso_db.progress_handler( 5, ph )
|
67
|
+
qt = query_thread( @iso_db )
|
68
|
+
qt.join
|
69
|
+
ph.call_count.should eql(25)
|
70
|
+
qt[:exception].should be_instance_of( ::Amalgalite::SQLite3::Error )
|
71
|
+
@iso_db.api.last_error_code.should be == 9
|
72
|
+
@iso_db.api.last_error_message.should =~ /interrupted/
|
73
|
+
qt[:exception].message.should =~ /interrupted/
|
74
|
+
end
|
75
|
+
|
76
|
+
it "cannot register a block with the wrong arity" do
|
77
|
+
lambda do
|
78
|
+
@iso_db.define_progress_handler { |x,y| puts "What!" }
|
79
|
+
end.should raise_error( ::Amalgalite::Database::ProgressHandlerError, /A progress handler expects 0 arguments, not 2/)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can remove a progress handler" do
|
83
|
+
ph = PH.new
|
84
|
+
@iso_db.progress_handler( 5, ph )
|
85
|
+
@iso_db.remove_progress_handler
|
86
|
+
qt = query_thread( @iso_db )
|
87
|
+
qt.join
|
88
|
+
ph.call_count.should eql(0)
|
89
|
+
qt[:exception].should be_nil
|
90
|
+
end
|
91
|
+
end
|