sequel 2.9.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG +56 -0
  2. data/{README → README.rdoc} +85 -57
  3. data/Rakefile +10 -5
  4. data/bin/sequel +7 -16
  5. data/doc/advanced_associations.rdoc +5 -17
  6. data/doc/cheat_sheet.rdoc +18 -20
  7. data/doc/dataset_filtering.rdoc +8 -32
  8. data/doc/schema.rdoc +20 -0
  9. data/lib/sequel_core.rb +35 -1
  10. data/lib/sequel_core/adapters/ado.rb +1 -1
  11. data/lib/sequel_core/adapters/db2.rb +2 -2
  12. data/lib/sequel_core/adapters/dbi.rb +2 -11
  13. data/lib/sequel_core/adapters/do.rb +205 -0
  14. data/lib/sequel_core/adapters/do/mysql.rb +38 -0
  15. data/lib/sequel_core/adapters/do/postgres.rb +92 -0
  16. data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
  17. data/lib/sequel_core/adapters/firebird.rb +298 -0
  18. data/lib/sequel_core/adapters/informix.rb +10 -1
  19. data/lib/sequel_core/adapters/jdbc.rb +78 -19
  20. data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
  21. data/lib/sequel_core/adapters/jdbc/mysql.rb +10 -0
  22. data/lib/sequel_core/adapters/jdbc/postgresql.rb +7 -3
  23. data/lib/sequel_core/adapters/mysql.rb +53 -77
  24. data/lib/sequel_core/adapters/odbc.rb +1 -1
  25. data/lib/sequel_core/adapters/openbase.rb +1 -1
  26. data/lib/sequel_core/adapters/oracle.rb +2 -2
  27. data/lib/sequel_core/adapters/postgres.rb +16 -14
  28. data/lib/sequel_core/adapters/shared/mysql.rb +44 -9
  29. data/lib/sequel_core/adapters/shared/oracle.rb +4 -5
  30. data/lib/sequel_core/adapters/shared/postgres.rb +86 -82
  31. data/lib/sequel_core/adapters/shared/sqlite.rb +39 -24
  32. data/lib/sequel_core/adapters/sqlite.rb +11 -1
  33. data/lib/sequel_core/connection_pool.rb +10 -2
  34. data/lib/sequel_core/core_sql.rb +13 -3
  35. data/lib/sequel_core/database.rb +131 -30
  36. data/lib/sequel_core/database/schema.rb +5 -5
  37. data/lib/sequel_core/dataset.rb +31 -6
  38. data/lib/sequel_core/dataset/convenience.rb +11 -11
  39. data/lib/sequel_core/dataset/query.rb +2 -2
  40. data/lib/sequel_core/dataset/sql.rb +6 -6
  41. data/lib/sequel_core/exceptions.rb +4 -0
  42. data/lib/sequel_core/migration.rb +4 -4
  43. data/lib/sequel_core/schema/generator.rb +19 -3
  44. data/lib/sequel_core/schema/sql.rb +24 -20
  45. data/lib/sequel_core/sql.rb +13 -16
  46. data/lib/sequel_core/version.rb +11 -0
  47. data/lib/sequel_model.rb +2 -0
  48. data/lib/sequel_model/base.rb +2 -2
  49. data/lib/sequel_model/hooks.rb +46 -7
  50. data/lib/sequel_model/record.rb +11 -9
  51. data/lib/sequel_model/schema.rb +1 -1
  52. data/lib/sequel_model/validations.rb +72 -61
  53. data/spec/adapters/firebird_spec.rb +371 -0
  54. data/spec/adapters/mysql_spec.rb +118 -62
  55. data/spec/adapters/oracle_spec.rb +5 -5
  56. data/spec/adapters/postgres_spec.rb +33 -18
  57. data/spec/adapters/sqlite_spec.rb +2 -2
  58. data/spec/integration/dataset_test.rb +3 -3
  59. data/spec/integration/schema_test.rb +55 -5
  60. data/spec/integration/spec_helper.rb +11 -0
  61. data/spec/integration/type_test.rb +59 -16
  62. data/spec/sequel_core/connection_pool_spec.rb +14 -0
  63. data/spec/sequel_core/core_sql_spec.rb +24 -14
  64. data/spec/sequel_core/database_spec.rb +96 -11
  65. data/spec/sequel_core/dataset_spec.rb +97 -37
  66. data/spec/sequel_core/expression_filters_spec.rb +51 -40
  67. data/spec/sequel_core/object_graph_spec.rb +2 -2
  68. data/spec/sequel_core/schema_generator_spec.rb +31 -6
  69. data/spec/sequel_core/schema_spec.rb +25 -9
  70. data/spec/sequel_core/spec_helper.rb +4 -1
  71. data/spec/sequel_core/version_spec.rb +7 -0
  72. data/spec/sequel_model/associations_spec.rb +1 -1
  73. data/spec/sequel_model/hooks_spec.rb +68 -13
  74. data/spec/sequel_model/model_spec.rb +4 -4
  75. data/spec/sequel_model/record_spec.rb +22 -0
  76. data/spec/sequel_model/spec_helper.rb +2 -1
  77. data/spec/sequel_model/validations_spec.rb +107 -7
  78. metadata +15 -5
@@ -33,6 +33,29 @@ def logger.method_missing(m, msg)
33
33
  end
34
34
  MYSQL_DB.logger = logger
35
35
 
36
+ if MYSQL_DB.class.adapter_scheme == :do
37
+ SQL_BEGIN = 'Transaction.begin'
38
+ SQL_ROLLBACK = 'Transaction.rollback'
39
+ SQL_COMMIT = 'Transaction.commit'
40
+ else
41
+ SQL_BEGIN = 'BEGIN'
42
+ SQL_ROLLBACK = 'ROLLBACK'
43
+ SQL_COMMIT = 'COMMIT'
44
+ end
45
+
46
+ context "MySQL", '#create_table' do
47
+ setup do
48
+ @db = MYSQL_DB
49
+ end
50
+ after(:each) do
51
+ @db.drop_table :dolls
52
+ end
53
+ specify "should allow to specify options for MySQL" do
54
+ @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2') { text :name }
55
+ @db.sqls.should == ["CREATE TABLE dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
56
+ end
57
+ end
58
+
36
59
  context "A MySQL database" do
37
60
  setup do
38
61
  @db = MYSQL_DB
@@ -142,13 +165,13 @@ context "A MySQL dataset" do
142
165
  @d.select('COUNT(*)'.lit).sql.should == \
143
166
  'SELECT COUNT(*) FROM `items`'
144
167
 
145
- @d.select(:max[:value]).sql.should == \
168
+ @d.select(:max.sql_function(:value)).sql.should == \
146
169
  'SELECT max(`value`) FROM `items`'
147
170
 
148
- @d.select(:NOW[]).sql.should == \
171
+ @d.select(:NOW.sql_function).sql.should == \
149
172
  'SELECT NOW() FROM `items`'
150
173
 
151
- @d.select(:max[:items__value]).sql.should == \
174
+ @d.select(:max.sql_function(:items__value)).sql.should == \
152
175
  'SELECT max(`items`.`value`) FROM `items`'
153
176
 
154
177
  @d.order(:name.desc).sql.should == \
@@ -163,13 +186,13 @@ context "A MySQL dataset" do
163
186
  @d.select('max(items.`name`) AS `max_name`'.lit).sql.should == \
164
187
  'SELECT max(items.`name`) AS `max_name` FROM `items`'
165
188
 
166
- @d.select(:test[:abc, 'hello']).sql.should == \
189
+ @d.select(:test.sql_function(:abc, 'hello')).sql.should == \
167
190
  "SELECT test(`abc`, 'hello') FROM `items`"
168
191
 
169
- @d.select(:test[:abc__def, 'hello']).sql.should == \
192
+ @d.select(:test.sql_function(:abc__def, 'hello')).sql.should == \
170
193
  "SELECT test(`abc`.`def`, 'hello') FROM `items`"
171
194
 
172
- @d.select(:test[:abc__def, 'hello'].as(:x2)).sql.should == \
195
+ @d.select(:test.sql_function(:abc__def, 'hello').as(:x2)).sql.should == \
173
196
  "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
174
197
 
175
198
  @d.insert_sql(:value => 333).should == \
@@ -220,7 +243,7 @@ context "A MySQL dataset" do
220
243
  end
221
244
  end.should raise_error(Interrupt)
222
245
 
223
- MYSQL_DB.sqls.should == ['BEGIN', "INSERT INTO items (name) VALUES ('abc')", 'ROLLBACK']
246
+ MYSQL_DB.sqls.should == [SQL_BEGIN, "INSERT INTO items (name) VALUES ('abc')", SQL_ROLLBACK]
224
247
  end
225
248
 
226
249
  specify "should handle returning inside of the block by committing" do
@@ -232,7 +255,7 @@ context "A MySQL dataset" do
232
255
  end
233
256
  end
234
257
  MYSQL_DB.ret_commit
235
- MYSQL_DB.sqls.should == ['BEGIN', "INSERT INTO items (name) VALUES ('abc')", 'COMMIT']
258
+ MYSQL_DB.sqls.should == [SQL_BEGIN, "INSERT INTO items (name) VALUES ('abc')", SQL_COMMIT]
236
259
  end
237
260
 
238
261
  specify "should support regexps" do
@@ -263,9 +286,9 @@ context "MySQL datasets" do
263
286
  market = 'ICE'
264
287
  ack_stamp = Time.now - 15 * 60 # 15 minutes ago
265
288
  @d.query do
266
- select :market, :minute[:from_unixtime[:ack]].as(:minute)
267
- where {(:ack > ack_stamp) & {:market => market}}
268
- group_by :minute[:from_unixtime[:ack]]
289
+ select :market, :minute.sql_function(:from_unixtime.sql_function(:ack)).as(:minute)
290
+ where {(:ack.sql_number > ack_stamp) & {:market => market}}
291
+ group_by :minute.sql_function(:from_unixtime.sql_function(:ack))
269
292
  end.sql.should == \
270
293
  "SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
271
294
  end
@@ -295,21 +318,6 @@ context "MySQL datasets" do
295
318
  end
296
319
  end
297
320
 
298
- # # Commented out because it was causing subsequent examples to fail for some reason
299
- # context "Simple stored procedure test" do
300
- # setup do
301
- # # Create a simple stored procedure but drop it first if there
302
- # MYSQL_DB.execute("DROP PROCEDURE IF EXISTS sp_get_server_id;")
303
- # MYSQL_DB.execute("CREATE PROCEDURE sp_get_server_id() SQL SECURITY DEFINER SELECT @@SERVER_ID as server_id;")
304
- # end
305
- #
306
- # specify "should return the server-id via a stored procedure call" do
307
- # @server_id = MYSQL_DB["SELECT @@SERVER_ID as server_id;"].first[:server_id] # grab the server_id via a simple query
308
- # @server_id_by_sp = MYSQL_DB["CALL sp_get_server_id();"].first[:server_id]
309
- # @server_id_by_sp.should == @server_id # compare it to output from stored procedure
310
- # end
311
- # end
312
- #
313
321
  context "MySQL join expressions" do
314
322
  setup do
315
323
  @ds = MYSQL_DB[:nodes]
@@ -452,6 +460,52 @@ context "A MySQL database" do
452
460
  end
453
461
  end
454
462
 
463
+ context "A MySQL database", "with table options" do
464
+ before(:all) do
465
+ @options = {}
466
+ @options[:engine] = 'MyISAM'
467
+ @options[:charset] = 'latin2'
468
+ @options[:collate] = 'swedish'
469
+
470
+ Sequel::MySQL.default_engine = 'InnoDB'
471
+ Sequel::MySQL.default_charset = 'utf8'
472
+ Sequel::MySQL.default_collate = 'utf8'
473
+
474
+ @db = MYSQL_DB
475
+ @g = Sequel::Schema::Generator.new(@db) do
476
+ integer :size
477
+ text :name
478
+ end
479
+ end
480
+
481
+ after(:all) do
482
+ Sequel::MySQL.default_engine = nil
483
+ Sequel::MySQL.default_charset = nil
484
+ Sequel::MySQL.default_collate = nil
485
+ end
486
+
487
+ specify "should allow to pass custom options (engine, charset, collate) for table creation" do
488
+ statements = @db.create_table_sql_list(:items, *(@g.create_info << @options))
489
+ statements.should == [
490
+ "CREATE TABLE items (size integer, name text) ENGINE=MyISAM DEFAULT CHARSET=latin2 DEFAULT COLLATE=swedish"
491
+ ]
492
+ end
493
+
494
+ specify "should use default options if specified (engine, charset, collate) for table creation" do
495
+ statements = @db.create_table_sql_list(:items, *(@g.create_info))
496
+ statements.should == [
497
+ "CREATE TABLE items (size integer, name text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8"
498
+ ]
499
+ end
500
+
501
+ specify "should not use default if option has a nil value" do
502
+ statements = @db.create_table_sql_list(:items, *(@g.create_info << {:engine=>nil, :charset=>nil, :collate=>nil}))
503
+ statements.should == [
504
+ "CREATE TABLE items (size integer, name text)"
505
+ ]
506
+ end
507
+ end
508
+
455
509
  context "A MySQL database" do
456
510
  setup do
457
511
  @db = MYSQL_DB
@@ -510,7 +564,7 @@ end
510
564
  end
511
565
 
512
566
  # Socket tests should only be run if the MySQL server is on localhost
513
- if %w'localhost 127.0.0.1 ::1'.include? MYSQL_URI.host
567
+ if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and MYSQL_DB.class.adapter_scheme == :mysql
514
568
  context "A MySQL database" do
515
569
  specify "should accept a socket option" do
516
570
  db = Sequel.mysql(MYSQL_DB.opts[:database], :host => 'localhost', :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
@@ -667,9 +721,9 @@ context "MySQL::Dataset#multi_insert" do
667
721
  @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
668
722
 
669
723
  MYSQL_DB.sqls.should == [
670
- 'BEGIN',
724
+ SQL_BEGIN,
671
725
  "INSERT INTO items (name) VALUES ('abc'), ('def')",
672
- 'COMMIT'
726
+ SQL_COMMIT
673
727
  ]
674
728
 
675
729
  @d.all.should == [
@@ -682,12 +736,12 @@ context "MySQL::Dataset#multi_insert" do
682
736
  :commit_every => 2)
683
737
 
684
738
  MYSQL_DB.sqls.should == [
685
- 'BEGIN',
739
+ SQL_BEGIN,
686
740
  "INSERT INTO items (value) VALUES (1), (2)",
687
- 'COMMIT',
688
- 'BEGIN',
741
+ SQL_COMMIT,
742
+ SQL_BEGIN,
689
743
  "INSERT INTO items (value) VALUES (3), (4)",
690
- 'COMMIT'
744
+ SQL_COMMIT
691
745
  ]
692
746
 
693
747
  @d.all.should == [
@@ -703,12 +757,12 @@ context "MySQL::Dataset#multi_insert" do
703
757
  :slice => 2)
704
758
 
705
759
  MYSQL_DB.sqls.should == [
706
- 'BEGIN',
760
+ SQL_BEGIN,
707
761
  "INSERT INTO items (value) VALUES (1), (2)",
708
- 'COMMIT',
709
- 'BEGIN',
762
+ SQL_COMMIT,
763
+ SQL_BEGIN,
710
764
  "INSERT INTO items (value) VALUES (3), (4)",
711
- 'COMMIT'
765
+ SQL_COMMIT
712
766
  ]
713
767
 
714
768
  @d.all.should == [
@@ -723,9 +777,9 @@ context "MySQL::Dataset#multi_insert" do
723
777
  @d.multi_insert([:name, :value], [['abc', 1], ['def', 2]])
724
778
 
725
779
  MYSQL_DB.sqls.should == [
726
- 'BEGIN',
780
+ SQL_BEGIN,
727
781
  "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2)",
728
- 'COMMIT'
782
+ SQL_COMMIT
729
783
  ]
730
784
 
731
785
  @d.all.should == [
@@ -778,7 +832,7 @@ context "MySQL::Dataset#complex_expression_sql" do
778
832
  specify "should handle string concatenation with CONCAT if more than one record" do
779
833
  @d.literal([:x, :y].sql_string_join).should == "CONCAT(x, y)"
780
834
  @d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(x, ' ', y)"
781
- @d.literal([:x[:y], 1, 'z'.lit].sql_string_join(:y|1)).should == "CONCAT(x(y), y[1], '1', y[1], z)"
835
+ @d.literal([:x.sql_function(:y), 1, 'z'.lit].sql_string_join(:y|1)).should == "CONCAT(x(y), y[1], '1', y[1], z)"
782
836
  end
783
837
 
784
838
  specify "should handle string concatenation as simple string if just one record" do
@@ -787,27 +841,29 @@ context "MySQL::Dataset#complex_expression_sql" do
787
841
  end
788
842
  end
789
843
 
790
- context "MySQL Stored Procedures" do
791
- teardown do
792
- MYSQL_DB.execute('DROP PROCEDURE test_sproc')
793
- end
794
-
795
- specify "should be callable on the database object" do
796
- MYSQL_DB.execute('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
797
- MYSQL_DB[:items].delete
798
- MYSQL_DB[:items].insert(:value=>1)
799
- MYSQL_DB[:items].count.should == 1
800
- MYSQL_DB.call_sproc(:test_sproc)
801
- MYSQL_DB[:items].count.should == 0
802
- end
803
-
804
- specify "should be callable on the dataset object" do
805
- MYSQL_DB.execute('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
806
- @d = MYSQL_DB[:items]
807
- @d.call_sproc(:select, :test_sproc, 3).should == []
808
- @d.insert(:value=>1)
809
- @d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
810
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
811
- @d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
844
+ unless MYSQL_DB.class.adapter_scheme == :do
845
+ context "MySQL Stored Procedures" do
846
+ teardown do
847
+ MYSQL_DB.execute('DROP PROCEDURE test_sproc')
848
+ end
849
+
850
+ specify "should be callable on the database object" do
851
+ MYSQL_DB.execute('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
852
+ MYSQL_DB[:items].delete
853
+ MYSQL_DB[:items].insert(:value=>1)
854
+ MYSQL_DB[:items].count.should == 1
855
+ MYSQL_DB.call_sproc(:test_sproc)
856
+ MYSQL_DB[:items].count.should == 0
857
+ end
858
+
859
+ specify "should be callable on the dataset object" do
860
+ MYSQL_DB.execute('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
861
+ @d = MYSQL_DB[:items]
862
+ @d.call_sproc(:select, :test_sproc, 3).should == []
863
+ @d.insert(:value=>1)
864
+ @d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
865
+ @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
866
+ @d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
867
+ end
812
868
  end
813
869
  end
@@ -113,25 +113,25 @@ context "An Oracle dataset" do
113
113
 
114
114
  @d.max(:value).to_i.should == 789
115
115
 
116
- @d.select(:name, :AVG[:value]).filter(:name => 'abc').group(:name).to_a.should == [
116
+ @d.select(:name, :AVG.sql_function(:value)).filter(:name => 'abc').group(:name).to_a.should == [
117
117
  {:name => 'abc', :"avg(value)" => (456+123)/2.0}
118
118
  ]
119
119
 
120
- @d.select(:AVG[:value]).group(:name).order(:name).limit(1).to_a.should == [
120
+ @d.select(:AVG.sql_function(:value)).group(:name).order(:name).limit(1).to_a.should == [
121
121
  {:"avg(value)" => (456+123)/2.0}
122
122
  ]
123
123
 
124
- @d.select(:name, :AVG[:value]).group(:name).order(:name).to_a.should == [
124
+ @d.select(:name, :AVG.sql_function(:value)).group(:name).order(:name).to_a.should == [
125
125
  {:name => 'abc', :"avg(value)" => (456+123)/2.0},
126
126
  {:name => 'def', :"avg(value)" => 789*1.0}
127
127
  ]
128
128
 
129
- @d.select(:name, :AVG[:value]).group(:name).order(:name).to_a.should == [
129
+ @d.select(:name, :AVG.sql_function(:value)).group(:name).order(:name).to_a.should == [
130
130
  {:name => 'abc', :"avg(value)" => (456+123)/2.0},
131
131
  {:name => 'def', :"avg(value)" => 789*1.0}
132
132
  ]
133
133
 
134
- @d.select(:name, :AVG[:value]).group(:name).having(:name => ['abc', 'def']).order(:name).to_a.should == [
134
+ @d.select(:name, :AVG.sql_function(:value)).group(:name).having(:name => ['abc', 'def']).order(:name).to_a.should == [
135
135
  {:name => 'abc', :"avg(value)" => (456+123)/2.0},
136
136
  {:name => 'def', :"avg(value)" => 789*1.0}
137
137
  ]
@@ -4,7 +4,7 @@ unless defined?(POSTGRES_DB)
4
4
  POSTGRES_URL = 'postgres://postgres:postgres@localhost:5432/reality_spec' unless defined? POSTGRES_URL
5
5
  POSTGRES_DB = Sequel.connect(ENV['SEQUEL_PG_SPEC_DB']||POSTGRES_URL)
6
6
  end
7
-
7
+ #POSTGRES_DB.instance_variable_set(:@server_version, 80100)
8
8
  POSTGRES_DB.create_table! :test do
9
9
  text :name
10
10
  integer :value, :index => true
@@ -125,13 +125,13 @@ context "A PostgreSQL dataset" do
125
125
  @d.select('COUNT(*)'.lit).sql.should == \
126
126
  'SELECT COUNT(*) FROM "test"'
127
127
 
128
- @d.select(:max[:value]).sql.should == \
128
+ @d.select(:max.sql_function(:value)).sql.should == \
129
129
  'SELECT max("value") FROM "test"'
130
130
 
131
- @d.select(:NOW[]).sql.should == \
131
+ @d.select(:NOW.sql_function).sql.should == \
132
132
  'SELECT NOW() FROM "test"'
133
133
 
134
- @d.select(:max[:items__value]).sql.should == \
134
+ @d.select(:max.sql_function(:items__value)).sql.should == \
135
135
  'SELECT max("items"."value") FROM "test"'
136
136
 
137
137
  @d.order(:name.desc).sql.should == \
@@ -146,13 +146,13 @@ context "A PostgreSQL dataset" do
146
146
  @d.select('max(test."name") AS "max_name"'.lit).sql.should == \
147
147
  'SELECT max(test."name") AS "max_name" FROM "test"'
148
148
 
149
- @d.select(:test[:abc, 'hello']).sql.should == \
149
+ @d.select(:test.sql_function(:abc, 'hello')).sql.should == \
150
150
  "SELECT test(\"abc\", 'hello') FROM \"test\""
151
151
 
152
- @d.select(:test[:abc__def, 'hello']).sql.should == \
152
+ @d.select(:test.sql_function(:abc__def, 'hello')).sql.should == \
153
153
  "SELECT test(\"abc\".\"def\", 'hello') FROM \"test\""
154
154
 
155
- @d.select(:test[:abc__def, 'hello'].as(:x2)).sql.should == \
155
+ @d.select(:test.sql_function(:abc__def, 'hello').as(:x2)).sql.should == \
156
156
  "SELECT test(\"abc\".\"def\", 'hello') AS \"x2\" FROM \"test\""
157
157
 
158
158
  @d.insert_sql(:value => 333).should =~ \
@@ -260,6 +260,10 @@ context "A PostgreSQL dataset" do
260
260
  POSTGRES_DB['SELECT ? AS a', "\\dingo"].get(:a) == "\\dingo"
261
261
  end
262
262
 
263
+ specify "should correctly escape strings with quotes" do
264
+ POSTGRES_DB['SELECT ? AS a', "\\'dingo"].get(:a) == "\\'dingo"
265
+ end
266
+
263
267
  specify "should properly escape binary data" do
264
268
  POSTGRES_DB['SELECT ? AS a', "\1\2\3".to_blob].get(:a) == "\1\2\3"
265
269
  end
@@ -343,7 +347,7 @@ context "A PostgreSQL database" do
343
347
  full_text_index [:title, :body]
344
348
  end
345
349
  POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
346
- "CREATE TABLE public.posts (title text, body text)",
350
+ "CREATE TABLE posts (title text, body text)",
347
351
  "CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('simple', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))"
348
352
  ]
349
353
  end
@@ -355,7 +359,7 @@ context "A PostgreSQL database" do
355
359
  full_text_index [:title, :body], :language => 'french'
356
360
  end
357
361
  POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
358
- "CREATE TABLE public.posts (title text, body text)",
362
+ "CREATE TABLE posts (title text, body text)",
359
363
  "CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('french', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))"
360
364
  ]
361
365
  end
@@ -377,7 +381,7 @@ context "A PostgreSQL database" do
377
381
  spatial_index [:geom]
378
382
  end
379
383
  POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
380
- "CREATE TABLE public.posts (geom geometry)",
384
+ "CREATE TABLE posts (geom geometry)",
381
385
  "CREATE INDEX posts_geom_index ON posts USING gist (geom)"
382
386
  ]
383
387
  end
@@ -388,7 +392,7 @@ context "A PostgreSQL database" do
388
392
  index :title, :type => 'hash'
389
393
  end
390
394
  POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
391
- "CREATE TABLE public.posts (title varchar(5))",
395
+ "CREATE TABLE posts (title varchar(5))",
392
396
  "CREATE INDEX posts_title_index ON posts USING hash (title)"
393
397
  ]
394
398
  end
@@ -399,7 +403,7 @@ context "A PostgreSQL database" do
399
403
  index :title, :type => 'hash', :unique => true
400
404
  end
401
405
  POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
402
- "CREATE TABLE public.posts (title varchar(5))",
406
+ "CREATE TABLE posts (title varchar(5))",
403
407
  "CREATE UNIQUE INDEX posts_title_index ON posts USING hash (title)"
404
408
  ]
405
409
  end
@@ -410,10 +414,21 @@ context "A PostgreSQL database" do
410
414
  index :title, :where => {:something => 5}
411
415
  end
412
416
  POSTGRES_DB.create_table_sql_list(:posts, *g.create_info).should == [
413
- "CREATE TABLE public.posts (title varchar(5))",
417
+ "CREATE TABLE posts (title varchar(5))",
414
418
  "CREATE INDEX posts_title_index ON posts (title) WHERE (something = 5)"
415
419
  ]
416
420
  end
421
+
422
+ specify "should support identifiers for table names in indicies" do
423
+ g = Sequel::Schema::Generator.new(POSTGRES_DB) do
424
+ varchar :title, :size => 5
425
+ index :title, :where => {:something => 5}
426
+ end
427
+ POSTGRES_DB.create_table_sql_list(Sequel::SQL::Identifier.new(:posts__test), *g.create_info).should == [
428
+ "CREATE TABLE posts__test (title varchar(5))",
429
+ "CREATE INDEX posts__test_title_index ON posts__test (title) WHERE (something = 5)"
430
+ ]
431
+ end
417
432
  end
418
433
 
419
434
  context "Postgres::Dataset#multi_insert_sql / #import" do
@@ -542,18 +557,18 @@ context "Postgres::Database schema qualified tables" do
542
557
 
543
558
  specify "should be able to get primary keys for tables in a given schema" do
544
559
  POSTGRES_DB.create_table(:schema_test__schema_test){primary_key :i}
545
- POSTGRES_DB.synchronize{|c| POSTGRES_DB.send(:primary_key_for_table, c, :schema_test__schema_test).should == 'i'}
560
+ POSTGRES_DB.primary_key(:schema_test__schema_test).should == 'i'
546
561
  end
547
562
 
548
563
  specify "should be able to get serial sequences for tables in a given schema" do
549
564
  POSTGRES_DB.create_table(:schema_test__schema_test){primary_key :i}
550
- POSTGRES_DB.synchronize{|c| POSTGRES_DB.send(:primary_key_sequence_for_table, c, :schema_test__schema_test).should == '"schema_test"."schema_test_i_seq"'}
565
+ POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test"."schema_test_i_seq"'
551
566
  end
552
567
 
553
568
  specify "should be able to get custom sequences for tables in a given schema" do
554
569
  POSTGRES_DB << "CREATE SEQUENCE schema_test.kseq"
555
570
  POSTGRES_DB.create_table(:schema_test__schema_test){integer :j; primary_key :k, :type=>:integer, :default=>"nextval('schema_test.kseq'::regclass)".lit}
556
- POSTGRES_DB.synchronize{|c| POSTGRES_DB.send(:primary_key_sequence_for_table, c, :schema_test__schema_test).should == '"schema_test"."kseq"'}
571
+ POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test"."kseq"'
557
572
  end
558
573
 
559
574
  specify "#default_schema= should change the default schema used from public" do
@@ -561,8 +576,8 @@ context "Postgres::Database schema qualified tables" do
561
576
  POSTGRES_DB.default_schema = :schema_test
562
577
  POSTGRES_DB.table_exists?(:schema_test).should == true
563
578
  POSTGRES_DB.tables.should == [:schema_test]
564
- POSTGRES_DB.synchronize{|c| POSTGRES_DB.send(:primary_key_for_table, c, :schema_test).should == 'i'}
565
- POSTGRES_DB.synchronize{|c| POSTGRES_DB.send(:primary_key_sequence_for_table, c, :schema_test).should == '"schema_test"."schema_test_i_seq"'}
579
+ POSTGRES_DB.primary_key(:schema_test__schema_test).should == 'i'
580
+ POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test"."schema_test_i_seq"'
566
581
  end
567
582
  end
568
583