sequel 4.46.0 → 4.49.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|