sequel 4.46.0 → 4.49.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 +210 -0
- data/Rakefile +1 -1
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.47.0.txt +56 -0
- data/doc/release_notes/4.48.0.txt +293 -0
- data/doc/release_notes/4.49.0.txt +222 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +30 -8
- data/lib/sequel/adapters/jdbc/as400.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
- data/lib/sequel/adapters/jdbc.rb +39 -23
- data/lib/sequel/adapters/mock.rb +27 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +91 -103
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +79 -25
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/adapters/shared/postgres.rb +199 -95
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/connection_pool.rb +9 -2
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +8 -8
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +72 -10
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +22 -11
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +11 -8
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +29 -25
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/server_block.rb +32 -15
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model/associations.rb +35 -7
- data/lib/sequel/model/base.rb +113 -87
- data/lib/sequel/model/dataset_module.rb +5 -43
- data/lib/sequel/model/errors.rb +2 -1
- data/lib/sequel/model/inflections.rb +17 -5
- data/lib/sequel/model.rb +26 -58
- data/lib/sequel/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/association_autoreloading.rb +2 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +2 -2
- data/lib/sequel/plugins/boolean_subsets.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +3 -3
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/defaults_setter.rb +13 -1
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +19 -12
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +6 -2
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -24
- data/lib/sequel/plugins/serialization.rb +9 -15
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +4 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +14 -8
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +18 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +83 -29
- data/spec/adapters/oracle_spec.rb +28 -24
- data/spec/adapters/postgres_spec.rb +40 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +45 -14
- data/spec/core/database_spec.rb +155 -0
- data/spec/core/dataset_spec.rb +219 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +106 -19
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/column_select_spec.rb +1 -0
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +20 -8
- data/spec/extensions/defaults_setter_spec.rb +15 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +108 -94
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/serialization_spec.rb +1 -1
- data/spec/extensions/server_block_spec.rb +7 -0
- data/spec/extensions/single_table_inheritance_spec.rb +17 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +10 -5
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/model_test.rb +53 -4
- data/spec/integration/plugin_test.rb +28 -4
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/association_reflection_spec.rb +43 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +20 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +45 -1
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +11 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -62,6 +62,11 @@ describe "class_table_inheritance plugin" do
|
|
|
62
62
|
Employee.cti_table_map.frozen?.must_equal true
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
deprecated "should support cti_key and cti_model_map" do
|
|
66
|
+
Employee.cti_key.must_equal Employee.sti_key
|
|
67
|
+
Employee.cti_model_map.must_equal Employee.sti_model_map
|
|
68
|
+
end
|
|
69
|
+
|
|
65
70
|
deprecated "should not attempt to use prepared statements" do
|
|
66
71
|
Manager.plugin :prepared_statements
|
|
67
72
|
Manager[1]
|
|
@@ -572,11 +577,15 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
572
577
|
@db.sqls.must_equal ["SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 1) LIMIT 1"]
|
|
573
578
|
end
|
|
574
579
|
|
|
575
|
-
|
|
580
|
+
deprecated "#cti_base_model should be the model that loaded the plugin" do
|
|
576
581
|
Executive.cti_base_model.must_equal Employee
|
|
577
582
|
end
|
|
578
583
|
|
|
579
|
-
it "#
|
|
584
|
+
it "#cti_models.first should be the model that loaded the plugin" do
|
|
585
|
+
Executive.cti_models.first.must_equal Employee
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
deprecated "#cti_columns should be a mapping of table names to columns" do
|
|
580
589
|
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
|
581
590
|
end
|
|
582
591
|
|
|
@@ -668,6 +677,39 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
668
677
|
"INSERT INTO executives (id) VALUES (1)"]
|
|
669
678
|
end
|
|
670
679
|
|
|
680
|
+
it "should sets the model class name for the key when creating new subclass records" do
|
|
681
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
682
|
+
Object.send(:remove_const, :Ceo)
|
|
683
|
+
Object.send(:remove_const, :Executive)
|
|
684
|
+
Object.send(:remove_const, :Manager)
|
|
685
|
+
class ::Manager < Employee; end
|
|
686
|
+
class ::Executive < Manager; end
|
|
687
|
+
class ::Ceo < Executive; end
|
|
688
|
+
Ceo.create
|
|
689
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('3')",
|
|
690
|
+
"INSERT INTO managers (id) VALUES (1)",
|
|
691
|
+
"INSERT INTO executives (id) VALUES (1)"]
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
it "should sets the model class name for the key when creating new subclass records" do
|
|
695
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
696
|
+
Object.send(:remove_const, :Ceo)
|
|
697
|
+
Object.send(:remove_const, :Executive)
|
|
698
|
+
Object.send(:remove_const, :Manager)
|
|
699
|
+
class ::Manager < Employee; end
|
|
700
|
+
class ::Executive < Employee; end
|
|
701
|
+
class ::Ceo < Employee; end
|
|
702
|
+
Ceo.create
|
|
703
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('3')"]
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
it "should not use a subquery for a class that doesn't join to a separate table" do
|
|
707
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
708
|
+
Object.send(:remove_const, :Ceo)
|
|
709
|
+
class ::Ceo < Employee; end
|
|
710
|
+
Ceo.dataset.sql.must_equal 'SELECT * FROM employees WHERE (employees.kind IN (3))'
|
|
711
|
+
end
|
|
712
|
+
|
|
671
713
|
it "should ignore existing cti_key value when creating new records" do
|
|
672
714
|
Employee.create(:kind=>'Manager')
|
|
673
715
|
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
@@ -1038,15 +1080,13 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1038
1080
|
class ::Staff < Employee
|
|
1039
1081
|
many_to_one :manager
|
|
1040
1082
|
end
|
|
1083
|
+
class ::Intern < Employee
|
|
1084
|
+
end
|
|
1041
1085
|
@ds = Employee.dataset
|
|
1042
1086
|
@db.sqls
|
|
1043
1087
|
end
|
|
1044
1088
|
after do
|
|
1045
|
-
Object.send(:remove_const,
|
|
1046
|
-
Object.send(:remove_const, :Executive)
|
|
1047
|
-
Object.send(:remove_const, :Manager)
|
|
1048
|
-
Object.send(:remove_const, :Staff)
|
|
1049
|
-
Object.send(:remove_const, :Employee)
|
|
1089
|
+
[:Intern, :Ceo, :Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)}
|
|
1050
1090
|
end
|
|
1051
1091
|
|
|
1052
1092
|
it "should freeze CTI information when freezing model class" do
|
|
@@ -1069,11 +1109,15 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1069
1109
|
@db.sqls.must_equal ["SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 1) LIMIT 1"]
|
|
1070
1110
|
end
|
|
1071
1111
|
|
|
1072
|
-
|
|
1112
|
+
deprecated "#cti_base_model should be the model that loaded the plugin" do
|
|
1073
1113
|
Executive.cti_base_model.must_equal Employee
|
|
1074
1114
|
end
|
|
1075
1115
|
|
|
1076
|
-
it "#
|
|
1116
|
+
it "#cti_models.first should be the model that loaded the plugin" do
|
|
1117
|
+
Executive.cti_models.first.must_equal Employee
|
|
1118
|
+
end
|
|
1119
|
+
|
|
1120
|
+
deprecated "#cti_columns should be a mapping of table names to columns" do
|
|
1077
1121
|
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
|
1078
1122
|
end
|
|
1079
1123
|
|
|
@@ -1082,6 +1126,7 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1082
1126
|
Executive.simple_table.must_be_nil
|
|
1083
1127
|
Ceo.simple_table.must_be_nil
|
|
1084
1128
|
Staff.simple_table.must_be_nil
|
|
1129
|
+
Intern.simple_table.must_be_nil
|
|
1085
1130
|
end
|
|
1086
1131
|
|
|
1087
1132
|
it "should have working row_proc if using set_dataset in subclass to remove columns" do
|
|
@@ -1096,10 +1141,11 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1096
1141
|
Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees'
|
|
1097
1142
|
Ceo.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (employees.kind IN (\'Ceo\'))) AS employees'
|
|
1098
1143
|
Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees'
|
|
1144
|
+
Intern.dataset.sql.must_equal 'SELECT * FROM employees WHERE (employees.kind IN (\'Intern\'))'
|
|
1099
1145
|
end
|
|
1100
1146
|
|
|
1101
1147
|
it "should return rows with the correct class based on the polymorphic_key value" do
|
|
1102
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}]).all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Ceo, Staff]
|
|
1148
|
+
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}, {:kind=>'Intern'}]).all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Ceo, Staff, Intern]
|
|
1103
1149
|
end
|
|
1104
1150
|
|
|
1105
1151
|
it "should return rows with the correct class based on the polymorphic_key value for subclasses" do
|
|
@@ -1119,7 +1165,7 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1119
1165
|
|
|
1120
1166
|
it "should return rows with the current class if cti_key is nil" do
|
|
1121
1167
|
Employee.plugin(:class_table_inheritance, :alias=>:employees)
|
|
1122
|
-
Employee.dataset.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Employee, Employee, Employee, Employee]
|
|
1168
|
+
Employee.dataset.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}, {:kind=>'Intern'}]).all.map{|x| x.class}.must_equal [Employee, Employee, Employee, Employee, Employee, Employee]
|
|
1123
1169
|
end
|
|
1124
1170
|
|
|
1125
1171
|
it "should return rows with the current class if cti_key is nil in subclasses" do
|
|
@@ -1132,15 +1178,17 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1132
1178
|
end
|
|
1133
1179
|
|
|
1134
1180
|
it "should handle a model map with integer values" do
|
|
1135
|
-
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
|
1181
|
+
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo, 4=>:Intern}, :alias=>:employees)
|
|
1182
|
+
Object.send(:remove_const, :Intern)
|
|
1136
1183
|
Object.send(:remove_const, :Ceo)
|
|
1137
1184
|
Object.send(:remove_const, :Executive)
|
|
1138
1185
|
Object.send(:remove_const, :Manager)
|
|
1186
|
+
class ::Intern < Employee; end
|
|
1139
1187
|
class ::Manager < Employee; end
|
|
1140
1188
|
class ::Executive < Manager; end
|
|
1141
1189
|
class ::Ceo < Executive; end
|
|
1142
|
-
Employee.dataset = Employee.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
|
1143
|
-
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive, Ceo]
|
|
1190
|
+
Employee.dataset = Employee.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}, {:kind=>4}])
|
|
1191
|
+
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive, Ceo, Intern]
|
|
1144
1192
|
Manager.dataset = Manager.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
|
1145
1193
|
Manager.all.collect{|x| x.class}.must_equal [Manager, Employee, Manager, Executive, Ceo]
|
|
1146
1194
|
end
|
|
@@ -1158,6 +1206,11 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1158
1206
|
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
1159
1207
|
end
|
|
1160
1208
|
|
|
1209
|
+
it "should sets the model class name for the key when creating new class records for subclass without separate table" do
|
|
1210
|
+
Intern.create
|
|
1211
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Intern')"]
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1161
1214
|
it "should sets the model class name for the key when creating new subclass records" do
|
|
1162
1215
|
Ceo.create
|
|
1163
1216
|
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Ceo')",
|
|
@@ -1232,10 +1285,11 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1232
1285
|
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
|
1233
1286
|
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
|
1234
1287
|
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
|
1288
|
+
Intern.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string})
|
|
1235
1289
|
end
|
|
1236
1290
|
|
|
1237
1291
|
it "should use the correct primary key (which should have the same name in all subclasses)" do
|
|
1238
|
-
[Employee, Manager, Executive, Ceo, Staff].each{|c| c.primary_key.must_equal :id}
|
|
1292
|
+
[Employee, Manager, Executive, Ceo, Staff, Intern].each{|c| c.primary_key.must_equal :id}
|
|
1239
1293
|
end
|
|
1240
1294
|
|
|
1241
1295
|
it "should have table_name return the table name of the most specific table" do
|
|
@@ -1244,20 +1298,43 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1244
1298
|
Executive.table_name.must_equal :employees
|
|
1245
1299
|
Ceo.table_name.must_equal :employees
|
|
1246
1300
|
Staff.table_name.must_equal :employees
|
|
1301
|
+
Intern.table_name.must_equal :employees
|
|
1247
1302
|
end
|
|
1248
1303
|
|
|
1249
1304
|
it "should delete the correct rows from all tables when deleting" do
|
|
1305
|
+
Employee.load(:id=>1).delete
|
|
1306
|
+
@db.sqls.must_equal ["DELETE FROM employees WHERE (id = 1)"]
|
|
1307
|
+
|
|
1308
|
+
Intern.load(:id=>1).delete
|
|
1309
|
+
@db.sqls.must_equal ["DELETE FROM employees WHERE (id = 1)"]
|
|
1310
|
+
|
|
1250
1311
|
Ceo.load(:id=>1).delete
|
|
1251
1312
|
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
|
1252
1313
|
end
|
|
1253
1314
|
|
|
1254
1315
|
it "should not allow deletion of frozen object" do
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1316
|
+
[Ceo, Executive, Employee, Manager, Intern].each do |c|
|
|
1317
|
+
o = c.load(:id=>1)
|
|
1318
|
+
o.freeze
|
|
1319
|
+
proc{o.delete}.must_raise(Sequel::Error)
|
|
1320
|
+
@db.sqls.must_equal []
|
|
1321
|
+
end
|
|
1259
1322
|
end
|
|
1260
1323
|
|
|
1324
|
+
it "should insert the correct rows into all tables when inserting into parent class" do
|
|
1325
|
+
Employee.create(:name=>'E')
|
|
1326
|
+
sqls = @db.sqls
|
|
1327
|
+
sqls.length.must_equal 1
|
|
1328
|
+
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Employee)', '(E|Employee)'\)/)
|
|
1329
|
+
end
|
|
1330
|
+
|
|
1331
|
+
it "should insert the correct rows into all tables when inserting into subclass without separate table" do
|
|
1332
|
+
Intern.create(:name=>'E')
|
|
1333
|
+
sqls = @db.sqls
|
|
1334
|
+
sqls.length.must_equal 1
|
|
1335
|
+
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Intern)', '(E|Intern)'\)/)
|
|
1336
|
+
end
|
|
1337
|
+
|
|
1261
1338
|
it "should insert the correct rows into all tables when inserting" do
|
|
1262
1339
|
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
1263
1340
|
sqls = @db.sqls
|
|
@@ -1296,6 +1373,16 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
|
1296
1373
|
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([23], [23]\)/)
|
|
1297
1374
|
end
|
|
1298
1375
|
|
|
1376
|
+
it "should update the correct rows in all tables when updating parent class" do
|
|
1377
|
+
Employee.load(:id=>2).update(:name=>'E')
|
|
1378
|
+
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)"]
|
|
1379
|
+
end
|
|
1380
|
+
|
|
1381
|
+
it "should update the correct rows in all tables when updating subclass without separate table" do
|
|
1382
|
+
Intern.load(:id=>2).update(:name=>'E')
|
|
1383
|
+
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)"]
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1299
1386
|
it "should update the correct rows in all tables when updating" do
|
|
1300
1387
|
Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
1301
1388
|
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)", "UPDATE executives SET num_managers = 3 WHERE (id = 2)"]
|
|
@@ -39,6 +39,17 @@ describe "column_conflicts plugin" do
|
|
|
39
39
|
@o.get_column_value(:model).must_equal 2
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
it "should not erase existing column conflicts when loading the plugin" do
|
|
43
|
+
@c.send(:define_method, :foo){raise}
|
|
44
|
+
@c.send(:define_method, :model=){raise}
|
|
45
|
+
@c.get_column_conflict!(:foo)
|
|
46
|
+
@c.set_column_conflict!(:model)
|
|
47
|
+
@c.plugin :column_conflicts
|
|
48
|
+
@o.get_column_value(:foo).must_equal 4
|
|
49
|
+
@o.set_column_value(:model=, 2).must_equal 2
|
|
50
|
+
@o.get_column_value(:model).must_equal 2
|
|
51
|
+
end
|
|
52
|
+
|
|
42
53
|
it "should work correctly in subclasses" do
|
|
43
54
|
@o = Class.new(@c).load(:model=>1, :use_transactions=>2)
|
|
44
55
|
@o.get_column_value(:model).must_equal 1
|
|
@@ -114,6 +114,7 @@ describe "Sequel::Plugins::ColumnSelect" do
|
|
|
114
114
|
def @db.supports_schema_parsing?() true end
|
|
115
115
|
def @db.schema_parse_table(t, *) [] end
|
|
116
116
|
@db.extend_datasets{def columns; raise Sequel::DatabaseError; end}
|
|
117
|
+
@Album.require_valid_table = false
|
|
117
118
|
@Album.plugin :column_select
|
|
118
119
|
@Album.dataset.sql.must_equal 'SELECT * FROM albums'
|
|
119
120
|
end
|
|
@@ -44,6 +44,19 @@ describe "Composition plugin" do
|
|
|
44
44
|
o.valid?.must_equal true
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
it "should have decomposer work with column_conflicts plugin" do
|
|
48
|
+
@c.plugin :column_conflicts
|
|
49
|
+
@c.set_column_conflict! :year
|
|
50
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
|
51
|
+
o = @c.new
|
|
52
|
+
def o.validate
|
|
53
|
+
[:year, :month, :day].each{|c| errors.add(c, "not present") unless send(c)}
|
|
54
|
+
end
|
|
55
|
+
o.valid?.must_equal false
|
|
56
|
+
o.date = Date.new(1, 2, 3)
|
|
57
|
+
o.valid?.must_equal true
|
|
58
|
+
end
|
|
59
|
+
|
|
47
60
|
it "should set column values even when not validating" do
|
|
48
61
|
@c.composition :date, :mapping=>[:year, :month, :day]
|
|
49
62
|
@c.load({}).set(:date=>Date.new(4, 8, 12)).save(:validate=>false)
|
|
@@ -104,7 +104,7 @@ connection_validator_specs = shared_description do
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it "should handle case where determining validity requires a connection" do
|
|
107
|
-
@db.
|
|
107
|
+
def @db.valid_connection?(c) synchronize{}; true end
|
|
108
108
|
@db.pool.connection_validation_timeout = -1
|
|
109
109
|
c1 = @db.synchronize{|c| c}
|
|
110
110
|
@db.synchronize{|c| c}.must_be_same_as(c1)
|
|
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "Sequel::Plugins::DatasetAssociations" do
|
|
4
4
|
before do
|
|
5
|
-
@db = Sequel.mock
|
|
5
|
+
@db = Sequel.mock(:host=>'postgres')
|
|
6
6
|
@db.extend_datasets do
|
|
7
7
|
def supports_window_functions?; true; end
|
|
8
8
|
def supports_distinct_on?; true; end
|
|
@@ -13,14 +13,17 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
13
13
|
@Artist = Class.new(@Base)
|
|
14
14
|
@Album = Class.new(@Base)
|
|
15
15
|
@Tag = Class.new(@Base)
|
|
16
|
+
@Track = Class.new(@Base)
|
|
16
17
|
|
|
17
|
-
@Artist.
|
|
18
|
-
@Album.
|
|
19
|
-
@Tag.
|
|
18
|
+
def @Artist.name; 'Artist' end
|
|
19
|
+
def @Album.name; 'Album' end
|
|
20
|
+
def @Tag.name; 'Tag' end
|
|
21
|
+
def @Track.name; 'Track' end
|
|
20
22
|
|
|
21
23
|
@Artist.dataset = @db[:artists]
|
|
22
24
|
@Album.dataset = @db[:albums]
|
|
23
25
|
@Tag.dataset = @db[:tags]
|
|
26
|
+
@Track.dataset = @db[:tracks]
|
|
24
27
|
|
|
25
28
|
@Artist.columns :id, :name
|
|
26
29
|
@Album.columns :id, :name, :artist_id
|
|
@@ -28,6 +31,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
28
31
|
|
|
29
32
|
@Album.plugin :many_through_many
|
|
30
33
|
@Artist.plugin :many_through_many
|
|
34
|
+
@Track.plugin :many_through_many
|
|
31
35
|
@Artist.plugin :pg_array_associations
|
|
32
36
|
@Tag.plugin :pg_array_associations
|
|
33
37
|
@Artist.one_to_many :albums, :class=>@Album
|
|
@@ -41,6 +45,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
41
45
|
@Tag.many_to_pg_array :artists, :class=>@Artist
|
|
42
46
|
@Artist.many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
|
43
47
|
@Artist.one_through_many :otag, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
|
48
|
+
@Track.many_through_many :artist_tracks, [[:albums, :id, :artist_id], [:albums, :artist_id, :id]], :class=>@Track, :left_primary_key=>:album_id, :right_primary_key=>:album_id
|
|
44
49
|
end
|
|
45
50
|
|
|
46
51
|
it "should work for many_to_one associations" do
|
|
@@ -85,6 +90,13 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
85
90
|
ds.sql.must_equal "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id) WHERE (albums.artist_id IN (SELECT artists.id FROM artists))))"
|
|
86
91
|
end
|
|
87
92
|
|
|
93
|
+
it "should work for self referential many_through_many associations" do
|
|
94
|
+
ds = @Track.artist_tracks
|
|
95
|
+
ds.must_be_kind_of(Sequel::Dataset)
|
|
96
|
+
ds.model.must_equal @Track
|
|
97
|
+
ds.sql.must_equal "SELECT tracks.* FROM tracks WHERE (tracks.album_id IN (SELECT albums_0.id FROM tracks INNER JOIN albums ON (albums.id = tracks.album_id) INNER JOIN albums AS albums_0 ON (albums_0.artist_id = albums.artist_id) INNER JOIN tracks AS tracks_0 ON (tracks_0.album_id = albums_0.id) WHERE (albums.id IN (SELECT tracks.album_id FROM tracks))))"
|
|
98
|
+
end
|
|
99
|
+
|
|
88
100
|
it "should work for many_through_many associations with a single join table" do
|
|
89
101
|
ds = @Album.mthm_tags
|
|
90
102
|
ds.must_be_kind_of(Sequel::Dataset)
|
|
@@ -142,7 +154,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
|
142
154
|
ds = @Tag.artists
|
|
143
155
|
ds.must_be_kind_of(Sequel::Dataset)
|
|
144
156
|
ds.model.must_equal @Artist
|
|
145
|
-
ds.sql.must_equal "SELECT * FROM artists WHERE coalesce((tag_ids && (SELECT array_agg(tags.id) FROM tags)),
|
|
157
|
+
ds.sql.must_equal "SELECT * FROM artists WHERE coalesce((tag_ids && (SELECT array_agg(tags.id) FROM tags)), false)"
|
|
146
158
|
end
|
|
147
159
|
|
|
148
160
|
it "should have an associated method that takes an association symbol" do
|
|
@@ -261,9 +273,9 @@ describe "Sequel::Plugins::DatasetAssociations with composite keys" do
|
|
|
261
273
|
@Album = Class.new(@Base)
|
|
262
274
|
@Tag = Class.new(@Base)
|
|
263
275
|
|
|
264
|
-
@Artist.
|
|
265
|
-
@Album.
|
|
266
|
-
@Tag.
|
|
276
|
+
def @Artist.name; 'Artist' end
|
|
277
|
+
def @Album.name; 'Album' end
|
|
278
|
+
def @Tag.name; 'Tag' end
|
|
267
279
|
|
|
268
280
|
@Artist.dataset = @db[:artists]
|
|
269
281
|
@Album.dataset = @db[:albums]
|
|
@@ -9,7 +9,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
|
9
9
|
@c.instance_variable_set(:@db_schema, {:a=>{}})
|
|
10
10
|
@c.plugin :defaults_setter
|
|
11
11
|
@c.columns :a
|
|
12
|
-
@pr = proc{|x|
|
|
12
|
+
@pr = proc{|x| meta_def(db, :schema){|*| [[:id, {:primary_key=>true}], [:a, {:ruby_default => x, :primary_key=>false}]]}; c.dataset = c.dataset; c}
|
|
13
13
|
end
|
|
14
14
|
after do
|
|
15
15
|
Sequel.datetime_class = Time
|
|
@@ -72,6 +72,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
|
72
72
|
|
|
73
73
|
it "should contain the default values in default_values" do
|
|
74
74
|
@pr.call(2).default_values.must_equal(:a=>2)
|
|
75
|
+
@c.default_values.clear
|
|
75
76
|
@pr.call(nil).default_values.must_equal({})
|
|
76
77
|
end
|
|
77
78
|
|
|
@@ -93,6 +94,19 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
|
93
94
|
@c.new.a.must_be_nil
|
|
94
95
|
end
|
|
95
96
|
|
|
97
|
+
it "should work in subclasses" do
|
|
98
|
+
@pr.call(2)
|
|
99
|
+
@c.default_values[:a] = proc{1}
|
|
100
|
+
c = Class.new(@c)
|
|
101
|
+
|
|
102
|
+
@c.new.a.must_equal 1
|
|
103
|
+
c.new.a.must_equal 1
|
|
104
|
+
|
|
105
|
+
c.default_values[:a] = proc{2}
|
|
106
|
+
@c.new.a.must_equal 1
|
|
107
|
+
c.new.a.must_equal 2
|
|
108
|
+
end
|
|
109
|
+
|
|
96
110
|
it "should work correctly on a model without a dataset" do
|
|
97
111
|
@pr.call(2)
|
|
98
112
|
c = Class.new(Sequel::Model(@db[:bar]))
|
|
@@ -2,7 +2,9 @@ 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
|
-
|
|
5
|
+
deprecated do
|
|
6
|
+
@ds = Sequel.mock[:t].extension(:filter_having)
|
|
7
|
+
end
|
|
6
8
|
@dsh = @ds.having(:a)
|
|
7
9
|
end
|
|
8
10
|
|
|
@@ -14,11 +16,11 @@ describe "filter_having extension" do
|
|
|
14
16
|
@ds.filter(:b).sql.must_equal 'SELECT * FROM t WHERE b'
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
deprecated "should make and operate on HAVING clause if dataset has a HAVING clause" do
|
|
18
20
|
@dsh.and(:b).sql.must_equal 'SELECT * FROM t HAVING (a AND b)'
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
deprecated "should make and operate on WHERE clause if dataset does not have a HAVING clause" do
|
|
22
24
|
@ds.where(:a).and(:b).sql.must_equal 'SELECT * FROM t WHERE (a AND b)'
|
|
23
25
|
end
|
|
24
26
|
|
|
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "hash_aliases extension" do
|
|
4
4
|
before do
|
|
5
|
-
|
|
5
|
+
deprecated do
|
|
6
|
+
@ds = Sequel.mock.dataset.extension(:hash_aliases)
|
|
7
|
+
end
|
|
6
8
|
end
|
|
7
9
|
|
|
8
10
|
it "should make from treat hash arguments as alias specifiers" do
|
|
@@ -9,13 +9,15 @@ describe "Sequel::Dataset::ImplicitSubquery" do
|
|
|
9
9
|
ods = db[:c]
|
|
10
10
|
ods.columns(:id, :b)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
deprecated do
|
|
13
|
+
ds.and(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE c"
|
|
14
|
+
ds.exclude_where(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE NOT c"
|
|
15
|
+
end
|
|
13
16
|
ds.cross_join(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 CROSS JOIN c"
|
|
14
17
|
ds.distinct.sql.must_equal "SELECT DISTINCT * FROM (SELECT * FROM table) AS t1"
|
|
15
18
|
ds.except(ods).sql.must_equal "SELECT * FROM (SELECT * FROM (SELECT * FROM table) AS t1 EXCEPT SELECT * FROM c) AS t1"
|
|
16
19
|
ds.exclude(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE NOT c"
|
|
17
20
|
ds.exclude_having(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 HAVING NOT c"
|
|
18
|
-
ds.exclude_where(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE NOT c"
|
|
19
21
|
ds.filter(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 WHERE c"
|
|
20
22
|
ds.for_update.sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 FOR UPDATE"
|
|
21
23
|
ds.full_join(:c).sql.must_equal "SELECT * FROM (SELECT * FROM table) AS t1 FULL JOIN c"
|
|
@@ -65,6 +65,12 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
65
65
|
Album.from_json(@album.to_json(:include=>:artist), :associations=>:artist).artist.must_equal @artist
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
it "should have #to_json support blocks for transformations" do
|
|
69
|
+
values = {}
|
|
70
|
+
@artist.values.each{|k,v| values[k.to_s] = v}
|
|
71
|
+
Sequel.parse_json(@artist.to_json{|h| {'data'=>h}}).must_equal({'data'=>values})
|
|
72
|
+
end
|
|
73
|
+
|
|
68
74
|
it "should raise an error if attempting to parse json when providing array to non-array association or vice-versa" do
|
|
69
75
|
proc{Artist.from_json('{"albums":{"id":1,"name":"RF","artist_id":2},"id":2,"name":"YJM"}', :associations=>:albums)}.must_raise(Sequel::Error)
|
|
70
76
|
proc{Album.from_json('{"artist":[{"id":2,"name":"YJM"}],"id":1,"name":"RF","artist_id":2}', :associations=>:artist)}.must_raise(Sequel::Error)
|
|
@@ -186,6 +192,18 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
186
192
|
Sequel.parse_json(ds.to_json).must_equal [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
|
|
187
193
|
end
|
|
188
194
|
|
|
195
|
+
it "should have class and dataset to_json method accept blocks for transformations" do
|
|
196
|
+
Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
197
|
+
Sequel.parse_json(Album.to_json{|h| {'data'=>h}}).must_equal('data'=>[@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}])
|
|
198
|
+
Sequel.parse_json(Album.dataset.to_json{|h| {'data'=>h}}).must_equal('data'=>[@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}])
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "should have class and dataset to_json method support :instance_block option for instance_transformations" do
|
|
202
|
+
Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
203
|
+
Sequel.parse_json(Album.to_json(:instance_block=>lambda{|h| {'data'=>h}})).must_equal [{'data'=>@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}}]
|
|
204
|
+
Sequel.parse_json(Album.dataset.to_json(:instance_block=>lambda{|h| {'data'=>h}})).must_equal [{'data'=>@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}}]
|
|
205
|
+
end
|
|
206
|
+
|
|
189
207
|
it "should have dataset to_json method respect :array option for the array to use" do
|
|
190
208
|
a = Album.new(:name=>'RF', :artist_id=>3)
|
|
191
209
|
Album.array_from_json(Album.to_json(:array=>[a])).must_equal [a]
|
|
@@ -5,13 +5,13 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
5
5
|
before do
|
|
6
6
|
@db = Sequel.mock
|
|
7
7
|
def @db.supports_schema_parsing?() true end
|
|
8
|
-
@db.
|
|
8
|
+
def @db.schema(*a) [[:id, {:type=>:integer}], [:name,{:type=>:string}]] end
|
|
9
9
|
class ::LazyAttributesModel < Sequel::Model(@db[:la])
|
|
10
10
|
plugin :lazy_attributes
|
|
11
11
|
set_columns([:id, :name])
|
|
12
|
-
|
|
12
|
+
def self.columns; [:id, :name] end
|
|
13
13
|
lazy_attributes :name
|
|
14
|
-
|
|
14
|
+
def self.columns; [:id] end
|
|
15
15
|
set_dataset dataset.with_fetch(proc do |sql|
|
|
16
16
|
if sql !~ /WHERE/
|
|
17
17
|
if sql =~ /name/
|
|
@@ -59,10 +59,10 @@ describe Sequel::Model, "many_through_many" do
|
|
|
59
59
|
DB.sqls.must_equal []
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
it "should handle a :
|
|
62
|
+
it "should handle a :predicate_key option to change the SQL used in the lookup" do
|
|
63
63
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
64
64
|
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
65
|
-
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :
|
|
65
|
+
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :predicate_key=>(Sequel[:albums_artists][:artist_id] / 3)
|
|
66
66
|
a = @c1.eager(:tags).all
|
|
67
67
|
a.must_equal [@c1.load(:id => 1)]
|
|
68
68
|
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, (albums_artists.artist_id / 3) AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id / 3) IN (1))"]
|
|
@@ -1231,10 +1231,10 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1231
1231
|
DB.sqls.must_equal []
|
|
1232
1232
|
end
|
|
1233
1233
|
|
|
1234
|
-
it "should handle a :
|
|
1234
|
+
it "should handle a :predicate_key option to change the SQL used in the lookup" do
|
|
1235
1235
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
1236
1236
|
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
1237
|
-
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :
|
|
1237
|
+
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :predicate_key=>(Sequel[:albums_artists][:artist_id] / 3)
|
|
1238
1238
|
a = @c1.eager(:tag).all
|
|
1239
1239
|
a.must_equal [@c1.load(:id => 1)]
|
|
1240
1240
|
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, (albums_artists.artist_id / 3) AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id / 3) IN (1))"]
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
|
3
3
|
describe "Sequel::Metaprogramming" do
|
|
4
|
+
before do
|
|
5
|
+
deprecated do
|
|
6
|
+
Sequel.extension :meta_def
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
after do
|
|
10
|
+
Sequel::Metaprogramming.send(:remove_method, :meta_def)
|
|
11
|
+
end
|
|
12
|
+
|
|
4
13
|
it "should add meta_def method to Database, Dataset, and Model classes and instances" do
|
|
5
14
|
Sequel::Database.meta_def(:foo){1}
|
|
6
15
|
Sequel::Database.foo.must_equal 1
|
|
@@ -429,13 +429,13 @@ describe "Sequel::IntegerMigrator" do
|
|
|
429
429
|
end
|
|
430
430
|
|
|
431
431
|
it "should use transactions by default if the database supports transactional ddl" do
|
|
432
|
-
@db.
|
|
432
|
+
def @db.supports_transactional_ddl?; true end
|
|
433
433
|
Sequel::Migrator.apply(@db, "spec/files/transaction_unspecified_migrations")
|
|
434
434
|
@db.sqls.must_equal ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
|
|
435
435
|
end
|
|
436
436
|
|
|
437
437
|
it "should respect transaction use on a per migration basis" do
|
|
438
|
-
@db.
|
|
438
|
+
def @db.supports_transactional_ddl?; true end
|
|
439
439
|
Sequel::Migrator.apply(@db, "spec/files/transaction_specified_migrations")
|
|
440
440
|
@db.sqls.must_equal ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
|
|
441
441
|
end
|
|
@@ -753,7 +753,7 @@ describe "Sequel::TimestampMigrator" do
|
|
|
753
753
|
end
|
|
754
754
|
|
|
755
755
|
it "should use transactions by default if database supports transactional ddl" do
|
|
756
|
-
@db.
|
|
756
|
+
def @db.supports_transactional_ddl?; true end
|
|
757
757
|
Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
|
|
758
758
|
@db.sqls.must_equal ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
|
|
759
759
|
end
|