colincasey-sequel 2.10.0 → 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/CHANGELOG +7 -1
  2. data/doc/advanced_associations.rdoc +614 -0
  3. data/doc/cheat_sheet.rdoc +223 -0
  4. data/doc/dataset_filtering.rdoc +158 -0
  5. data/doc/prepared_statements.rdoc +104 -0
  6. data/doc/release_notes/1.0.txt +38 -0
  7. data/doc/release_notes/1.1.txt +143 -0
  8. data/doc/release_notes/1.3.txt +101 -0
  9. data/doc/release_notes/1.4.0.txt +53 -0
  10. data/doc/release_notes/1.5.0.txt +155 -0
  11. data/doc/release_notes/2.0.0.txt +298 -0
  12. data/doc/release_notes/2.1.0.txt +271 -0
  13. data/doc/release_notes/2.10.0.txt +328 -0
  14. data/doc/release_notes/2.2.0.txt +253 -0
  15. data/doc/release_notes/2.3.0.txt +88 -0
  16. data/doc/release_notes/2.4.0.txt +106 -0
  17. data/doc/release_notes/2.5.0.txt +137 -0
  18. data/doc/release_notes/2.6.0.txt +157 -0
  19. data/doc/release_notes/2.7.0.txt +166 -0
  20. data/doc/release_notes/2.8.0.txt +171 -0
  21. data/doc/release_notes/2.9.0.txt +97 -0
  22. data/doc/schema.rdoc +29 -0
  23. data/doc/sharding.rdoc +113 -0
  24. data/lib/sequel.rb +1 -0
  25. data/lib/sequel_core/adapters/ado.rb +89 -0
  26. data/lib/sequel_core/adapters/db2.rb +143 -0
  27. data/lib/sequel_core/adapters/dbi.rb +112 -0
  28. data/lib/sequel_core/adapters/do/mysql.rb +38 -0
  29. data/lib/sequel_core/adapters/do/postgres.rb +92 -0
  30. data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
  31. data/lib/sequel_core/adapters/do.rb +205 -0
  32. data/lib/sequel_core/adapters/firebird.rb +298 -0
  33. data/lib/sequel_core/adapters/informix.rb +85 -0
  34. data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
  35. data/lib/sequel_core/adapters/jdbc/mysql.rb +66 -0
  36. data/lib/sequel_core/adapters/jdbc/oracle.rb +23 -0
  37. data/lib/sequel_core/adapters/jdbc/postgresql.rb +113 -0
  38. data/lib/sequel_core/adapters/jdbc/sqlite.rb +43 -0
  39. data/lib/sequel_core/adapters/jdbc.rb +491 -0
  40. data/lib/sequel_core/adapters/mysql.rb +369 -0
  41. data/lib/sequel_core/adapters/odbc.rb +174 -0
  42. data/lib/sequel_core/adapters/openbase.rb +68 -0
  43. data/lib/sequel_core/adapters/oracle.rb +107 -0
  44. data/lib/sequel_core/adapters/postgres.rb +456 -0
  45. data/lib/sequel_core/adapters/shared/ms_access.rb +110 -0
  46. data/lib/sequel_core/adapters/shared/mssql.rb +102 -0
  47. data/lib/sequel_core/adapters/shared/mysql.rb +325 -0
  48. data/lib/sequel_core/adapters/shared/oracle.rb +61 -0
  49. data/lib/sequel_core/adapters/shared/postgres.rb +715 -0
  50. data/lib/sequel_core/adapters/shared/progress.rb +31 -0
  51. data/lib/sequel_core/adapters/shared/sqlite.rb +265 -0
  52. data/lib/sequel_core/adapters/sqlite.rb +248 -0
  53. data/lib/sequel_core/connection_pool.rb +258 -0
  54. data/lib/sequel_core/core_ext.rb +217 -0
  55. data/lib/sequel_core/core_sql.rb +202 -0
  56. data/lib/sequel_core/database/schema.rb +164 -0
  57. data/lib/sequel_core/database.rb +691 -0
  58. data/lib/sequel_core/dataset/callback.rb +13 -0
  59. data/lib/sequel_core/dataset/convenience.rb +237 -0
  60. data/lib/sequel_core/dataset/pagination.rb +96 -0
  61. data/lib/sequel_core/dataset/prepared_statements.rb +220 -0
  62. data/lib/sequel_core/dataset/query.rb +41 -0
  63. data/lib/sequel_core/dataset/schema.rb +15 -0
  64. data/lib/sequel_core/dataset/sql.rb +1010 -0
  65. data/lib/sequel_core/dataset/stored_procedures.rb +75 -0
  66. data/lib/sequel_core/dataset/unsupported.rb +43 -0
  67. data/lib/sequel_core/dataset.rb +511 -0
  68. data/lib/sequel_core/deprecated.rb +26 -0
  69. data/lib/sequel_core/exceptions.rb +44 -0
  70. data/lib/sequel_core/migration.rb +212 -0
  71. data/lib/sequel_core/object_graph.rb +230 -0
  72. data/lib/sequel_core/pretty_table.rb +71 -0
  73. data/lib/sequel_core/schema/generator.rb +320 -0
  74. data/lib/sequel_core/schema/sql.rb +325 -0
  75. data/lib/sequel_core/schema.rb +2 -0
  76. data/lib/sequel_core/sql.rb +887 -0
  77. data/lib/sequel_core/version.rb +11 -0
  78. data/lib/sequel_core.rb +172 -0
  79. data/lib/sequel_model/association_reflection.rb +267 -0
  80. data/lib/sequel_model/associations.rb +499 -0
  81. data/lib/sequel_model/base.rb +523 -0
  82. data/lib/sequel_model/caching.rb +82 -0
  83. data/lib/sequel_model/dataset_methods.rb +26 -0
  84. data/lib/sequel_model/eager_loading.rb +370 -0
  85. data/lib/sequel_model/exceptions.rb +7 -0
  86. data/lib/sequel_model/hooks.rb +101 -0
  87. data/lib/sequel_model/inflector.rb +281 -0
  88. data/lib/sequel_model/plugins.rb +62 -0
  89. data/lib/sequel_model/record.rb +568 -0
  90. data/lib/sequel_model/schema.rb +49 -0
  91. data/lib/sequel_model/validations.rb +429 -0
  92. data/lib/sequel_model.rb +91 -0
  93. data/spec/adapters/ado_spec.rb +46 -0
  94. data/spec/adapters/firebird_spec.rb +376 -0
  95. data/spec/adapters/informix_spec.rb +96 -0
  96. data/spec/adapters/mysql_spec.rb +881 -0
  97. data/spec/adapters/oracle_spec.rb +244 -0
  98. data/spec/adapters/postgres_spec.rb +687 -0
  99. data/spec/adapters/spec_helper.rb +10 -0
  100. data/spec/adapters/sqlite_spec.rb +555 -0
  101. data/spec/integration/dataset_test.rb +134 -0
  102. data/spec/integration/eager_loader_test.rb +696 -0
  103. data/spec/integration/prepared_statement_test.rb +130 -0
  104. data/spec/integration/schema_test.rb +180 -0
  105. data/spec/integration/spec_helper.rb +58 -0
  106. data/spec/integration/type_test.rb +96 -0
  107. data/spec/rcov.opts +6 -0
  108. data/spec/sequel_core/connection_pool_spec.rb +526 -0
  109. data/spec/sequel_core/core_ext_spec.rb +156 -0
  110. data/spec/sequel_core/core_sql_spec.rb +522 -0
  111. data/spec/sequel_core/database_spec.rb +1188 -0
  112. data/spec/sequel_core/dataset_spec.rb +3481 -0
  113. data/spec/sequel_core/expression_filters_spec.rb +363 -0
  114. data/spec/sequel_core/migration_spec.rb +261 -0
  115. data/spec/sequel_core/object_graph_spec.rb +272 -0
  116. data/spec/sequel_core/pretty_table_spec.rb +58 -0
  117. data/spec/sequel_core/schema_generator_spec.rb +167 -0
  118. data/spec/sequel_core/schema_spec.rb +780 -0
  119. data/spec/sequel_core/spec_helper.rb +55 -0
  120. data/spec/sequel_core/version_spec.rb +7 -0
  121. data/spec/sequel_model/association_reflection_spec.rb +93 -0
  122. data/spec/sequel_model/associations_spec.rb +1767 -0
  123. data/spec/sequel_model/base_spec.rb +419 -0
  124. data/spec/sequel_model/caching_spec.rb +215 -0
  125. data/spec/sequel_model/dataset_methods_spec.rb +78 -0
  126. data/spec/sequel_model/eager_loading_spec.rb +1165 -0
  127. data/spec/sequel_model/hooks_spec.rb +485 -0
  128. data/spec/sequel_model/inflector_spec.rb +119 -0
  129. data/spec/sequel_model/model_spec.rb +588 -0
  130. data/spec/sequel_model/plugins_spec.rb +80 -0
  131. data/spec/sequel_model/record_spec.rb +1184 -0
  132. data/spec/sequel_model/schema_spec.rb +90 -0
  133. data/spec/sequel_model/spec_helper.rb +78 -0
  134. data/spec/sequel_model/validations_spec.rb +1067 -0
  135. data/spec/spec.opts +0 -0
  136. data/spec/spec_config.rb.example +10 -0
  137. metadata +177 -3
@@ -0,0 +1,376 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
+
3
+ unless defined?(FIREBIRD_DB)
4
+ FIREBIRD_URL = 'firebird://sysdba:masterkey@localhost/reality_spec' unless defined? FIREBIRD_URL
5
+ FIREBIRD_DB = Sequel.connect(ENV['SEQUEL_FB_SPEC_DB']||FIREBIRD_URL)
6
+ end
7
+
8
+ FIREBIRD_DB.create_table! :test do
9
+ varchar :name, :size => 50
10
+ integer :val, :index => true
11
+ end
12
+
13
+ FIREBIRD_DB.create_table! :test2 do
14
+ integer :val
15
+ timestamp :time_stamp
16
+ end
17
+
18
+ FIREBIRD_DB.create_table! :test3 do
19
+ integer :val
20
+ timestamp :time_stamp
21
+ end
22
+
23
+ FIREBIRD_DB.create_table! :test5 do
24
+ primary_key :xid
25
+ integer :val
26
+ end
27
+
28
+ context "A Firebird database" do
29
+ setup do
30
+ @db = FIREBIRD_DB
31
+ end
32
+
33
+ specify "should provide disconnect functionality" do
34
+ @db.tables
35
+ @db.pool.size.should == 1
36
+ @db.disconnect
37
+ @db.pool.size.should == 0
38
+ end
39
+
40
+ specify "should raise Sequel::Error on error" do
41
+ proc{@db << "SELECT 1 + 'a'"}.should raise_error(Sequel::Error)
42
+ end
43
+ end
44
+
45
+ context "A Firebird dataset" do
46
+ setup do
47
+ @d = FIREBIRD_DB[:test]
48
+ @d.delete # remove all records
49
+ end
50
+
51
+ specify "should return the correct record count" do
52
+ @d.count.should == 0
53
+ @d << {:name => 'abc', :val => 123}
54
+ @d << {:name => 'abc', :val => 456}
55
+ @d << {:name => 'def', :val => 789}
56
+ @d.count.should == 3
57
+ end
58
+
59
+ specify "should return the correct records" do
60
+ @d.to_a.should == []
61
+ @d << {:name => 'abc', :val => 123}
62
+ @d << {:name => 'abc', :val => 456}
63
+ @d << {:name => 'def', :val => 789}
64
+
65
+ @d.order(:val).to_a.should == [
66
+ {:name => 'abc', :val => 123},
67
+ {:name => 'abc', :val => 456},
68
+ {:name => 'def', :val => 789}
69
+ ]
70
+ end
71
+
72
+ specify "should update records correctly" do
73
+ @d << {:name => 'abc', :val => 123}
74
+ @d << {:name => 'abc', :val => 456}
75
+ @d << {:name => 'def', :val => 789}
76
+ @d.filter(:name => 'abc').update(:val => 530)
77
+
78
+ # the third record should stay the same
79
+ # floating-point precision bullshit
80
+ @d[:name => 'def'][:val].should == 789
81
+ @d.filter(:val => 530).count.should == 2
82
+ end
83
+
84
+ specify "should delete records correctly" do
85
+ @d << {:name => 'abc', :val => 123}
86
+ @d << {:name => 'abc', :val => 456}
87
+ @d << {:name => 'def', :val => 789}
88
+ @d.filter(:name => 'abc').delete
89
+
90
+ @d.count.should == 1
91
+ @d.first[:name].should == 'def'
92
+ end
93
+
94
+ specify "should be able to literalize booleans" do
95
+ proc {@d.literal(true)}.should_not raise_error
96
+ proc {@d.literal(false)}.should_not raise_error
97
+ end
98
+
99
+ specify "should quote columns and tables using double quotes if quoting identifiers" do
100
+ @d.quote_identifiers = true
101
+ @d.select(:name).sql.should == \
102
+ 'SELECT "NAME" FROM "TEST"'
103
+
104
+ @d.select('COUNT(*)'.lit).sql.should == \
105
+ 'SELECT COUNT(*) FROM "TEST"'
106
+
107
+ @d.select(:max[:val]).sql.should == \
108
+ 'SELECT max("VAL") FROM "TEST"'
109
+
110
+ @d.select(:now[]).sql.should == \
111
+ 'SELECT now() FROM "TEST"'
112
+
113
+ @d.select(:max[:items__val]).sql.should == \
114
+ 'SELECT max("ITEMS"."VAL") FROM "TEST"'
115
+
116
+ @d.order(:name.desc).sql.should == \
117
+ 'SELECT * FROM "TEST" ORDER BY "NAME" DESC'
118
+
119
+ @d.select('TEST.NAME AS item_:name'.lit).sql.should == \
120
+ 'SELECT TEST.NAME AS item_:name FROM "TEST"'
121
+
122
+ @d.select('"NAME"'.lit).sql.should == \
123
+ 'SELECT "NAME" FROM "TEST"'
124
+
125
+ @d.select('max(TEST."NAME") AS "max_:name"'.lit).sql.should == \
126
+ 'SELECT max(TEST."NAME") AS "max_:name" FROM "TEST"'
127
+
128
+ @d.select(:test[:ABC, 'hello']).sql.should == \
129
+ "SELECT test(\"ABC\", 'hello') FROM \"TEST\""
130
+
131
+ @d.select(:test[:ABC__DEF, 'hello']).sql.should == \
132
+ "SELECT test(\"ABC\".\"DEF\", 'hello') FROM \"TEST\""
133
+
134
+ @d.select(:test[:ABC__DEF, 'hello'].as(:X2)).sql.should == \
135
+ "SELECT test(\"ABC\".\"DEF\", 'hello') AS \"X2\" FROM \"TEST\""
136
+
137
+ @d.insert_sql(:val => 333).should =~ \
138
+ /\AINSERT INTO "TEST" \("VAL"\) VALUES \(333\)( RETURNING NULL)?\z/
139
+
140
+ @d.insert_sql(:X => :Y).should =~ \
141
+ /\AINSERT INTO "TEST" \("X"\) VALUES \("Y"\)( RETURNING NULL)?\z/
142
+ end
143
+
144
+ specify "should quote fields correctly when reversing the order if quoting identifiers" do
145
+ @d.quote_identifiers = true
146
+ @d.reverse_order(:name).sql.should == \
147
+ 'SELECT * FROM "TEST" ORDER BY "NAME" DESC'
148
+
149
+ @d.reverse_order(:name.desc).sql.should == \
150
+ 'SELECT * FROM "TEST" ORDER BY "NAME" ASC'
151
+
152
+ @d.reverse_order(:name, :test.desc).sql.should == \
153
+ 'SELECT * FROM "TEST" ORDER BY "NAME" DESC, "TEST" ASC'
154
+
155
+ @d.reverse_order(:name.desc, :test).sql.should == \
156
+ 'SELECT * FROM "TEST" ORDER BY "NAME" ASC, "TEST" DESC'
157
+ end
158
+
159
+ specify "should support transactions" do
160
+ FIREBIRD_DB.transaction do
161
+ @d << {:name => 'abc', :val => 1}
162
+ end
163
+
164
+ @d.count.should == 1
165
+ end
166
+
167
+ specify "should have #transaction yield the connection" do
168
+ FIREBIRD_DB.transaction do |conn|
169
+ conn.should_not == nil
170
+ end
171
+ end
172
+
173
+ specify "should correctly rollback transactions" do
174
+ proc do
175
+ FIREBIRD_DB.transaction do
176
+ @d << {:name => 'abc', :val => 1}
177
+ raise RuntimeError, 'asdf'
178
+ end
179
+ end.should raise_error(RuntimeError)
180
+
181
+ @d.count.should == 0
182
+ end
183
+
184
+ specify "should handle returning inside of the block by committing" do
185
+ def FIREBIRD_DB.ret_commit
186
+ transaction do
187
+ self[:test] << {:name => 'abc'}
188
+ return
189
+ self[:test] << {:name => 'd'}
190
+ end
191
+ end
192
+ @d.count.should == 0
193
+ FIREBIRD_DB.ret_commit
194
+ @d.count.should == 1
195
+ FIREBIRD_DB.ret_commit
196
+ @d.count.should == 2
197
+ proc do
198
+ FIREBIRD_DB.transaction do
199
+ raise RuntimeError, 'asdf'
200
+ end
201
+ end.should raise_error(RuntimeError)
202
+
203
+ @d.count.should == 2
204
+ end
205
+
206
+ specify "should quote and upcase reserved keywords" do
207
+ @d = FIREBIRD_DB[:testing]
208
+ @d.quote_identifiers = true
209
+ @d.select(:select).sql.should == \
210
+ 'SELECT "SELECT" FROM "TESTING"'
211
+ end
212
+ end
213
+
214
+ context "A Firebird dataset with a timestamp field" do
215
+ setup do
216
+ @d = FIREBIRD_DB[:test3]
217
+ @d.delete
218
+ end
219
+
220
+ specify "should store milliseconds in time fields" do
221
+ t = Time.now
222
+ @d << {:val=>1, :time_stamp=>t}
223
+ @d.literal(@d[:val =>'1'][:time_stamp]).should == @d.literal(t)
224
+ @d[:val=>'1'][:time_stamp].usec.should == t.usec - t.usec % 100
225
+ end
226
+ end
227
+
228
+ context "A Firebird database" do
229
+ setup do
230
+ @db = FIREBIRD_DB
231
+ end
232
+
233
+ specify "should allow us to name the sequences" do
234
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
235
+ primary_key :id, :sequence_name => "seq_test"
236
+ end
237
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
238
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
239
+ "CREATE SEQUENCE SEQ_TEST",
240
+ " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
241
+ ], "DROP SEQUENCE SEQ_TEST" ]
242
+ end
243
+
244
+ specify "should allow us to set the starting position for the sequences" do
245
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
246
+ primary_key :id, :sequence_start_position => 999
247
+ end
248
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
249
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
250
+ "CREATE SEQUENCE SEQ_POSTS_ID",
251
+ "ALTER SEQUENCE SEQ_POSTS_ID RESTART WITH 999",
252
+ " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
253
+ ], "DROP SEQUENCE SEQ_POSTS_ID" ]
254
+ end
255
+
256
+ specify "should allow us to name and set the starting position for the sequences" do
257
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
258
+ primary_key :id, :sequence_name => "seq_test", :sequence_start_position => 999
259
+ end
260
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
261
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
262
+ "CREATE SEQUENCE SEQ_TEST",
263
+ "ALTER SEQUENCE SEQ_TEST RESTART WITH 999",
264
+ " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
265
+ ], "DROP SEQUENCE SEQ_TEST" ]
266
+ end
267
+
268
+ specify "should allow us to name the triggers" do
269
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
270
+ primary_key :id, :trigger_name => "trig_test"
271
+ end
272
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
273
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
274
+ "CREATE SEQUENCE SEQ_POSTS_ID",
275
+ " CREATE TRIGGER TRIG_TEST for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
276
+ ], "DROP SEQUENCE SEQ_POSTS_ID" ]
277
+ end
278
+
279
+ specify "should allow us to not create the sequence" do
280
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
281
+ primary_key :id, :create_sequence => false
282
+ end
283
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
284
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
285
+ " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
286
+ ], nil]
287
+ end
288
+
289
+ specify "should allow us to not create the trigger" do
290
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
291
+ primary_key :id, :create_trigger => false
292
+ end
293
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
294
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
295
+ "CREATE SEQUENCE SEQ_POSTS_ID",
296
+ ], "DROP SEQUENCE SEQ_POSTS_ID"]
297
+ end
298
+
299
+ specify "should allow us to not create either the sequence nor the trigger" do
300
+ g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
301
+ primary_key :id, :create_sequence => false, :create_trigger => false
302
+ end
303
+ FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
304
+ "CREATE TABLE POSTS (ID integer PRIMARY KEY )"
305
+ ], nil]
306
+ end
307
+
308
+ specify "should support column operations" do
309
+ @db.create_table!(:test2){varchar :name, :size => 50; integer :val}
310
+ @db[:test2] << {}
311
+ @db[:test2].columns.should == [:name, :val]
312
+
313
+ @db.add_column :test2, :xyz, :varchar, :size => 50
314
+ @db[:test2].columns.should == [:name, :val, :xyz]
315
+
316
+ @db[:test2].columns.should == [:name, :val, :xyz]
317
+ @db.drop_column :test2, :xyz
318
+
319
+ @db[:test2].columns.should == [:name, :val]
320
+
321
+ @db[:test2].delete
322
+ @db.add_column :test2, :xyz, :varchar, :default => '000', :size => 50#, :create_domain => 'xyz_varchar'
323
+ @db[:test2] << {:name => 'mmm', :val => 111, :xyz => 'qqqq'}
324
+
325
+ @db[:test2].columns.should == [:name, :val, :xyz]
326
+ @db.rename_column :test2, :xyz, :zyx
327
+ @db[:test2].columns.should == [:name, :val, :zyx]
328
+ @db[:test2].first[:zyx].should == 'qqqq'
329
+
330
+ @db.add_column :test2, :xyz, :decimal, :elements => [12, 2]
331
+ @db[:test2].delete
332
+ @db[:test2] << {:name => 'mmm', :val => 111, :xyz => 56.4}
333
+ @db.set_column_type :test2, :xyz, :varchar, :size => 50
334
+
335
+ @db[:test2].first[:xyz].should == "56.40"
336
+ end
337
+
338
+ specify "should allow us to retrieve the primary key for a table" do
339
+ @db.create_table!(:test2){primary_key :id}
340
+ @db.primary_key(:test2).should == ["id"]
341
+ end
342
+ end
343
+
344
+ context "Postgres::Dataset#insert" do
345
+ setup do
346
+ @ds = FIREBIRD_DB[:test5]
347
+ @ds.delete
348
+ end
349
+
350
+ specify "should using call insert_returning_sql" do
351
+ @ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID', :server=> :default)
352
+ @ds.insert(:val=>10)
353
+ end
354
+
355
+ specify "should have insert_returning_sql use the RETURNING keyword" do
356
+ @ds.insert_returning_sql(:XID, :val=>10).should == "INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID"
357
+ @ds.insert_returning_sql('*'.lit, :val=>10).should == "INSERT INTO TEST5 (VAL) VALUES (10) RETURNING *"
358
+ @ds.insert_returning_sql('NULL'.lit, :val=>10).should == "INSERT INTO TEST5 (VAL) VALUES (10) RETURNING NULL"
359
+ end
360
+
361
+ specify "should correctly return the inserted record's primary key value" do
362
+ value1 = 10
363
+ id1 = @ds.insert(:val=>value1)
364
+ @ds.first(:XID=>id1)[:val].should == value1
365
+ value2 = 20
366
+ id2 = @ds.insert(:val=>value2)
367
+ @ds.first(:XID=>id2)[:val].should == value2
368
+ end
369
+
370
+ specify "should return nil if the table has no primary key" do
371
+ ds = FIREBIRD_DB[:test]
372
+ ds.delete
373
+ ds.insert(:name=>'a').should == nil
374
+ end
375
+ end
376
+
@@ -0,0 +1,96 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
+
3
+ unless defined?(INFORMIX_DB)
4
+ INFORMIX_DB = Sequel.connect('informix://localhost/mydb')
5
+ end
6
+
7
+ if INFORMIX_DB.table_exists?(:test)
8
+ INFORMIX_DB.drop_table :test
9
+ end
10
+ INFORMIX_DB.create_table :test do
11
+ text :name
12
+ integer :value
13
+
14
+ index :value
15
+ end
16
+
17
+ context "A Informix database" do
18
+ specify "should provide disconnect functionality" do
19
+ INFORMIX_DB.execute("select user from dual")
20
+ INFORMIX_DB.pool.size.should == 1
21
+ INFORMIX_DB.disconnect
22
+ INFORMIX_DB.pool.size.should == 0
23
+ end
24
+ end
25
+
26
+ context "A Informix dataset" do
27
+ setup do
28
+ @d = INFORMIX_DB[:test]
29
+ @d.delete # remove all records
30
+ end
31
+
32
+ specify "should return the correct record count" do
33
+ @d.count.should == 0
34
+ @d << {:name => 'abc', :value => 123}
35
+ @d << {:name => 'abc', :value => 456}
36
+ @d << {:name => 'def', :value => 789}
37
+ @d.count.should == 3
38
+ end
39
+
40
+ specify "should return the correct records" do
41
+ @d.to_a.should == []
42
+ @d << {:name => 'abc', :value => 123}
43
+ @d << {:name => 'abc', :value => 456}
44
+ @d << {:name => 'def', :value => 789}
45
+
46
+ @d.order(:value).to_a.should == [
47
+ {:name => 'abc', :value => 123},
48
+ {:name => 'abc', :value => 456},
49
+ {:name => 'def', :value => 789}
50
+ ]
51
+ end
52
+
53
+ specify "should update records correctly" do
54
+ @d << {:name => 'abc', :value => 123}
55
+ @d << {:name => 'abc', :value => 456}
56
+ @d << {:name => 'def', :value => 789}
57
+ @d.filter(:name => 'abc').update(:value => 530)
58
+
59
+ # the third record should stay the same
60
+ # floating-point precision bullshit
61
+ @d[:name => 'def'][:value].should == 789
62
+ @d.filter(:value => 530).count.should == 2
63
+ end
64
+
65
+ specify "should delete records correctly" do
66
+ @d << {:name => 'abc', :value => 123}
67
+ @d << {:name => 'abc', :value => 456}
68
+ @d << {:name => 'def', :value => 789}
69
+ @d.filter(:name => 'abc').delete
70
+
71
+ @d.count.should == 1
72
+ @d.first[:name].should == 'def'
73
+ end
74
+
75
+ specify "should be able to literalize booleans" do
76
+ proc {@d.literal(true)}.should_not raise_error
77
+ proc {@d.literal(false)}.should_not raise_error
78
+ end
79
+
80
+ specify "should support transactions" do
81
+ INFORMIX_DB.transaction do
82
+ @d << {:name => 'abc', :value => 1}
83
+ end
84
+
85
+ @d.count.should == 1
86
+ end
87
+
88
+ specify "should support #first and #last" do
89
+ @d << {:name => 'abc', :value => 123}
90
+ @d << {:name => 'abc', :value => 456}
91
+ @d << {:name => 'def', :value => 789}
92
+
93
+ @d.order(:value).first.should == {:name => 'abc', :value => 123}
94
+ @d.order(:value).last.should == {:name => 'def', :value => 789}
95
+ end
96
+ end