sequel 4.24.0 → 4.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +40 -0
  3. data/doc/association_basics.rdoc +2 -5
  4. data/doc/dataset_basics.rdoc +1 -1
  5. data/doc/postgresql.rdoc +47 -0
  6. data/doc/querying.rdoc +5 -0
  7. data/doc/release_notes/4.25.0.txt +181 -0
  8. data/lib/sequel/adapters/ibmdb.rb +0 -28
  9. data/lib/sequel/adapters/shared/db2.rb +31 -2
  10. data/lib/sequel/adapters/shared/mssql.rb +12 -12
  11. data/lib/sequel/adapters/shared/postgres.rb +102 -3
  12. data/lib/sequel/adapters/shared/sqlite.rb +1 -0
  13. data/lib/sequel/adapters/swift/sqlite.rb +12 -0
  14. data/lib/sequel/database/schema_generator.rb +4 -0
  15. data/lib/sequel/database/schema_methods.rb +3 -1
  16. data/lib/sequel/dataset/actions.rb +1 -1
  17. data/lib/sequel/dataset/prepared_statements.rb +15 -7
  18. data/lib/sequel/dataset/query.rb +16 -2
  19. data/lib/sequel/dataset/sql.rb +19 -16
  20. data/lib/sequel/extensions/empty_array_consider_nulls.rb +35 -0
  21. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -34
  22. data/lib/sequel/extensions/pg_json_ops.rb +9 -1
  23. data/lib/sequel/extensions/query_literals.rb +1 -1
  24. data/lib/sequel/model/base.rb +7 -11
  25. data/lib/sequel/model/dataset_module.rb +1 -1
  26. data/lib/sequel/plugins/association_pks.rb +6 -0
  27. data/lib/sequel/plugins/dirty.rb +6 -1
  28. data/lib/sequel/plugins/inverted_subsets.rb +48 -0
  29. data/lib/sequel/plugins/serialization.rb +2 -0
  30. data/lib/sequel/plugins/singular_table_names.rb +31 -0
  31. data/lib/sequel/plugins/static_cache.rb +17 -0
  32. data/lib/sequel/sql.rb +1 -0
  33. data/lib/sequel/version.rb +1 -1
  34. data/spec/adapters/db2_spec.rb +12 -0
  35. data/spec/adapters/mysql_spec.rb +1 -0
  36. data/spec/adapters/postgres_spec.rb +41 -1
  37. data/spec/core/database_spec.rb +1 -0
  38. data/spec/core/dataset_spec.rb +55 -7
  39. data/spec/core/expression_filters_spec.rb +18 -0
  40. data/spec/core/schema_spec.rb +10 -2
  41. data/spec/extensions/association_pks_spec.rb +12 -0
  42. data/spec/extensions/{empty_array_ignore_nulls_spec.rb → empty_array_consider_nulls_spec.rb} +7 -7
  43. data/spec/extensions/inverted_subsets_spec.rb +33 -0
  44. data/spec/extensions/query_literals_spec.rb +16 -0
  45. data/spec/extensions/serialization_spec.rb +21 -0
  46. data/spec/extensions/singular_table_names_spec.rb +22 -0
  47. data/spec/integration/dataset_test.rb +2 -1
  48. data/spec/integration/prepared_statement_test.rb +35 -1
  49. data/spec/model/associations_spec.rb +2 -2
  50. data/spec/model/base_spec.rb +13 -8
  51. data/spec/model/class_dataset_methods_spec.rb +1 -0
  52. metadata +10 -5
  53. data/lib/sequel/adapters/firebird.rb +0 -105
  54. data/lib/sequel/adapters/informix.rb +0 -68
@@ -345,10 +345,18 @@ describe "DB#create_table" do
345
345
  end
346
346
 
347
347
  it "should accept collation" do
348
+ @db.quote_identifiers = true
348
349
  @db.create_table(:cats) do
349
- varchar :name, :collate => :utf8_bin
350
+ String :name, :collate => :utf8_bin
350
351
  end
351
- @db.sqls.must_equal ["CREATE TABLE cats (name varchar(255) COLLATE utf8_bin)"]
352
+ @db.sqls.must_equal ['CREATE TABLE "cats" ("name" varchar(255) COLLATE utf8_bin)']
353
+ end
354
+
355
+ it "should accept collation as a String, treated literally" do
356
+ @db.create_table(:cats) do
357
+ String :name, :collate => '"utf8_bin"'
358
+ end
359
+ @db.sqls.must_equal ['CREATE TABLE cats (name varchar(255) COLLATE "utf8_bin")']
352
360
  end
353
361
 
354
362
  it "should accept inline index definition" do
@@ -350,4 +350,16 @@ describe "Sequel::Plugins::AssociationPks" do
350
350
  "COMMIT",
351
351
  ]
352
352
  end
353
+
354
+ it "should clear delayed associated pks if refreshing, if :delay plugin option is used" do
355
+ @Artist.one_to_many :albums, :clone=>:albums, :delay_pks=>:always
356
+ @Album.many_to_many :tags, :clone=>:tags, :delay_pks=>:always
357
+
358
+ ar = @Artist.load(:id=>1)
359
+ ar.album_pks.must_equal [1,2,3]
360
+ ar.album_pks = [2,4]
361
+ ar.album_pks.must_equal [2,4]
362
+ ar.refresh
363
+ ar.album_pks.must_equal [1,2,3]
364
+ end
353
365
  end
@@ -2,23 +2,23 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "filter_having extension" do
4
4
  before do
5
- @dataset = Sequel.mock[:test].extension(:empty_array_ignore_nulls)
5
+ @dataset = Sequel.mock[:test].extension(:empty_array_consider_nulls)
6
6
  end
7
7
 
8
8
  it "should handle all types of IN/NOT IN queries with empty arrays" do
9
- @dataset.filter(:id => []).sql.must_equal "SELECT * FROM test WHERE (1 = 0)"
10
- @dataset.filter([:id1, :id2] => []).sql.must_equal "SELECT * FROM test WHERE (1 = 0)"
11
- @dataset.exclude(:id => []).sql.must_equal "SELECT * FROM test WHERE (1 = 1)"
12
- @dataset.exclude([:id1, :id2] => []).sql.must_equal "SELECT * FROM test WHERE (1 = 1)"
9
+ @dataset.filter(:id => []).sql.must_equal "SELECT * FROM test WHERE (id != id)"
10
+ @dataset.filter([:id1, :id2] => []).sql.must_equal "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
11
+ @dataset.exclude(:id => []).sql.must_equal "SELECT * FROM test WHERE (id = id)"
12
+ @dataset.exclude([:id1, :id2] => []).sql.must_equal "SELECT * FROM test WHERE ((id1 = id1) AND (id2 = id2))"
13
13
  end
14
14
 
15
15
  it "should handle IN/NOT IN queries with multiple columns and an empty dataset where the database doesn't support it" do
16
16
  @dataset.meta_def(:supports_multiple_column_in?){false}
17
17
  db = Sequel.mock
18
18
  d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
19
- @dataset.filter([:id1, :id2] => d1).sql.must_equal "SELECT * FROM test WHERE (1 = 0)"
19
+ @dataset.filter([:id1, :id2] => d1).sql.must_equal "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
20
20
  db.sqls.must_equal ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
21
- @dataset.exclude([:id1, :id2] => d1).sql.must_equal "SELECT * FROM test WHERE (1 = 1)"
21
+ @dataset.exclude([:id1, :id2] => d1).sql.must_equal "SELECT * FROM test WHERE ((id1 = id1) AND (id2 = id2))"
22
22
  db.sqls.must_equal ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
23
23
  end
24
24
  end
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::InvertedSubsets" do
4
+ it "should add an inverted subset method which inverts the condition" do
5
+ c = Class.new(Sequel::Model(:a))
6
+ c.plugin :inverted_subsets
7
+ c.subset(:published, :published => true)
8
+ c.not_published.sql.must_equal 'SELECT * FROM a WHERE (published IS NOT TRUE)'
9
+ end
10
+
11
+ it "should support a configuration block to customise the inverted method name" do
12
+ c = Class.new(Sequel::Model(:a))
13
+ c.plugin(:inverted_subsets){|name| "exclude_#{name}"}
14
+ c.subset(:published, :published => true)
15
+ c.exclude_published.sql.must_equal 'SELECT * FROM a WHERE (published IS NOT TRUE)'
16
+ end
17
+
18
+ it "should chain to existing dataset" do
19
+ c = Class.new(Sequel::Model(:a))
20
+ c.plugin :inverted_subsets
21
+ c.subset(:published, :published => true)
22
+ c.where(1=>0).not_published.sql.must_equal 'SELECT * FROM a WHERE ((1 = 0) AND (published IS NOT TRUE))'
23
+ end
24
+
25
+ it "should work in subclasses" do
26
+ c = Class.new(Sequel::Model)
27
+ c.plugin(:inverted_subsets){|name| "exclude_#{name}"}
28
+ c = Class.new(c)
29
+ c.dataset = :a
30
+ c.subset(:published, :published => true)
31
+ c.exclude_published.sql.must_equal 'SELECT * FROM a WHERE (published IS NOT TRUE)'
32
+ end
33
+ end
@@ -111,6 +111,22 @@ describe "query_literals extension" do
111
111
  @ds.group_and_count(:a, 1).sql.must_equal 'SELECT a, 1, count(*) AS count FROM t GROUP BY a, 1'
112
112
  end
113
113
 
114
+ it "should have #group_append use literal string if given a single string" do
115
+ @ds.group(:d).group_append('a, b, c').sql.must_equal 'SELECT * FROM t GROUP BY d, a, b, c'
116
+ end
117
+
118
+ it "should have #group_append use placeholder literal string if given a string and additional arguments" do
119
+ @ds.group(:d).group_append('a, b, ?', 1).sql.must_equal 'SELECT * FROM t GROUP BY d, a, b, 1'
120
+ end
121
+
122
+ it "should have #group_append work the standard way if initial string is a literal string already" do
123
+ @ds.group(:d).group_append(Sequel.lit('a, b, ?'), 1).sql.must_equal 'SELECT * FROM t GROUP BY d, a, b, ?, 1'
124
+ end
125
+
126
+ it "should have #group_append work regularly if not given a string as the first argument" do
127
+ @ds.group(:d).group_append(:a, 1).sql.must_equal 'SELECT * FROM t GROUP BY d, a, 1'
128
+ end
129
+
114
130
  it "should have #order use literal string if given a single string" do
115
131
  @ds.order('a, b, c').sql.must_equal 'SELECT * FROM t ORDER BY a, b, c'
116
132
  end
@@ -338,4 +338,25 @@ describe "Serialization plugin" do
338
338
  o.def = 'hello2'
339
339
  o.changed_columns.must_equal [:abc, :def]
340
340
  end
341
+
342
+ it "should update column_changes if the dirty plugin is used" do
343
+ @c.plugin :serialization, :yaml, :abc, :def
344
+ @c.plugin :dirty
345
+ @c.dataset._fetch = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
346
+ o = @c.first
347
+ o.column_changes.must_equal({})
348
+ o.abc = 1
349
+ o.column_changes.must_equal({})
350
+ o.abc = 1
351
+ o.column_changes.must_equal({})
352
+ o.abc = 2
353
+ o.column_changes.must_equal(:abc=>[1, 2])
354
+ o.def = 'hello'
355
+ o.column_changes.must_equal(:abc=>[1, 2])
356
+ o.def = 'hello'
357
+ o.column_changes.must_equal(:abc=>[1, 2])
358
+ o.def = 'hello2'
359
+ o.column_changes.must_equal(:abc=>[1, 2], :def=>["hello", "hello2"])
360
+ end
361
+
341
362
  end
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::SingularTableNames" do
4
+ before do
5
+ @c = Class.new(Sequel::Model)
6
+ @c.plugin :singular_table_names
7
+ end
8
+ after do
9
+ Object.send(:remove_const, :Foo)
10
+ end
11
+
12
+ it "should not used the pluralized table name" do
13
+ class ::Foo < @c; end
14
+ Foo.table_name.must_equal :foo
15
+ end
16
+
17
+ it "should handle nested moedls name" do
18
+ module ::Foo; end
19
+ class Foo::Bar < @c; end
20
+ Foo::Bar.table_name.must_equal :bar
21
+ end
22
+ end
@@ -1408,6 +1408,7 @@ describe "Sequel::Dataset DSL support" do
1408
1408
  end
1409
1409
 
1410
1410
  it "should work empty arrays with nulls" do
1411
+ @ds = @ds.extension(:empty_array_consider_nulls)
1411
1412
  @ds.insert(nil, nil)
1412
1413
  @ds.filter(:a=>[]).all.must_equal []
1413
1414
  @ds.exclude(:a=>[]).all.must_equal []
@@ -1425,7 +1426,7 @@ describe "Sequel::Dataset DSL support" do
1425
1426
  end
1426
1427
 
1427
1428
  it "should work empty arrays with nulls and the empty_array_ignore_nulls extension" do
1428
- ds = @ds.extension(:empty_array_ignore_nulls)
1429
+ ds = @ds
1429
1430
  ds.insert(nil, nil)
1430
1431
  ds.filter(:a=>[]).all.must_equal []
1431
1432
  ds.exclude(:a=>[]).all.must_equal [{:a=>nil, :b=>nil}]
@@ -123,6 +123,23 @@ describe "Prepared Statements and Bound Arguments" do
123
123
  @ds.order(:id).map(:numb).must_equal [10, 20]
124
124
  end if DB.dataset.supports_insert_select?
125
125
 
126
+ it "should support bound variables with insert returning" do
127
+ @ds.returning.call(:insert, {:n=>20}, :numb=>:$n).must_equal([{:id=>2, :numb=>20}])
128
+ @ds.count.must_equal 2
129
+ @ds.order(:id).map(:numb).must_equal [10, 20]
130
+ end if DB.dataset.supports_returning?(:insert)
131
+
132
+ it "should support bound variables with update returning" do
133
+ @ds.returning.call(:update, {:n=>20}, :numb=>:$n).must_equal([{:id=>1, :numb=>20}])
134
+ @ds.count.must_equal 1
135
+ @ds.order(:id).map(:numb).must_equal [20]
136
+ end if DB.dataset.supports_returning?(:update)
137
+
138
+ it "should support bound variables with delete returning" do
139
+ @ds.where(:id=>:$id).returning.call(:delete, :id=>1).must_equal([{:id=>1, :numb=>10}])
140
+ @ds.count.must_equal 0
141
+ end if DB.dataset.supports_returning?(:delete)
142
+
126
143
  it "should support bound variables with delete" do
127
144
  @ds.filter(:numb=>:$n).call(:delete, :n=>10).must_equal 1
128
145
  @ds.count.must_equal 0
@@ -240,6 +257,23 @@ describe "Prepared Statements and Bound Arguments" do
240
257
  @ds.order(:id).map(:numb).must_equal [10, 20]
241
258
  end if DB.dataset.supports_insert_select?
242
259
 
260
+ it "should support bound variables with insert returning" do
261
+ @ds.returning.prepare(:insert, :insert_rn, :numb=>:$n).call(:n=>20).must_equal([{:id=>2, :numb=>20}])
262
+ @ds.count.must_equal 2
263
+ @ds.order(:id).map(:numb).must_equal [10, 20]
264
+ end if DB.dataset.supports_returning?(:insert)
265
+
266
+ it "should support bound variables with update returning" do
267
+ @ds.returning.prepare(:update, :update_rn, :numb=>:$n).call(:n=>20).must_equal([{:id=>1, :numb=>20}])
268
+ @ds.count.must_equal 1
269
+ @ds.order(:id).map(:numb).must_equal [20]
270
+ end if DB.dataset.supports_returning?(:update)
271
+
272
+ it "should support bound variables with delete returning" do
273
+ @ds.where(:id=>:$id).returning.prepare(:delete, :delete_rn).call(:id=>1).must_equal([{:id=>1, :numb=>10}])
274
+ @ds.count.must_equal 0
275
+ end if DB.dataset.supports_returning?(:delete)
276
+
243
277
  it "should support prepared statements with delete" do
244
278
  @ds.filter(:numb=>:$n).prepare(:delete, :delete_n)
245
279
  @db.call(:delete_n, :n=>10).must_equal 1
@@ -413,7 +447,7 @@ describe "Dataset#unbind" do
413
447
  @u[@ds.filter{items__c > 1}].must_equal(:c=>10)
414
448
  end
415
449
 
416
- it "should handle deep nesting" do
450
+ cspecify "should handle deep nesting", :h2 do
417
451
  DB.create_table!(:items) do
418
452
  Integer :a
419
453
  Integer :b
@@ -3336,8 +3336,8 @@ describe "Filtering by associations" do
3336
3336
  end
3337
3337
 
3338
3338
  it "should not affect non-association IN/NOT IN filtering with an empty array" do
3339
- @Album.filter(:tag_id=>[]).sql.must_equal 'SELECT * FROM albums WHERE (tag_id != tag_id)'
3340
- @Album.exclude(:tag_id=>[]).sql.must_equal 'SELECT * FROM albums WHERE (tag_id = tag_id)'
3339
+ @Album.filter(:tag_id=>[]).sql.must_equal 'SELECT * FROM albums WHERE (1 = 0)'
3340
+ @Album.exclude(:tag_id=>[]).sql.must_equal 'SELECT * FROM albums WHERE (1 = 1)'
3341
3341
  end
3342
3342
 
3343
3343
  it "should work correctly in subclasses" do
@@ -91,18 +91,23 @@ describe Sequel::Model, "dataset" do
91
91
  it "should raise if no dataset is explicitly set and the class is anonymous" do
92
92
  proc {@b.dataset}.must_raise(Sequel::Error)
93
93
  end
94
+ end
94
95
 
96
+ describe Sequel::Model, "implicit table names" do
97
+ after do
98
+ Object.send(:remove_const, :BlahBlah)
99
+ end
95
100
  it "should disregard namespaces for the table name" do
96
- begin
97
- module ::BlahBlah
98
- class MwaHaHa < Sequel::Model
99
- end
101
+ module ::BlahBlah
102
+ class MwaHaHa < Sequel::Model
100
103
  end
101
-
102
- BlahBlah::MwaHaHa.dataset.sql.must_equal 'SELECT * FROM mwa_ha_has'
103
- ensure
104
- Object.send(:remove_const, :BlahBlah)
105
104
  end
105
+ BlahBlah::MwaHaHa.dataset.sql.must_equal 'SELECT * FROM mwa_ha_has'
106
+ end
107
+
108
+ it "should automatically set datasets when anonymous class of Sequel::Model is used as superclass" do
109
+ class BlahBlah < Class.new(Sequel::Model); end
110
+ BlahBlah.dataset.sql.must_equal 'SELECT * FROM blah_blahs'
106
111
  end
107
112
  end
108
113
 
@@ -50,6 +50,7 @@ describe Sequel::Model, "class dataset methods" do
50
50
  @db.sqls
51
51
  @c.grep(:id, 'a%').sql.must_equal "SELECT * FROM items WHERE ((id LIKE 'a%' ESCAPE '\\'))"
52
52
  @c.group(:a).sql.must_equal "SELECT * FROM items GROUP BY a"
53
+ @c.group_append(:a).sql.must_equal "SELECT * FROM items GROUP BY a"
53
54
  @c.group_and_count(:a).sql.must_equal "SELECT a, count(*) AS count FROM items GROUP BY a"
54
55
  @c.group_by(:a).sql.must_equal "SELECT * FROM items GROUP BY a"
55
56
  @c.having(:a).sql.must_equal "SELECT * FROM items HAVING a"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.24.0
4
+ version: 4.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-01 00:00:00.000000000 Z
11
+ date: 2015-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -225,6 +225,7 @@ extra_rdoc_files:
225
225
  - doc/release_notes/4.22.0.txt
226
226
  - doc/release_notes/4.23.0.txt
227
227
  - doc/release_notes/4.24.0.txt
228
+ - doc/release_notes/4.25.0.txt
228
229
  files:
229
230
  - CHANGELOG
230
231
  - MIT-LICENSE
@@ -337,6 +338,7 @@ files:
337
338
  - doc/release_notes/4.22.0.txt
338
339
  - doc/release_notes/4.23.0.txt
339
340
  - doc/release_notes/4.24.0.txt
341
+ - doc/release_notes/4.25.0.txt
340
342
  - doc/release_notes/4.3.0.txt
341
343
  - doc/release_notes/4.4.0.txt
342
344
  - doc/release_notes/4.5.0.txt
@@ -363,9 +365,7 @@ files:
363
365
  - lib/sequel/adapters/do/mysql.rb
364
366
  - lib/sequel/adapters/do/postgres.rb
365
367
  - lib/sequel/adapters/do/sqlite3.rb
366
- - lib/sequel/adapters/firebird.rb
367
368
  - lib/sequel/adapters/ibmdb.rb
368
- - lib/sequel/adapters/informix.rb
369
369
  - lib/sequel/adapters/jdbc.rb
370
370
  - lib/sequel/adapters/jdbc/as400.rb
371
371
  - lib/sequel/adapters/jdbc/cubrid.rb
@@ -462,6 +462,7 @@ files:
462
462
  - lib/sequel/extensions/current_datetime_timestamp.rb
463
463
  - lib/sequel/extensions/dataset_source_alias.rb
464
464
  - lib/sequel/extensions/date_arithmetic.rb
465
+ - lib/sequel/extensions/empty_array_consider_nulls.rb
465
466
  - lib/sequel/extensions/empty_array_ignore_nulls.rb
466
467
  - lib/sequel/extensions/error_sql.rb
467
468
  - lib/sequel/extensions/eval_inspect.rb
@@ -548,6 +549,7 @@ files:
548
549
  - lib/sequel/plugins/insert_returning_select.rb
549
550
  - lib/sequel/plugins/instance_filters.rb
550
551
  - lib/sequel/plugins/instance_hooks.rb
552
+ - lib/sequel/plugins/inverted_subsets.rb
551
553
  - lib/sequel/plugins/json_serializer.rb
552
554
  - lib/sequel/plugins/lazy_attributes.rb
553
555
  - lib/sequel/plugins/list.rb
@@ -571,6 +573,7 @@ files:
571
573
  - lib/sequel/plugins/serialization_modification_detection.rb
572
574
  - lib/sequel/plugins/sharding.rb
573
575
  - lib/sequel/plugins/single_table_inheritance.rb
576
+ - lib/sequel/plugins/singular_table_names.rb
574
577
  - lib/sequel/plugins/skip_create_refresh.rb
575
578
  - lib/sequel/plugins/split_values.rb
576
579
  - lib/sequel/plugins/static_cache.rb
@@ -647,7 +650,7 @@ files:
647
650
  - spec/extensions/delay_add_association_spec.rb
648
651
  - spec/extensions/dirty_spec.rb
649
652
  - spec/extensions/eager_each_spec.rb
650
- - spec/extensions/empty_array_ignore_nulls_spec.rb
653
+ - spec/extensions/empty_array_consider_nulls_spec.rb
651
654
  - spec/extensions/error_splitter_spec.rb
652
655
  - spec/extensions/error_sql_spec.rb
653
656
  - spec/extensions/eval_inspect_spec.rb
@@ -662,6 +665,7 @@ files:
662
665
  - spec/extensions/insert_returning_select_spec.rb
663
666
  - spec/extensions/instance_filters_spec.rb
664
667
  - spec/extensions/instance_hooks_spec.rb
668
+ - spec/extensions/inverted_subsets_spec.rb
665
669
  - spec/extensions/json_serializer_spec.rb
666
670
  - spec/extensions/lazy_attributes_spec.rb
667
671
  - spec/extensions/list_spec.rb
@@ -717,6 +721,7 @@ files:
717
721
  - spec/extensions/sharding_spec.rb
718
722
  - spec/extensions/shared_caching_spec.rb
719
723
  - spec/extensions/single_table_inheritance_spec.rb
724
+ - spec/extensions/singular_table_names_spec.rb
720
725
  - spec/extensions/skip_create_refresh_spec.rb
721
726
  - spec/extensions/spec_helper.rb
722
727
  - spec/extensions/split_array_nil_spec.rb
@@ -1,105 +0,0 @@
1
- require 'fb'
2
- Sequel.require 'adapters/shared/firebird'
3
- Sequel::Deprecation.deprecate 'The firebird adapter is deprecated and will be removed in a future version of Sequel.'
4
-
5
- module Sequel
6
- # The Sequel Firebird adapter requires the ruby fb driver located at
7
- # http://github.com/wishdev/fb.
8
- module Firebird
9
- class Database < Sequel::Database
10
- include Sequel::Firebird::DatabaseMethods
11
-
12
- set_adapter_scheme :firebird
13
-
14
- DISCONNECT_ERRORS = /Unsuccessful execution caused by a system error that precludes successful execution of subsequent statements/
15
-
16
- def connect(server)
17
- opts = server_opts(server)
18
-
19
- Fb::Database.new(
20
- :database => "#{opts[:host]}:#{opts[:database]}",
21
- :username => opts[:user],
22
- :password => opts[:password]).connect
23
- end
24
-
25
- def disconnect_connection(conn)
26
- begin
27
- conn.close
28
- rescue Fb::Error
29
- nil
30
- end
31
- end
32
-
33
- def execute(sql, opts=OPTS)
34
- begin
35
- synchronize(opts[:server]) do |conn|
36
- if conn.transaction_started && !_trans(conn)
37
- conn.rollback
38
- raise DatabaseDisconnectError, "transaction accidently left open, rolling back and disconnecting"
39
- end
40
- r = log_yield(sql){conn.execute(sql)}
41
- yield(r) if block_given?
42
- r
43
- end
44
- rescue Fb::Error => e
45
- raise_error(e, :disconnect=>DISCONNECT_ERRORS.match(e.message))
46
- end
47
- end
48
-
49
- private
50
-
51
- # Add the primary_keys instance variable so we can get the correct return values for inserted rows.
52
- def adapter_initialize
53
- @primary_keys = {}
54
- end
55
-
56
- def begin_transaction(conn, opts=OPTS)
57
- log_yield(TRANSACTION_BEGIN) do
58
- begin
59
- conn.transaction
60
- rescue Fb::Error => e
61
- conn.rollback
62
- raise_error(e, :disconnect=>true)
63
- end
64
- end
65
- end
66
-
67
- def commit_transaction(conn, opts=OPTS)
68
- log_yield(TRANSACTION_COMMIT){conn.commit}
69
- end
70
-
71
- def database_error_classes
72
- [Fb::Error]
73
- end
74
-
75
- def rollback_transaction(conn, opts=OPTS)
76
- log_yield(TRANSACTION_ROLLBACK){conn.rollback}
77
- end
78
- end
79
-
80
- # Dataset class for Firebird datasets
81
- class Dataset < Sequel::Dataset
82
- include Sequel::Firebird::DatasetMethods
83
-
84
- Database::DatasetClass = self
85
-
86
- # Yield all rows returned by executing the given SQL and converting
87
- # the types.
88
- def fetch_rows(sql)
89
- execute(sql) do |s|
90
- begin
91
- @columns = columns = s.fields.map{|c| output_identifier(c.name)}
92
- s.fetchall.each do |r|
93
- h = {}
94
- r.zip(columns).each{|v, c| h[c] = v}
95
- yield h
96
- end
97
- ensure
98
- s.close
99
- end
100
- end
101
- self
102
- end
103
- end
104
- end
105
- end