sequel 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|