epugh-sequel 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/README.rdoc +652 -0
  2. data/VERSION.yml +4 -0
  3. data/bin/sequel +104 -0
  4. data/lib/sequel.rb +1 -0
  5. data/lib/sequel/adapters/ado.rb +85 -0
  6. data/lib/sequel/adapters/db2.rb +132 -0
  7. data/lib/sequel/adapters/dbi.rb +101 -0
  8. data/lib/sequel/adapters/do.rb +197 -0
  9. data/lib/sequel/adapters/do/mysql.rb +38 -0
  10. data/lib/sequel/adapters/do/postgres.rb +92 -0
  11. data/lib/sequel/adapters/do/sqlite.rb +31 -0
  12. data/lib/sequel/adapters/firebird.rb +307 -0
  13. data/lib/sequel/adapters/informix.rb +75 -0
  14. data/lib/sequel/adapters/jdbc.rb +485 -0
  15. data/lib/sequel/adapters/jdbc/h2.rb +62 -0
  16. data/lib/sequel/adapters/jdbc/mysql.rb +56 -0
  17. data/lib/sequel/adapters/jdbc/oracle.rb +23 -0
  18. data/lib/sequel/adapters/jdbc/postgresql.rb +101 -0
  19. data/lib/sequel/adapters/jdbc/sqlite.rb +43 -0
  20. data/lib/sequel/adapters/mysql.rb +370 -0
  21. data/lib/sequel/adapters/odbc.rb +184 -0
  22. data/lib/sequel/adapters/openbase.rb +57 -0
  23. data/lib/sequel/adapters/oracle.rb +140 -0
  24. data/lib/sequel/adapters/postgres.rb +453 -0
  25. data/lib/sequel/adapters/shared/mssql.rb +93 -0
  26. data/lib/sequel/adapters/shared/mysql.rb +341 -0
  27. data/lib/sequel/adapters/shared/oracle.rb +62 -0
  28. data/lib/sequel/adapters/shared/postgres.rb +743 -0
  29. data/lib/sequel/adapters/shared/progress.rb +34 -0
  30. data/lib/sequel/adapters/shared/sqlite.rb +263 -0
  31. data/lib/sequel/adapters/sqlite.rb +243 -0
  32. data/lib/sequel/adapters/utils/date_format.rb +21 -0
  33. data/lib/sequel/adapters/utils/stored_procedures.rb +75 -0
  34. data/lib/sequel/adapters/utils/unsupported.rb +62 -0
  35. data/lib/sequel/connection_pool.rb +258 -0
  36. data/lib/sequel/core.rb +204 -0
  37. data/lib/sequel/core_sql.rb +185 -0
  38. data/lib/sequel/database.rb +687 -0
  39. data/lib/sequel/database/schema_generator.rb +324 -0
  40. data/lib/sequel/database/schema_methods.rb +164 -0
  41. data/lib/sequel/database/schema_sql.rb +324 -0
  42. data/lib/sequel/dataset.rb +422 -0
  43. data/lib/sequel/dataset/convenience.rb +237 -0
  44. data/lib/sequel/dataset/prepared_statements.rb +220 -0
  45. data/lib/sequel/dataset/sql.rb +1105 -0
  46. data/lib/sequel/deprecated.rb +529 -0
  47. data/lib/sequel/exceptions.rb +44 -0
  48. data/lib/sequel/extensions/blank.rb +42 -0
  49. data/lib/sequel/extensions/inflector.rb +288 -0
  50. data/lib/sequel/extensions/pagination.rb +96 -0
  51. data/lib/sequel/extensions/pretty_table.rb +78 -0
  52. data/lib/sequel/extensions/query.rb +48 -0
  53. data/lib/sequel/extensions/string_date_time.rb +47 -0
  54. data/lib/sequel/metaprogramming.rb +44 -0
  55. data/lib/sequel/migration.rb +212 -0
  56. data/lib/sequel/model.rb +142 -0
  57. data/lib/sequel/model/association_reflection.rb +263 -0
  58. data/lib/sequel/model/associations.rb +1024 -0
  59. data/lib/sequel/model/base.rb +911 -0
  60. data/lib/sequel/model/deprecated.rb +188 -0
  61. data/lib/sequel/model/deprecated_hooks.rb +103 -0
  62. data/lib/sequel/model/deprecated_inflector.rb +335 -0
  63. data/lib/sequel/model/deprecated_validations.rb +384 -0
  64. data/lib/sequel/model/errors.rb +37 -0
  65. data/lib/sequel/model/exceptions.rb +7 -0
  66. data/lib/sequel/model/inflections.rb +230 -0
  67. data/lib/sequel/model/plugins.rb +74 -0
  68. data/lib/sequel/object_graph.rb +230 -0
  69. data/lib/sequel/plugins/caching.rb +122 -0
  70. data/lib/sequel/plugins/hook_class_methods.rb +122 -0
  71. data/lib/sequel/plugins/schema.rb +53 -0
  72. data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
  73. data/lib/sequel/plugins/validation_class_methods.rb +373 -0
  74. data/lib/sequel/sql.rb +854 -0
  75. data/lib/sequel/version.rb +11 -0
  76. data/lib/sequel_core.rb +1 -0
  77. data/lib/sequel_model.rb +1 -0
  78. data/spec/adapters/ado_spec.rb +46 -0
  79. data/spec/adapters/firebird_spec.rb +376 -0
  80. data/spec/adapters/informix_spec.rb +96 -0
  81. data/spec/adapters/mysql_spec.rb +875 -0
  82. data/spec/adapters/oracle_spec.rb +272 -0
  83. data/spec/adapters/postgres_spec.rb +692 -0
  84. data/spec/adapters/spec_helper.rb +10 -0
  85. data/spec/adapters/sqlite_spec.rb +550 -0
  86. data/spec/core/connection_pool_spec.rb +526 -0
  87. data/spec/core/core_ext_spec.rb +156 -0
  88. data/spec/core/core_sql_spec.rb +528 -0
  89. data/spec/core/database_spec.rb +1214 -0
  90. data/spec/core/dataset_spec.rb +3513 -0
  91. data/spec/core/expression_filters_spec.rb +363 -0
  92. data/spec/core/migration_spec.rb +261 -0
  93. data/spec/core/object_graph_spec.rb +280 -0
  94. data/spec/core/pretty_table_spec.rb +58 -0
  95. data/spec/core/schema_generator_spec.rb +167 -0
  96. data/spec/core/schema_spec.rb +778 -0
  97. data/spec/core/spec_helper.rb +82 -0
  98. data/spec/core/version_spec.rb +7 -0
  99. data/spec/extensions/blank_spec.rb +67 -0
  100. data/spec/extensions/caching_spec.rb +201 -0
  101. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  102. data/spec/extensions/inflector_spec.rb +122 -0
  103. data/spec/extensions/pagination_spec.rb +99 -0
  104. data/spec/extensions/pretty_table_spec.rb +91 -0
  105. data/spec/extensions/query_spec.rb +85 -0
  106. data/spec/extensions/schema_spec.rb +111 -0
  107. data/spec/extensions/single_table_inheritance_spec.rb +53 -0
  108. data/spec/extensions/spec_helper.rb +90 -0
  109. data/spec/extensions/string_date_time_spec.rb +93 -0
  110. data/spec/extensions/validation_class_methods_spec.rb +1054 -0
  111. data/spec/integration/dataset_test.rb +160 -0
  112. data/spec/integration/eager_loader_test.rb +683 -0
  113. data/spec/integration/prepared_statement_test.rb +130 -0
  114. data/spec/integration/schema_test.rb +183 -0
  115. data/spec/integration/spec_helper.rb +75 -0
  116. data/spec/integration/type_test.rb +96 -0
  117. data/spec/model/association_reflection_spec.rb +93 -0
  118. data/spec/model/associations_spec.rb +1780 -0
  119. data/spec/model/base_spec.rb +494 -0
  120. data/spec/model/caching_spec.rb +217 -0
  121. data/spec/model/dataset_methods_spec.rb +78 -0
  122. data/spec/model/eager_loading_spec.rb +1165 -0
  123. data/spec/model/hooks_spec.rb +472 -0
  124. data/spec/model/inflector_spec.rb +126 -0
  125. data/spec/model/model_spec.rb +588 -0
  126. data/spec/model/plugins_spec.rb +142 -0
  127. data/spec/model/record_spec.rb +1243 -0
  128. data/spec/model/schema_spec.rb +92 -0
  129. data/spec/model/spec_helper.rb +124 -0
  130. data/spec/model/validations_spec.rb +1080 -0
  131. data/spec/rcov.opts +6 -0
  132. data/spec/spec.opts +0 -0
  133. data/spec/spec_config.rb.example +10 -0
  134. metadata +202 -0
@@ -0,0 +1,778 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "DB#create_table" do
4
+ setup do
5
+ @db = SchemaDummyDatabase.new
6
+ end
7
+
8
+ specify "should accept the table name" do
9
+ @db.create_table(:cats) {}
10
+ @db.sqls.should == ['CREATE TABLE cats ()']
11
+ end
12
+
13
+ specify "should accept the table name in multiple formats" do
14
+ @db.create_table(:cats__cats) {}
15
+ @db.create_table("cats__cats1") {}
16
+ @db.create_table(:cats__cats2.identifier) {}
17
+ @db.create_table(:cats.qualify(:cats3)) {}
18
+ @db.sqls.should == ['CREATE TABLE cats.cats ()', 'CREATE TABLE cats__cats1 ()', 'CREATE TABLE cats__cats2 ()', 'CREATE TABLE cats3.cats ()']
19
+ end
20
+
21
+ specify "should raise an error if the table name argument is not valid" do
22
+ proc{@db.create_table(1) {}}.should raise_error(Sequel::Error)
23
+ proc{@db.create_table(:cats.as(:c)) {}}.should raise_error(Sequel::Error)
24
+ end
25
+
26
+ specify "should accept multiple columns" do
27
+ @db.create_table(:cats) do
28
+ column :id, :integer
29
+ column :name, :text
30
+ end
31
+ @db.sqls.should == ['CREATE TABLE cats (id integer, name text)']
32
+ end
33
+
34
+ specify "should accept method calls as data types" do
35
+ @db.create_table(:cats) do
36
+ integer :id
37
+ text :name
38
+ end
39
+ @db.sqls.should == ['CREATE TABLE cats (id integer, name text)']
40
+ end
41
+
42
+ specify "should transform types given as ruby classes to database-specific types" do
43
+ @db.create_table(:cats) do
44
+ String :a
45
+ Integer :b
46
+ Fixnum :c
47
+ Bignum :d
48
+ Float :e
49
+ BigDecimal :f
50
+ Date :g
51
+ DateTime :h
52
+ Time :i
53
+ Numeric :j
54
+ File :k
55
+ TrueClass :l
56
+ FalseClass :m
57
+ column :n, Fixnum
58
+ primary_key :o, :type=>String
59
+ foreign_key :p, :f, :type=>Date
60
+ end
61
+ @db.sqls.should == ['CREATE TABLE cats (o varchar(255) PRIMARY KEY AUTOINCREMENT, a varchar(255), b integer, c integer, d bigint, e double precision, f numeric, g date, h timestamp, i timestamp, j numeric, k blob, l boolean, m boolean, n integer, p date REFERENCES f)']
62
+ end
63
+
64
+ specify "should accept primary key definition" do
65
+ @db.create_table(:cats) do
66
+ primary_key :id
67
+ end
68
+ @db.sqls.should == ['CREATE TABLE cats (id integer PRIMARY KEY AUTOINCREMENT)']
69
+
70
+ @db.sqls.clear
71
+ @db.create_table(:cats) do
72
+ primary_key :id, :serial, :auto_increment => false
73
+ end
74
+ @db.sqls.should == ['CREATE TABLE cats (id serial PRIMARY KEY)']
75
+
76
+ @db.sqls.clear
77
+ @db.create_table(:cats) do
78
+ primary_key :id, :type => :serial, :auto_increment => false
79
+ end
80
+ @db.sqls.should == ['CREATE TABLE cats (id serial PRIMARY KEY)']
81
+ end
82
+
83
+ specify "should accept and literalize default values" do
84
+ @db.create_table(:cats) do
85
+ integer :id, :default => 123
86
+ text :name, :default => "abc'def"
87
+ end
88
+ @db.sqls.should == ["CREATE TABLE cats (id integer DEFAULT 123, name text DEFAULT 'abc''def')"]
89
+ end
90
+
91
+ specify "should accept not null definition" do
92
+ @db.create_table(:cats) do
93
+ integer :id
94
+ text :name, :null => false
95
+ end
96
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text NOT NULL)"]
97
+ end
98
+
99
+ specify "should accept null definition" do
100
+ @db.create_table(:cats) do
101
+ integer :id
102
+ text :name, :null => true
103
+ end
104
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text NULL)"]
105
+ end
106
+
107
+ specify "should accept unique definition" do
108
+ @db.create_table(:cats) do
109
+ integer :id
110
+ text :name, :unique => true
111
+ end
112
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text UNIQUE)"]
113
+ end
114
+
115
+ specify "should accept unsigned definition" do
116
+ @db.create_table(:cats) do
117
+ integer :value, :unsigned => true
118
+ end
119
+ @db.sqls.should == ["CREATE TABLE cats (value integer UNSIGNED)"]
120
+ end
121
+
122
+ specify "should accept [SET|ENUM](...) types" do
123
+ @db.create_table(:cats) do
124
+ set :color, :elements => ['black', 'tricolor', 'grey']
125
+ end
126
+ @db.sqls.should == ["CREATE TABLE cats (color set('black', 'tricolor', 'grey'))"]
127
+ end
128
+
129
+ specify "should accept varchar size" do
130
+ @db.create_table(:cats) do
131
+ varchar :name
132
+ end
133
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(255))"]
134
+ @db.sqls.clear
135
+ @db.create_table(:cats) do
136
+ varchar :name, :size => 51
137
+ end
138
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(51))"]
139
+ end
140
+
141
+ specify "should use double precision for double type" do
142
+ @db.create_table(:cats) do
143
+ double :name
144
+ end
145
+ @db.sqls.should == ["CREATE TABLE cats (name double precision)"]
146
+ end
147
+
148
+ specify "should accept foreign keys without options" do
149
+ @db.create_table(:cats) do
150
+ foreign_key :project_id
151
+ end
152
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer)"]
153
+ end
154
+
155
+ specify "should accept foreign keys with options" do
156
+ @db.create_table(:cats) do
157
+ foreign_key :project_id, :table => :projects
158
+ end
159
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects)"]
160
+ end
161
+
162
+ specify "should accept foreign keys with separate table argument" do
163
+ @db.create_table(:cats) do
164
+ foreign_key :project_id, :projects, :default=>3
165
+ end
166
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer DEFAULT 3 REFERENCES projects)"]
167
+ end
168
+
169
+ specify "should raise an error if the table argument to foreign_key isn't a hash, symbol, or nil" do
170
+ proc{@db.create_table(:cats){foreign_key :project_id, Object.new, :default=>3}}.should raise_error(Sequel::Error)
171
+ end
172
+
173
+ specify "should accept foreign keys with arbitrary keys" do
174
+ @db.create_table(:cats) do
175
+ foreign_key :project_id, :table => :projects, :key => :id
176
+ end
177
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects(id))"]
178
+
179
+ @db.sqls.clear
180
+ @db.create_table(:cats) do
181
+ foreign_key :project_id, :table => :projects, :key => :zzz
182
+ end
183
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects(zzz))"]
184
+ end
185
+
186
+ specify "should accept foreign keys with ON DELETE clause" do
187
+ @db.create_table(:cats) do
188
+ foreign_key :project_id, :table => :projects, :on_delete => :restrict
189
+ end
190
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE RESTRICT)"]
191
+
192
+ @db.sqls.clear
193
+ @db.create_table(:cats) do
194
+ foreign_key :project_id, :table => :projects, :on_delete => :cascade
195
+ end
196
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)"]
197
+
198
+ @db.sqls.clear
199
+ @db.create_table(:cats) do
200
+ foreign_key :project_id, :table => :projects, :on_delete => :no_action
201
+ end
202
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE NO ACTION)"]
203
+ @db.sqls.clear
204
+
205
+ @db.sqls.clear
206
+ @db.create_table(:cats) do
207
+ foreign_key :project_id, :table => :projects, :on_delete => :set_null
208
+ end
209
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET NULL)"]
210
+ @db.sqls.clear
211
+
212
+ @db.sqls.clear
213
+ @db.create_table(:cats) do
214
+ foreign_key :project_id, :table => :projects, :on_delete => :set_default
215
+ end
216
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET DEFAULT)"]
217
+ @db.sqls.clear
218
+ end
219
+
220
+ specify "should accept foreign keys with ON UPDATE clause" do
221
+ @db.create_table(:cats) do
222
+ foreign_key :project_id, :table => :projects, :on_update => :restrict
223
+ end
224
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE RESTRICT)"]
225
+
226
+ @db.sqls.clear
227
+ @db.create_table(:cats) do
228
+ foreign_key :project_id, :table => :projects, :on_update => :cascade
229
+ end
230
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE CASCADE)"]
231
+
232
+ @db.sqls.clear
233
+ @db.create_table(:cats) do
234
+ foreign_key :project_id, :table => :projects, :on_update => :no_action
235
+ end
236
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE NO ACTION)"]
237
+ @db.sqls.clear
238
+
239
+ @db.sqls.clear
240
+ @db.create_table(:cats) do
241
+ foreign_key :project_id, :table => :projects, :on_update => :set_null
242
+ end
243
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE SET NULL)"]
244
+ @db.sqls.clear
245
+
246
+ @db.sqls.clear
247
+ @db.create_table(:cats) do
248
+ foreign_key :project_id, :table => :projects, :on_update => :set_default
249
+ end
250
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE SET DEFAULT)"]
251
+ @db.sqls.clear
252
+ end
253
+
254
+ specify "should accept inline index definition" do
255
+ @db.create_table(:cats) do
256
+ integer :id, :index => true
257
+ end
258
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
259
+ end
260
+
261
+ specify "should accept inline index definition for foreign keys" do
262
+ @db.create_table(:cats) do
263
+ foreign_key :project_id, :table => :projects, :on_delete => :cascade, :index => true
264
+ end
265
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)",
266
+ "CREATE INDEX cats_project_id_index ON cats (project_id)"]
267
+ end
268
+
269
+ specify "should accept index definitions" do
270
+ @db.create_table(:cats) do
271
+ integer :id
272
+ index :id
273
+ end
274
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
275
+ end
276
+
277
+ specify "should accept unique index definitions" do
278
+ @db.create_table(:cats) do
279
+ text :name
280
+ unique :name
281
+ end
282
+ @db.sqls.should == ["CREATE TABLE cats (name text, UNIQUE (name))"]
283
+ end
284
+
285
+ specify "should raise on full-text index definitions" do
286
+ proc {
287
+ @db.create_table(:cats) do
288
+ text :name
289
+ full_text_index :name
290
+ end
291
+ }.should raise_error(Sequel::Error)
292
+ end
293
+
294
+ specify "should raise on spatial index definitions" do
295
+ proc {
296
+ @db.create_table(:cats) do
297
+ point :geom
298
+ spatial_index :geom
299
+ end
300
+ }.should raise_error(Sequel::Error)
301
+ end
302
+
303
+ specify "should raise on partial index definitions" do
304
+ proc {
305
+ @db.create_table(:cats) do
306
+ text :name
307
+ index :name, :where => {:something => true}
308
+ end
309
+ }.should raise_error(Sequel::Error)
310
+ end
311
+
312
+ specify "should raise index definitions with type" do
313
+ proc {
314
+ @db.create_table(:cats) do
315
+ text :name
316
+ index :name, :type => :hash
317
+ end
318
+ }.should raise_error(Sequel::Error)
319
+ end
320
+
321
+ specify "should accept multiple index definitions" do
322
+ @db.create_table(:cats) do
323
+ integer :id
324
+ index :id
325
+ index :name
326
+ end
327
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)", "CREATE INDEX cats_name_index ON cats (name)"]
328
+ end
329
+
330
+ specify "should accept functional indexes" do
331
+ @db.create_table(:cats) do
332
+ integer :id
333
+ index :lower.sql_function(:name)
334
+ end
335
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_lower_name__index ON cats (lower(name))"]
336
+ end
337
+
338
+ specify "should accept indexes with identifiers" do
339
+ @db.create_table(:cats) do
340
+ integer :id
341
+ index :lower__name.identifier
342
+ end
343
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_lower__name_index ON cats (lower__name)"]
344
+ end
345
+
346
+ specify "should accept custom index names" do
347
+ @db.create_table(:cats) do
348
+ integer :id
349
+ index :id, :name => 'abc'
350
+ end
351
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX abc ON cats (id)"]
352
+ end
353
+
354
+ specify "should accept unique index definitions" do
355
+ @db.create_table(:cats) do
356
+ integer :id
357
+ index :id, :unique => true
358
+ end
359
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_index ON cats (id)"]
360
+ end
361
+
362
+ specify "should accept composite index definitions" do
363
+ @db.create_table(:cats) do
364
+ integer :id
365
+ index [:id, :name], :unique => true
366
+ end
367
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_name_index ON cats (id, name)"]
368
+ end
369
+
370
+ specify "should accept unnamed constraint definitions with blocks" do
371
+ @db.create_table(:cats) do
372
+ integer :score
373
+ check {(:x.sql_number > 0) & (:y.sql_number < 1)}
374
+ end
375
+ @db.sqls.should == ["CREATE TABLE cats (score integer, CHECK ((x > 0) AND (y < 1)))"]
376
+ end
377
+
378
+ specify "should accept unnamed constraint definitions" do
379
+ @db.create_table(:cats) do
380
+ check 'price < ?', 100
381
+ end
382
+ @db.sqls.should == ["CREATE TABLE cats (CHECK (price < 100))"]
383
+ end
384
+
385
+ specify "should accept hash constraints" do
386
+ @db.create_table(:cats) do
387
+ check :price=>100
388
+ end
389
+ @db.sqls.should == ["CREATE TABLE cats (CHECK (price = 100))"]
390
+ end
391
+
392
+ specify "should accept named constraint definitions" do
393
+ @db.create_table(:cats) do
394
+ integer :score
395
+ constraint :valid_score, 'score <= 100'
396
+ end
397
+ @db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100))"]
398
+ end
399
+
400
+ specify "should accept named constraint definitions with block" do
401
+ @db.create_table(:cats) do
402
+ constraint(:blah_blah) {(:x.sql_number > 0) & (:y.sql_number < 1)}
403
+ end
404
+ @db.sqls.should == ["CREATE TABLE cats (CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1)))"]
405
+ end
406
+
407
+ specify "should accept composite primary keys" do
408
+ @db.create_table(:cats) do
409
+ integer :a
410
+ integer :b
411
+ primary_key [:a, :b]
412
+ end
413
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, PRIMARY KEY (a, b))"]
414
+ end
415
+
416
+ specify "should accept named composite primary keys" do
417
+ @db.create_table(:cats) do
418
+ integer :a
419
+ integer :b
420
+ primary_key [:a, :b], :name => :cpk
421
+ end
422
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, CONSTRAINT cpk PRIMARY KEY (a, b))"]
423
+ end
424
+
425
+ specify "should accept composite foreign keys" do
426
+ @db.create_table(:cats) do
427
+ integer :a
428
+ integer :b
429
+ foreign_key [:a, :b], :abc
430
+ end
431
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc)"]
432
+ end
433
+
434
+ specify "should accept named composite foreign keys" do
435
+ @db.create_table(:cats) do
436
+ integer :a
437
+ integer :b
438
+ foreign_key [:a, :b], :abc, :name => :cfk
439
+ end
440
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, CONSTRAINT cfk FOREIGN KEY (a, b) REFERENCES abc)"]
441
+ end
442
+
443
+ specify "should accept composite foreign keys with arbitrary keys" do
444
+ @db.create_table(:cats) do
445
+ integer :a
446
+ integer :b
447
+ foreign_key [:a, :b], :abc, :key => [:real_a, :real_b]
448
+ end
449
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(real_a, real_b))"]
450
+ @db.sqls.clear
451
+
452
+ @db.create_table(:cats) do
453
+ integer :a
454
+ integer :b
455
+ foreign_key [:a, :b], :abc, :key => [:z, :x]
456
+ end
457
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(z, x))"]
458
+ end
459
+
460
+ specify "should accept composite foreign keys with on delete and on update clauses" do
461
+ @db.create_table(:cats) do
462
+ integer :a
463
+ integer :b
464
+ foreign_key [:a, :b], :abc, :on_delete => :cascade
465
+ end
466
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON DELETE CASCADE)"]
467
+
468
+ @db.sqls.clear
469
+ @db.create_table(:cats) do
470
+ integer :a
471
+ integer :b
472
+ foreign_key [:a, :b], :abc, :on_update => :no_action
473
+ end
474
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON UPDATE NO ACTION)"]
475
+
476
+ @db.sqls.clear
477
+ @db.create_table(:cats) do
478
+ integer :a
479
+ integer :b
480
+ foreign_key [:a, :b], :abc, :on_delete => :restrict, :on_update => :set_default
481
+ end
482
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON DELETE RESTRICT ON UPDATE SET DEFAULT)"]
483
+
484
+ @db.sqls.clear
485
+ @db.create_table(:cats) do
486
+ integer :a
487
+ integer :b
488
+ foreign_key [:a, :b], :abc, :key => [:x, :y], :on_delete => :set_null, :on_update => :set_null
489
+ end
490
+ @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(x, y) ON DELETE SET NULL ON UPDATE SET NULL)"]
491
+ end
492
+ end
493
+
494
+ context "DB#create_table!" do
495
+ setup do
496
+ @db = SchemaDummyDatabase.new
497
+ end
498
+
499
+ specify "should drop the table and then create it" do
500
+ @db.create_table!(:cats) {}
501
+ @db.sqls.should == ['DROP TABLE cats', 'CREATE TABLE cats ()']
502
+ end
503
+ end
504
+
505
+ context "DB#drop_table" do
506
+ setup do
507
+ @db = SchemaDummyDatabase.new
508
+ end
509
+
510
+ specify "should generate a DROP TABLE statement" do
511
+ @db.drop_table :cats
512
+ @db.sqls.should == ['DROP TABLE cats']
513
+ end
514
+ end
515
+
516
+ context "DB#alter_table" do
517
+ setup do
518
+ @db = SchemaDummyDatabase.new
519
+ end
520
+
521
+ specify "should allow adding not null constraint" do
522
+ @db.alter_table(:cats) do
523
+ set_column_allow_null :score, false
524
+ end
525
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score SET NOT NULL"]
526
+ end
527
+
528
+ specify "should allow droping not null constraint" do
529
+ @db.alter_table(:cats) do
530
+ set_column_allow_null :score, true
531
+ end
532
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score DROP NOT NULL"]
533
+ end
534
+
535
+ specify "should support add_column" do
536
+ @db.alter_table(:cats) do
537
+ add_column :score, :integer
538
+ end
539
+ @db.sqls.should == ["ALTER TABLE cats ADD COLUMN score integer"]
540
+ end
541
+
542
+ specify "should support add_constraint" do
543
+ @db.alter_table(:cats) do
544
+ add_constraint :valid_score, 'score <= 100'
545
+ end
546
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100)"]
547
+ end
548
+
549
+ specify "should support add_constraint with block" do
550
+ @db.alter_table(:cats) do
551
+ add_constraint(:blah_blah) {(:x.sql_number > 0) & (:y.sql_number < 1)}
552
+ end
553
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1))"]
554
+ end
555
+
556
+ specify "should support add_unique_constraint" do
557
+ @db.alter_table(:cats) do
558
+ add_unique_constraint [:a, :b]
559
+ end
560
+ @db.sqls.should == ["ALTER TABLE cats ADD UNIQUE (a, b)"]
561
+
562
+ @db.sqls.clear
563
+ @db.alter_table(:cats) do
564
+ add_unique_constraint [:a, :b], :name => :ab_uniq
565
+ end
566
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT ab_uniq UNIQUE (a, b)"]
567
+ end
568
+
569
+ specify "should support add_foreign_key" do
570
+ @db.alter_table(:cats) do
571
+ add_foreign_key :node_id, :nodes
572
+ end
573
+ @db.sqls.should == ["ALTER TABLE cats ADD COLUMN node_id integer REFERENCES nodes"]
574
+ end
575
+
576
+ specify "should support add_foreign_key with composite foreign keys" do
577
+ @db.alter_table(:cats) do
578
+ add_foreign_key [:node_id, :prop_id], :nodes_props
579
+ end
580
+ @db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props"]
581
+
582
+ @db.sqls.clear
583
+ @db.alter_table(:cats) do
584
+ add_foreign_key [:node_id, :prop_id], :nodes_props, :name => :cfk
585
+ end
586
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT cfk FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props"]
587
+
588
+ @db.sqls.clear
589
+ @db.alter_table(:cats) do
590
+ add_foreign_key [:node_id, :prop_id], :nodes_props, :key => [:nid, :pid]
591
+ end
592
+ @db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props(nid, pid)"]
593
+
594
+ @db.sqls.clear
595
+ @db.alter_table(:cats) do
596
+ add_foreign_key [:node_id, :prop_id], :nodes_props, :on_delete => :restrict, :on_update => :cascade
597
+ end
598
+ @db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props ON DELETE RESTRICT ON UPDATE CASCADE"]
599
+ end
600
+
601
+ specify "should support add_index" do
602
+ @db.alter_table(:cats) do
603
+ add_index :name
604
+ end
605
+ @db.sqls.should == ["CREATE INDEX cats_name_index ON cats (name)"]
606
+ end
607
+
608
+ specify "should support add_primary_key" do
609
+ @db.alter_table(:cats) do
610
+ add_primary_key :id
611
+ end
612
+ @db.sqls.should == ["ALTER TABLE cats ADD COLUMN id integer PRIMARY KEY AUTOINCREMENT"]
613
+ end
614
+
615
+ specify "should support add_primary_key with composite primary keys" do
616
+ @db.alter_table(:cats) do
617
+ add_primary_key [:id, :type]
618
+ end
619
+ @db.sqls.should == ["ALTER TABLE cats ADD PRIMARY KEY (id, type)"]
620
+
621
+ @db.sqls.clear
622
+ @db.alter_table(:cats) do
623
+ add_primary_key [:id, :type], :name => :cpk
624
+ end
625
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT cpk PRIMARY KEY (id, type)"]
626
+ end
627
+
628
+ specify "should support drop_column" do
629
+ @db.alter_table(:cats) do
630
+ drop_column :score
631
+ end
632
+ @db.sqls.should == ["ALTER TABLE cats DROP COLUMN score"]
633
+ end
634
+
635
+ specify "should support drop_constraint" do
636
+ @db.alter_table(:cats) do
637
+ drop_constraint :valid_score
638
+ end
639
+ @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score"]
640
+ end
641
+
642
+ specify "should support drop_index" do
643
+ @db.alter_table(:cats) do
644
+ drop_index :name
645
+ end
646
+ @db.sqls.should == ["DROP INDEX cats_name_index"]
647
+ end
648
+
649
+ specify "should support rename_column" do
650
+ @db.alter_table(:cats) do
651
+ rename_column :name, :old_name
652
+ end
653
+ @db.sqls.should == ["ALTER TABLE cats RENAME COLUMN name TO old_name"]
654
+ end
655
+
656
+ specify "should support set_column_default" do
657
+ @db.alter_table(:cats) do
658
+ set_column_default :score, 3
659
+ end
660
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score SET DEFAULT 3"]
661
+ end
662
+
663
+ specify "should support set_column_type" do
664
+ @db.alter_table(:cats) do
665
+ set_column_type :score, :real
666
+ end
667
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score TYPE real"]
668
+ end
669
+
670
+ specify "should support set_column_type with options" do
671
+ @db.alter_table(:cats) do
672
+ set_column_type :score, :integer, :unsigned=>true
673
+ set_column_type :score, :varchar, :size=>30
674
+ set_column_type :score, :enum, :elements=>['a', 'b']
675
+ end
676
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score TYPE integer UNSIGNED",
677
+ "ALTER TABLE cats ALTER COLUMN score TYPE varchar(30)",
678
+ "ALTER TABLE cats ALTER COLUMN score TYPE enum('a', 'b')"]
679
+ end
680
+ end
681
+
682
+ context "Schema Parser" do
683
+ setup do
684
+ @sqls = []
685
+ @db = Sequel::Database.new
686
+ end
687
+ after do
688
+ Sequel.convert_tinyint_to_bool = true
689
+ end
690
+
691
+ specify "should raise an error if there are no columns" do
692
+ @db.meta_def(:schema_parse_table) do |t, opts|
693
+ []
694
+ end
695
+ proc{@db.schema(:x)}.should raise_error(Sequel::Error)
696
+ end
697
+
698
+ specify "should parse the schema correctly for a single table" do
699
+ sqls = @sqls
700
+ proc{@db.schema(:x)}.should raise_error(Sequel::Error)
701
+ @db.meta_def(:schema_parse_table) do |t, opts|
702
+ sqls << t
703
+ [[:a, {:db_type=>t.to_s}]]
704
+ end
705
+ @db.schema(:x).should == [[:a, {:db_type=>"x"}]]
706
+ @sqls.should == ['x']
707
+ @db.schema(:x).should == [[:a, {:db_type=>"x"}]]
708
+ @sqls.should == ['x']
709
+ @db.schema(:x, :reload=>true).should == [[:a, {:db_type=>"x"}]]
710
+ @sqls.should == ['x', 'x']
711
+ end
712
+
713
+ deprec_specify "should parse the schema correctly for all tables" do
714
+ sqls = @sqls
715
+ proc{@db.schema}.should raise_error(Sequel::Error)
716
+ @db.meta_def(:tables){[:x]}
717
+ @db.meta_def(:schema_parse_table) do |t, opts|
718
+ sqls << t
719
+ [[:x, {:db_type=>t.to_s}]]
720
+ end
721
+ @db.schema.should == {'x'=>[[:x, {:db_type=>"x"}]]}
722
+ @sqls.should == ['x']
723
+ @db.schema.should == {'x'=>[[:x, {:db_type=>"x"}]]}
724
+ @sqls.should == ['x']
725
+ @db.schema(nil, :reload=>true).should == {'x'=>[[:x, {:db_type=>"x"}]]}
726
+ @sqls.should == ['x', 'x']
727
+ end
728
+
729
+ specify "should convert various types of table name arguments" do
730
+ @db.meta_def(:schema_parse_table) do |t, opts|
731
+ [[t, {:db_type=>t}]]
732
+ end
733
+ s1 = @db.schema(:x)
734
+ s1.should == [['x', {:db_type=>'x'}]]
735
+ @db.schema(:x).object_id.should == s1.object_id
736
+ @db.schema(:x.identifier).object_id.should == s1.object_id
737
+ s2 = @db.schema(:x__y)
738
+ s2.should == [['y', {:db_type=>'y'}]]
739
+ @db.schema(:x__y).object_id.should == s2.object_id
740
+ @db.schema(:y.qualify(:x)).object_id.should == s2.object_id
741
+ end
742
+
743
+ specify "should correctly parse all supported data types" do
744
+ @db.meta_def(:schema_parse_table) do |t, opts|
745
+ [[:x, {:type=>schema_column_type(t.to_s)}]]
746
+ end
747
+ @db.schema(:tinyint).first.last[:type].should == :boolean
748
+ Sequel.convert_tinyint_to_bool = false
749
+ @db.schema(:tinyint, :reload=>true).first.last[:type].should == :integer
750
+ @db.schema(:interval).first.last[:type].should == :interval
751
+ @db.schema(:int).first.last[:type].should == :integer
752
+ @db.schema(:integer).first.last[:type].should == :integer
753
+ @db.schema(:bigint).first.last[:type].should == :integer
754
+ @db.schema(:smallint).first.last[:type].should == :integer
755
+ @db.schema(:character).first.last[:type].should == :string
756
+ @db.schema(:"character varying").first.last[:type].should == :string
757
+ @db.schema(:varchar).first.last[:type].should == :string
758
+ @db.schema(:"varchar(255)").first.last[:type].should == :string
759
+ @db.schema(:text).first.last[:type].should == :string
760
+ @db.schema(:date).first.last[:type].should == :date
761
+ @db.schema(:datetime).first.last[:type].should == :datetime
762
+ @db.schema(:timestamp).first.last[:type].should == :datetime
763
+ @db.schema(:"timestamp with time zone").first.last[:type].should == :datetime
764
+ @db.schema(:"timestamp without time zone").first.last[:type].should == :datetime
765
+ @db.schema(:time).first.last[:type].should == :time
766
+ @db.schema(:"time with time zone").first.last[:type].should == :time
767
+ @db.schema(:"time without time zone").first.last[:type].should == :time
768
+ @db.schema(:boolean).first.last[:type].should == :boolean
769
+ @db.schema(:real).first.last[:type].should == :float
770
+ @db.schema(:float).first.last[:type].should == :float
771
+ @db.schema(:double).first.last[:type].should == :float
772
+ @db.schema(:"double precision").first.last[:type].should == :float
773
+ @db.schema(:numeric).first.last[:type].should == :decimal
774
+ @db.schema(:decimal).first.last[:type].should == :decimal
775
+ @db.schema(:money).first.last[:type].should == :decimal
776
+ @db.schema(:bytea).first.last[:type].should == :blob
777
+ end
778
+ end