amalgalite 0.10.1-x86-mingw32

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.
Files changed (100) hide show
  1. data/HISTORY +201 -0
  2. data/LICENSE +29 -0
  3. data/README +51 -0
  4. data/bin/amalgalite-pack +126 -0
  5. data/examples/a.rb +9 -0
  6. data/examples/blob.rb +88 -0
  7. data/examples/bootstrap.rb +36 -0
  8. data/examples/define_aggregate.rb +75 -0
  9. data/examples/define_function.rb +104 -0
  10. data/examples/gem-db.rb +94 -0
  11. data/examples/gems.db +0 -0
  12. data/examples/require_me.rb +11 -0
  13. data/examples/requires.rb +42 -0
  14. data/examples/schema-info.rb +34 -0
  15. data/ext/amalgalite/amalgalite3.c +290 -0
  16. data/ext/amalgalite/amalgalite3.h +151 -0
  17. data/ext/amalgalite/amalgalite3_blob.c +240 -0
  18. data/ext/amalgalite/amalgalite3_constants.c +221 -0
  19. data/ext/amalgalite/amalgalite3_database.c +1148 -0
  20. data/ext/amalgalite/amalgalite3_requires_bootstrap.c +210 -0
  21. data/ext/amalgalite/amalgalite3_statement.c +639 -0
  22. data/ext/amalgalite/extconf.rb +36 -0
  23. data/ext/amalgalite/gen_constants.rb +130 -0
  24. data/ext/amalgalite/sqlite3.c +106729 -0
  25. data/ext/amalgalite/sqlite3.h +5626 -0
  26. data/ext/amalgalite/sqlite3_options.h +4 -0
  27. data/ext/amalgalite/sqlite3ext.h +380 -0
  28. data/gemspec.rb +60 -0
  29. data/lib/amalgalite.rb +43 -0
  30. data/lib/amalgalite/1.8/amalgalite3.so +0 -0
  31. data/lib/amalgalite/1.9/amalgalite3.so +0 -0
  32. data/lib/amalgalite/aggregate.rb +67 -0
  33. data/lib/amalgalite/blob.rb +186 -0
  34. data/lib/amalgalite/boolean.rb +42 -0
  35. data/lib/amalgalite/busy_timeout.rb +47 -0
  36. data/lib/amalgalite/column.rb +97 -0
  37. data/lib/amalgalite/core_ext/kernel/require.rb +21 -0
  38. data/lib/amalgalite/database.rb +947 -0
  39. data/lib/amalgalite/function.rb +61 -0
  40. data/lib/amalgalite/index.rb +43 -0
  41. data/lib/amalgalite/packer.rb +226 -0
  42. data/lib/amalgalite/paths.rb +70 -0
  43. data/lib/amalgalite/profile_tap.rb +131 -0
  44. data/lib/amalgalite/progress_handler.rb +21 -0
  45. data/lib/amalgalite/requires.rb +120 -0
  46. data/lib/amalgalite/schema.rb +191 -0
  47. data/lib/amalgalite/sqlite3.rb +6 -0
  48. data/lib/amalgalite/sqlite3/constants.rb +80 -0
  49. data/lib/amalgalite/sqlite3/database/function.rb +48 -0
  50. data/lib/amalgalite/sqlite3/database/status.rb +68 -0
  51. data/lib/amalgalite/sqlite3/status.rb +60 -0
  52. data/lib/amalgalite/sqlite3/version.rb +37 -0
  53. data/lib/amalgalite/statement.rb +414 -0
  54. data/lib/amalgalite/table.rb +90 -0
  55. data/lib/amalgalite/taps.rb +2 -0
  56. data/lib/amalgalite/taps/console.rb +27 -0
  57. data/lib/amalgalite/taps/io.rb +71 -0
  58. data/lib/amalgalite/trace_tap.rb +35 -0
  59. data/lib/amalgalite/type_map.rb +63 -0
  60. data/lib/amalgalite/type_maps/default_map.rb +167 -0
  61. data/lib/amalgalite/type_maps/storage_map.rb +40 -0
  62. data/lib/amalgalite/type_maps/text_map.rb +22 -0
  63. data/lib/amalgalite/version.rb +37 -0
  64. data/lib/amalgalite/view.rb +26 -0
  65. data/spec/aggregate_spec.rb +169 -0
  66. data/spec/amalgalite_spec.rb +4 -0
  67. data/spec/blob_spec.rb +81 -0
  68. data/spec/boolean_spec.rb +23 -0
  69. data/spec/busy_handler.rb +165 -0
  70. data/spec/database_spec.rb +494 -0
  71. data/spec/default_map_spec.rb +87 -0
  72. data/spec/function_spec.rb +94 -0
  73. data/spec/integeration_spec.rb +111 -0
  74. data/spec/packer_spec.rb +60 -0
  75. data/spec/paths_spec.rb +28 -0
  76. data/spec/progress_handler_spec.rb +105 -0
  77. data/spec/requires_spec.rb +23 -0
  78. data/spec/rtree_spec.rb +71 -0
  79. data/spec/schema_spec.rb +120 -0
  80. data/spec/spec_helper.rb +27 -0
  81. data/spec/sqlite3/constants_spec.rb +65 -0
  82. data/spec/sqlite3/database_status_spec.rb +36 -0
  83. data/spec/sqlite3/status_spec.rb +18 -0
  84. data/spec/sqlite3/version_spec.rb +14 -0
  85. data/spec/sqlite3_spec.rb +53 -0
  86. data/spec/statement_spec.rb +161 -0
  87. data/spec/storage_map_spec.rb +41 -0
  88. data/spec/tap_spec.rb +59 -0
  89. data/spec/text_map_spec.rb +23 -0
  90. data/spec/type_map_spec.rb +17 -0
  91. data/spec/version_spec.rb +15 -0
  92. data/tasks/announce.rake +43 -0
  93. data/tasks/config.rb +107 -0
  94. data/tasks/distribution.rake +77 -0
  95. data/tasks/documentation.rake +32 -0
  96. data/tasks/extension.rake +141 -0
  97. data/tasks/rspec.rake +33 -0
  98. data/tasks/rubyforge.rake +59 -0
  99. data/tasks/utils.rb +80 -0
  100. metadata +237 -0
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
+ #require 'amalgalite/requires'
6
+
7
+ #describe Amalgalite::Requires do
8
+ # it "#require_order has all files in 'lib' and no more" do
9
+ # dir_files = Dir.glob( File.join( Amalgalite::Paths.lib_path , "**", "*.rb" ) )
10
+ # require_files = Amalgalite::Requires.require_order.collect { |r| Amalgalite::Paths.lib_path r }
11
+ # dir_files.size.should == require_files.size
12
+ # (dir_files - require_files).size.should == 0
13
+ # (require_files - dir_files).size.should == 0
14
+ # end
15
+ #
16
+ # it "can compress and uncompress data" do
17
+ # s = IO.read( __FILE__ )
18
+ # s_gz = Amalgalite::Requires.gzip( s )
19
+ # s.should == Amalgalite::Requires.gunzip( s_gz )
20
+ # end
21
+ #end
22
+
23
+
@@ -0,0 +1,71 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require File.expand_path( File.join( File.dirname(__FILE__), 'spec_helper'))
4
+
5
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
6
+ require 'amalgalite'
7
+ require 'amalgalite/database'
8
+
9
+ # Example from http://sqlite.org/rtree.html
10
+ #
11
+ describe "SQLite3 R*Tree extension" do
12
+ before( :each ) do
13
+ @db = Amalgalite::Database.new( ":memory:" )
14
+ x = @db.execute_batch <<-sql
15
+ CREATE VIRTUAL TABLE demo_index USING rtree(
16
+ id, -- Integer primary key
17
+ minX, maxX, -- Minimum and maximum X coordinate
18
+ minY, maxY -- Minimum and maximum Y coordinate
19
+ );
20
+ --
21
+ INSERT INTO demo_index VALUES(
22
+ 1, -- Primary key
23
+ -80.7749, -80.7747, -- Longitude range
24
+ 30.3776, 30.3778 -- Latitude range
25
+ );
26
+ INSERT INTO demo_index VALUES(
27
+ 2,
28
+ -81.0, -79.6,
29
+ 35.0, 36.2
30
+ );
31
+ sql
32
+ x.should == 3
33
+ end
34
+
35
+ after( :each ) do
36
+ @db.close
37
+ end
38
+
39
+ it "has 2 rows" do
40
+ r = @db.first_value_from( "SELECT count(*) FROM demo_index")
41
+ r.should == 2
42
+ end
43
+
44
+ it "queries normally" do
45
+ r = @db.execute "SELECT * FROM demo_index WHERE id=1;"
46
+ r.size.should == 1
47
+ row = r.first
48
+ row['id'].should == 1
49
+ end
50
+
51
+ it "does a 'contained within' query" do
52
+ r = @db.execute <<-sql
53
+ SELECT id FROM demo_index
54
+ WHERE minX>=-81.08 AND maxX<=-80.58
55
+ AND minY>=30.00 AND maxY<=30.44;
56
+ sql
57
+
58
+ r.size.should == 1
59
+ r.first['id'].should == 1
60
+ end
61
+
62
+ it "does an 'overlapping' query" do
63
+ r = @db.execute <<-sql
64
+ SELECT id FROM demo_index
65
+ WHERE maxX>=-81.08 AND minX<=-80.58
66
+ AND maxY>=30.00 AND minY<=35.44;
67
+ sql
68
+ r.size.should == 2
69
+ end
70
+ end
71
+
@@ -0,0 +1,120 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
+ require 'amalgalite'
6
+ require 'amalgalite/schema'
7
+
8
+ describe Amalgalite::Schema do
9
+ before(:each) do
10
+ @schema = IO.read( SpecInfo.test_schema_file )
11
+ @iso_db_file = SpecInfo.make_iso_db
12
+ @iso_db = Amalgalite::Database.new( SpecInfo.make_iso_db )
13
+ end
14
+
15
+ after(:each) do
16
+ File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
17
+ @iso_db.close
18
+ File.unlink @iso_db_file if File.exist?( @iso_db_file )
19
+ end
20
+
21
+ it "loads the schema of a database" do
22
+ schema = @iso_db.schema
23
+ schema.load_tables
24
+ schema.tables.size.should eql(2)
25
+ end
26
+
27
+ it "lazily loads new table schema" do
28
+ @iso_db.schema.tables.size.should eql(2)
29
+ sql = "CREATE TABLE t1 ( a, b, c )"
30
+ @iso_db.execute( sql )
31
+ @iso_db.schema.tables.size.should eql(2)
32
+ @iso_db.schema.dirty!
33
+ @iso_db.schema.tables['t1'].column_names.should eql(%w[ a b c ])
34
+ @iso_db.schema.tables.size.should eql(3)
35
+ end
36
+
37
+ it "loads the views in the database" do
38
+ sql = "CREATE VIEW v1 AS SELECT c.name, c.two_letter, s.name, s.subdivision FROM country AS c JOIN subcountry AS s ON c.two_letter = s.country"
39
+ @iso_db.execute( sql )
40
+ @iso_db.schema.load_views
41
+ @iso_db.schema.views.size.should eql(1)
42
+ @iso_db.schema.views["v1"].sql.should eql(sql)
43
+ end
44
+
45
+ it "removes quotes from around default values in columns" do
46
+ sql = "CREATE TABLE t1( d1 default 't' )"
47
+ @iso_db.execute( sql )
48
+ @iso_db.schema.dirty!
49
+ tt = @iso_db.schema.tables['t1']
50
+ tt.columns['d1'].default_value.should == "t"
51
+ end
52
+
53
+ it "loads the tables and columns" do
54
+ ct = @iso_db.schema.tables['country']
55
+ ct.name.should eql("country")
56
+ ct.columns.size.should eql(3)
57
+ ct.indexes.size.should eql(2)
58
+ ct.column_names.should eql(%w[ name two_letter id ])
59
+ @iso_db.schema.tables.size.should eql(2)
60
+
61
+
62
+ ct.columns['two_letter'].should be_primary_key
63
+ ct.columns['two_letter'].declared_data_type.should eql("TEXT")
64
+ ct.columns['name'].should_not be_nullable
65
+ ct.columns['name'].should be_not_null_constraint
66
+ ct.columns['name'].should_not be_has_default_value
67
+ ct.columns['id'].should_not be_auto_increment
68
+ end
69
+
70
+ it "knows what the primary key of a table is" do
71
+ ct = @iso_db.schema.tables['country']
72
+ ct.primary_key.should == [ ct.columns['two_letter'] ]
73
+ end
74
+
75
+ it "knows the primary key of a table even without an explicity unique index" do
76
+ sql = "CREATE TABLE u( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , other text )"
77
+ @iso_db.execute( sql )
78
+ @iso_db.schema.dirty!
79
+ ut = @iso_db.schema.tables['u']
80
+ ut.primary_key.should == [ ut.columns['id'] ]
81
+ end
82
+
83
+ it "knows the primary key of a temporary table" do
84
+ @iso_db.execute "CREATE TEMPORARY TABLE tt( a, b INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, c )"
85
+ @iso_db.schema.dirty!
86
+ tt = @iso_db.schema.load_table( 'tt' )
87
+ tt.primary_key.should == [ tt.columns['b'] ]
88
+
89
+ end
90
+
91
+ it "knows what the primary key of a table is when it is a multiple column primary key" do
92
+ sql = "CREATE TABLE m ( id1, id2, PRIMARY KEY (id2, id1) )"
93
+ @iso_db.execute( sql )
94
+ @iso_db.schema.dirty!
95
+ mt = @iso_db.schema.tables['m']
96
+ mt.primary_key.should == [ mt.columns['id2'], mt.columns['id1'] ]
97
+ end
98
+
99
+ it "loads the indexes" do
100
+ c = @iso_db.schema.tables['country']
101
+ c.indexes.size.should eql(2)
102
+ c.indexes['country_name'].columns.size.should eql(1)
103
+ c.indexes['country_name'].should_not be_unique
104
+ c.indexes['country_name'].sequence_number.should eql(0)
105
+ c.indexes['country_name'].columns.first.should eql(@iso_db.schema.tables['country'].columns['name'])
106
+ c.indexes['sqlite_autoindex_country_1'].should be_unique
107
+
108
+ subc = @iso_db.schema.tables['subcountry']
109
+ subc.indexes.size.should eql(3)
110
+ subc.indexes['subcountry_country'].columns.first.should eql(@iso_db.schema.tables['subcountry'].columns['country'])
111
+ end
112
+
113
+ it "can load the schema of a temporary table" do
114
+ @iso_db.execute "CREATE TEMPORARY TABLE tt( a, b, c )"
115
+ @iso_db.schema.dirty!
116
+ @iso_db.schema.tables['tt'].should be_nil
117
+ @iso_db.schema.load_table('tt').should_not be_nil
118
+ @iso_db.schema.tables['tt'].should be_temporary
119
+ end
120
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
+
6
+ require 'amalgalite'
7
+
8
+ class SpecInfo
9
+ class << self
10
+ def test_db
11
+ @test_db ||= File.expand_path(File.join(File.dirname(__FILE__), "test.db"))
12
+ end
13
+
14
+ def test_schema_file
15
+ @test_schema_file ||= File.expand_path(File.join(File.dirname(__FILE__),"iso-3166-schema.sql"))
16
+ end
17
+
18
+ def make_iso_db
19
+ @iso_db ||= File.expand_path(File.join(File.dirname(__FILE__), "iso-3166.db"))
20
+ @new_is_db = File.expand_path(File.join(File.dirname(__FILE__), "iso-3166-testing.db"))
21
+ FileUtils.cp @iso_db, @new_is_db
22
+ return @new_is_db
23
+ end
24
+
25
+ end
26
+ end
27
+
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),%w[ .. spec_helper.rb ]))
2
+
3
+ require 'amalgalite/sqlite3/constants'
4
+
5
+ describe Amalgalite::SQLite3::Constants do
6
+
7
+ it "has Open constants" do
8
+ Amalgalite::SQLite3::Constants::Open::READONLY.should > 0
9
+ end
10
+
11
+ it "has DataType constants" do
12
+ Amalgalite::SQLite3::Constants::DataType::BLOB.should > 0
13
+ end
14
+
15
+ it "has ResultCode constants" do
16
+ end
17
+
18
+ describe 'ResultCode' do
19
+ it "has constants" do
20
+ Amalgalite::SQLite3::Constants::ResultCode::OK.should == 0
21
+ end
22
+
23
+ it "can return the constant from a number" do
24
+ c = Amalgalite::SQLite3::Constants::ResultCode.name_from_value( 21 )
25
+ c.should == "MISUSE"
26
+ end
27
+
28
+ it "can return the number from a name" do
29
+ v = Amalgalite::SQLite3::Constants::ResultCode.value_from_name( "MISUSE" )
30
+ v.should == 21
31
+ end
32
+ end
33
+
34
+ describe 'Status' do
35
+ it "has constants" do
36
+ Amalgalite::SQLite3::Constants::Status::MEMORY_USED.should == 0
37
+ end
38
+
39
+ it "can return the constant from a number" do
40
+ c = Amalgalite::SQLite3::Constants::Status.name_from_value( 3 )
41
+ c.should == "SCRATCH_USED"
42
+ end
43
+
44
+ it "can return the number from a name" do
45
+ v = Amalgalite::SQLite3::Constants::Status.value_from_name( "memory_used" )
46
+ v.should == 0
47
+ end
48
+ end
49
+
50
+ describe 'DBStatus' do
51
+ it "has constants" do
52
+ Amalgalite::SQLite3::Constants::DBStatus::LOOKASIDE_USED.should == 0
53
+ end
54
+
55
+ it "can return the constant from a number" do
56
+ c = Amalgalite::SQLite3::Constants::DBStatus.name_from_value( 0 )
57
+ c.should == "LOOKASIDE_USED"
58
+ end
59
+
60
+ it "can return the number from a name" do
61
+ v = Amalgalite::SQLite3::Constants::DBStatus.value_from_name( "lookaside_used" )
62
+ v.should == 0
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper.rb"))
2
+ require 'amalgalite/sqlite3'
3
+ require 'rbconfig'
4
+
5
+ describe "Amalgalite::SQLite3::Database::Status" do
6
+ before(:each) do
7
+ @db = Amalgalite::Database.new( "lookaside-test.db" )
8
+ @db.execute(" create table t(a, b)")
9
+ 20.times do |x|
10
+ @db.execute("insert into t(a, b) values (?,?);", x, x+1)
11
+ end
12
+ end
13
+
14
+ after(:each) do
15
+ @db.close
16
+ FileUtils.rm_f "lookaside-test.db"
17
+ end
18
+
19
+
20
+ it "knows how much lookaside memory it has used" do
21
+ @db.api.status.lookaside_used.highwater.should > 0
22
+ @db.api.status.lookaside_used.current.should >= 0
23
+ end
24
+
25
+ it "can reset the highwater value" do
26
+ stat = @db.api.status.lookaside_used
27
+ before = stat.highwater
28
+ before.should > 0
29
+
30
+ stat.reset!
31
+ after = stat.highwater
32
+
33
+ after.should eql(0)
34
+ after.should_not eql(before)
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper.rb"))
2
+ require 'amalgalite/sqlite3'
3
+ require 'rbconfig'
4
+
5
+ describe "Amalgalite::SQLite3::Status" do
6
+ it "knows how much memory it has used" do
7
+ Amalgalite::SQLite3.status.memory_used.current.should >= 0
8
+ Amalgalite::SQLite3.status.memory_used.highwater.should >= 0
9
+ end
10
+
11
+ it "can reset the highwater value" do
12
+ before = Amalgalite::SQLite3.status.memory_used.highwater
13
+ Amalgalite::SQLite3.status.memory_used.reset!
14
+ Amalgalite::SQLite3.status.memory_used.highwater.should > 0
15
+ after = Amalgalite::SQLite3.status.memory_used.highwater
16
+ after.should_not eql(before)
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"..","spec_helper.rb"))
2
+ require 'amalgalite/sqlite3/version'
3
+
4
+ describe "Amalgalite::SQLite3::Version" do
5
+ it "should have the sqlite3 version" do
6
+ Amalgalite::SQLite3::VERSION.should =~ /\d\.\d\.\d/
7
+ Amalgalite::SQLite3::Version.to_s.should =~ /\d\.\d\.\d/
8
+ Amalgalite::SQLite3::Version.to_i.should eql(3006016)
9
+ Amalgalite::SQLite3::Version::MAJOR.should eql(3)
10
+ Amalgalite::SQLite3::Version::MINOR.should eql(6)
11
+ Amalgalite::SQLite3::Version::RELEASE.should eql(16)
12
+ Amalgalite::SQLite3::Version.to_a.should have(3).items
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
2
+ require 'amalgalite/sqlite3'
3
+ require 'rbconfig'
4
+
5
+ describe "Amalgalite::SQLite3" do
6
+ it "is threadsafe is ruby is compiled with pthread support, in this case that is (#{Config::CONFIG['configure_args'].include?( "--enable-pthread" )})" do
7
+ Amalgalite::SQLite3.threadsafe?.should eql(Config::CONFIG['configure_args'].include?( "--enable-pthread" ))
8
+ end
9
+
10
+ it "knows if an SQL statement is complete" do
11
+ Amalgalite::SQLite3.complete?("SELECT * FROM sometable;").should eql(true)
12
+ #Amalgalite::SQLite3.complete?("SELECT * FROM sometable;", :utf16 => true).should eql(true)
13
+ end
14
+
15
+ it "knows if an SQL statement is not complete" do
16
+ Amalgalite::SQLite3.complete?("SELECT * FROM sometable ").should eql(false)
17
+ #Amalgalite::SQLite3.complete?("SELECT * FROM sometable WHERE ", :utf16 => true).should eql(false)
18
+ end
19
+
20
+ it "can produce random data" do
21
+ Amalgalite::SQLite3.randomness( 42 ).size.should eql(42)
22
+ end
23
+
24
+ it "has nil for the default sqlite temporary directory" do
25
+ Amalgalite::SQLite3.temp_directory.should eql(nil)
26
+ end
27
+
28
+ it "can set the temporary directory" do
29
+ Amalgalite::SQLite3.temp_directory.should eql(nil)
30
+ Amalgalite::SQLite3.temp_directory = "/tmp/testing"
31
+ Amalgalite::SQLite3.temp_directory.should eql("/tmp/testing")
32
+ Amalgalite::SQLite3.temp_directory = nil
33
+ Amalgalite::SQLite3.temp_directory.should eql(nil)
34
+ end
35
+
36
+ it "can escape quoted strings" do
37
+ Amalgalite::SQLite3.escape( "It's a happy day!" ).should eql("It''s a happy day!")
38
+ end
39
+
40
+ it "can escape a symble into a string" do
41
+ Amalgalite::SQLite3.escape( :stuff ).should eql("stuff")
42
+ Amalgalite::SQLite3.escape( :"stuff'n" ).should eql("stuff''n")
43
+ end
44
+
45
+ it "can quote and escape single quoted strings" do
46
+ Amalgalite::SQLite3.quote( "It's a happy day!" ).should eql("'It''s a happy day!'")
47
+ end
48
+
49
+ it "can quote and escape symbols" do
50
+ Amalgalite::SQLite3.quote( :stuff ).should eql("'stuff'")
51
+ Amalgalite::SQLite3.quote( :"stuff'n" ).should eql("'stuff''n'")
52
+ end
53
+ end
@@ -0,0 +1,161 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
5
+
6
+ require 'amalgalite'
7
+
8
+ describe Amalgalite::Statement do
9
+ before(:each) do
10
+ @db = Amalgalite::Database.new( SpecInfo.test_db )
11
+ @schema_sql = IO.read( SpecInfo.test_schema_file )
12
+ @iso_db_file = SpecInfo.make_iso_db
13
+ @iso_db = Amalgalite::Database.new( SpecInfo.make_iso_db )
14
+ end
15
+
16
+ after(:each) do
17
+ @db.close
18
+ File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
19
+
20
+ @iso_db.close
21
+ File.unlink @iso_db_file if File.exist?( @iso_db_file )
22
+ end
23
+
24
+ it "a statement has a copy of the sql it was prepared with" do
25
+ stmt = @db.prepare( "SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
26
+ stmt.sql.should eql("SELECT strftime('%Y-%m-%d %H:%M:%S', 'now')")
27
+ stmt.close
28
+ end
29
+
30
+ it "steps through results" do
31
+ now = Time.new.utc.strftime("%Y-%m-%d %H:%M")
32
+ @db.prepare( "SELECT strftime('%Y-%m-%d %H:%M', 'now') as now") do |stmt|
33
+ stmt.should_not eql(nil)
34
+ stmt.each do |row|
35
+ row['now'].should eql(now)
36
+ end
37
+ end
38
+ end
39
+
40
+ it "can prepare a statement without a block" do
41
+ stmt = @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two")
42
+ rs = stmt.execute( ":two" => "JP" )
43
+ rs.size.should eql(1)
44
+ stmt.close
45
+ end
46
+
47
+ it "knows how many parameters are in the statement" do
48
+ @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
49
+ stmt.check_parameter_count!( 1 ).should eql(1)
50
+ end
51
+ end
52
+
53
+ it "raises an error if there are not enough parameters are passed in a statement" do
54
+ @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
55
+ lambda{ stmt.execute }.should raise_error( Amalgalite::Error )
56
+ end
57
+ end
58
+
59
+
60
+ it "can run a query with a named parameter" do
61
+ @iso_db.prepare("SELECT * FROM country WHERE two_letter = :two") do |stmt|
62
+ all_rows = stmt.execute( ":two" => "JP" )
63
+ all_rows.size.should eql(1)
64
+ all_rows.first['name'].should eql("Japan")
65
+ end
66
+ end
67
+
68
+ it "it can execute a query with a named parameter and yield the rows" do
69
+ @iso_db.prepare("SELECT * FROM country WHERE id = @id ORDER BY name") do |stmt|
70
+ rows = []
71
+ stmt.execute( "@id" => 891 ) do |row|
72
+ rows << row
73
+ end
74
+ rows.size.should eql(2)
75
+ rows.last['name'].should eql("Yugoslavia")
76
+ rows.first['two_letter'].should eql("CS")
77
+ end
78
+ end
79
+
80
+ it "can execute the same prepared statement multiple times" do
81
+ @db.execute(" CREATE TABLE t(x,y); ")
82
+ values = {}
83
+ @db.prepare("INSERT INTO t( x, y ) VALUES( $x, $y )" ) do |stmt|
84
+ 20.times do |x|
85
+ y = rand( x )
86
+ stmt.execute( { "$x" => x, "$y" => y } )
87
+ values[x] = y
88
+ end
89
+ end
90
+ c = 0
91
+ @db.execute("SELECT * from t") do |row|
92
+ c += 1
93
+ values[ row['x'] ].should eql(row['y'])
94
+ end
95
+ c.should eql(20)
96
+ end
97
+
98
+ it "binds a integer variable correctly" do
99
+ @iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
100
+ all_rows = stmt.execute( 891 )
101
+ all_rows.size.should eql(2)
102
+ all_rows.last['name'].should eql("Yugoslavia")
103
+ all_rows.first['two_letter'].should eql("CS")
104
+ end
105
+ end
106
+
107
+ it "raises and error if an invaliding binding is attempted" do
108
+ @iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ") do |stmt|
109
+ lambda{ stmt.execute( "blah" => 42 ) }.should raise_error(Amalgalite::Error)
110
+ end
111
+ end
112
+
113
+ it "can reset the statement to the state it was before executing" do
114
+ stmt = @iso_db.prepare("SELECT * FROM country WHERE id = :somevar ORDER BY name ")
115
+ stmt.reset_and_clear_bindings!
116
+ stmt.close
117
+ end
118
+
119
+ it "can execute a single sql command and say if there is remaining sql to execute" do
120
+ db = Amalgalite::Database.new( SpecInfo.test_db )
121
+ stmt = @db.prepare( @schema_sql )
122
+ stmt.execute
123
+ stmt.remaining_sql.size.should > 0
124
+ stmt.close
125
+ end
126
+
127
+ it "can select the rowid from the table" do
128
+ db = Amalgalite::Database.new( ":memory:" )
129
+ db.execute( "create table t1(c1,c2,c3)" )
130
+ db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
131
+ rows = db.execute( "select rowid,* from t1")
132
+ rows.size.should eql(1)
133
+ rows.first['rowid'].should eql(1)
134
+ rows.first['c1'].should eql(1 )
135
+ rows.first['c3'].should eql('abc')
136
+ end
137
+
138
+ it "shows that the rowid column is rowid column" do
139
+ db = Amalgalite::Database.new( ":memory:" )
140
+ db.execute( "create table t1(c1,c2,c3)" )
141
+ db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
142
+ db.prepare( "select oid,* from t1" ) do |stmt|
143
+ rows = stmt.execute
144
+ stmt.should be_using_rowid_column
145
+ end
146
+
147
+ db.prepare( "select * from t1" ) do |stmt|
148
+ stmt.execute
149
+ stmt.should_not be_using_rowid_column
150
+ end
151
+ end
152
+
153
+ it "has index based access to the result set" do
154
+ @iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
155
+ all_rows = stmt.execute( 891 )
156
+ all_rows.size.should eql(2)
157
+ all_rows.last.first.should eql("Yugoslavia")
158
+ all_rows.first[1].should eql("CS")
159
+ end
160
+ end
161
+ end