amalgalite 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/HISTORY +4 -0
  2. data/LICENSE +31 -0
  3. data/README +28 -0
  4. data/ext/amalgalite3.c +191 -0
  5. data/ext/amalgalite3.h +97 -0
  6. data/ext/amalgalite3_constants.c +179 -0
  7. data/ext/amalgalite3_database.c +458 -0
  8. data/ext/amalgalite3_statement.c +546 -0
  9. data/ext/gen_constants.rb +114 -0
  10. data/ext/mkrf_conf.rb +6 -0
  11. data/ext/sqlite3.c +87003 -0
  12. data/ext/sqlite3.h +5638 -0
  13. data/ext/sqlite3_options.h +4 -0
  14. data/ext/sqlite3ext.h +362 -0
  15. data/gemspec.rb +50 -0
  16. data/lib/amalgalite.rb +28 -0
  17. data/lib/amalgalite/blob.rb +14 -0
  18. data/lib/amalgalite/boolean.rb +42 -0
  19. data/lib/amalgalite/column.rb +83 -0
  20. data/lib/amalgalite/database.rb +505 -0
  21. data/lib/amalgalite/index.rb +27 -0
  22. data/lib/amalgalite/paths.rb +70 -0
  23. data/lib/amalgalite/profile_tap.rb +130 -0
  24. data/lib/amalgalite/schema.rb +90 -0
  25. data/lib/amalgalite/sqlite3.rb +4 -0
  26. data/lib/amalgalite/sqlite3/constants.rb +48 -0
  27. data/lib/amalgalite/sqlite3/version.rb +38 -0
  28. data/lib/amalgalite/statement.rb +307 -0
  29. data/lib/amalgalite/table.rb +34 -0
  30. data/lib/amalgalite/taps/console.rb +27 -0
  31. data/lib/amalgalite/taps/io.rb +71 -0
  32. data/lib/amalgalite/trace_tap.rb +35 -0
  33. data/lib/amalgalite/type_map.rb +60 -0
  34. data/lib/amalgalite/type_maps/default_map.rb +153 -0
  35. data/lib/amalgalite/type_maps/storage_map.rb +41 -0
  36. data/lib/amalgalite/type_maps/text_map.rb +23 -0
  37. data/lib/amalgalite/version.rb +32 -0
  38. data/lib/amalgalite/view.rb +24 -0
  39. data/spec/amalgalite_spec.rb +4 -0
  40. data/spec/boolean_spec.rb +26 -0
  41. data/spec/database_spec.rb +222 -0
  42. data/spec/default_map_spec.rb +85 -0
  43. data/spec/integeration_spec.rb +111 -0
  44. data/spec/paths_spec.rb +28 -0
  45. data/spec/schema_spec.rb +46 -0
  46. data/spec/spec_helper.rb +25 -0
  47. data/spec/sqlite3/constants_spec.rb +25 -0
  48. data/spec/sqlite3/version_spec.rb +14 -0
  49. data/spec/sqlite3_spec.rb +34 -0
  50. data/spec/statement_spec.rb +116 -0
  51. data/spec/storage_map_spec.rb +41 -0
  52. data/spec/tap_spec.rb +59 -0
  53. data/spec/text_map_spec.rb +23 -0
  54. data/spec/type_map_spec.rb +17 -0
  55. data/spec/version_spec.rb +9 -0
  56. data/tasks/announce.rake +38 -0
  57. data/tasks/config.rb +108 -0
  58. data/tasks/distribution.rake +38 -0
  59. data/tasks/documentation.rake +31 -0
  60. data/tasks/extension.rake +45 -0
  61. data/tasks/rspec.rake +32 -0
  62. data/tasks/rubyforge.rake +48 -0
  63. data/tasks/utils.rb +80 -0
  64. metadata +165 -0
@@ -0,0 +1,32 @@
1
+ #--
2
+ # Copyright (c) 2008 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for licensingn details
4
+ #++
5
+
6
+ module Amalgalite
7
+ # Version information for Amagalite
8
+ module Version
9
+
10
+ MAJOR = 0
11
+ MINOR = 1
12
+ BUILD = 0
13
+
14
+ #
15
+ # return the Version as an array of MAJOR, MINOR, BUILD
16
+ #
17
+ def self.to_a
18
+ [MAJOR, MINOR, BUILD]
19
+ end
20
+
21
+ # return the Version as a dotted String MAJOR.MINOR.BUILD
22
+ def self.to_s
23
+ to_a.join(".")
24
+ end
25
+
26
+ # Version string constant
27
+ STRING = Version.to_s.freeze
28
+ end
29
+
30
+ # Version string constant
31
+ VERSION = Version.to_s.freeze
32
+ end
@@ -0,0 +1,24 @@
1
+ #--
2
+ # Copyright (c) 2008 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for details.
4
+ #++
5
+
6
+ module Amalgalite
7
+ #
8
+ # a class representing the meta information about an SQLite view
9
+ #
10
+ class View
11
+
12
+ # the table name
13
+ attr_reader :name
14
+
15
+ # the original sql that was used to create this table
16
+ attr_reader :sql
17
+
18
+ def initialize( name, sql )
19
+ @name = name
20
+ @sql = sql
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
2
+
3
+ describe Amalgalite do
4
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
+ require 'amalgalite'
6
+ require 'amalgalite/boolean'
7
+
8
+ describe Amalgalite::Boolean do
9
+ %w[ True Y Yes T 1 ].each do |v|
10
+ it "converts #{v} to true" do
11
+ Amalgalite::Boolean.to_bool(v).should == true
12
+ end
13
+ end
14
+
15
+ %w[ False F f No n 0 ].each do |v|
16
+ it "converts #{v} to false " do
17
+ Amalgalite::Boolean.to_bool(v).should == false
18
+ end
19
+ end
20
+
21
+ %w[ other things nil ].each do |v|
22
+ it "converts #{v} to nil" do
23
+ Amalgalite::Boolean.to_bool(v).should == nil
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,222 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
+ require 'amalgalite'
6
+ require 'amalgalite/taps/io'
7
+ require 'amalgalite/taps/console'
8
+
9
+ describe Amalgalite::Database do
10
+ before(:each) do
11
+ @schema = 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
+ File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
18
+ @iso_db.close
19
+ File.unlink @iso_db_file if File.exist?( @iso_db_file )
20
+ end
21
+
22
+ it "can create a new database" do
23
+ db = Amalgalite::Database.new( SpecInfo.test_db )
24
+ db.instance_of?(Amalgalite::Database)
25
+ db.api.instance_of?(Amalgalite::SQLite3::Database)
26
+ File.exist?( SpecInfo.test_db ).should == true
27
+ end
28
+
29
+ it "creates a new UTF-8 database (need exec to check pragma encoding)" do
30
+ db = Amalgalite::Database.new( SpecInfo.test_db )
31
+ db.execute_batch( @schema );
32
+ db.should_not be_utf16
33
+ db.encoding.should == "UTF-8"
34
+ end
35
+
36
+ it "creates a new UTF-16 database (need exec to check pragma encoding)"
37
+
38
+ it "raises an error if the file does not exist and the database is opened with a non-create mode" do
39
+ lambda { Amalgalite::Database.new( SpecInfo.test_db, "r") }.should raise_error(Amalgalite::SQLite3::Error)
40
+ lambda { Amalgalite::Database.new( SpecInfo.test_db, "r+") }.should raise_error(Amalgalite::SQLite3::Error)
41
+ end
42
+
43
+ it "raises an error if an invalid mode is used" do
44
+ lambda { Amalgalite::Database.new( SpecInfo.test_db, "b+" ) }.should raise_error(Amalgalite::Database::InvalidModeError)
45
+ end
46
+
47
+ it "can be in autocommit mode, and is by default" do
48
+ @iso_db.autocommit?.should == true
49
+ end
50
+
51
+ it "reports false for autocommit? when inside a transaction" do
52
+ @iso_db.execute(" BEGIN ")
53
+ @iso_db.autocommit?.should == false
54
+ @iso_db.in_transaction?.should == true
55
+ @iso_db.execute(" COMMIT")
56
+ @iso_db.in_transaction?.should == false
57
+ end
58
+
59
+ it "prepares a statment" do
60
+ db = Amalgalite::Database.new( SpecInfo.test_db )
61
+ stmt = db.prepare("SELECT datetime()")
62
+ stmt.instance_of?(Amalgalite::Statement)
63
+ stmt.api.instance_of?(Amalgalite::SQLite3::Statement)
64
+ end
65
+
66
+ it "raises an error on invalid syntax when preparing a bad sql statement" do
67
+ db = Amalgalite::Database.new( SpecInfo.test_db )
68
+ lambda { db.prepare("SELECT nothing FROM stuf") }.should raise_error(Amalgalite::SQLite3::Error)
69
+ end
70
+
71
+ it "closes normally" do
72
+ db = Amalgalite::Database.new( SpecInfo.test_db )
73
+ lambda { db.close }.should_not raise_error( Amalgalite::SQLite3::Error )
74
+ end
75
+
76
+ it "returns the id of the last inserted row" do
77
+ db = Amalgalite::Database.new( SpecInfo.test_db )
78
+ db.last_insert_rowid.should == 0
79
+ end
80
+
81
+ it "is in autocommit mode by default" do
82
+ db = Amalgalite::Database.new( SpecInfo.test_db )
83
+ db.should be_autocommit
84
+ end
85
+
86
+ it "report the number of rows changed with an insert" do
87
+ db = Amalgalite::Database.new( SpecInfo.test_db )
88
+ db.execute_batch <<-sql
89
+ CREATE TABLE t1( x );
90
+ INSERT INTO t1( x ) values ( 1 );
91
+ INSERT INTO t1( x ) values ( 2 );
92
+ INSERT INTO t1( x ) values ( 3 );
93
+ sql
94
+
95
+ db.row_changes.should == 1
96
+ db.total_changes.should == 3
97
+ db.close
98
+ end
99
+
100
+ it "reports the number of rows deleted" do
101
+ db = Amalgalite::Database.new( SpecInfo.test_db )
102
+ db.execute_batch <<-sql
103
+ CREATE TABLE t1( x );
104
+ INSERT INTO t1( x ) values ( 1 );
105
+ INSERT INTO t1( x ) values ( 2 );
106
+ INSERT INTO t1( x ) values ( 3 );
107
+ DELETE FROM t1 where x < 3;
108
+ sql
109
+ db.row_changes.should == 2
110
+ db.close
111
+ end
112
+
113
+
114
+
115
+ it "can immediately execute an sql statement " do
116
+ db = Amalgalite::Database.new( SpecInfo.test_db )
117
+ db.execute( "CREATE TABLE t1( x, y, z )" ).should be_empty
118
+ end
119
+
120
+ it "can execute a batch of commands" do
121
+ db = Amalgalite::Database.new( SpecInfo.test_db )
122
+ db.execute_batch( @schema ).should == 5
123
+ end
124
+
125
+ it "traces the execution of code" do
126
+ db = Amalgalite::Database.new( SpecInfo.test_db )
127
+ sql = "CREATE TABLE trace_test( x, y, z)"
128
+ s = db.trace_tap = ::Amalgalite::Taps::StringIO.new
129
+ db.execute( sql )
130
+ db.trace_tap.string.should== "registered as trace tap\n#{sql}\n"
131
+ db.trace_tap = nil
132
+ s.string.should== "registered as trace tap\n#{sql}\nunregistered as trace tap\n"
133
+ end
134
+
135
+ it "raises an exception if the wrong type of object is used for tracing" do
136
+ db = Amalgalite::Database.new( SpecInfo.test_db )
137
+ lambda { db.trace_tap = Object.new }.should raise_error(Amalgalite::Error)
138
+ end
139
+
140
+ it "raises an exception if the wrong type of object is used for profile" do
141
+ db = Amalgalite::Database.new( SpecInfo.test_db )
142
+ lambda { db.profile_tap = Object.new }.should raise_error(Amalgalite::Error)
143
+ end
144
+
145
+ it "profiles the execution of code" do
146
+ db = Amalgalite::Database.new( SpecInfo.test_db )
147
+ s = db.profile_tap = ::Amalgalite::Taps::StringIO.new
148
+ db.execute_batch( @schema )
149
+ db.profile_tap.samplers.size.should == 6
150
+ db.profile_tap = nil
151
+ s.string.should =~ /unregistered as profile tap/m
152
+ end
153
+
154
+ it "#execute yields each row when called with a block" do
155
+ count = 0
156
+ @iso_db.execute( "SELECT * FROM country LIMIT 10") do |row|
157
+ count += 1
158
+ end
159
+ count.should == 10
160
+ end
161
+
162
+ it "can use something that responds to 'write' as a tap" do
163
+ db = Amalgalite::Database.new( SpecInfo.test_db )
164
+ s2 = db.trace_tap = StringIO.new
165
+ s2.string.should == "registered as trace tap"
166
+ end
167
+
168
+ it "can clear all registered taps" do
169
+ db = Amalgalite::Database.new( SpecInfo.test_db )
170
+ s = db.profile_tap = ::Amalgalite::Taps::StringIO.new
171
+ db.trace_tap = s
172
+ db.execute_batch( @schema )
173
+ db.profile_tap.samplers.size.should == 6
174
+ db.clear_taps!
175
+ s.string.should =~ /unregistered as trace tap/m
176
+ s.string.should =~ /unregistered as profile tap/m
177
+ end
178
+
179
+ it "raises an error if a transaction is attempted within a transaction" do
180
+ db = Amalgalite::Database.new( SpecInfo.test_db )
181
+ db.transaction do |db2|
182
+ lambda{ db2.transaction }.should raise_error(Amalgalite::Error)
183
+ end
184
+ end
185
+
186
+ it "#reload_schema!" do
187
+ @iso_db = Amalgalite::Database.new( SpecInfo.make_iso_db )
188
+ schema = @iso_db.schema
189
+ schema.instance_of?( Amalgalite::Schema ).should == true
190
+ s2 = @iso_db.reload_schema!
191
+ s2.object_id.should_not == schema.object_id
192
+ end
193
+
194
+ it "can rollback a transaction" do
195
+ @iso_db.transaction
196
+ r = @iso_db.execute("SELECT count(1) as cnt FROM country");
197
+ r.first['cnt'].should == 242
198
+ @iso_db.execute("DELETE FROM country")
199
+ r = @iso_db.execute("SELECT count(1) as cnt FROM country");
200
+ r.first['cnt'].should == 0
201
+ @iso_db.rollback
202
+
203
+ r = @iso_db.execute("SELECT count(1) as cnt FROM country");
204
+ r.first['cnt'].should == 242
205
+ end
206
+
207
+ it "rolls back if an exception happens during a transaction block" do
208
+ begin
209
+ @iso_db.transaction do |db|
210
+ r = db.execute("SELECT count(1) as cnt FROM country");
211
+ r.first['cnt'].should == 242
212
+ db.execute("DELETE FROM country")
213
+ db.in_transaction?.should == true
214
+ raise "testing rollback"
215
+ end
216
+ rescue => e
217
+ @iso_db.in_transaction?.should == false
218
+ @iso_db.execute("SELECT count(1) as cnt FROM country").first['cnt'].should == 242
219
+ end
220
+ end
221
+ end
222
+
@@ -0,0 +1,85 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
+ require 'amalgalite/type_maps/default_map'
6
+
7
+ describe Amalgalite::TypeMaps::DefaultMap do
8
+ before(:each) do
9
+ @map = Amalgalite::TypeMaps::DefaultMap.new
10
+ end
11
+
12
+ describe "#bind_type_of" do
13
+
14
+ it "Float is bound to DataType::FLOAT" do
15
+ @map.bind_type_of( 3.14 ).should == ::Amalgalite::SQLite3::Constants::DataType::FLOAT
16
+ end
17
+
18
+ it "Fixnum is bound to DataType::INTGER" do
19
+ @map.bind_type_of( 42 ).should == ::Amalgalite::SQLite3::Constants::DataType::INTEGER
20
+ end
21
+
22
+ it "nil is bound to DataType::NULL" do
23
+ @map.bind_type_of( nil ).should == ::Amalgalite::SQLite3::Constants::DataType::NULL
24
+ end
25
+
26
+ it "::Amalgalite::Blob is bound to DataType::BLOB" do
27
+ @map.bind_type_of( ::Amalgalite::Blob.new ).should == ::Amalgalite::SQLite3::Constants::DataType::BLOB
28
+ end
29
+
30
+ it "everything else is bound to DataType::TEXT" do
31
+ @map.bind_type_of( "everything else" ).should == ::Amalgalite::SQLite3::Constants::DataType::TEXT
32
+ end
33
+
34
+ end
35
+
36
+
37
+ describe "#result_value_of" do
38
+
39
+ it "Numeric's are returned" do
40
+ y = 42
41
+ x = @map.result_value_of( "INT", 42 )
42
+ x.object_id.should == y.object_id
43
+ end
44
+
45
+ it "Nil is returned" do
46
+ @map.result_value_of( "NULL", nil ).should == nil
47
+ end
48
+
49
+ it "DateTime is returned for delcared types of 'datetime'" do
50
+ @map.result_value_of( "DaTeTiME", "2008-04-01 23:23:23" ).should be_kind_of(DateTime)
51
+ end
52
+
53
+ it "Date is returned for declared types of 'date'" do
54
+ @map.result_value_of( "date", "2008-04-01 23:42:42" ).should be_kind_of(Date)
55
+ end
56
+
57
+ it "Time is returned for declared types of 'time'" do
58
+ @map.result_value_of( "timestamp", "2008-04-01T23:42:42" ).should be_kind_of(Time)
59
+ end
60
+
61
+ it "Float is returned for declared types of 'double'" do
62
+ @map.result_value_of( "double", "3.14" ).should be_kind_of(Float)
63
+ end
64
+
65
+ it "Integer is returned for declared types of 'int'" do
66
+ @map.result_value_of( "int", "42" ).should be_kind_of(Integer)
67
+ end
68
+
69
+ it "boolean is returned for declared types of 'bool'" do
70
+ @map.result_value_of( "bool", "True" ).should == true
71
+ end
72
+
73
+ it "raises NotImplemeted for blob conversion" do
74
+ lambda{ @map.result_value_of( "Blob", "some blob" ) }.should raise_error( NotImplementedError )
75
+ end
76
+
77
+ it "raises and error if an unknown sql type is returned" do
78
+ lambda{ @map.result_value_of( "footype", "foo" ) }.should raise_error( ::Amalgalite::Error )
79
+ end
80
+
81
+ it "raises and error if an ruby class is attempted to be mapped" do
82
+ lambda{ @map.result_value_of( "footype", 1..3 ) }.should raise_error( ::Amalgalite::Error )
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,111 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'date'
4
+ require 'time'
5
+
6
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
7
+ require 'amalgalite'
8
+
9
+ describe "Integration specifications" do
10
+ before(:each) do
11
+ @schema = 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
+ File.unlink SpecInfo.test_db if File.exist?( SpecInfo.test_db )
18
+ @iso_db.close
19
+ File.unlink @iso_db_file if File.exist?( @iso_db_file )
20
+ end
21
+
22
+ describe " - invalid queries" do
23
+ it "raises error with an invalid syntax" do
24
+ lambda{ @iso_db.prepare "SELECT from country" }.should raise_error( ::Amalgalite::SQLite3::Error )
25
+ end
26
+
27
+ it "raises error with invalid table" do
28
+ lambda{ @iso_db.prepare "SELECT * FROM foo" }.should raise_error( ::Amalgalite::SQLite3::Error )
29
+ end
30
+
31
+ it "raises error with invalid column" do
32
+ lambda{ @iso_db.prepare "SELECT foo FROM country" }.should raise_error( ::Amalgalite::SQLite3::Error )
33
+ end
34
+ end
35
+
36
+ describe " - default types conversion" do
37
+
38
+ {
39
+ "datetime" => { :value => DateTime.now, :klass => DateTime },
40
+ "timestamp" => { :value => Time.now, :klass => Time } ,
41
+ "date" => { :value => Date.today, :klass => Date },
42
+ "integer" => { :value => 42, :klass => Fixnum } ,
43
+ "double" => { :value => 3.14, :klass => Float },
44
+ "varchar" => { :value => "foobarbaz", :klass => String },
45
+ "boolean" => { :value => true, :klass => TrueClass },
46
+ "varchar(2)"=> { :value => nil, :klass => NilClass }
47
+ }.each_pair do |sql_type, ruby_info|
48
+ it "converts a ruby obj (#{ruby_info[:value].to_s}) of #{ruby_info[:klass]} to an SQL type of #{sql_type} and back again " do
49
+ db = Amalgalite::Database.new( SpecInfo.test_db )
50
+ db.execute "CREATE TABLE t( c #{sql_type} )"
51
+ db.execute "insert into t (c) values ( ? )", ruby_info[:value]
52
+ rows = db.execute "select * from t"
53
+ rows.first['c'].class.should == ruby_info[:klass]
54
+
55
+ if [ DateTime, Time ].include?( ruby_info[:klass] ) then
56
+ rows.first['c'].strftime("%Y-%m-%d %H:%M:%S").should == ruby_info[:value].strftime("%Y-%m-%d %H:%M:%S")
57
+ else
58
+ rows.first['c'].should == ruby_info[:value]
59
+ end
60
+ db.close
61
+ end
62
+ end
63
+ end
64
+
65
+ describe " - storage type conversion" do
66
+ {
67
+ "datetime" => { :value => DateTime.now, :result => DateTime.now.strftime("%Y-%m-%dT%H:%M:%S%Z") } ,
68
+ "timestamp" => { :value => Time.now, :result => Time.now.to_s },
69
+ "date" => { :value => Date.today, :result => Date.today.to_s },
70
+ "integer" => { :value => 42, :result => 42 } ,
71
+ "double" => { :value => 3.14, :result => 3.14 } ,
72
+ "varchar" => { :value => "foobarbaz", :result => "foobarbaz" },
73
+ "boolean" => { :value => true, :result => "true" },
74
+ "varchar(2)"=> { :value => nil, :result => nil }
75
+ }.each_pair do |sql_type, ruby_info|
76
+ it "converts a ruby obj (#{ruby_info[:value].to_s}) of class #{ruby_info[:value].class.name} to an SQL type of #{sql_type} and back to a storage type" do
77
+ db = Amalgalite::Database.new( SpecInfo.test_db )
78
+ db.type_map = Amalgalite::TypeMaps::StorageMap.new
79
+ db.execute "CREATE TABLE t( c #{sql_type} )"
80
+ db.execute "insert into t (c) values ( ? )", ruby_info[:value]
81
+ rows = db.execute "select * from t"
82
+ rows.first['c'].should == ruby_info[:result]
83
+ db.close
84
+ end
85
+ end
86
+ end
87
+
88
+ describe " - text type conversion" do
89
+ {
90
+ "datetime" => { :value => DateTime.now, :result => DateTime.now.strftime("%Y-%m-%dT%H:%M:%S%Z") } ,
91
+ "timestamp" => { :value => Time.now, :result => Time.now.to_s },
92
+ "date" => { :value => Date.today, :result => Date.today.to_s },
93
+ "integer" => { :value => 42, :result => "42" } ,
94
+ "double" => { :value => 3.14, :result => "3.14" } ,
95
+ "varchar" => { :value => "foobarbaz", :result => "foobarbaz" },
96
+ "boolean" => { :value => true, :result => "true" },
97
+ "varchar(2)"=> { :value => nil, :result => "" }
98
+ }.each_pair do |sql_type, ruby_info|
99
+ it "converts a ruby obj (#{ruby_info[:value].to_s}) of class #{ruby_info[:value].class.name} to an SQL type of #{sql_type} and back to text" do
100
+ db = Amalgalite::Database.new( SpecInfo.test_db )
101
+ db.type_map = Amalgalite::TypeMaps::TextMap.new
102
+ db.execute "CREATE TABLE t( c #{sql_type} )"
103
+ db.execute "insert into t (c) values ( ? )", ruby_info[:value]
104
+ rows = db.execute "select * from t"
105
+ rows.first['c'].should == ruby_info[:result]
106
+ db.close
107
+ end
108
+ end
109
+ end
110
+ end
111
+