sequel 4.38.0 → 4.39.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.
- checksums.yaml +4 -4
- data/CHANGELOG +28 -0
- data/doc/association_basics.rdoc +1 -1
- data/doc/core_extensions.rdoc +8 -8
- data/doc/object_model.rdoc +7 -8
- data/doc/querying.rdoc +2 -2
- data/doc/release_notes/4.39.0.txt +127 -0
- data/doc/sql.rdoc +31 -31
- data/doc/transactions.rdoc +1 -1
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/mock.rb +22 -66
- data/lib/sequel/adapters/shared/access.rb +2 -0
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/db2.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +10 -2
- data/lib/sequel/adapters/shared/mysql.rb +17 -4
- data/lib/sequel/adapters/shared/oracle.rb +9 -0
- data/lib/sequel/adapters/shared/postgres.rb +34 -1
- data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -0
- data/lib/sequel/adapters/shared/sqlite.rb +8 -0
- data/lib/sequel/core.rb +10 -0
- data/lib/sequel/database.rb +5 -0
- data/lib/sequel/database/connecting.rb +28 -0
- data/lib/sequel/database/misc.rb +0 -51
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +9 -0
- data/lib/sequel/database/transactions.rb +65 -0
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/core_extensions.rb +1 -1
- data/lib/sequel/extensions/core_refinements.rb +1 -1
- data/lib/sequel/extensions/migration.rb +17 -1
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pg_array_ops.rb +1 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +1 -1
- data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
- data/lib/sequel/extensions/pg_interval.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +28 -15
- data/lib/sequel/extensions/pg_range_ops.rb +1 -1
- data/lib/sequel/extensions/pg_row_ops.rb +1 -1
- data/lib/sequel/extensions/select_remove.rb +1 -1
- data/lib/sequel/extensions/sql_expr.rb +1 -1
- data/lib/sequel/model/associations.rb +1 -1
- data/lib/sequel/plugins/active_model.rb +19 -8
- data/lib/sequel/plugins/dataset_associations.rb +1 -1
- data/lib/sequel/plugins/hook_class_methods.rb +38 -2
- data/lib/sequel/plugins/list.rb +1 -1
- data/lib/sequel/plugins/pg_array_associations.rb +3 -3
- data/lib/sequel/plugins/timestamps.rb +15 -2
- data/lib/sequel/plugins/touch.rb +6 -0
- data/lib/sequel/sql.rb +15 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +18 -0
- data/spec/adapters/postgres_spec.rb +30 -1
- data/spec/core/database_spec.rb +29 -0
- data/spec/core/mock_adapter_spec.rb +32 -1
- data/spec/extensions/migration_spec.rb +46 -0
- data/spec/extensions/pg_interval_spec.rb +1 -0
- data/spec/extensions/pg_json_ops_spec.rb +13 -0
- data/spec/extensions/timestamps_spec.rb +11 -0
- data/spec/extensions/touch_spec.rb +8 -0
- metadata +4 -2
data/lib/sequel/plugins/list.rb
CHANGED
|
@@ -491,14 +491,14 @@ module Sequel
|
|
|
491
491
|
expr = case obj
|
|
492
492
|
when Sequel::Model
|
|
493
493
|
if (assoc_pks = obj.get_column_value(key)) && !assoc_pks.empty?
|
|
494
|
-
Sequel
|
|
494
|
+
Sequel[pk=>assoc_pks.to_a]
|
|
495
495
|
end
|
|
496
496
|
when Array
|
|
497
497
|
if (assoc_pks = obj.map{|o| o.get_column_value(key)}.flatten.compact.uniq) && !assoc_pks.empty?
|
|
498
|
-
Sequel
|
|
498
|
+
Sequel[pk=>assoc_pks]
|
|
499
499
|
end
|
|
500
500
|
when Sequel::Dataset
|
|
501
|
-
Sequel
|
|
501
|
+
Sequel[pk=>obj.select{Sequel.pg_array_op(ref.qualify(obj.model.table_name, ref[:key_column])).unnest}]
|
|
502
502
|
end
|
|
503
503
|
expr = Sequel::SQL::Constants::FALSE unless expr
|
|
504
504
|
expr = add_association_filter_conditions(ref, obj, expr)
|
|
@@ -24,12 +24,14 @@ module Sequel
|
|
|
24
24
|
# Configure the plugin by setting the available options. Note that
|
|
25
25
|
# if this method is run more than once, previous settings are ignored,
|
|
26
26
|
# and it will just use the settings given or the default settings. Options:
|
|
27
|
+
# :allow_manual_update :: Whether to skip setting the update timestamp if it has been modified manually (default: false)
|
|
27
28
|
# :create :: The field to hold the create timestamp (default: :created_at)
|
|
28
29
|
# :force :: Whether to overwrite an existing create timestamp (default: false)
|
|
29
30
|
# :update :: The field to hold the update timestamp (default: :updated_at)
|
|
30
31
|
# :update_on_create :: Whether to set the update timestamp to the create timestamp when creating (default: false)
|
|
31
32
|
def self.configure(model, opts=OPTS)
|
|
32
33
|
model.instance_eval do
|
|
34
|
+
@allow_manual_timestamp_update = opts[:allow_manual_update]||false
|
|
33
35
|
@create_timestamp_field = opts[:create]||:created_at
|
|
34
36
|
@update_timestamp_field = opts[:update]||:updated_at
|
|
35
37
|
@create_timestamp_overwrite = opts[:force]||false
|
|
@@ -49,9 +51,19 @@ module Sequel
|
|
|
49
51
|
@create_timestamp_overwrite
|
|
50
52
|
end
|
|
51
53
|
|
|
52
|
-
Plugins.inherited_instance_variables(self,
|
|
53
|
-
:@
|
|
54
|
+
Plugins.inherited_instance_variables(self,
|
|
55
|
+
:@allow_manual_timestamp_update=>nil,
|
|
56
|
+
:@create_timestamp_field=>nil,
|
|
57
|
+
:@create_timestamp_overwrite=>nil,
|
|
58
|
+
:@set_update_timestamp_on_create=>nil,
|
|
59
|
+
:@update_timestamp_field=>nil)
|
|
54
60
|
|
|
61
|
+
|
|
62
|
+
# Whether to allow manual setting of the update timestamp when creating
|
|
63
|
+
def allow_manual_timestamp_update?
|
|
64
|
+
@allow_manual_timestamp_update
|
|
65
|
+
end
|
|
66
|
+
|
|
55
67
|
# Whether to set the update timestamp to the create timestamp when creating
|
|
56
68
|
def set_update_timestamp_on_create?
|
|
57
69
|
@set_update_timestamp_on_create
|
|
@@ -88,6 +100,7 @@ module Sequel
|
|
|
88
100
|
# Set the update timestamp to the time given or the current time if the
|
|
89
101
|
# object has a setter method for the update timestamp field.
|
|
90
102
|
def set_update_timestamp(time=nil)
|
|
103
|
+
return if model.allow_manual_timestamp_update? && modified?(model.update_timestamp_field)
|
|
91
104
|
meth = :"#{model.update_timestamp_field}="
|
|
92
105
|
set_column_value(meth, time||model.dataset.current_datetime) if respond_to?(meth)
|
|
93
106
|
end
|
data/lib/sequel/plugins/touch.rb
CHANGED
|
@@ -78,6 +78,12 @@ module Sequel
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
module InstanceMethods
|
|
81
|
+
# Touch all of the model's touched_associations when creating the object.
|
|
82
|
+
def after_create
|
|
83
|
+
super
|
|
84
|
+
touch_associations
|
|
85
|
+
end
|
|
86
|
+
|
|
81
87
|
# Touch all of the model's touched_associations when destroying the object.
|
|
82
88
|
def after_destroy
|
|
83
89
|
super
|
data/lib/sequel/sql.rb
CHANGED
|
@@ -465,6 +465,10 @@ module Sequel
|
|
|
465
465
|
# to construct via other methods. For example:
|
|
466
466
|
#
|
|
467
467
|
# Sequel.expr(1) - :a # SQL: (1 - a)
|
|
468
|
+
#
|
|
469
|
+
# On the Sequel module, this is aliased as #[], for easier use:
|
|
470
|
+
#
|
|
471
|
+
# Sequel[1] - :a # SQL: (1 - a)
|
|
468
472
|
def expr(arg=(no_arg=true), &block)
|
|
469
473
|
if block_given?
|
|
470
474
|
if no_arg
|
|
@@ -793,7 +797,7 @@ module Sequel
|
|
|
793
797
|
# If the argument given is Numeric, treat it as a NumericExpression,
|
|
794
798
|
# allowing code such as:
|
|
795
799
|
#
|
|
796
|
-
# 1 + Sequel
|
|
800
|
+
# 1 + Sequel[:x] # SQL: (1 + x)
|
|
797
801
|
# Sequel.expr{1 - x(y)} # SQL: (1 - x(y))
|
|
798
802
|
def coerce(other)
|
|
799
803
|
if other.is_a?(Numeric)
|
|
@@ -822,17 +826,17 @@ module Sequel
|
|
|
822
826
|
# return when using a hash with a single entry, where the receiver was the key
|
|
823
827
|
# and the argument was the value. Example:
|
|
824
828
|
#
|
|
825
|
-
# Sequel
|
|
826
|
-
# Sequel
|
|
827
|
-
# Sequel
|
|
829
|
+
# Sequel[:a] =~ 1 # (a = 1)
|
|
830
|
+
# Sequel[:a] =~ [1, 2] # (a IN [1, 2])
|
|
831
|
+
# Sequel[:a] =~ nil # (a IS NULL)
|
|
828
832
|
#
|
|
829
833
|
# On Ruby 1.9+, this also adds the !~ method, for easily setting up not equals,
|
|
830
834
|
# exclusion, and inverse pattern matching. This is the same as as inverting the
|
|
831
835
|
# result of the =~ method
|
|
832
836
|
#
|
|
833
|
-
# Sequel
|
|
834
|
-
# Sequel
|
|
835
|
-
# Sequel
|
|
837
|
+
# Sequel[:a] !~ 1 # (a != 1)
|
|
838
|
+
# Sequel[:a] !~ [1, 2] # (a NOT IN [1, 2])
|
|
839
|
+
# Sequel[:a] !~ nil # (a IS NOT NULL)
|
|
836
840
|
module PatternMatchMethods
|
|
837
841
|
# Set up an equality, inclusion, or pattern match operation, based on the type
|
|
838
842
|
# of the argument.
|
|
@@ -929,7 +933,7 @@ module Sequel
|
|
|
929
933
|
module QualifyingMethods
|
|
930
934
|
# If no arguments are given, return an SQL::ColumnAll:
|
|
931
935
|
#
|
|
932
|
-
# Sequel
|
|
936
|
+
# Sequel[:a__b].* # a.b.*
|
|
933
937
|
def *(ce=(arg=false;nil))
|
|
934
938
|
if arg == false
|
|
935
939
|
Sequel::SQL::ColumnAll.new(self)
|
|
@@ -940,8 +944,8 @@ module Sequel
|
|
|
940
944
|
|
|
941
945
|
# Qualify the receiver with the given +qualifier+ (table for column/schema for table).
|
|
942
946
|
#
|
|
943
|
-
# Sequel
|
|
944
|
-
# Sequel
|
|
947
|
+
# Sequel[:column].qualify(:table) # "table"."column"
|
|
948
|
+
# Sequel[:table].qualify(:schema) # "schema"."table"
|
|
945
949
|
# Sequel.qualify(:table, :column).qualify(:schema) # "schema"."table"."column"
|
|
946
950
|
def qualify(qualifier)
|
|
947
951
|
QualifiedIdentifier.new(qualifier, self)
|
|
@@ -1392,7 +1396,7 @@ module Sequel
|
|
|
1392
1396
|
# Return a new function where the function name will not be quoted even
|
|
1393
1397
|
# if the database supports quoted functions:
|
|
1394
1398
|
#
|
|
1395
|
-
# Sequel
|
|
1399
|
+
# Sequel[:foo].function.unquoted # foo()
|
|
1396
1400
|
def unquoted
|
|
1397
1401
|
with_opts(:quoted=>false)
|
|
1398
1402
|
end
|
data/lib/sequel/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Sequel
|
|
|
5
5
|
MAJOR = 4
|
|
6
6
|
# The minor version of Sequel. Bumped for every non-patch level
|
|
7
7
|
# release, generally around once a month.
|
|
8
|
-
MINOR =
|
|
8
|
+
MINOR = 39
|
|
9
9
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
|
10
10
|
# releases that fix regressions from previous versions.
|
|
11
11
|
TINY = 0
|
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -515,6 +515,24 @@ describe "A MySQL database" do
|
|
|
515
515
|
end
|
|
516
516
|
end
|
|
517
517
|
|
|
518
|
+
it "should correctly handle add_column :after option" do
|
|
519
|
+
@db.create_table(:items){Integer :id; Integer :value}
|
|
520
|
+
@db.alter_table(:items){add_column :name, String, :after=>:id}
|
|
521
|
+
@db[:items].columns.must_equal [:id, :name, :value]
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
it "should correctly handle add_column :first option" do
|
|
525
|
+
@db.create_table(:items){Integer :id; Integer :value}
|
|
526
|
+
@db.alter_table(:items){add_column :name, String, :first => true}
|
|
527
|
+
@db[:items].columns.must_equal [:name, :id, :value]
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
it "should correctly handle add_foreign_key :first option" do
|
|
531
|
+
@db.create_table(:items){primary_key :id; Integer :value}
|
|
532
|
+
@db.alter_table(:items){add_foreign_key :parent_id, :items, :first => true}
|
|
533
|
+
@db[:items].columns.must_equal [:parent_id, :id, :value]
|
|
534
|
+
end
|
|
535
|
+
|
|
518
536
|
it "should have rename_column support keep existing options" do
|
|
519
537
|
@db.create_table(:items){String :id, :null=>false, :default=>'blah'}
|
|
520
538
|
@db.alter_table(:items){rename_column :id, :nid}
|
|
@@ -204,6 +204,17 @@ describe "PostgreSQL", 'INSERT ON CONFLICT' do
|
|
|
204
204
|
@ds.all.must_equal [{:a=>1, :b=>2, :c=>3}]
|
|
205
205
|
end
|
|
206
206
|
|
|
207
|
+
it "Dataset#insert_ignore and insert_conflict should work with multi_insert/import" do
|
|
208
|
+
@ds.insert(1, 2, 3)
|
|
209
|
+
@ds.insert_ignore.multi_insert([{:a=>1, :b=>3, :c=>4}])
|
|
210
|
+
@ds.insert_ignore.import([:a, :b, :c], [[1, 3, 4]])
|
|
211
|
+
@ds.all.must_equal [{:a=>1, :b=>2, :c=>3}]
|
|
212
|
+
@ds.insert_conflict(:target=>:a, :update=>{:b=>3}).import([:a, :b, :c], [[1, 3, 4]])
|
|
213
|
+
@ds.all.must_equal [{:a=>1, :b=>3, :c=>3}]
|
|
214
|
+
@ds.insert_conflict(:target=>:a, :update=>{:b=>4}).multi_insert([{:a=>1, :b=>5, :c=>6}])
|
|
215
|
+
@ds.all.must_equal [{:a=>1, :b=>4, :c=>3}]
|
|
216
|
+
end
|
|
217
|
+
|
|
207
218
|
it "Dataset#insert_conflict should handle upserts" do
|
|
208
219
|
@ds.insert(1, 2, 3)
|
|
209
220
|
@ds.insert_conflict(:target=>:a, :update=>{:b=>3}).insert(1, 3, 4).must_equal nil
|
|
@@ -991,6 +1002,11 @@ describe "A PostgreSQL database" do
|
|
|
991
1002
|
@db[:posts].full_text_search(:title, 'rubinius ruby', :plain=>true).select_order_map(:title).must_equal ['jruby rubinius ruby maglev mri iron', 'ruby jruby maglev mri rubinius iron']
|
|
992
1003
|
@db[:posts].full_text_search(:title, 'jruby maglev', :plain=>true).select_order_map(:title).must_equal ['jruby rubinius ruby maglev mri iron', 'ruby jruby maglev mri rubinius iron']
|
|
993
1004
|
|
|
1005
|
+
if DB.server_version >= 90600
|
|
1006
|
+
@db[:posts].full_text_search(:title, 'rubinius ruby', :to_tsquery=>:phrase).select_order_map(:title).must_equal ['jruby rubinius ruby maglev mri iron']
|
|
1007
|
+
@db[:posts].full_text_search(:title, 'jruby maglev', :to_tsquery=>:phrase).select_order_map(:title).must_equal ['ruby jruby maglev mri rubinius iron']
|
|
1008
|
+
end
|
|
1009
|
+
|
|
994
1010
|
@db[:posts].full_text_search(Sequel.function(:to_tsvector, 'simple', :title), 'rails', :tsvector=>true).all.must_equal [{:title=>'ruby rails', :body=>'yowsa'}]
|
|
995
1011
|
@db[:posts].full_text_search(:title, Sequel.function(:to_tsquery, 'simple', 'rails'), :tsquery=>true).all.must_equal [{:title=>'ruby rails', :body=>'yowsa'}]
|
|
996
1012
|
proc{@db[:posts].full_text_search(Sequel.function(:to_tsvector, 'simple', :title), 'rubinius ruby', :tsvector=>true, :phrase=>true)}.must_raise(Sequel::Error)
|
|
@@ -1058,6 +1074,13 @@ describe "A PostgreSQL database" do
|
|
|
1058
1074
|
@db.create_table!(:posts1){primary_key :a}
|
|
1059
1075
|
@db.rename_table(:posts1, :posts)
|
|
1060
1076
|
end
|
|
1077
|
+
|
|
1078
|
+
it "should adding a primary key only if it does not already exists" do
|
|
1079
|
+
@db.create_table(:posts){Integer :a}
|
|
1080
|
+
@db.alter_table(:posts){add_column :b, Integer}
|
|
1081
|
+
@db.alter_table(:posts){add_column :b, Integer, :if_not_exists=>true}
|
|
1082
|
+
proc{@db.alter_table(:posts){add_column :b, Integer}}.must_raise Sequel::DatabaseError
|
|
1083
|
+
end if DB.server_version >= 90600
|
|
1061
1084
|
end
|
|
1062
1085
|
|
|
1063
1086
|
describe "Postgres::Dataset#import" do
|
|
@@ -1071,7 +1094,6 @@ describe "Postgres::Dataset#import" do
|
|
|
1071
1094
|
@db.drop_table?(:test)
|
|
1072
1095
|
end
|
|
1073
1096
|
|
|
1074
|
-
|
|
1075
1097
|
it "#import should a single insert statement" do
|
|
1076
1098
|
@ds.import([:x, :y], [[1, 2], [3, 4]])
|
|
1077
1099
|
check_sqls do
|
|
@@ -2916,6 +2938,13 @@ describe 'PostgreSQL json type' do
|
|
|
2916
2938
|
@db.get(jo.set(%w'a', 'f'=>'g')['a']['f']).must_equal 'g'
|
|
2917
2939
|
end
|
|
2918
2940
|
|
|
2941
|
+
if DB.server_version >= 90600 && json_type == :jsonb
|
|
2942
|
+
@db.get(pg_json.call([3]).op.insert(['0'], {'a'=>2})[0]['a']).must_equal 2
|
|
2943
|
+
@db.get(pg_json.call([3]).op.insert(['0'], {'a'=>2}, false)[0]['a']).must_equal 2
|
|
2944
|
+
@db.get(pg_json.call([3]).op.insert(['0'], {'a'=>2}, true)[0]).must_equal 3
|
|
2945
|
+
@db.get(pg_json.call([3]).op.insert(['0'], {'a'=>2}, true)[1]['a']).must_equal 2
|
|
2946
|
+
end
|
|
2947
|
+
|
|
2919
2948
|
@db.from(jo.keys.as(:k)).select_order_map(:k).must_equal %w'a b'
|
|
2920
2949
|
@db.from(jo.each).select_order_map(:key).must_equal %w'a b'
|
|
2921
2950
|
@db.from(jo.each).order(:key).select_map(:value).must_equal [1, {'c'=>2, 'd'=>{'e'=>3}}]
|
data/spec/core/database_spec.rb
CHANGED
|
@@ -834,6 +834,35 @@ DatabaseTransactionSpecs = shared_description do
|
|
|
834
834
|
@db.in_transaction?.must_equal false
|
|
835
835
|
end
|
|
836
836
|
|
|
837
|
+
it "should have rollback_checker return a proc which returns whether the transaction was rolled back" do
|
|
838
|
+
proc{@db.rollback_checker}.must_raise Sequel::Error
|
|
839
|
+
proc{@db.transaction(:server=>:test){@db.rollback_checker}}.must_raise Sequel::Error
|
|
840
|
+
|
|
841
|
+
rbc = nil
|
|
842
|
+
@db.transaction do
|
|
843
|
+
rbc = @db.rollback_checker
|
|
844
|
+
rbc.call.must_equal nil
|
|
845
|
+
end
|
|
846
|
+
rbc.call.must_equal false
|
|
847
|
+
|
|
848
|
+
@db.transaction(:rollback=>:always) do
|
|
849
|
+
rbc = @db.rollback_checker
|
|
850
|
+
rbc.call.must_equal nil
|
|
851
|
+
end
|
|
852
|
+
rbc.call.must_equal true
|
|
853
|
+
|
|
854
|
+
proc do
|
|
855
|
+
@db.transaction do
|
|
856
|
+
rbc = @db.rollback_checker
|
|
857
|
+
raise
|
|
858
|
+
end
|
|
859
|
+
end.must_raise RuntimeError
|
|
860
|
+
rbc.call.must_equal true
|
|
861
|
+
|
|
862
|
+
@db.transaction(:server=>:test){rbc = @db.rollback_checker(:server=>:test)}
|
|
863
|
+
rbc.call.must_equal false
|
|
864
|
+
end
|
|
865
|
+
|
|
837
866
|
it "should return nil if Sequel::Rollback is called in the transaction" do
|
|
838
867
|
@db.transaction{raise Sequel::Rollback}.must_equal nil
|
|
839
868
|
end
|
|
@@ -7,6 +7,37 @@ describe "Sequel Mock Adapter" do
|
|
|
7
7
|
db.adapter_scheme.must_equal :mock
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
it "should support registering mock adapter type" do
|
|
11
|
+
begin
|
|
12
|
+
mod = Module.new do
|
|
13
|
+
Sequel::Database.set_shared_adapter_scheme(:foo, self)
|
|
14
|
+
|
|
15
|
+
def self.mock_adapter_setup(db)
|
|
16
|
+
db.instance_variable_set(:@foo, :foo)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module self::DatabaseMethods
|
|
20
|
+
def foo
|
|
21
|
+
@foo
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module self::DatasetMethods
|
|
26
|
+
def foo
|
|
27
|
+
db.foo
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Sequel.connect('mock://foo') do |db|
|
|
33
|
+
db.foo.must_equal :foo
|
|
34
|
+
db.dataset.foo.must_equal :foo
|
|
35
|
+
end
|
|
36
|
+
ensure
|
|
37
|
+
Sequel.synchronize{Sequel::SHARED_ADAPTER_MAP.delete(:foo)}
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
10
41
|
it "should have constructor accept no arguments" do
|
|
11
42
|
Sequel::Mock::Database.new.must_be_kind_of(Sequel::Mock::Database)
|
|
12
43
|
end
|
|
@@ -443,7 +474,7 @@ describe "Sequel Mock Adapter" do
|
|
|
443
474
|
end
|
|
444
475
|
end
|
|
445
476
|
|
|
446
|
-
it "should automatically set version for adapters
|
|
477
|
+
it "should automatically set version for adapters needing versions" do
|
|
447
478
|
Sequel.mock(:host=>'postgres').server_version.must_be :>=, 90400
|
|
448
479
|
Sequel.mock(:host=>'mssql').server_version.must_be :>=, 11000000
|
|
449
480
|
Sequel.mock(:host=>'mysql').server_version.must_be :>=, 50617
|
|
@@ -319,6 +319,52 @@ describe "Sequel::IntegerMigrator" do
|
|
|
319
319
|
@db.dataset.columns.must_equal [:sic]
|
|
320
320
|
end
|
|
321
321
|
|
|
322
|
+
it "should support :relative option for running relative migrations" do
|
|
323
|
+
Sequel::Migrator.run(@db, @dirname, :relative=>2).must_equal 2
|
|
324
|
+
@db.creates.must_equal [1111, 2222]
|
|
325
|
+
@db.version.must_equal 2
|
|
326
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [1, 2]
|
|
327
|
+
|
|
328
|
+
Sequel::Migrator.run(@db, @dirname, :relative=>-1).must_equal 1
|
|
329
|
+
@db.drops.must_equal [2222]
|
|
330
|
+
@db.version.must_equal 1
|
|
331
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [1]
|
|
332
|
+
|
|
333
|
+
Sequel::Migrator.run(@db, @dirname, :relative=>2).must_equal 3
|
|
334
|
+
@db.creates.must_equal [1111, 2222, 2222, 3333]
|
|
335
|
+
@db.version.must_equal 3
|
|
336
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [2, 3]
|
|
337
|
+
|
|
338
|
+
Sequel::Migrator.run(@db, @dirname, :relative=>-3).must_equal 0
|
|
339
|
+
@db.drops.must_equal [2222, 3333, 2222, 1111]
|
|
340
|
+
@db.version.must_equal 0
|
|
341
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [2, 1, 0]
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
it "should handle :relative option beyond the upper and lower limit" do
|
|
345
|
+
Sequel::Migrator.run(@db, @dirname, :relative=>100).must_equal 3
|
|
346
|
+
@db.creates.must_equal [1111, 2222, 3333]
|
|
347
|
+
@db.version.must_equal 3
|
|
348
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [1, 2, 3]
|
|
349
|
+
|
|
350
|
+
Sequel::Migrator.run(@db, @dirname, :relative=>-200).must_equal 0
|
|
351
|
+
@db.drops.must_equal [3333, 2222, 1111]
|
|
352
|
+
@db.version.must_equal 0
|
|
353
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [2, 1, 0]
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
it "should correctly handle migration target versions beyond the upper and lower limits" do
|
|
357
|
+
Sequel::Migrator.run(@db, @dirname, :target=>100).must_equal 3
|
|
358
|
+
@db.creates.must_equal [1111, 2222, 3333]
|
|
359
|
+
@db.version.must_equal 3
|
|
360
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [1, 2, 3]
|
|
361
|
+
|
|
362
|
+
Sequel::Migrator.run(@db, @dirname, :target=>-100).must_equal 0
|
|
363
|
+
@db.drops.must_equal [3333, 2222, 1111]
|
|
364
|
+
@db.version.must_equal 0
|
|
365
|
+
@db.sqls.map{|x| x =~ /\AUPDATE.*(\d+)/ ? $1.to_i : nil}.compact.must_equal [2, 1, 0]
|
|
366
|
+
end
|
|
367
|
+
|
|
322
368
|
it "should apply migrations correctly in the up direction if no target is given" do
|
|
323
369
|
Sequel::Migrator.apply(@db, @dirname)
|
|
324
370
|
@db.creates.must_equal [1111, 2222, 3333]
|
|
@@ -15,6 +15,7 @@ describe "pg_interval extension" do
|
|
|
15
15
|
@db.literal(ActiveSupport::Duration.new(0, [])).must_equal "'0'::interval"
|
|
16
16
|
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 0]])).must_equal "'0'::interval"
|
|
17
17
|
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 10], [:minutes, 20], [:days, 3], [:months, 4], [:years, 6]])).must_equal "'6 years 4 months 3 days 20 minutes 10 seconds '::interval"
|
|
18
|
+
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, 10], [:minutes, 20], [:hours, 8], [:days, 3], [:weeks, 2], [:months, 4], [:years, 6]])).must_equal "'6 years 4 months 2 weeks 3 days 8 hours 20 minutes 10 seconds '::interval"
|
|
18
19
|
@db.literal(ActiveSupport::Duration.new(0, [[:seconds, -10.000001], [:minutes, -20], [:days, -3], [:months, -4], [:years, -6]])).must_equal "'-6 years -4 months -3 days -20 minutes -10.000001 seconds '::interval"
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -190,6 +190,19 @@ describe "Sequel::Postgres::JSONOp" do
|
|
|
190
190
|
@l[@jb.concat([1, 2])].must_equal "(j || '[1,2]'::jsonb)"
|
|
191
191
|
end
|
|
192
192
|
|
|
193
|
+
it "#insert should use the jsonb_insert function" do
|
|
194
|
+
@l[@jb.insert(:a, :h)].must_equal "jsonb_insert(j, a, h, false)"
|
|
195
|
+
@l[@jb.insert(:a, :h, true)].must_equal "jsonb_insert(j, a, h, true)"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "#insert should handle hashes" do
|
|
199
|
+
@l[@jb.insert(:a, 'a'=>'b')].must_equal "jsonb_insert(j, a, '{\"a\":\"b\"}'::jsonb, false)"
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "#insert should handle arrays" do
|
|
203
|
+
@l[@jb.insert(%w'a b', [1, 2])].must_equal "jsonb_insert(j, ARRAY['a','b'], '[1,2]'::jsonb, false)"
|
|
204
|
+
end
|
|
205
|
+
|
|
193
206
|
it "#set should use the jsonb_set function" do
|
|
194
207
|
@l[@jb.set(:a, :h)].must_equal "jsonb_set(j, a, h, true)"
|
|
195
208
|
@l[@jb.set(:a, :h, false)].must_equal "jsonb_set(j, a, h, false)"
|
|
@@ -50,6 +50,17 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
50
50
|
o.updated_at.must_equal '2009-08-01'
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
it "should leave manually set update timestamp, if :allow_manual_update was given" do
|
|
54
|
+
o = @c.load(:id=>1).update(:updated_at=>Date.new(2016))
|
|
55
|
+
@c.db.sqls.must_equal ["UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
|
|
56
|
+
o.updated_at.must_equal '2009-08-01'
|
|
57
|
+
|
|
58
|
+
@c.plugin :timestamps, :allow_manual_update=>true
|
|
59
|
+
o = @c.load(:id=>1).update(:updated_at=>Date.new(2016))
|
|
60
|
+
@c.db.sqls.must_equal ["UPDATE t SET updated_at = '2016-01-01' WHERE (id = 1)"]
|
|
61
|
+
o.updated_at.must_equal Date.new(2016)
|
|
62
|
+
end
|
|
63
|
+
|
|
53
64
|
it "should work with current_datetime_timestamp extension" do
|
|
54
65
|
Sequel.datetime_class = Time
|
|
55
66
|
@c.dataset = @c.dataset.extension(:current_datetime_timestamp)
|
|
@@ -127,6 +127,14 @@ describe "Touch plugin" do
|
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
it "should be able to touch many_to_one associations" do
|
|
130
|
+
@Album.plugin :touch, :associations=>:artist
|
|
131
|
+
@Album.plugin :skip_create_refresh
|
|
132
|
+
@Album.create(:artist_id=>4)
|
|
133
|
+
DB.sqls.must_equal ["INSERT INTO albums (artist_id) VALUES (4)",
|
|
134
|
+
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 4)"]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should be able to touch one_to_one associations" do
|
|
130
138
|
@Artist.one_to_one :album, :class=>@Album, :key=>:artist_id
|
|
131
139
|
@Artist.plugin :touch, :associations=>:album
|
|
132
140
|
@a.touch
|