libsql 0.1.0-x64-mingw-ucrt
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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +60 -0
- data/HISTORY.md +6 -0
- data/LICENSE +31 -0
- data/Manifest.txt +96 -0
- data/README.md +59 -0
- data/Rakefile +28 -0
- data/TODO.md +57 -0
- data/examples/a.rb +9 -0
- data/examples/blob.rb +106 -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/schema-info.rb +34 -0
- data/ext/libsql/c/extconf.rb +86 -0
- data/ext/libsql/c/gen_constants.rb +353 -0
- data/ext/libsql/c/libsql_blob.c +240 -0
- data/ext/libsql/c/libsql_constants.c +1518 -0
- data/ext/libsql/c/libsql_database.c +1188 -0
- data/ext/libsql/c/libsql_ext.c +383 -0
- data/ext/libsql/c/libsql_ext.h +149 -0
- data/ext/libsql/c/libsql_statement.c +649 -0
- data/ext/libsql/c/notes.txt +134 -0
- data/ext/libsql/c/sqlite3.c +247030 -0
- data/ext/libsql/c/sqlite3.h +13436 -0
- data/lib/libsql/3.1/libsql_ext.so +0 -0
- data/lib/libsql/3.2/libsql_ext.so +0 -0
- data/lib/libsql/aggregate.rb +73 -0
- data/lib/libsql/blob.rb +186 -0
- data/lib/libsql/boolean.rb +42 -0
- data/lib/libsql/busy_timeout.rb +47 -0
- data/lib/libsql/column.rb +99 -0
- data/lib/libsql/csv_table_importer.rb +75 -0
- data/lib/libsql/database.rb +933 -0
- data/lib/libsql/function.rb +61 -0
- data/lib/libsql/index.rb +43 -0
- data/lib/libsql/memory_database.rb +15 -0
- data/lib/libsql/paths.rb +80 -0
- data/lib/libsql/profile_tap.rb +131 -0
- data/lib/libsql/progress_handler.rb +21 -0
- data/lib/libsql/schema.rb +225 -0
- data/lib/libsql/sqlite3/constants.rb +95 -0
- data/lib/libsql/sqlite3/database/function.rb +48 -0
- data/lib/libsql/sqlite3/database/status.rb +68 -0
- data/lib/libsql/sqlite3/libsql_version.rb +32 -0
- data/lib/libsql/sqlite3/status.rb +60 -0
- data/lib/libsql/sqlite3/version.rb +55 -0
- data/lib/libsql/sqlite3.rb +7 -0
- data/lib/libsql/statement.rb +421 -0
- data/lib/libsql/table.rb +91 -0
- data/lib/libsql/taps/console.rb +27 -0
- data/lib/libsql/taps/io.rb +74 -0
- data/lib/libsql/taps.rb +2 -0
- data/lib/libsql/trace_tap.rb +35 -0
- data/lib/libsql/type_map.rb +63 -0
- data/lib/libsql/type_maps/default_map.rb +166 -0
- data/lib/libsql/type_maps/storage_map.rb +38 -0
- data/lib/libsql/type_maps/text_map.rb +21 -0
- data/lib/libsql/version.rb +8 -0
- data/lib/libsql/view.rb +26 -0
- data/lib/libsql-ruby.rb +1 -0
- data/lib/libsql.rb +51 -0
- data/spec/aggregate_spec.rb +158 -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 +505 -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/json_spec.rb +24 -0
- data/spec/libsql_spec.rb +4 -0
- data/spec/paths_spec.rb +28 -0
- data/spec/progress_handler_spec.rb +91 -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/libsql_version_spec.rb +16 -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 +134 -0
- data/tasks/default.rake +257 -0
- data/tasks/extension.rake +29 -0
- data/tasks/this.rb +208 -0
- metadata +329 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class AggregateTest1 < ::Libsql::Aggregate
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@name = 'atest1'
|
7
|
+
@arity = -1
|
8
|
+
@count = 0
|
9
|
+
end
|
10
|
+
def step( *args )
|
11
|
+
@count += 1
|
12
|
+
end
|
13
|
+
def finalize
|
14
|
+
return @count
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "Aggregate SQL Functions" do
|
20
|
+
|
21
|
+
it "must have a finalize method implemented" do
|
22
|
+
ag = ::Libsql::Aggregate.new
|
23
|
+
lambda { ag.finalize }.should raise_error( NotImplementedError, /Aggregate#finalize must be implemented/ )
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can define a custom SQL aggregate as a class with N params" do
|
27
|
+
@iso_db.define_aggregate("atest1", AggregateTest1 )
|
28
|
+
r = @iso_db.execute("SELECT atest1(id,name) as a, count(*) as c FROM country")
|
29
|
+
r.first['a'].should eql(r.first['c'])
|
30
|
+
r.first['a'].should eql(242)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can remove a custom SQL aggregate by class" do
|
34
|
+
@iso_db.define_aggregate("atest1", AggregateTest1 )
|
35
|
+
@iso_db.aggregates.size.should eql(1)
|
36
|
+
r = @iso_db.execute("SELECT atest1(id,name) as a, count(*) as c FROM country")
|
37
|
+
r.first['a'].should eql(r.first['c'])
|
38
|
+
r.first['a'].should eql(242)
|
39
|
+
@iso_db.remove_aggregate( "atest1", AggregateTest1 )
|
40
|
+
@iso_db.aggregates.size.should eql(0)
|
41
|
+
lambda{ @iso_db.execute("SELECT atest1(id,name) as a, count(*) as c FROM country") }.should raise_error(::Libsql::SQLite3::Error, /no such function: atest1/ )
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can remove a custom SQL aggregate by arity" do
|
45
|
+
@iso_db.define_aggregate("atest1", AggregateTest1 )
|
46
|
+
@iso_db.aggregates.size.should eql(1)
|
47
|
+
r = @iso_db.execute("SELECT atest1(id,name) as a, count(*) as c FROM country")
|
48
|
+
r.first['a'].should eql(r.first['c'])
|
49
|
+
r.first['a'].should eql(242)
|
50
|
+
@iso_db.remove_aggregate( "atest1", -1)
|
51
|
+
@iso_db.aggregates.size.should eql(0)
|
52
|
+
lambda{ @iso_db.execute("SELECT atest1(id,name) as a, count(*) as c FROM country") }.should raise_error(::Libsql::SQLite3::Error, /no such function: atest1/ )
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can remove all custom SQL aggregates with the same name" do
|
56
|
+
class AT2 < AggregateTest1
|
57
|
+
def arity() 1; end
|
58
|
+
end
|
59
|
+
@iso_db.define_aggregate("atest1", AggregateTest1 )
|
60
|
+
@iso_db.define_aggregate("atest1", AT2)
|
61
|
+
@iso_db.aggregates.size.should eql(2)
|
62
|
+
r = @iso_db.execute("SELECT atest1(id,name) as a, atest1(id), count(*) as c FROM country")
|
63
|
+
r.first['a'].should eql(r.first['c'])
|
64
|
+
r.first['a'].should eql(242)
|
65
|
+
@iso_db.remove_aggregate( "atest1" )
|
66
|
+
@iso_db.aggregates.size.should eql(0)
|
67
|
+
lambda{ @iso_db.execute("SELECT atest1(id,name) as a, count(*) as c FROM country") }.should raise_error(::Libsql::SQLite3::Error, /no such function: atest1/ )
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
it "does not allow mixing of arbitrary and mandatory arguments to an SQL function" do
|
73
|
+
class AggregateTest2 < AggregateTest1
|
74
|
+
def name() "atest2"; end
|
75
|
+
def arity() -2; end
|
76
|
+
end
|
77
|
+
lambda { @iso_db.define_aggregate("atest2", AggregateTest2 ) }.should raise_error( ::Libsql::Database::AggregateError,
|
78
|
+
/Use only mandatory or arbitrary parameters in an SQL Aggregate, not both/ )
|
79
|
+
end
|
80
|
+
|
81
|
+
it "does not allow outrageous arity" do
|
82
|
+
class AggregateTest3 < AggregateTest1
|
83
|
+
def name() "atest3"; end
|
84
|
+
def arity() 128; end
|
85
|
+
end
|
86
|
+
lambda { @iso_db.define_aggregate("atest3", AggregateTest3 ) }.should raise_error( ::Libsql::SQLite3::Error, /SQLITE_ERROR .* Library used incorrectly/ )
|
87
|
+
end
|
88
|
+
|
89
|
+
it "does not allow registering a function which does not match the defined name " do
|
90
|
+
class AggregateTest4 < AggregateTest1
|
91
|
+
def name() "name_mismatch"; end
|
92
|
+
end
|
93
|
+
lambda { @iso_db.define_aggregate("atest4", AggregateTest4 ) }.should raise_error( ::Libsql::Database::AggregateError,
|
94
|
+
/Aggregate implementation name 'name_mismatch' does not match defined name 'atest4'/)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "handles an error being thrown during the step function" do
|
98
|
+
class AggregateTest5 < AggregateTest1
|
99
|
+
def initialize
|
100
|
+
super
|
101
|
+
@name = "atest5"
|
102
|
+
@arity = -1
|
103
|
+
@count = 0
|
104
|
+
end
|
105
|
+
|
106
|
+
def step( *args )
|
107
|
+
@count += 1
|
108
|
+
if @count > 50 then
|
109
|
+
raise "Stepwise error!" if @count > 50
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
@iso_db.define_aggregate( "atest5", AggregateTest5 )
|
116
|
+
lambda { @iso_db.execute( "SELECT atest5(*) AS a FROM country" ) }.should raise_error( ::Libsql::SQLite3::Error, /Stepwise error!/ )
|
117
|
+
end
|
118
|
+
|
119
|
+
it "handles an error being thrown during the finalize function" do
|
120
|
+
class AggregateTest6 < AggregateTest1
|
121
|
+
def initialize
|
122
|
+
super
|
123
|
+
@name = "atest6"
|
124
|
+
@count = 0
|
125
|
+
@arity = -1
|
126
|
+
end
|
127
|
+
def finalize
|
128
|
+
raise "Finalize error!"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
@iso_db.define_aggregate( "atest6", AggregateTest6 )
|
132
|
+
lambda { @iso_db.execute( "SELECT atest6(*) AS a FROM country" ) }.should raise_error( ::Libsql::SQLite3::Error, /Finalize error!/ )
|
133
|
+
end
|
134
|
+
|
135
|
+
it "handles an error being thrown during initialization in the C extension" do
|
136
|
+
class AggregateTest7 < AggregateTest1
|
137
|
+
@called = false
|
138
|
+
def self.called?
|
139
|
+
if @called then
|
140
|
+
raise "Initialization error!"
|
141
|
+
else
|
142
|
+
@called = true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def initialize
|
147
|
+
super
|
148
|
+
@name = "atest7"
|
149
|
+
@count = 0
|
150
|
+
@arity = -1
|
151
|
+
self.class.called?
|
152
|
+
end
|
153
|
+
end
|
154
|
+
@iso_db.define_aggregate( "atest7", AggregateTest7 )
|
155
|
+
lambda { @iso_db.execute( "SELECT atest7(*) AS a FROM country" ) }.should raise_error( ::Libsql::SQLite3::Error, /Initialization error!/ )
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
data/spec/blob_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Libsql::Blob do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@blob_db_name = File.join(File.dirname( __FILE__ ), "blob.db")
|
7
|
+
File.unlink @blob_db_name if File.exist?( @blob_db_name )
|
8
|
+
@db = ::Libsql::Database.new( @blob_db_name )
|
9
|
+
@schema_sql = <<-SQL
|
10
|
+
CREATE TABLE blobs(
|
11
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
12
|
+
name VARCHAR(128) NOT NULL UNIQUE,
|
13
|
+
data TEXT );
|
14
|
+
SQL
|
15
|
+
@db.execute( @schema_sql )
|
16
|
+
@country_data_file = ::Libsql::Iso3166Database.country_data_file
|
17
|
+
@junk_file = File.join( File.dirname(__FILE__), "test_output")
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:each) do
|
21
|
+
@db.close
|
22
|
+
File.unlink @blob_db_name if File.exist?( @blob_db_name )
|
23
|
+
File.unlink @junk_file if File.exist?( @junk_file )
|
24
|
+
end
|
25
|
+
|
26
|
+
{ :file => ::Libsql::Iso3166Database.country_data_file,
|
27
|
+
:string => IO.read( ::Libsql::Iso3166Database.country_data_file),
|
28
|
+
:io => StringIO.new( IO.read( ::Libsql::Iso3166Database.country_data_file) ) }.each_pair do |style, data |
|
29
|
+
describe "inserts a blob from a #{style}" do
|
30
|
+
before(:each) do
|
31
|
+
column = @db.schema.tables['blobs'].columns['data']
|
32
|
+
@db.execute("INSERT INTO blobs(name, data) VALUES ($name, $data)",
|
33
|
+
{ "$name" => @country_data_file,
|
34
|
+
"$data" => ::Libsql::Blob.new( style => data,
|
35
|
+
:column => column ) } )
|
36
|
+
@db.execute("VACUUM")
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:each) do
|
40
|
+
@db.execute("DELETE FROM blobs")
|
41
|
+
data.rewind if data.respond_to?( :rewind )
|
42
|
+
end
|
43
|
+
|
44
|
+
it "and retrieves the data as a single value" do
|
45
|
+
all_rows = @db.execute("SELECT name,data FROM blobs")
|
46
|
+
all_rows.size.should eql(1)
|
47
|
+
all_rows.first['name'].should eql(@country_data_file)
|
48
|
+
all_rows.first['data'].should_not be_incremental
|
49
|
+
all_rows.first['data'].to_string_io.string.should eql(IO.read( @country_data_file ))
|
50
|
+
end
|
51
|
+
|
52
|
+
it "and retrieves the data using incremental IO" do
|
53
|
+
all_rows = @db.execute("SELECT * FROM blobs")
|
54
|
+
all_rows.size.should eql(1)
|
55
|
+
all_rows.first['name'].should eql(@country_data_file)
|
56
|
+
all_rows.first['data'].should be_incremental
|
57
|
+
all_rows.first['data'].to_string_io.string.should eql(IO.read( @country_data_file ))
|
58
|
+
end
|
59
|
+
|
60
|
+
it "writes the data to a file " do
|
61
|
+
all_rows = @db.execute("SELECT * FROM blobs")
|
62
|
+
all_rows.size.should eql(1)
|
63
|
+
all_rows.first['name'].should eql(@country_data_file)
|
64
|
+
all_rows.first['data'].should be_incremental
|
65
|
+
all_rows.first['data'].write_to_file( @junk_file )
|
66
|
+
IO.read( @junk_file).should eql(IO.read( @country_data_file ))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
it "raises an error if initialized incorrectly" do
|
74
|
+
lambda{ ::Libsql::Blob.new( :file => "/dev/null", :string => "foo" ) }.should raise_error( ::Libsql::Blob::Error )
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'libsql'
|
4
|
+
require 'libsql/boolean'
|
5
|
+
|
6
|
+
describe ::Libsql::Boolean do
|
7
|
+
%w[ True Y Yes T 1 ].each do |v|
|
8
|
+
it "converts #{v} to true" do
|
9
|
+
::Libsql::Boolean.to_bool(v).should == true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
%w[ False F f No n 0 ].each do |v|
|
14
|
+
it "converts #{v} to false " do
|
15
|
+
::Libsql::Boolean.to_bool(v).should == false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
%w[ other things nil ].each do |v|
|
20
|
+
it "converts #{v} to nil" do
|
21
|
+
::Libsql::Boolean.to_bool(v).should == nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class BusyHandlerTest < ::Libsql::BusyHandler
|
4
|
+
attr_accessor :call_count
|
5
|
+
def initialize( max = 5 )
|
6
|
+
@max = max
|
7
|
+
@call_count = 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def call( c )
|
11
|
+
@call_count += 1
|
12
|
+
if call_count >= @max then
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Busy Handlers" do
|
20
|
+
before(:each) do
|
21
|
+
@read_db = ::Libsql::Database.new( @iso_db_path )
|
22
|
+
@write_db = ::Libsql::Database.new( @iso_db_path )
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
@write_db.close
|
27
|
+
@read_db.close
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises NotImplemented if #call is not overwritten" do
|
31
|
+
bh = ::Libsql::BusyHandler.new
|
32
|
+
lambda { bh.call( 42 ) }.should raise_error( ::NotImplementedError, /The busy handler call\(N\) method must be implemented/ )
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can be registered as block" do
|
36
|
+
call_count = 0
|
37
|
+
@write_db.busy_handler do |x|
|
38
|
+
call_count = x
|
39
|
+
if call_count >= 20 then
|
40
|
+
false
|
41
|
+
else
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# put a read lock on the database
|
47
|
+
@read_db.transaction( "DEFERRED" )
|
48
|
+
|
49
|
+
# put a read lock on the database, but want to go to an exclusive
|
50
|
+
@write_db.transaction( "IMMEDIATE" )
|
51
|
+
|
52
|
+
# do a read operation
|
53
|
+
@read_db.execute("SELECT count(*) FROM subcountry")
|
54
|
+
|
55
|
+
# attempt to do a write operation and commit it
|
56
|
+
@write_db.execute("DELETE FROM subcountry")
|
57
|
+
lambda { @write_db.execute("COMMIT"); }.should raise_error( ::Libsql::SQLite3::Error, /database is locked/ )
|
58
|
+
call_count.should == 20
|
59
|
+
end
|
60
|
+
|
61
|
+
it "can be registered as lambda" do
|
62
|
+
call_count = 0
|
63
|
+
callable = lambda do |x|
|
64
|
+
call_count = x
|
65
|
+
if call_count >= 40 then
|
66
|
+
false
|
67
|
+
else
|
68
|
+
true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
@write_db.busy_handler( callable )
|
73
|
+
|
74
|
+
# put a read lock on the database
|
75
|
+
@read_db.transaction( "DEFERRED" )
|
76
|
+
|
77
|
+
# put a read lock on the database, but want to go to an exclusive
|
78
|
+
@write_db.transaction( "IMMEDIATE" )
|
79
|
+
|
80
|
+
# do a read operation
|
81
|
+
@read_db.execute("SELECT count(*) FROM subcountry")
|
82
|
+
|
83
|
+
# attempt to do a write operation and commit it
|
84
|
+
@write_db.execute("DELETE FROM subcountry")
|
85
|
+
lambda { @write_db.execute("COMMIT"); }.should raise_error( ::Libsql::SQLite3::Error, /database is locked/ )
|
86
|
+
call_count.should == 40
|
87
|
+
end
|
88
|
+
|
89
|
+
it "can be registered as a class" do
|
90
|
+
h = BusyHandlerTest.new( 10 )
|
91
|
+
@write_db.busy_handler( h )
|
92
|
+
|
93
|
+
# put a read lock on the database
|
94
|
+
@read_db.transaction( "DEFERRED" )
|
95
|
+
|
96
|
+
# put a read lock on the database, but want to go to an exclusive
|
97
|
+
@write_db.transaction( "IMMEDIATE" )
|
98
|
+
|
99
|
+
# do a read operation
|
100
|
+
@read_db.execute("SELECT count(*) FROM subcountry")
|
101
|
+
|
102
|
+
# attempt to do a write operation and commit it
|
103
|
+
@write_db.execute("DELETE FROM subcountry")
|
104
|
+
lambda { @write_db.execute("COMMIT"); }.should raise_error( ::Libsql::SQLite3::Error, /database is locked/ )
|
105
|
+
h.call_count.should == 10
|
106
|
+
end
|
107
|
+
|
108
|
+
it "has a default timeout class available " do
|
109
|
+
to = ::Libsql::BusyTimeout.new( 5, 10 )
|
110
|
+
@write_db.busy_handler( to )
|
111
|
+
|
112
|
+
# put a read lock on the database
|
113
|
+
@read_db.transaction( "DEFERRED" )
|
114
|
+
|
115
|
+
# put a read lock on the database, but want to go to an exclusive
|
116
|
+
@write_db.transaction( "IMMEDIATE" )
|
117
|
+
|
118
|
+
# do a read operation
|
119
|
+
@read_db.execute("SELECT count(*) FROM subcountry")
|
120
|
+
|
121
|
+
# attempt to do a write operation and commit it
|
122
|
+
@write_db.execute("DELETE FROM subcountry")
|
123
|
+
before = Time.now
|
124
|
+
lambda { @write_db.execute("COMMIT"); }.should raise_error( ::Libsql::SQLite3::Error, /database is locked/ )
|
125
|
+
after = Time.now
|
126
|
+
to.call_count.should > 5
|
127
|
+
(after - before).should > 0.05
|
128
|
+
end
|
129
|
+
|
130
|
+
it "cannot register a block with the wrong arity" do
|
131
|
+
lambda do
|
132
|
+
@write_db.define_busy_handler { |x,y| puts "What!" }
|
133
|
+
end.should raise_error( ::Libsql::Database::BusyHandlerError, /A busy handler expects 1 and only 1 argument/ )
|
134
|
+
end
|
135
|
+
|
136
|
+
it "can remove a busy handler" do
|
137
|
+
bht = BusyHandlerTest.new
|
138
|
+
|
139
|
+
@write_db.busy_handler( bht )
|
140
|
+
|
141
|
+
# put a read lock on the database
|
142
|
+
@read_db.transaction( "DEFERRED" )
|
143
|
+
|
144
|
+
# put a read lock on the database, but want to go to an exclusive
|
145
|
+
@write_db.transaction( "IMMEDIATE" )
|
146
|
+
|
147
|
+
# do a read operation
|
148
|
+
@read_db.execute("SELECT count(*) FROM subcountry")
|
149
|
+
|
150
|
+
# attempt to do a write operation and commit it
|
151
|
+
@write_db.execute("DELETE FROM subcountry")
|
152
|
+
@write_db.remove_busy_handler
|
153
|
+
lambda { @write_db.execute("COMMIT"); }.should raise_error( ::Libsql::SQLite3::Error, /database is locked/ )
|
154
|
+
bht.call_count.should == 0
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
Afghanistan|AF|4
|
2
|
+
Albania|AL|8
|
3
|
+
Algeria|DZ|12
|
4
|
+
American Samoa|AS|16
|
5
|
+
Andorra|AD|20
|
6
|
+
Angola|AO|24
|
7
|
+
Anguilla|AI|660
|
8
|
+
Antarctica|AQ|10
|
9
|
+
Antigua and Barbuda|AG|28
|
10
|
+
Argentina|AR|32
|
11
|
+
Armenia|AM|51
|
12
|
+
Aruba|AW|533
|
13
|
+
Australia|AU|36
|
14
|
+
Austria|AT|40
|
15
|
+
Azerbaijan|AZ|31
|
16
|
+
Bahamas|BS|44
|
17
|
+
Bahrain|BH|48
|
18
|
+
Bangladesh|BD|50
|
19
|
+
Barbados|BB|52
|
20
|
+
Belarus|BY|112
|
21
|
+
Belgium|BE|56
|
22
|
+
Belize|BZ|84
|
23
|
+
Benin|BJ|204
|
24
|
+
Bermuda|BM|60
|
25
|
+
Bhutan|BT|64
|
26
|
+
Bolivia|BO|68
|
27
|
+
Bosnia and Herzegowina|BA|70
|
28
|
+
Botswana|BW|72
|
29
|
+
Bouvet Island|BV|74
|
30
|
+
Brazil|BR|76
|
31
|
+
British Indian Ocean Territory|IO|86
|
32
|
+
Brunei Darussalam|BN|96
|
33
|
+
Bulgaria|BG|100
|
34
|
+
Burkina Faso|BF|854
|
35
|
+
Burundi|BI|108
|
36
|
+
Cambodia|KH|116
|
37
|
+
Cameroon|CM|120
|
38
|
+
Cape Verde|CV|132
|
39
|
+
Cayman Islands|KY|136
|
40
|
+
Central African Republic|CF|140
|
41
|
+
Chad|TD|148
|
42
|
+
Chile|CL|152
|
43
|
+
China|CN|156
|
44
|
+
Christmas Island|CX|162
|
45
|
+
Cocos (Keeling) Islands|CC|166
|
46
|
+
Colombia|CO|170
|
47
|
+
Comoros|KM|174
|
48
|
+
Congo|CG|178
|
49
|
+
Congo, The Democratic Republic of the|CD|180
|
50
|
+
Cook Islands|CK|184
|
51
|
+
Costa Rica|CR|188
|
52
|
+
Cote D'Ivoire|CI|384
|
53
|
+
Croatia (local name: Hrvatska)|HR|191
|
54
|
+
Cuba|CU|192
|
55
|
+
Cyprus|CY|196
|
56
|
+
Czech Republic|CZ|203
|
57
|
+
Denmark|DK|208
|
58
|
+
Djibouti|DJ|262
|
59
|
+
Dominica|DM|212
|
60
|
+
Dominican Republic|DO|214
|
61
|
+
East Timor|TP|626
|
62
|
+
Ecuador|EC|218
|
63
|
+
Egypt|EG|818
|
64
|
+
El Salvador|SV|222
|
65
|
+
Equatorial Guinea|GQ|226
|
66
|
+
Eritrea|ER|232
|
67
|
+
Estonia|EE|233
|
68
|
+
Ethiopia|ET|231
|
69
|
+
Falkland Islands (Malvinas)|FK|238
|
70
|
+
Faroe Islands|FO|234
|
71
|
+
Fiji|FJ|242
|
72
|
+
Finland|FI|246
|
73
|
+
France|FR|250
|
74
|
+
France, Metropolitan|FX|249
|
75
|
+
French Guiana|GF|254
|
76
|
+
French Polynesia|PF|258
|
77
|
+
French Southern Territories|TF|260
|
78
|
+
Gabon|GA|266
|
79
|
+
Gambia|GM|270
|
80
|
+
Georgia|GE|268
|
81
|
+
Germany|DE|276
|
82
|
+
Ghana|GH|288
|
83
|
+
Gibraltar|GI|292
|
84
|
+
Greece|GR|300
|
85
|
+
Greenland|GL|304
|
86
|
+
Grenada|GD|308
|
87
|
+
Guadeloupe|GP|312
|
88
|
+
Guam|GU|316
|
89
|
+
Guatemala|GT|320
|
90
|
+
Guinea|GN|324
|
91
|
+
Guinea-Bissau|GW|624
|
92
|
+
Guyana|GY|328
|
93
|
+
Haiti|HT|332
|
94
|
+
Heard and McDonald Islands|HM|334
|
95
|
+
Holy See (Vatican City State)|VA|336
|
96
|
+
Honduras|HN|340
|
97
|
+
Hong Kong|HK|344
|
98
|
+
Hungary|HU|348
|
99
|
+
Iceland|IS|352
|
100
|
+
India|IN|356
|
101
|
+
Indonesia|ID|360
|
102
|
+
Iran (Islamic Republic of)|IR|364
|
103
|
+
Iraq|IQ|368
|
104
|
+
Ireland|IE|372
|
105
|
+
Israel|IL|376
|
106
|
+
Italy|IT|380
|
107
|
+
Jamaica|JM|388
|
108
|
+
Japan|JP|392
|
109
|
+
Jordan|JO|400
|
110
|
+
Kazakhstan|KZ|398
|
111
|
+
Kenya|KE|404
|
112
|
+
Kiribati|KI|296
|
113
|
+
Korea, Democratic People's Republic of|KP|408
|
114
|
+
Korea, Republic of|KR|410
|
115
|
+
Kuwait|KW|414
|
116
|
+
Kyrgyzstan|KG|417
|
117
|
+
Lao People's Democratic Republic|LA|418
|
118
|
+
Latvia|LV|428
|
119
|
+
Lebanon|LB|422
|
120
|
+
Lesotho|LS|426
|
121
|
+
Liberia|LR|430
|
122
|
+
Libyan Arab Jamahiriya|LY|434
|
123
|
+
Liechtenstein|LI|438
|
124
|
+
Lithuania|LT|440
|
125
|
+
Luxembourg|LU|442
|
126
|
+
Macau|MO|446
|
127
|
+
Macedonia, the Former Yugoslav Republic of|MK|807
|
128
|
+
Madagascar|MG|450
|
129
|
+
Malawi|MW|454
|
130
|
+
Malaysia|MY|458
|
131
|
+
Maldives|MV|462
|
132
|
+
Mali|ML|466
|
133
|
+
Malta|MT|470
|
134
|
+
Marshall Islands|MH|584
|
135
|
+
Martinique|MQ|474
|
136
|
+
Mauritania|MR|478
|
137
|
+
Mauritius|MU|480
|
138
|
+
Mayotte|YT|175
|
139
|
+
Micronesia, Federated States of|FM|583
|
140
|
+
Moldova, Republic of|MD|498
|
141
|
+
Monaco|MC|492
|
142
|
+
Mongolia|MN|496
|
143
|
+
Montserrat|MS|500
|
144
|
+
Morocco|MA|504
|
145
|
+
Mozambique|MZ|508
|
146
|
+
Myanmar|MM|104
|
147
|
+
Namibia|NA|516
|
148
|
+
Nauru|NR|520
|
149
|
+
Nepal|NP|524
|
150
|
+
Netherlands|NL|528
|
151
|
+
Netherlands Antilles|AN|530
|
152
|
+
New Caledonia|NC|540
|
153
|
+
New Zealand|NZ|554
|
154
|
+
Nicaragua|NI|558
|
155
|
+
Niger|NE|562
|
156
|
+
Nigeria|NG|566
|
157
|
+
Niue|NU|570
|
158
|
+
Norfolk Island|NF|574
|
159
|
+
Northern Mariana Islands|MP|580
|
160
|
+
Norway|NO|578
|
161
|
+
Oman|OM|512
|
162
|
+
Pakistan|PK|586
|
163
|
+
Palau|PW|585
|
164
|
+
Palestinian Territory, Occupied|PS|275
|
165
|
+
Panama|PA|591
|
166
|
+
Papua New Guinea|PG|598
|
167
|
+
Paraguay|PY|600
|
168
|
+
Peru|PE|604
|
169
|
+
Philippines|PH|608
|
170
|
+
Pitcairn|PN|612
|
171
|
+
Poland|PL|616
|
172
|
+
Portugal|PT|620
|
173
|
+
Puerto Rico|PR|630
|
174
|
+
Qatar|QA|634
|
175
|
+
Reunion|RE|638
|
176
|
+
Romania|RO|642
|
177
|
+
Russian Federation|RU|643
|
178
|
+
Rwanda|RW|646
|
179
|
+
Saint Kitts and Nevis|KN|659
|
180
|
+
Saint Lucia|LC|662
|
181
|
+
Saint Vincent and the Grenadines|VC|670
|
182
|
+
Samoa|WS|882
|
183
|
+
San Marino|SM|674
|
184
|
+
Sao Tome and Principe|ST|678
|
185
|
+
Saudi Arabia|SA|682
|
186
|
+
Senegal|SN|686
|
187
|
+
Serbia and Montenegro|CS|891
|
188
|
+
Seychelles|SC|690
|
189
|
+
Sierra Leone|SL|694
|
190
|
+
Singapore|SG|702
|
191
|
+
Slovakia (Slovak Republic)|SK|703
|
192
|
+
Slovenia|SI|705
|
193
|
+
Solomon Islands|SB|90
|
194
|
+
Somalia|SO|706
|
195
|
+
South Africa|ZA|710
|
196
|
+
South Georgia and the South Sandwich Islands|GS|239
|
197
|
+
Spain|ES|724
|
198
|
+
Sri Lanka|LK|144
|
199
|
+
St. Helena|SH|654
|
200
|
+
St. Pierre and Miquelon|PM|666
|
201
|
+
Sudan|SD|736
|
202
|
+
Suriname|SR|740
|
203
|
+
Svalbard and Jan Mayen Islands|SJ|744
|
204
|
+
Swaziland|SZ|748
|
205
|
+
Sweden|SE|752
|
206
|
+
Switzerland|CH|756
|
207
|
+
Syrian Arab Republic|SY|760
|
208
|
+
Taiwan, Province of China|TW|158
|
209
|
+
Tajikistan|TJ|762
|
210
|
+
Tanzania, United Republic of|TZ|834
|
211
|
+
Thailand|TH|764
|
212
|
+
Timor-Leste|TL|626
|
213
|
+
Togo|TG|768
|
214
|
+
Tokelau|TK|772
|
215
|
+
Tonga|TO|776
|
216
|
+
Trinidad and Tobago|TT|780
|
217
|
+
Tunisia|TN|788
|
218
|
+
Turkey|TR|792
|
219
|
+
Turkmenistan|TM|795
|
220
|
+
Turks and Caicos Islands|TC|796
|
221
|
+
Tuvalu|TV|798
|
222
|
+
Uganda|UG|800
|
223
|
+
Ukraine|UA|804
|
224
|
+
United Arab Emirates|AE|784
|
225
|
+
United States Minor Outlying Islands|UM|581
|
226
|
+
Uruguay|UY|858
|
227
|
+
Uzbekistan|UZ|860
|
228
|
+
Vanuatu|VU|548
|
229
|
+
Venezuela|VE|862
|
230
|
+
Viet Nam|VN|704
|
231
|
+
Virgin Islands (British)|VG|92
|
232
|
+
Virgin Islands (U.S.)|VI|850
|
233
|
+
Wallis and Futuna Islands|WF|876
|
234
|
+
Western Sahara|EH|732
|
235
|
+
Yemen|YE|887
|
236
|
+
Yugoslavia|YU|891
|
237
|
+
Zambia|ZM|894
|
238
|
+
Zimbabwe|ZW|716
|
239
|
+
Canada|CA|124
|
240
|
+
Mexico|MX|484
|
241
|
+
United Kingdom|GB|826
|
242
|
+
United States|US|840
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
-- SET client_encoding TO 'UNICODE';
|
3
|
+
|
4
|
+
CREATE TABLE country (
|
5
|
+
name TEXT NOT NULL,
|
6
|
+
two_letter TEXT PRIMARY KEY,
|
7
|
+
id integer NOT NULL
|
8
|
+
);
|
9
|
+
CREATE INDEX country_name ON country(name);
|
10
|
+
|
11
|
+
|
12
|
+
CREATE TABLE subcountry (
|
13
|
+
country TEXT NOT NULL REFERENCES country(two_letter),
|
14
|
+
name TEXT,
|
15
|
+
subdivision TEXT,
|
16
|
+
level TEXT,
|
17
|
+
UNIQUE(country, name)
|
18
|
+
);
|
19
|
+
|
20
|
+
CREATE INDEX subcountry_country ON subcountry(country);
|
21
|
+
CREATE INDEX subcountry_name ON subcountry(name);
|
22
|
+
|