amalgalite 1.6.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +49 -0
  3. data/HISTORY.md +346 -0
  4. data/LICENSE +31 -0
  5. data/Manifest.txt +104 -0
  6. data/README.md +65 -0
  7. data/Rakefile +26 -0
  8. data/TODO.md +57 -0
  9. data/bin/amalgalite-pack +147 -0
  10. data/examples/a.rb +9 -0
  11. data/examples/blob.rb +88 -0
  12. data/examples/bootstrap.rb +36 -0
  13. data/examples/define_aggregate.rb +75 -0
  14. data/examples/define_function.rb +104 -0
  15. data/examples/fts5.rb +152 -0
  16. data/examples/gem-db.rb +94 -0
  17. data/examples/require_me.rb +11 -0
  18. data/examples/requires.rb +42 -0
  19. data/examples/schema-info.rb +34 -0
  20. data/ext/amalgalite/c/amalgalite.c +355 -0
  21. data/ext/amalgalite/c/amalgalite.h +151 -0
  22. data/ext/amalgalite/c/amalgalite_blob.c +240 -0
  23. data/ext/amalgalite/c/amalgalite_constants.c +1226 -0
  24. data/ext/amalgalite/c/amalgalite_database.c +1178 -0
  25. data/ext/amalgalite/c/amalgalite_requires_bootstrap.c +282 -0
  26. data/ext/amalgalite/c/amalgalite_statement.c +649 -0
  27. data/ext/amalgalite/c/extconf.rb +62 -0
  28. data/ext/amalgalite/c/gen_constants.rb +330 -0
  29. data/ext/amalgalite/c/notes.txt +134 -0
  30. data/ext/amalgalite/c/sqlite3.c +205352 -0
  31. data/ext/amalgalite/c/sqlite3.h +10727 -0
  32. data/ext/amalgalite/c/sqlite3_options.h +4 -0
  33. data/ext/amalgalite/c/sqlite3ext.h +578 -0
  34. data/lib/amalgalite.rb +51 -0
  35. data/lib/amalgalite/2.0/amalgalite.so +0 -0
  36. data/lib/amalgalite/2.1/amalgalite.so +0 -0
  37. data/lib/amalgalite/2.2/amalgalite.so +0 -0
  38. data/lib/amalgalite/2.3/amalgalite.so +0 -0
  39. data/lib/amalgalite/2.4/amalgalite.so +0 -0
  40. data/lib/amalgalite/aggregate.rb +67 -0
  41. data/lib/amalgalite/blob.rb +186 -0
  42. data/lib/amalgalite/boolean.rb +42 -0
  43. data/lib/amalgalite/busy_timeout.rb +47 -0
  44. data/lib/amalgalite/column.rb +99 -0
  45. data/lib/amalgalite/core_ext/kernel/require.rb +21 -0
  46. data/lib/amalgalite/csv_table_importer.rb +74 -0
  47. data/lib/amalgalite/database.rb +984 -0
  48. data/lib/amalgalite/function.rb +61 -0
  49. data/lib/amalgalite/index.rb +43 -0
  50. data/lib/amalgalite/memory_database.rb +15 -0
  51. data/lib/amalgalite/packer.rb +231 -0
  52. data/lib/amalgalite/paths.rb +80 -0
  53. data/lib/amalgalite/profile_tap.rb +131 -0
  54. data/lib/amalgalite/progress_handler.rb +21 -0
  55. data/lib/amalgalite/requires.rb +151 -0
  56. data/lib/amalgalite/schema.rb +225 -0
  57. data/lib/amalgalite/sqlite3.rb +6 -0
  58. data/lib/amalgalite/sqlite3/constants.rb +95 -0
  59. data/lib/amalgalite/sqlite3/database/function.rb +48 -0
  60. data/lib/amalgalite/sqlite3/database/status.rb +68 -0
  61. data/lib/amalgalite/sqlite3/status.rb +60 -0
  62. data/lib/amalgalite/sqlite3/version.rb +55 -0
  63. data/lib/amalgalite/statement.rb +418 -0
  64. data/lib/amalgalite/table.rb +91 -0
  65. data/lib/amalgalite/taps.rb +2 -0
  66. data/lib/amalgalite/taps/console.rb +27 -0
  67. data/lib/amalgalite/taps/io.rb +71 -0
  68. data/lib/amalgalite/trace_tap.rb +35 -0
  69. data/lib/amalgalite/type_map.rb +63 -0
  70. data/lib/amalgalite/type_maps/default_map.rb +166 -0
  71. data/lib/amalgalite/type_maps/storage_map.rb +38 -0
  72. data/lib/amalgalite/type_maps/text_map.rb +21 -0
  73. data/lib/amalgalite/version.rb +8 -0
  74. data/lib/amalgalite/view.rb +26 -0
  75. data/spec/aggregate_spec.rb +154 -0
  76. data/spec/amalgalite_spec.rb +4 -0
  77. data/spec/blob_spec.rb +78 -0
  78. data/spec/boolean_spec.rb +24 -0
  79. data/spec/busy_handler.rb +157 -0
  80. data/spec/data/iso-3166-country.txt +242 -0
  81. data/spec/data/iso-3166-schema.sql +22 -0
  82. data/spec/data/iso-3166-subcountry.txt +3995 -0
  83. data/spec/data/make-iso-db.sh +12 -0
  84. data/spec/database_spec.rb +508 -0
  85. data/spec/default_map_spec.rb +92 -0
  86. data/spec/function_spec.rb +78 -0
  87. data/spec/integeration_spec.rb +97 -0
  88. data/spec/iso_3166_database.rb +58 -0
  89. data/spec/packer_spec.rb +60 -0
  90. data/spec/paths_spec.rb +28 -0
  91. data/spec/progress_handler_spec.rb +91 -0
  92. data/spec/requires_spec.rb +54 -0
  93. data/spec/rtree_spec.rb +66 -0
  94. data/spec/schema_spec.rb +131 -0
  95. data/spec/spec_helper.rb +48 -0
  96. data/spec/sqlite3/constants_spec.rb +108 -0
  97. data/spec/sqlite3/database_status_spec.rb +36 -0
  98. data/spec/sqlite3/status_spec.rb +22 -0
  99. data/spec/sqlite3/version_spec.rb +28 -0
  100. data/spec/sqlite3_spec.rb +53 -0
  101. data/spec/statement_spec.rb +168 -0
  102. data/spec/storage_map_spec.rb +38 -0
  103. data/spec/tap_spec.rb +57 -0
  104. data/spec/text_map_spec.rb +20 -0
  105. data/spec/type_map_spec.rb +14 -0
  106. data/spec/version_spec.rb +8 -0
  107. data/tasks/custom.rake +102 -0
  108. data/tasks/default.rake +240 -0
  109. data/tasks/extension.rake +38 -0
  110. data/tasks/this.rb +208 -0
  111. metadata +318 -0
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'amalgalite/requires'
3
+
4
+ #describe Amalgalite::Requires do
5
+ # it "#require_order has all files in 'lib' and no more" do
6
+ # dir_files = Dir.glob( File.join( Amalgalite::Paths.lib_path , "**", "*.rb" ) )
7
+ # require_files = Amalgalite::Requires.require_order.collect { |r| Amalgalite::Paths.lib_path r }
8
+ # dir_files.size.should == require_files.size
9
+ # (dir_files - require_files).size.should == 0
10
+ # (require_files - dir_files).size.should == 0
11
+ # end
12
+ #
13
+ # it "can compress and uncompress data" do
14
+ # s = IO.read( __FILE__ )
15
+ # s_gz = Amalgalite::Requires.gzip( s )
16
+ # s.should == Amalgalite::Requires.gunzip( s_gz )
17
+ # end
18
+ #end
19
+
20
+
21
+ describe Amalgalite::Requires do
22
+ it "can import to an in-memory database" do
23
+ sql = <<-SQL
24
+ CREATE TABLE rubylibs (
25
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ filename TEXT UNIQUE,
27
+ compressed BOOLEAN,
28
+ contents BLOB
29
+ );
30
+ INSERT INTO "rubylibs" VALUES(1, "application", "false", 'A=1');
31
+ SQL
32
+ r = Amalgalite::Requires.new(:dbfile_name => ":memory:")
33
+ r.import(sql)
34
+ r.file_contents( "application" ).should == "A=1"
35
+ end
36
+
37
+
38
+ it "gives equal instances for file databases" do
39
+ a = Amalgalite::Requires.new( :dbfile_name => SpecInfo.test_db )
40
+ b = Amalgalite::Requires.new( :dbfile_name => SpecInfo.test_db )
41
+
42
+ a.db_connection.should equal( b.db_connection )
43
+ end
44
+
45
+
46
+ it "gives separate instances for in-memory databases" do
47
+ a = Amalgalite::Requires.new( :dbfile_name => ":memory:" )
48
+ b = Amalgalite::Requires.new( :dbfile_name => ":memory:" )
49
+
50
+ a.db_connection.should_not equal(b.db_connection)
51
+ end
52
+
53
+
54
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ #
4
+ # Example from http://sqlite.org/rtree.html
5
+ #
6
+ describe "SQLite3 R*Tree extension" do
7
+ before( :each ) do
8
+ @db = Amalgalite::Database.new( ":memory:" )
9
+ x = @db.execute_batch <<-sql
10
+ CREATE VIRTUAL TABLE demo_index USING rtree(
11
+ id, -- Integer primary key
12
+ minX, maxX, -- Minimum and maximum X coordinate
13
+ minY, maxY -- Minimum and maximum Y coordinate
14
+ );
15
+ --
16
+ INSERT INTO demo_index VALUES(
17
+ 1, -- Primary key
18
+ -80.7749, -80.7747, -- Longitude range
19
+ 30.3776, 30.3778 -- Latitude range
20
+ );
21
+ INSERT INTO demo_index VALUES(
22
+ 2,
23
+ -81.0, -79.6,
24
+ 35.0, 36.2
25
+ );
26
+ sql
27
+ x.should == 3
28
+ end
29
+
30
+ after( :each ) do
31
+ @db.close
32
+ end
33
+
34
+ it "has 2 rows" do
35
+ r = @db.first_value_from( "SELECT count(*) FROM demo_index")
36
+ r.should == 2
37
+ end
38
+
39
+ it "queries normally" do
40
+ r = @db.execute "SELECT * FROM demo_index WHERE id=1;"
41
+ r.size.should be == 1
42
+ row = r.first
43
+ row['id'].should be == 1
44
+ end
45
+
46
+ it "does a 'contained within' query" do
47
+ r = @db.execute <<-sql
48
+ SELECT id FROM demo_index
49
+ WHERE minX>=-81.08 AND maxX<=-80.58
50
+ AND minY>=30.00 AND maxY<=30.44;
51
+ sql
52
+
53
+ r.size.should be == 1
54
+ r.first['id'].should be == 1
55
+ end
56
+
57
+ it "does an 'overlapping' query" do
58
+ r = @db.execute <<-sql
59
+ SELECT id FROM demo_index
60
+ WHERE maxX>=-81.08 AND minX<=-80.58
61
+ AND maxY>=30.00 AND minY<=35.44;
62
+ sql
63
+ r.size.should == 2
64
+ end
65
+ end
66
+
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ require 'amalgalite'
4
+ require 'amalgalite/schema'
5
+
6
+ describe Amalgalite::Schema do
7
+
8
+ it "loads the schema of a database" do
9
+ schema = @iso_db.schema
10
+ schema.load_tables
11
+ schema.tables.size.should eql(2)
12
+ end
13
+
14
+ it "loads the views in the database" do
15
+ s = @iso_db.schema
16
+ 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"
17
+ @iso_db.execute( sql )
18
+ s.dirty?.should be == true
19
+ @iso_db.schema.load_views
20
+ @iso_db.schema.views.size.should eql(1)
21
+ @iso_db.schema.views["v1"].sql.should eql(sql)
22
+ end
23
+
24
+ it "removes quotes from around default values in columns" do
25
+ s = @iso_db.schema
26
+ sql = "CREATE TABLE t1( d1 default 't' )"
27
+ @iso_db.execute( sql )
28
+ s.dirty?.should be == true
29
+ tt = @iso_db.schema.tables['t1']
30
+ tt.columns['d1'].default_value.should be == "t"
31
+ end
32
+
33
+ it "loads the tables and columns" do
34
+ ct = @iso_db.schema.tables['country']
35
+ ct.name.should eql("country")
36
+ ct.columns.size.should eql(3)
37
+ ct.indexes.size.should eql(2)
38
+ ct.column_names.should eql(%w[ name two_letter id ])
39
+ @iso_db.schema.tables.size.should eql(2)
40
+
41
+
42
+ ct.columns['two_letter'].should be_primary_key
43
+ ct.columns['two_letter'].declared_data_type.should eql("TEXT")
44
+ ct.columns['name'].should_not be_nullable
45
+ ct.columns['name'].should be_not_null_constraint
46
+ ct.columns['name'].should_not be_has_default_value
47
+ ct.columns['id'].should_not be_auto_increment
48
+ end
49
+
50
+ it "knows what the primary key of a table is" do
51
+ ct = @iso_db.schema.tables['country']
52
+ ct.primary_key.should == [ ct.columns['two_letter'] ]
53
+ end
54
+
55
+ it "knows the primary key of a table even without an explicity unique index" do
56
+ s = @iso_db.schema
57
+ sql = "CREATE TABLE u( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , other text )"
58
+ @iso_db.execute( sql )
59
+ s.dirty?.should be == true
60
+ ut = @iso_db.schema.tables['u']
61
+ ut.primary_key.should == [ ut.columns['id'] ]
62
+ end
63
+
64
+ it "knows the primary key of a temporary table" do
65
+ @iso_db.execute "CREATE TEMPORARY TABLE tt( a, b INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, c )"
66
+ tt = @iso_db.schema.tables[ 'tt' ]
67
+ tt.primary_key.should == [ tt.columns['b'] ]
68
+ end
69
+
70
+ it "knows what the primary key of a table is when it is a multiple column primary key" do
71
+ sql = "CREATE TABLE m ( id1, id2, PRIMARY KEY (id2, id1) )"
72
+ s = @iso_db.schema
73
+ @iso_db.execute( sql )
74
+ s.dirty?.should be == true
75
+ mt = @iso_db.schema.tables['m']
76
+ mt.primary_key.should == [ mt.columns['id2'], mt.columns['id1'] ]
77
+ end
78
+
79
+ it "loads the indexes" do
80
+ c = @iso_db.schema.tables['country']
81
+ c.indexes.size.should eql(2)
82
+ c.indexes['country_name'].columns.size.should eql(1)
83
+ c.indexes['country_name'].should_not be_unique
84
+ c.indexes['country_name'].sequence_number.should eql(0)
85
+ c.indexes['country_name'].columns.first.should eql(@iso_db.schema.tables['country'].columns['name'])
86
+ c.indexes['sqlite_autoindex_country_1'].should be_unique
87
+
88
+ subc = @iso_db.schema.tables['subcountry']
89
+ subc.indexes.size.should eql(3)
90
+ subc.indexes['subcountry_country'].columns.first.should eql(@iso_db.schema.tables['subcountry'].columns['country'])
91
+ end
92
+
93
+ it "knows the schema is dirty when a table is created" do
94
+ s = @iso_db.schema
95
+ s.tables['country']
96
+ s.dirty?.should be == false
97
+ @iso_db.execute( "create table x1( a, b )" )
98
+ s.dirty?.should be == true
99
+ end
100
+
101
+ it "knows the schema is dirty when a table is dropped" do
102
+ s = @iso_db.schema
103
+ s.tables['country']
104
+ @iso_db.execute( "create table x1( a, b )" )
105
+ s.dirty?.should be == true
106
+
107
+ @iso_db.schema.load_schema!
108
+ s = @iso_db.schema
109
+
110
+ s.dirty?.should be == false
111
+ @iso_db.execute("drop table x1")
112
+ s.dirty?.should be == true
113
+ end
114
+
115
+ it "knows if a temporary table exists" do
116
+ @iso_db.execute "CREATE TEMPORARY TABLE tt(a,b,c)"
117
+ @iso_db.schema.tables.keys.include?('tt').should be == true
118
+ @iso_db.schema.tables['tt'].temporary?.should be == true
119
+ end
120
+
121
+ it "sees that temporary tables shadow real tables" do
122
+ @iso_db.execute "CREATE TABLE tt(x)"
123
+ @iso_db.schema.tables['tt'].temporary?.should be == false
124
+ @iso_db.execute "CREATE TEMP TABLE tt(a,b,c)"
125
+ @iso_db.schema.tables['tt'].temporary?.should be == true
126
+ @iso_db.execute "DROP TABLE tt"
127
+ @iso_db.schema.tables['tt'].temporary?.should be == false
128
+ @iso_db.schema.tables['tt'].columns.size.should be == 1
129
+ end
130
+
131
+ end
@@ -0,0 +1,48 @@
1
+ require 'rspec'
2
+ require 'fileutils'
3
+
4
+ require 'amalgalite'
5
+ require Amalgalite::Paths.spec_path( "iso_3166_database.rb" )
6
+
7
+ class SpecInfo
8
+ class << self
9
+ def test_db
10
+ @test_db ||= Amalgalite::Paths.spec_path("data", "test.db")
11
+ end
12
+
13
+ def make_master_iso_db
14
+ @master_db ||= Amalgalite::Iso3166Database.new
15
+ end
16
+
17
+ def make_clone_iso_db
18
+ make_master_iso_db.duplicate( 'testing' )
19
+ end
20
+ end
21
+ end
22
+
23
+ RSpec.configure do |config|
24
+ config.expect_with :rspec do |c|
25
+ c.syntax = [:should, :expect]
26
+ end
27
+
28
+ config.before(:all) do
29
+ SpecInfo.make_master_iso_db
30
+ end
31
+
32
+ config.after(:all) do
33
+ File.unlink( Amalgalite::Iso3166Database.default_db_file ) if File.exist?( Amalgalite::Iso3166Database.default_db_file )
34
+ end
35
+
36
+ config.before( :each ) do
37
+ @iso_db_path = SpecInfo.make_clone_iso_db
38
+ @iso_db = Amalgalite::Database.new( @iso_db_path )
39
+ @schema = IO.read( Amalgalite::Iso3166Database.schema_file )
40
+ end
41
+
42
+ config.after( :each ) do
43
+ @iso_db.close
44
+ File.unlink( @iso_db_path ) if File.exist?( @iso_db_path )
45
+ File.unlink( SpecInfo.test_db ) if File.exist?( SpecInfo.test_db )
46
+ end
47
+ end
48
+
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
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
+ describe 'ResultCode' do
12
+ it "has constants" do
13
+ Amalgalite::SQLite3::Constants::ResultCode::OK.should == 0
14
+ end
15
+
16
+ it "can return the constant from a number" do
17
+ c = Amalgalite::SQLite3::Constants::ResultCode.name_from_value( 21 )
18
+ c.should == "MISUSE"
19
+ end
20
+
21
+ it "can return the number from a name" do
22
+ v = Amalgalite::SQLite3::Constants::ResultCode.value_from_name( "MISUSE" )
23
+ v.should == 21
24
+ end
25
+ end
26
+
27
+ describe "DataType" do
28
+ it "has constants" do
29
+ Amalgalite::SQLite3::Constants::DataType::NULL.should == 5
30
+ end
31
+
32
+ it "can return the constant from a number" do
33
+ c = Amalgalite::SQLite3::Constants::DataType.name_from_value( 5 )
34
+ c.should == "NULL"
35
+ end
36
+
37
+ it "can return the number from a name" do
38
+ v = Amalgalite::SQLite3::Constants::DataType.value_from_name( "Null" )
39
+ v.should == 5
40
+ end
41
+
42
+ end
43
+
44
+ describe "Config" do
45
+ it "has constants" do
46
+ Amalgalite::SQLite3::Constants::Config::HEAP.should == 8
47
+ end
48
+
49
+ it "can return the constant from a number" do
50
+ c = Amalgalite::SQLite3::Constants::Config.name_from_value( 8 )
51
+ c.should == "HEAP"
52
+ end
53
+
54
+ it "can return the number from a name" do
55
+ v = Amalgalite::SQLite3::Constants::Config.value_from_name( "heap" )
56
+ v.should == 8
57
+ end
58
+
59
+ end
60
+
61
+ describe 'Status' do
62
+ it "has constants" do
63
+ Amalgalite::SQLite3::Constants::Status::MEMORY_USED.should == 0
64
+ end
65
+
66
+ it "can return the constant from a number" do
67
+ c = Amalgalite::SQLite3::Constants::Status.name_from_value( 3 )
68
+ c.should == "SCRATCH_USED"
69
+ end
70
+
71
+ it "can return the number from a name" do
72
+ v = Amalgalite::SQLite3::Constants::Status.value_from_name( "memory_used" )
73
+ v.should == 0
74
+ end
75
+ end
76
+
77
+ describe 'DBStatus' do
78
+ it "has constants" do
79
+ Amalgalite::SQLite3::Constants::DBStatus::LOOKASIDE_USED.should == 0
80
+ end
81
+
82
+ it "can return the constant from a number" do
83
+ c = Amalgalite::SQLite3::Constants::DBStatus.name_from_value( 0 )
84
+ c.should == "LOOKASIDE_USED"
85
+ end
86
+
87
+ it "can return the number from a name" do
88
+ v = Amalgalite::SQLite3::Constants::DBStatus.value_from_name( "lookaside_used" )
89
+ v.should == 0
90
+ end
91
+ end
92
+
93
+ describe "StatementStatus" do
94
+ it "has constants" do
95
+ Amalgalite::SQLite3::Constants::StatementStatus::AUTOINDEX.should == 3
96
+ end
97
+
98
+ it "can return the constant from a number" do
99
+ c = Amalgalite::SQLite3::Constants::StatementStatus.name_from_value( 3 )
100
+ c.should == "AUTOINDEX"
101
+ end
102
+
103
+ it "can return the number from a name" do
104
+ v = Amalgalite::SQLite3::Constants::StatementStatus.value_from_name( "autoindex" )
105
+ v.should == 3
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
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 be > 0
22
+ @db.api.status.lookaside_used.current.should be >= 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 be > 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