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,22 @@
1
+ require 'spec_helper'
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 be >= 0
8
+ Amalgalite::SQLite3.status.memory_used.highwater.should be >= 0
9
+ end
10
+
11
+ it "can reset the highwater value" do
12
+ before = Amalgalite::SQLite3.status.memory_used.highwater
13
+ before.should be > 0
14
+
15
+ current = Amalgalite::SQLite3.status.memory_used.current
16
+ Amalgalite::SQLite3.status.memory_used.reset!
17
+ Amalgalite::SQLite3.status.memory_used.highwater.should be == current
18
+
19
+ after = Amalgalite::SQLite3.status.memory_used.highwater
20
+ after.should_not eql(before)
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ require 'amalgalite/sqlite3/version'
3
+
4
+ describe "Amalgalite::SQLite3::Version" do
5
+ it "should have the sqlite3 version" do
6
+ expect(Amalgalite::SQLite3::VERSION).to match(/\d+\.\d+\.\d+/)
7
+ expect(Amalgalite::SQLite3::Version.to_s).to match( /\d+\.\d+\.\d+/ )
8
+ expect(Amalgalite::SQLite3::Version.runtime_version).to match( /\d+\.\d+\.\d+/ )
9
+
10
+ Amalgalite::SQLite3::Version.to_i.should eql(3021000)
11
+ Amalgalite::SQLite3::Version.runtime_version_number.should eql(3021000)
12
+
13
+ Amalgalite::SQLite3::Version::MAJOR.should eql(3)
14
+ Amalgalite::SQLite3::Version::MINOR.should eql(21)
15
+ Amalgalite::SQLite3::Version::RELEASE.should eql(0)
16
+ expect(Amalgalite::SQLite3::Version.to_a.size).to eql(3)
17
+
18
+ Amalgalite::SQLite3::Version.compiled_version.should be == "3.21.0"
19
+ Amalgalite::SQLite3::Version.compiled_version_number.should be == 3021000
20
+ Amalgalite::SQLite3::Version.compiled_matches_runtime?.should be == true
21
+ end
22
+
23
+ it "should have the sqlite3 source id" do
24
+ source_id = "2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de48827"
25
+ Amalgalite::SQLite3::Version.compiled_source_id.should be == source_id
26
+ Amalgalite::SQLite3::Version.runtime_source_id.should be == source_id
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
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 (#{RbConfig::CONFIG['configure_args'].include?( "--enable-pthread" )})" do
7
+ Amalgalite::SQLite3.threadsafe?.should eql(RbConfig::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,168 @@
1
+ require 'spec_helper'
2
+
3
+ describe Amalgalite::Statement do
4
+ before(:each) do
5
+ @db = Amalgalite::Database.new( SpecInfo.test_db )
6
+ end
7
+
8
+ after(:each) do
9
+ @db.close
10
+ end
11
+
12
+ it "a statement has a copy of the sql it was prepared with" do
13
+ stmt = @db.prepare( "SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
14
+ stmt.sql.should eql("SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
15
+ stmt.close
16
+ end
17
+
18
+ it "steps through results" do
19
+ now = Time.new.utc.strftime("%Y-%m-%d %H:%M")
20
+ @db.prepare( "SELECT strftime('%Y-%m-%d %H:%M', 'now') as now") do |stmt|
21
+ stmt.should_not eql(nil)
22
+ stmt.each do |row|
23
+ row['now'].should eql(now)
24
+ end
25
+ end
26
+ end
27
+
28
+ it "can prepare a statement without a block" do
29
+ stmt = @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two")
30
+ rs = stmt.execute( ":two" => "JP" )
31
+ rs.size.should eql(1)
32
+ stmt.close
33
+ end
34
+
35
+ it "knows how many parameters are in the statement" do
36
+ @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
37
+ stmt.check_parameter_count!( 1 ).should eql(1)
38
+ end
39
+ end
40
+
41
+ it "raises an error if there are not enough parameters are passed in a statement" do
42
+ @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
43
+ lambda{ stmt.execute }.should raise_error( Amalgalite::Error )
44
+ end
45
+ end
46
+
47
+
48
+ it "can run a query with a named parameter" do
49
+ @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
50
+ all_rows = stmt.execute( ":two" => "JP" )
51
+ all_rows.size.should eql(1)
52
+ all_rows.first['name'].should eql("Japan")
53
+ end
54
+ end
55
+
56
+ it "it can execute a query with a named parameter and yield the rows" do
57
+ @iso_db.prepare("SELECT * FROM country WHERE id = @id ORDER BY name") do |stmt|
58
+ rows = []
59
+ stmt.execute( "@id" => 891 ) do |row|
60
+ rows << row
61
+ end
62
+ rows.size.should eql(2)
63
+ rows.last['name'].should eql("Yugoslavia")
64
+ rows.first['two_letter'].should eql("CS")
65
+ end
66
+ end
67
+
68
+ it "can execute the same prepared statement multiple times" do
69
+ @db.execute(" CREATE TABLE t(x,y); ")
70
+ values = {}
71
+ @db.prepare("INSERT INTO t( x, y ) VALUES( $x, $y )" ) do |stmt|
72
+ 20.times do |x|
73
+ y = rand( x )
74
+ stmt.execute( { "$x" => x, "$y" => y } )
75
+ values[x] = y
76
+ end
77
+ end
78
+ c = 0
79
+ @db.execute("SELECT * from t") do |row|
80
+ c += 1
81
+ values[ row['x'] ].should eql(row['y'])
82
+ end
83
+ c.should eql(20)
84
+ end
85
+
86
+ it "expands an array when binding parameters" do
87
+ @db.execute(" CREATE TABLE t(x,y); ")
88
+ values = {}
89
+ @db.prepare( "INSERT INTO t( x, y ) VALUES( ?, ? )") do |stmt|
90
+ 20.times do |x|
91
+ y = rand( x )
92
+ a = [ x, y ]
93
+ stmt.execute( a )
94
+ values[x] = y
95
+ end
96
+ end
97
+ c = 0
98
+ @db.execute("SELECT * from t") do |row|
99
+ c += 1
100
+ values[ row['x'] ].should eql(row['y'])
101
+ end
102
+ c.should eql(20)
103
+
104
+ end
105
+
106
+ it "binds a integer variable correctly" do
107
+ @iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
108
+ all_rows = stmt.execute( 891 )
109
+ all_rows.size.should eql(2)
110
+ all_rows.last['name'].should eql("Yugoslavia")
111
+ all_rows.first['two_letter'].should eql("CS")
112
+ end
113
+ end
114
+
115
+ it "raises and error if an invaliding binding is attempted" do
116
+ @iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ") do |stmt|
117
+ lambda{ stmt.execute( "blah" => 42 ) }.should raise_error(Amalgalite::Error)
118
+ end
119
+ end
120
+
121
+ it "can reset the statement to the state it was before executing" do
122
+ stmt = @iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ")
123
+ stmt.reset_and_clear_bindings!
124
+ stmt.close
125
+ end
126
+
127
+ it "can execute a single sql command and say if there is remaining sql to execute" do
128
+ stmt = @db.prepare( @schema )
129
+ stmt.execute
130
+ stmt.remaining_sql.size.should be > 0
131
+ stmt.close
132
+ end
133
+
134
+ it "can select the rowid from the table" do
135
+ db = Amalgalite::Database.new( ":memory:" )
136
+ db.execute( "create table t1(c1,c2,c3)" )
137
+ db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
138
+ rows = db.execute( "select rowid,* from t1")
139
+ rows.size.should eql(1)
140
+ rows.first['rowid'].should eql(1)
141
+ rows.first['c1'].should eql(1 )
142
+ rows.first['c3'].should eql('abc')
143
+ end
144
+
145
+ it "shows that the rowid column is rowid column" do
146
+ db = Amalgalite::Database.new( ":memory:" )
147
+ db.execute( "create table t1(c1,c2,c3)" )
148
+ db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
149
+ db.prepare( "select oid,* from t1" ) do |stmt|
150
+ stmt.execute
151
+ stmt.should be_using_rowid_column
152
+ end
153
+
154
+ db.prepare( "select * from t1" ) do |stmt|
155
+ stmt.execute
156
+ stmt.should_not be_using_rowid_column
157
+ end
158
+ end
159
+
160
+ it "has index based access to the result set" do
161
+ @iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
162
+ all_rows = stmt.execute( 891 )
163
+ all_rows.size.should eql(2)
164
+ all_rows.last.first.should eql("Yugoslavia")
165
+ all_rows.first[1].should eql("CS")
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'amalgalite/type_maps/storage_map'
3
+
4
+ describe Amalgalite::TypeMaps::StorageMap do
5
+ before(:each) do
6
+ @map = Amalgalite::TypeMaps::StorageMap.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( :string => "testing mapping", :column => true ) ).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
+ describe "#result_value_of" do
34
+ it "returns the original object for everything passed in" do
35
+ @map.result_value_of( "doesn't matter", 42 ).should == 42
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ require 'amalgalite'
4
+ require 'amalgalite/trace_tap'
5
+ require 'amalgalite/profile_tap'
6
+ require 'amalgalite/taps/console'
7
+ require 'stringio'
8
+
9
+ describe Amalgalite::TraceTap do
10
+ it "wraps up an object and delegates the 'trace' method to a method on that object" do
11
+ s = StringIO.new
12
+ tt = ::Amalgalite::TraceTap.new( s, 'puts' )
13
+ tt.trace('test trace')
14
+ s.string.should eql("test trace\n")
15
+ end
16
+
17
+ it "raises an error if an the wrapped object does not respond to the indicated method" do
18
+ lambda{ ::Amalgalite::TraceTap.new( Object.new ) }.should raise_error( Amalgalite::Error )
19
+ end
20
+ end
21
+
22
+ describe Amalgalite::ProfileTap do
23
+ it "raises an error if an the wrapped object does not respond to the indicated method" do
24
+ lambda{ ::Amalgalite::ProfileTap.new( Object.new ) }.should raise_error( Amalgalite::Error )
25
+ end
26
+ end
27
+
28
+ describe Amalgalite::Taps::StringIO do
29
+ it "dumps profile information" do
30
+ s = ::Amalgalite::Taps::StringIO.new
31
+ s.profile( 'test', 42 )
32
+ s.dump_profile
33
+ s.string.should eql("42 : test\n[test] => sum: 42, sumsq: 1764, n: 1, mean: 42.000000, stddev: 0.000000, min: 42, max: 42\n")
34
+ end
35
+
36
+ it "has a stdout tap" do
37
+ ::Amalgalite::Taps::Stdout.new
38
+ end
39
+
40
+ it "has a stderr tap" do
41
+ ::Amalgalite::Taps::Stderr.new
42
+ end
43
+ end
44
+
45
+ describe Amalgalite::ProfileSampler do
46
+ it "aggregates samples" do
47
+ s = Amalgalite::ProfileSampler.new( 'test1' )
48
+ s.sample( 42 )
49
+ s.sample( 84 )
50
+ s.sample( 21 )
51
+ h = s.to_h
52
+ h['min'].should eql(21)
53
+ h['max'].should eql(84)
54
+ h['mean'].should eql(49.0)
55
+ h['n'].should eql(3)
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'amalgalite/type_maps/text_map'
3
+
4
+ describe Amalgalite::TypeMaps::TextMap do
5
+ before(:each) do
6
+ @map = Amalgalite::TypeMaps::TextMap.new
7
+ end
8
+
9
+ describe "#bind_type_of" do
10
+ it "returnes text for everything" do
11
+ @map.bind_type_of( 3.14 ).should == ::Amalgalite::SQLite3::Constants::DataType::TEXT
12
+ end
13
+ end
14
+
15
+ describe "#result_value_of" do
16
+ it "returns the string value of the object for everything passed in" do
17
+ @map.result_value_of( "doesn't matter", 42 ).should == "42"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'amalgalite/type_map'
3
+
4
+ describe Amalgalite::TypeMap do
5
+ it "#bind_type_of raises NotImplemented error" do
6
+ tm = Amalgalite::TypeMap.new
7
+ lambda { tm.bind_type_of( Object.new ) }.should raise_error( NotImplementedError )
8
+ end
9
+
10
+ it "#result_value_of raises NotImplemented error" do
11
+ tm = Amalgalite::TypeMap.new
12
+ lambda { tm.result_value_of( "foo", Object.new ) }.should raise_error( NotImplementedError )
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'amalgalite/version'
3
+
4
+ describe "Amalgalite::VERSION" do
5
+ it "should have a version string" do
6
+ expect(Amalgalite::VERSION).to match( /\d+\.\d+\.\d+/ )
7
+ end
8
+ end
@@ -0,0 +1,102 @@
1
+ #-----------------------------------------------------------------------
2
+ # Custom tasks for this project
3
+ #-----------------------------------------------------------------------
4
+ require 'pathname'
5
+ namespace :util do
6
+ desc "List the sqlite api calls that are not implemented"
7
+ task :todo do
8
+
9
+ not_implementing = %w[
10
+ sqlite3_exec
11
+ sqlite3_open
12
+ sqlite3_os_end
13
+ sqlite3_os_init
14
+ sqlite3_malloc
15
+ sqlite3_realloc
16
+ sqlite3_free
17
+ sqlite3_get_table
18
+ sqlite3_free_table
19
+ sqlite3_key
20
+ sqlite3_rekey
21
+ sqlite3_next_stmt
22
+ sqlite3_release_memory
23
+ sqlite3_sleep
24
+ sqlite3_snprintf
25
+ sqlite3_vmprintf
26
+ sqlite3_strnicmp
27
+ sqlite3_test_control
28
+ sqlite3_unlock_notify
29
+ sqlite3_vfs_find
30
+ sqlite3_vfs_register
31
+ sqlite3_vfs_unregister
32
+ ]
33
+
34
+ sqlite_h = File.join( *%w[ ext amalgalite c sqlite3.h ] )
35
+ api_todo = {}
36
+ IO.readlines( sqlite_h ).each do |line|
37
+ if line =~ /\ASQLITE_API/ then
38
+ if line !~ /SQLITE_DEPRECATED/ and line !~ /SQLITE_EXPERIMENTAL/ then
39
+ if md = line.match( /(sqlite3_[^(\s]+)\(/ ) then
40
+ next if not_implementing.include?(md.captures[0])
41
+ api_todo[md.captures[0]] = true
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ Dir.glob("ext/amalgalite/c/amalgalite*.c").each do |am_file|
48
+ IO.readlines( am_file ).each do |am_line|
49
+ if md = am_line.match( /(sqlite3_[^(\s]+)\(/ ) then
50
+ api_todo.delete( md.captures[0] )
51
+ end
52
+ end
53
+ end
54
+
55
+ puts "#{api_todo.keys.size} functions to still implement"
56
+ puts api_todo.keys.sort.join("\n")
57
+ end
58
+
59
+ desc "Download and integrate a version of sqlite"
60
+ task :update_sqlite, [:version,:year] do |task, args|
61
+ version = args[:version] or abort "A version of SQLite please `rake #{task.name}[version,year]`"
62
+ version_year = args[:year] or abort "The Year #{version} was released please `rake #{task.name}[version,year]`"
63
+
64
+ require 'uri'
65
+ require 'open-uri'
66
+ require 'zip'
67
+
68
+ parts = version.split(".")
69
+ next_version = [ parts.shift.to_s ]
70
+ parts.each do |p|
71
+ next_version << "#{"%02d" % p }"
72
+ end
73
+ next_version << "00" if next_version.size == 3
74
+
75
+ next_version = next_version.join('')
76
+
77
+ url = ::URI.parse("http://sqlite.org/#{version_year}/sqlite-amalgamation-#{next_version}.zip")
78
+ puts "downloading #{url.to_s} ..."
79
+ file = "tmp/#{File.basename( url.path ) }"
80
+ FileUtils.mkdir "tmp" unless File.directory?( "tmp" )
81
+ File.open( file, "wb+") do |f|
82
+ open(url) do |input|
83
+ f.write( input.read )
84
+ end
85
+ end
86
+
87
+ puts "extracting..."
88
+ upstream_files = %w[ sqlite3.h sqlite3.c sqlite3ext.h ]
89
+ Zip::ZipInputStream.open( file ) do |io|
90
+ loop do
91
+ entry = io.get_next_entry
92
+ break unless entry
93
+ bname = File.basename( entry.name )
94
+ if upstream_files.include?( bname ) then
95
+ dest_file = File.join( "ext", "amalgalite", "c", bname )
96
+ puts "updating #{dest_file}"
97
+ entry.extract( dest_file ) { true }
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end