sequel 2.9.0 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +56 -0
- data/{README → README.rdoc} +85 -57
- data/Rakefile +10 -5
- data/bin/sequel +7 -16
- data/doc/advanced_associations.rdoc +5 -17
- data/doc/cheat_sheet.rdoc +18 -20
- data/doc/dataset_filtering.rdoc +8 -32
- data/doc/schema.rdoc +20 -0
- data/lib/sequel_core.rb +35 -1
- data/lib/sequel_core/adapters/ado.rb +1 -1
- data/lib/sequel_core/adapters/db2.rb +2 -2
- data/lib/sequel_core/adapters/dbi.rb +2 -11
- data/lib/sequel_core/adapters/do.rb +205 -0
- data/lib/sequel_core/adapters/do/mysql.rb +38 -0
- data/lib/sequel_core/adapters/do/postgres.rb +92 -0
- data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
- data/lib/sequel_core/adapters/firebird.rb +298 -0
- data/lib/sequel_core/adapters/informix.rb +10 -1
- data/lib/sequel_core/adapters/jdbc.rb +78 -19
- data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
- data/lib/sequel_core/adapters/jdbc/mysql.rb +10 -0
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +7 -3
- data/lib/sequel_core/adapters/mysql.rb +53 -77
- data/lib/sequel_core/adapters/odbc.rb +1 -1
- data/lib/sequel_core/adapters/openbase.rb +1 -1
- data/lib/sequel_core/adapters/oracle.rb +2 -2
- data/lib/sequel_core/adapters/postgres.rb +16 -14
- data/lib/sequel_core/adapters/shared/mysql.rb +44 -9
- data/lib/sequel_core/adapters/shared/oracle.rb +4 -5
- data/lib/sequel_core/adapters/shared/postgres.rb +86 -82
- data/lib/sequel_core/adapters/shared/sqlite.rb +39 -24
- data/lib/sequel_core/adapters/sqlite.rb +11 -1
- data/lib/sequel_core/connection_pool.rb +10 -2
- data/lib/sequel_core/core_sql.rb +13 -3
- data/lib/sequel_core/database.rb +131 -30
- data/lib/sequel_core/database/schema.rb +5 -5
- data/lib/sequel_core/dataset.rb +31 -6
- data/lib/sequel_core/dataset/convenience.rb +11 -11
- data/lib/sequel_core/dataset/query.rb +2 -2
- data/lib/sequel_core/dataset/sql.rb +6 -6
- data/lib/sequel_core/exceptions.rb +4 -0
- data/lib/sequel_core/migration.rb +4 -4
- data/lib/sequel_core/schema/generator.rb +19 -3
- data/lib/sequel_core/schema/sql.rb +24 -20
- data/lib/sequel_core/sql.rb +13 -16
- data/lib/sequel_core/version.rb +11 -0
- data/lib/sequel_model.rb +2 -0
- data/lib/sequel_model/base.rb +2 -2
- data/lib/sequel_model/hooks.rb +46 -7
- data/lib/sequel_model/record.rb +11 -9
- data/lib/sequel_model/schema.rb +1 -1
- data/lib/sequel_model/validations.rb +72 -61
- data/spec/adapters/firebird_spec.rb +371 -0
- data/spec/adapters/mysql_spec.rb +118 -62
- data/spec/adapters/oracle_spec.rb +5 -5
- data/spec/adapters/postgres_spec.rb +33 -18
- data/spec/adapters/sqlite_spec.rb +2 -2
- data/spec/integration/dataset_test.rb +3 -3
- data/spec/integration/schema_test.rb +55 -5
- data/spec/integration/spec_helper.rb +11 -0
- data/spec/integration/type_test.rb +59 -16
- data/spec/sequel_core/connection_pool_spec.rb +14 -0
- data/spec/sequel_core/core_sql_spec.rb +24 -14
- data/spec/sequel_core/database_spec.rb +96 -11
- data/spec/sequel_core/dataset_spec.rb +97 -37
- data/spec/sequel_core/expression_filters_spec.rb +51 -40
- data/spec/sequel_core/object_graph_spec.rb +2 -2
- data/spec/sequel_core/schema_generator_spec.rb +31 -6
- data/spec/sequel_core/schema_spec.rb +25 -9
- data/spec/sequel_core/spec_helper.rb +4 -1
- data/spec/sequel_core/version_spec.rb +7 -0
- data/spec/sequel_model/associations_spec.rb +1 -1
- data/spec/sequel_model/hooks_spec.rb +68 -13
- data/spec/sequel_model/model_spec.rb +4 -4
- data/spec/sequel_model/record_spec.rb +22 -0
- data/spec/sequel_model/spec_helper.rb +2 -1
- data/spec/sequel_model/validations_spec.rb +107 -7
- metadata +15 -5
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -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
|
168
|
+
@d.select(:max.sql_function(:value)).sql.should == \
|
146
169
|
'SELECT max(`value`) FROM `items`'
|
147
170
|
|
148
|
-
@d.select(:NOW
|
171
|
+
@d.select(:NOW.sql_function).sql.should == \
|
149
172
|
'SELECT NOW() FROM `items`'
|
150
173
|
|
151
|
-
@d.select(:max
|
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
|
189
|
+
@d.select(:test.sql_function(:abc, 'hello')).sql.should == \
|
167
190
|
"SELECT test(`abc`, 'hello') FROM `items`"
|
168
191
|
|
169
|
-
@d.select(:test
|
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
|
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 == [
|
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 == [
|
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
|
267
|
-
where {(:ack > ack_stamp) & {:market => market}}
|
268
|
-
group_by :minute
|
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?
|
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
|
-
|
724
|
+
SQL_BEGIN,
|
671
725
|
"INSERT INTO items (name) VALUES ('abc'), ('def')",
|
672
|
-
|
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
|
-
|
739
|
+
SQL_BEGIN,
|
686
740
|
"INSERT INTO items (value) VALUES (1), (2)",
|
687
|
-
|
688
|
-
|
741
|
+
SQL_COMMIT,
|
742
|
+
SQL_BEGIN,
|
689
743
|
"INSERT INTO items (value) VALUES (3), (4)",
|
690
|
-
|
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
|
-
|
760
|
+
SQL_BEGIN,
|
707
761
|
"INSERT INTO items (value) VALUES (1), (2)",
|
708
|
-
|
709
|
-
|
762
|
+
SQL_COMMIT,
|
763
|
+
SQL_BEGIN,
|
710
764
|
"INSERT INTO items (value) VALUES (3), (4)",
|
711
|
-
|
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
|
-
|
780
|
+
SQL_BEGIN,
|
727
781
|
"INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2)",
|
728
|
-
|
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
|
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
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
128
|
+
@d.select(:max.sql_function(:value)).sql.should == \
|
129
129
|
'SELECT max("value") FROM "test"'
|
130
130
|
|
131
|
-
@d.select(:NOW
|
131
|
+
@d.select(:NOW.sql_function).sql.should == \
|
132
132
|
'SELECT NOW() FROM "test"'
|
133
133
|
|
134
|
-
@d.select(:max
|
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
|
149
|
+
@d.select(:test.sql_function(:abc, 'hello')).sql.should == \
|
150
150
|
"SELECT test(\"abc\", 'hello') FROM \"test\""
|
151
151
|
|
152
|
-
@d.select(:test
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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.
|
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.
|
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.
|
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.
|
565
|
-
POSTGRES_DB.
|
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
|
|