sequel 3.21.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +576 -0
- data/doc/opening_databases.rdoc +121 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +539 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +334 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +137 -16
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +77 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +168 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +227 -33
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/connection_validator_spec.rb +118 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +324 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +200 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +340 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +65 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +53 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "arbtirary servers" do
|
|
4
|
+
before do
|
|
5
|
+
@db = Sequel.mock(:servers=>{})
|
|
6
|
+
@db.extension :arbitrary_servers
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
specify "should allow arbitrary server options using a hash" do
|
|
10
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
11
|
+
c.opts[:host].should == 'host1'
|
|
12
|
+
c.opts[:database].should == 'db1'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
specify "should not cache connections to arbitrary servers" do
|
|
17
|
+
x = nil
|
|
18
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
19
|
+
x = c
|
|
20
|
+
end
|
|
21
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
|
22
|
+
c2.should_not equal(x)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
specify "should yield same connection correctly when nesting" do
|
|
27
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
28
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
|
29
|
+
c2.should equal(c)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
specify "should disconnect when connection is finished" do
|
|
35
|
+
x, x1 = nil, nil
|
|
36
|
+
@db.meta_def(:disconnect_connection){|c| x = c}
|
|
37
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
38
|
+
x1 = c
|
|
39
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
|
40
|
+
c2.should equal(c)
|
|
41
|
+
end
|
|
42
|
+
x.should equal(nil)
|
|
43
|
+
end
|
|
44
|
+
x.should equal(x1)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
specify "should yield different connection correctly when nesting" do
|
|
48
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
49
|
+
c.opts[:host].should == 'host1'
|
|
50
|
+
@db.synchronize(:host=>'host2', :database=>'db1') do |c2|
|
|
51
|
+
c2.opts[:host].should == 'host2'
|
|
52
|
+
c2.should_not equal(c)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
specify "should respect multithreaded access" do
|
|
58
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
|
59
|
+
Thread.new do
|
|
60
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
|
61
|
+
c2.should_not equal(c)
|
|
62
|
+
end
|
|
63
|
+
end.join
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
specify "should work correctly with server_block plugin" do
|
|
68
|
+
@db.extend Sequel::ServerBlock
|
|
69
|
+
@db.with_server(:host=>'host1', :database=>'db1') do
|
|
70
|
+
@db.synchronize do |c|
|
|
71
|
+
c.opts[:host].should == 'host1'
|
|
72
|
+
c.opts[:database].should == 'db1'
|
|
73
|
+
@db.synchronize do |c2|
|
|
74
|
+
c2.should equal(c)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
specify "should respect multithreaded access with server block plugin" do
|
|
82
|
+
@db.extend Sequel::ServerBlock
|
|
83
|
+
q, q1 = Queue.new, Queue.new
|
|
84
|
+
|
|
85
|
+
t = nil
|
|
86
|
+
@db[:t].all
|
|
87
|
+
@db.with_server(:host=>'a') do
|
|
88
|
+
@db[:t].all
|
|
89
|
+
t = Thread.new do
|
|
90
|
+
@db[:t].all
|
|
91
|
+
@db.with_server(:host=>'c') do
|
|
92
|
+
@db[:t].all
|
|
93
|
+
@db.with_server(:host=>'d'){@db[:t].all}
|
|
94
|
+
q.push nil
|
|
95
|
+
q1.pop
|
|
96
|
+
@db[:t].all
|
|
97
|
+
end
|
|
98
|
+
@db[:t].all
|
|
99
|
+
end
|
|
100
|
+
q.pop
|
|
101
|
+
@db.with_server(:host=>'b'){@db[:t].all}
|
|
102
|
+
@db[:t].all
|
|
103
|
+
end
|
|
104
|
+
@db[:t].all
|
|
105
|
+
q1.push nil
|
|
106
|
+
t.join
|
|
107
|
+
@db.sqls.should == ['SELECT * FROM t', 'SELECT * FROM t -- {:host=>"a"}', 'SELECT * FROM t', 'SELECT * FROM t -- {:host=>"c"}', 'SELECT * FROM t -- {:host=>"d"}',
|
|
108
|
+
'SELECT * FROM t -- {:host=>"b"}', 'SELECT * FROM t -- {:host=>"a"}', 'SELECT * FROM t', 'SELECT * FROM t -- {:host=>"c"}', 'SELECT * FROM t']
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -5,11 +5,7 @@ describe "AssociationAutoreloading plugin" do
|
|
|
5
5
|
@c = Class.new(Sequel::Model)
|
|
6
6
|
@c.plugin :association_autoreloading
|
|
7
7
|
@Artist = Class.new(@c).set_dataset(:artists)
|
|
8
|
-
|
|
9
|
-
def ds1.fetch_rows(s)
|
|
10
|
-
(MODEL_DB.sqls ||= []) << s
|
|
11
|
-
yield({:id=>2, :name=>'Ar'})
|
|
12
|
-
end
|
|
8
|
+
@Artist.dataset._fetch = {:id=>2, :name=>'Ar'}
|
|
13
9
|
@Album = Class.new(@c).set_dataset(:albums)
|
|
14
10
|
@Artist.columns :id, :name
|
|
15
11
|
@Album.columns :id, :name, :artist_id
|
|
@@ -22,18 +18,33 @@ describe "AssociationAutoreloading plugin" do
|
|
|
22
18
|
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
23
19
|
album.artist
|
|
24
20
|
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1']
|
|
25
|
-
MODEL_DB.reset
|
|
26
21
|
|
|
27
22
|
album.artist_id = 1
|
|
28
23
|
album.artist
|
|
29
24
|
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1']
|
|
30
25
|
end
|
|
31
26
|
|
|
27
|
+
specify "should handle multiple many_to_one association with the same foreign key" do
|
|
28
|
+
@Album.many_to_one :artist2, :key=>:artist_id, :class=>@Artist
|
|
29
|
+
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
30
|
+
album.artist
|
|
31
|
+
album.artist2
|
|
32
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1'] * 2
|
|
33
|
+
|
|
34
|
+
album.artist
|
|
35
|
+
album.artist2
|
|
36
|
+
MODEL_DB.sqls.should == []
|
|
37
|
+
|
|
38
|
+
album.artist_id = 1
|
|
39
|
+
album.artist
|
|
40
|
+
album.artist2
|
|
41
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1'] * 2
|
|
42
|
+
end
|
|
43
|
+
|
|
32
44
|
specify "should not reload when value has not changed" do
|
|
33
45
|
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
34
46
|
album.artist
|
|
35
47
|
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1']
|
|
36
|
-
MODEL_DB.reset
|
|
37
48
|
|
|
38
49
|
album.artist_id = 2
|
|
39
50
|
album.artist
|
|
@@ -54,7 +65,6 @@ describe "AssociationAutoreloading plugin" do
|
|
|
54
65
|
album.artist_id = 1
|
|
55
66
|
album.artist
|
|
56
67
|
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1']
|
|
57
|
-
MODEL_DB.reset
|
|
58
68
|
|
|
59
69
|
album.other_artist
|
|
60
70
|
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1']
|
|
@@ -69,7 +79,6 @@ describe "AssociationAutoreloading plugin" do
|
|
|
69
79
|
album.artist_id = 1
|
|
70
80
|
album.composite_artist
|
|
71
81
|
MODEL_DB.sqls.should == ["SELECT * FROM artists WHERE ((artists.id = 1) AND (artists.name = 'Al')) LIMIT 1"]
|
|
72
|
-
MODEL_DB.reset
|
|
73
82
|
|
|
74
83
|
album.name = 'Al2'
|
|
75
84
|
album.composite_artist
|
|
@@ -84,7 +93,6 @@ describe "AssociationAutoreloading plugin" do
|
|
|
84
93
|
album = salbum.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
85
94
|
album.artist
|
|
86
95
|
MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1']
|
|
87
|
-
MODEL_DB.reset
|
|
88
96
|
|
|
89
97
|
album.artist_id = 1
|
|
90
98
|
album.artist
|
|
@@ -6,17 +6,9 @@ describe "AssociationDependencies plugin" do
|
|
|
6
6
|
@c = Class.new(Sequel::Model)
|
|
7
7
|
@c.plugin :association_dependencies
|
|
8
8
|
@Artist = Class.new(@c).set_dataset(:artists)
|
|
9
|
-
|
|
10
|
-
def ds1.fetch_rows(s)
|
|
11
|
-
(MODEL_DB.sqls ||= []) << s
|
|
12
|
-
yield({:id=>2, :name=>'Ar'})
|
|
13
|
-
end
|
|
9
|
+
@Artist.dataset._fetch = {:id=>2, :name=>'Ar'}
|
|
14
10
|
@Album = Class.new(@c).set_dataset(:albums)
|
|
15
|
-
|
|
16
|
-
def ds1.fetch_rows(s)
|
|
17
|
-
(MODEL_DB.sqls ||= []) << s
|
|
18
|
-
yield({:id=>1, :name=>'Al', :artist_id=>2})
|
|
19
|
-
end
|
|
11
|
+
@Album.dataset._fetch = {:id=>1, :name=>'Al', :artist_id=>2}
|
|
20
12
|
@Artist.columns :id, :name
|
|
21
13
|
@Album.columns :id, :name, :artist_id
|
|
22
14
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
|
@@ -29,55 +21,55 @@ describe "AssociationDependencies plugin" do
|
|
|
29
21
|
specify "should allow destroying associated many_to_one associated object" do
|
|
30
22
|
@Album.add_association_dependencies :artist=>:destroy
|
|
31
23
|
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
|
|
32
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE
|
|
24
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
|
|
33
25
|
end
|
|
34
26
|
|
|
35
27
|
specify "should allow deleting associated many_to_one associated object" do
|
|
36
28
|
@Album.add_association_dependencies :artist=>:delete
|
|
37
29
|
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
|
|
38
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE
|
|
30
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE id = 1', 'DELETE FROM artists WHERE (artists.id = 2)']
|
|
39
31
|
end
|
|
40
32
|
|
|
41
33
|
specify "should allow destroying associated one_to_one associated object" do
|
|
42
34
|
@Artist.add_association_dependencies :first_album=>:destroy
|
|
43
35
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
44
|
-
MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE ((albums.artist_id = 2) AND (position = 1)) LIMIT 1', 'DELETE FROM albums WHERE
|
|
36
|
+
MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE ((albums.artist_id = 2) AND (position = 1)) LIMIT 1', 'DELETE FROM albums WHERE id = 1', 'DELETE FROM artists WHERE id = 2']
|
|
45
37
|
end
|
|
46
38
|
|
|
47
39
|
specify "should allow deleting associated one_to_one associated object" do
|
|
48
40
|
@Artist.add_association_dependencies :first_album=>:delete
|
|
49
41
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
50
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE ((albums.artist_id = 2) AND (position = 1))', 'DELETE FROM artists WHERE
|
|
42
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE ((albums.artist_id = 2) AND (position = 1))', 'DELETE FROM artists WHERE id = 2']
|
|
51
43
|
end
|
|
52
44
|
|
|
53
45
|
specify "should allow destroying associated one_to_many objects" do
|
|
54
46
|
@Artist.add_association_dependencies :albums=>:destroy
|
|
55
47
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
56
|
-
MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM albums WHERE
|
|
48
|
+
MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM albums WHERE id = 1', 'DELETE FROM artists WHERE id = 2']
|
|
57
49
|
end
|
|
58
50
|
|
|
59
51
|
specify "should allow deleting associated one_to_many objects" do
|
|
60
52
|
@Artist.add_association_dependencies :albums=>:delete
|
|
61
53
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
62
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM artists WHERE
|
|
54
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM artists WHERE id = 2']
|
|
63
55
|
end
|
|
64
56
|
|
|
65
57
|
specify "should allow nullifying associated one_to_one objects" do
|
|
66
58
|
@Artist.add_association_dependencies :first_album=>:nullify
|
|
67
59
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
68
|
-
MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = NULL WHERE ((artist_id = 2) AND (position = 1))', 'DELETE FROM artists WHERE
|
|
60
|
+
MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = NULL WHERE ((artist_id = 2) AND (position = 1))', 'DELETE FROM artists WHERE id = 2']
|
|
69
61
|
end
|
|
70
62
|
|
|
71
63
|
specify "should allow nullifying associated one_to_many objects" do
|
|
72
64
|
@Artist.add_association_dependencies :albums=>:nullify
|
|
73
65
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
74
|
-
MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = NULL WHERE (artist_id = 2)', 'DELETE FROM artists WHERE
|
|
66
|
+
MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = NULL WHERE (artist_id = 2)', 'DELETE FROM artists WHERE id = 2']
|
|
75
67
|
end
|
|
76
68
|
|
|
77
69
|
specify "should allow nullifying associated many_to_many associations" do
|
|
78
70
|
@Artist.add_association_dependencies :other_artists=>:nullify
|
|
79
71
|
@Artist.load(:id=>2, :name=>'Ar').destroy
|
|
80
|
-
MODEL_DB.sqls.should == ['DELETE FROM aoa WHERE (l = 2)', 'DELETE FROM artists WHERE
|
|
72
|
+
MODEL_DB.sqls.should == ['DELETE FROM aoa WHERE (l = 2)', 'DELETE FROM artists WHERE id = 2']
|
|
81
73
|
end
|
|
82
74
|
|
|
83
75
|
specify "should raise an error if attempting to nullify a many_to_one association" do
|
|
@@ -105,23 +97,21 @@ describe "AssociationDependencies plugin" do
|
|
|
105
97
|
specify "should allow specifying association dependencies in the plugin call" do
|
|
106
98
|
@Album.plugin :association_dependencies, :artist=>:destroy
|
|
107
99
|
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
|
|
108
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE
|
|
100
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
|
|
109
101
|
end
|
|
110
102
|
|
|
111
103
|
specify "should work with subclasses" do
|
|
112
104
|
c = Class.new(@Album)
|
|
113
105
|
c.add_association_dependencies :artist=>:destroy
|
|
114
106
|
c.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
|
|
115
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE
|
|
116
|
-
MODEL_DB.reset
|
|
107
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
|
|
117
108
|
|
|
118
109
|
@Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
|
|
119
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE
|
|
120
|
-
MODEL_DB.reset
|
|
110
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE id = 1']
|
|
121
111
|
|
|
122
112
|
@Album.add_association_dependencies :artist=>:destroy
|
|
123
113
|
c2 = Class.new(@Album)
|
|
124
114
|
c2.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
|
|
125
|
-
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE
|
|
115
|
+
MODEL_DB.sqls.should == ['DELETE FROM albums WHERE id = 1', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE id = 2']
|
|
126
116
|
end
|
|
127
117
|
end
|
|
@@ -2,42 +2,62 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "Sequel::Plugins::AssociationPks" do
|
|
4
4
|
before do
|
|
5
|
-
@db =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
@db = Sequel.mock(:fetch=>proc do |sql|
|
|
6
|
+
case sql
|
|
7
|
+
when "SELECT id FROM albums WHERE (albums.artist_id = 1)"
|
|
8
|
+
[{:id=>1}, {:id=>2}, {:id=>3}]
|
|
9
|
+
when /SELECT tag_id FROM albums_tags WHERE \(album_id = (\d)\)/
|
|
10
|
+
a = []
|
|
11
|
+
a << {:tag_id=>1} if $1 == '1'
|
|
12
|
+
a << {:tag_id=>2} if $1 != '3'
|
|
13
|
+
a << {:tag_id=>3} if $1 == '2'
|
|
14
|
+
a
|
|
15
|
+
when "SELECT first, last FROM vocalists WHERE (vocalists.album_id = 1)"
|
|
16
|
+
[{:first=>"F1", :last=>"L1"}, {:first=>"F2", :last=>"L2"}]
|
|
17
|
+
when /SELECT first, last FROM albums_vocalists WHERE \(album_id = (\d)\)/
|
|
18
|
+
a = []
|
|
19
|
+
a << {:first=>"F1", :last=>"L1"} if $1 == '1'
|
|
20
|
+
a << {:first=>"F2", :last=>"L2"} if $1 != '3'
|
|
21
|
+
a << {:first=>"F3", :last=>"L3"} if $1 == '2'
|
|
22
|
+
a
|
|
23
|
+
when "SELECT id FROM instruments WHERE ((instruments.first = 'F1') AND (instruments.last = 'L1'))"
|
|
24
|
+
[{:id=>1}, {:id=>2}]
|
|
25
|
+
when /SELECT instrument_id FROM vocalists_instruments WHERE \(\((?:first|last) = '?[FL1](\d)/
|
|
26
|
+
a = []
|
|
27
|
+
a << {:instrument_id=>1} if $1 == "1"
|
|
28
|
+
a << {:instrument_id=>2} if $1 != "3"
|
|
29
|
+
a << {:instrument_id=>3} if $1 == "2"
|
|
30
|
+
a
|
|
31
|
+
when "SELECT year, week FROM hits WHERE ((hits.first = 'F1') AND (hits.last = 'L1'))"
|
|
32
|
+
[{:year=>1997, :week=>1}, {:year=>1997, :week=>2}]
|
|
33
|
+
when /SELECT year, week FROM vocalists_hits WHERE \(\((?:first|last) = '?[FL1](\d)/
|
|
34
|
+
a = []
|
|
35
|
+
a << {:year=>1997, :week=>1} if $1 == "1"
|
|
36
|
+
a << {:year=>1997, :week=>2} if $1 != "3"
|
|
37
|
+
a << {:year=>1997, :week=>3} if $1 == "2"
|
|
38
|
+
a
|
|
18
39
|
end
|
|
19
|
-
end
|
|
20
|
-
@db.meta_def(:dataset) do |*opts|
|
|
21
|
-
ds = super(*opts)
|
|
22
|
-
ds.extend mod
|
|
23
|
-
ds
|
|
24
|
-
end
|
|
25
|
-
def @db.transaction(opts)
|
|
26
|
-
execute('BEGIN')
|
|
27
|
-
yield
|
|
28
|
-
execute('COMMIT')
|
|
29
|
-
end
|
|
40
|
+
end)
|
|
30
41
|
@Artist = Class.new(Sequel::Model(@db[:artists]))
|
|
31
42
|
@Artist.columns :id
|
|
32
|
-
@Album= Class.new(Sequel::Model(@db[:albums]))
|
|
43
|
+
@Album = Class.new(Sequel::Model(@db[:albums]))
|
|
33
44
|
@Album.columns :id, :artist_id
|
|
34
45
|
@Tag = Class.new(Sequel::Model(@db[:tags]))
|
|
35
46
|
@Tag.columns :id
|
|
47
|
+
@Vocalist = Class.new(Sequel::Model(@db[:vocalists]))
|
|
48
|
+
@Vocalist.columns :first, :last, :album_id
|
|
49
|
+
@Vocalist.set_primary_key [:first, :last]
|
|
50
|
+
@Instrument = Class.new(Sequel::Model(@db[:instruments]))
|
|
51
|
+
@Instrument.columns :id, :first, :last
|
|
52
|
+
@Hit = Class.new(Sequel::Model(@db[:hits]))
|
|
53
|
+
@Hit.columns :year, :week, :first, :last
|
|
54
|
+
@Hit.set_primary_key [:year, :week]
|
|
36
55
|
@Artist.plugin :association_pks
|
|
37
56
|
@Album.plugin :association_pks
|
|
57
|
+
@Vocalist.plugin :association_pks
|
|
38
58
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
|
39
59
|
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id
|
|
40
|
-
@db.
|
|
60
|
+
@db.sqls
|
|
41
61
|
end
|
|
42
62
|
|
|
43
63
|
specify "should return correct associated pks for one_to_many associations" do
|
|
@@ -57,10 +77,117 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
57
77
|
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN (1, 2)))"]
|
|
58
78
|
end
|
|
59
79
|
|
|
80
|
+
specify "should use associated class's primary key for a one_to_many association" do
|
|
81
|
+
@Album.set_primary_key :foo
|
|
82
|
+
@Artist.load(:id=>1).album_pks = [1, 2]
|
|
83
|
+
@db.sqls.should == ["UPDATE albums SET artist_id = 1 WHERE (foo IN (1, 2))",
|
|
84
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (foo NOT IN (1, 2)))"]
|
|
85
|
+
end
|
|
86
|
+
|
|
60
87
|
specify "should set associated pks correctly for a many_to_many association" do
|
|
61
88
|
@Album.load(:id=>2).tag_pks = [1, 3]
|
|
62
|
-
@db.sqls
|
|
63
|
-
|
|
89
|
+
sqls = @db.sqls
|
|
90
|
+
sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 3)))"
|
|
91
|
+
sqls[1].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
|
|
92
|
+
sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
|
|
93
|
+
sqls.length.should == 3
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
specify "should return correct right-side associated cpks for one_to_many associations" do
|
|
97
|
+
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id
|
|
98
|
+
@Album.load(:id=>1).vocalist_pks.should == [["F1", "L1"], ["F2", "L2"]]
|
|
99
|
+
@Album.load(:id=>2).vocalist_pks.should == []
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
specify "should return correct right-side associated cpks for many_to_many associations" do
|
|
103
|
+
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last]
|
|
104
|
+
@Album.load(:id=>1).vocalist_pks.should == [["F1", "L1"], ["F2", "L2"]]
|
|
105
|
+
@Album.load(:id=>2).vocalist_pks.should == [["F2", "L2"], ["F3", "L3"]]
|
|
106
|
+
@Album.load(:id=>3).vocalist_pks.should == []
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
specify "should set associated right-side cpks correctly for a one_to_many association" do
|
|
110
|
+
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id
|
|
111
|
+
@Album.load(:id=>1).vocalist_pks = [["F1", "L1"], ["F2", "L2"]]
|
|
112
|
+
@db.sqls.should == ["UPDATE vocalists SET album_id = 1 WHERE ((first, last) IN (('F1', 'L1'), ('F2', 'L2')))",
|
|
113
|
+
"UPDATE vocalists SET album_id = NULL WHERE ((vocalists.album_id = 1) AND ((first, last) NOT IN (('F1', 'L1'), ('F2', 'L2'))))"]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
specify "should set associated right-side cpks correctly for a many_to_many association" do
|
|
117
|
+
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last]
|
|
118
|
+
@Album.load(:id=>2).vocalist_pks = [["F1", "L1"], ["F2", "L2"]]
|
|
119
|
+
sqls = @db.sqls
|
|
120
|
+
sqls[0].should == "DELETE FROM albums_vocalists WHERE ((album_id = 2) AND ((first, last) NOT IN (('F1', 'L1'), ('F2', 'L2'))))"
|
|
121
|
+
sqls[1].should == 'SELECT first, last FROM albums_vocalists WHERE (album_id = 2)'
|
|
122
|
+
match = sqls[2].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
|
|
123
|
+
Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F1'", "last"=>"'L1'", "album_id"=>"2"}
|
|
124
|
+
sqls.length.should == 3
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
specify "should return correct associated pks for left-side cpks for one_to_many associations" do
|
|
128
|
+
@Vocalist.one_to_many :instruments, :class=>@Instrument, :key=>[:first, :last]
|
|
129
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').instrument_pks.should == [1, 2]
|
|
130
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').instrument_pks.should == []
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
specify "should return correct associated pks for left-side cpks for many_to_many associations" do
|
|
134
|
+
@Vocalist.many_to_many :instruments, :class=>@Instrument, :join_table=>:vocalists_instruments, :left_key=>[:first, :last]
|
|
135
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').instrument_pks.should == [1, 2]
|
|
136
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').instrument_pks.should == [2, 3]
|
|
137
|
+
@Vocalist.load(:first=>'F3', :last=>'L3').instrument_pks.should == []
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
specify "should set associated pks correctly for left-side cpks for a one_to_many association" do
|
|
141
|
+
@Vocalist.one_to_many :instruments, :class=>@Instrument, :key=>[:first, :last]
|
|
142
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').instrument_pks = [1, 2]
|
|
143
|
+
sqls = @db.sqls
|
|
144
|
+
sqls[0].should =~ /UPDATE instruments SET (first = 'F1', last = 'L1'|last = 'L1', first = 'F1') WHERE \(id IN \(1, 2\)\)/
|
|
145
|
+
sqls[1].should =~ /UPDATE instruments SET (first = NULL, last = NULL|last = NULL, first = NULL) WHERE \(\(instruments.first = 'F1'\) AND \(instruments.last = 'L1'\) AND \(id NOT IN \(1, 2\)\)\)/
|
|
146
|
+
sqls.length.should == 2
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
specify "should set associated pks correctly for left-side cpks for a many_to_many association" do
|
|
150
|
+
@Vocalist.many_to_many :instruments, :class=>@Instrument, :join_table=>:vocalists_instruments, :left_key=>[:first, :last]
|
|
151
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').instrument_pks = [1, 2]
|
|
152
|
+
sqls = @db.sqls
|
|
153
|
+
sqls[0].should == "DELETE FROM vocalists_instruments WHERE ((first = 'F2') AND (last = 'L2') AND (instrument_id NOT IN (1, 2)))"
|
|
154
|
+
sqls[1].should == "SELECT instrument_id FROM vocalists_instruments WHERE ((first = 'F2') AND (last = 'L2'))"
|
|
155
|
+
match = sqls[2].match(/INSERT INTO vocalists_instruments \((.*)\) VALUES \((.*)\)/)
|
|
156
|
+
Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F2'", "last"=>"'L2'", "instrument_id"=>"1"}
|
|
157
|
+
sqls.length.should == 3
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
specify "should return correct right-side associated cpks for left-side cpks for one_to_many associations" do
|
|
161
|
+
@Vocalist.one_to_many :hits, :class=>@Hit, :key=>[:first, :last]
|
|
162
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks.should == [[1997, 1], [1997, 2]]
|
|
163
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks.should == []
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
specify "should return correct right-side associated cpks for left-side cpks for many_to_many associations" do
|
|
167
|
+
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week]
|
|
168
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks.should == [[1997, 1], [1997, 2]]
|
|
169
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks.should == [[1997, 2], [1997, 3]]
|
|
170
|
+
@Vocalist.load(:first=>'F3', :last=>'L3').hit_pks.should == []
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
specify "should set associated right-side cpks correctly for left-side cpks for a one_to_many association" do
|
|
174
|
+
@Vocalist.one_to_many :hits, :class=>@Hit, :key=>[:first, :last], :order=>:week
|
|
175
|
+
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks = [[1997, 1], [1997, 2]]
|
|
176
|
+
sqls = @db.sqls
|
|
177
|
+
sqls[0].should =~ /UPDATE hits SET (first = 'F1', last = 'L1'|last = 'L1', first = 'F1') WHERE \(\(year, week\) IN \(\(1997, 1\), \(1997, 2\)\)\)/
|
|
178
|
+
sqls[1].should =~ /UPDATE hits SET (first = NULL, last = NULL|last = NULL, first = NULL) WHERE \(\(hits.first = 'F1'\) AND \(hits.last = 'L1'\) AND \(\(year, week\) NOT IN \(\(1997, 1\), \(1997, 2\)\)\)\)/
|
|
179
|
+
sqls.length.should == 2
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
specify "should set associated right-side cpks correctly for left-side cpks for a many_to_many association" do
|
|
183
|
+
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week]
|
|
184
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks = [[1997, 1], [1997, 2]]
|
|
185
|
+
sqls = @db.sqls
|
|
186
|
+
sqls[0].should == "DELETE FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2') AND ((year, week) NOT IN ((1997, 1), (1997, 2))))"
|
|
187
|
+
sqls[1].should == "SELECT year, week FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2'))"
|
|
188
|
+
match = sqls[2].match(/INSERT INTO vocalists_hits \((.*)\) VALUES \((.*)\)/)
|
|
189
|
+
Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F2'", "last"=>"'L2'", "year"=>"1997", "week"=>"1"}
|
|
190
|
+
sqls.length.should == 3
|
|
64
191
|
end
|
|
65
192
|
|
|
66
193
|
specify "should use transactions if the object is configured to use transactions" do
|
|
@@ -71,15 +198,82 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
71
198
|
"UPDATE albums SET artist_id = 1 WHERE (id IN (1, 2))",
|
|
72
199
|
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN (1, 2)))",
|
|
73
200
|
"COMMIT"]
|
|
74
|
-
@db.reset
|
|
75
201
|
|
|
76
202
|
album = @Album.load(:id=>2)
|
|
77
203
|
album.use_transactions = true
|
|
78
204
|
album.tag_pks = [1, 3]
|
|
79
|
-
@db.sqls
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
205
|
+
sqls = @db.sqls
|
|
206
|
+
sqls[0].should == "BEGIN"
|
|
207
|
+
sqls[1].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 3)))"
|
|
208
|
+
sqls[2].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
|
|
209
|
+
sqls[3].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
|
|
210
|
+
sqls[4].should == "COMMIT"
|
|
211
|
+
sqls.length.should == 5
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
specify "should automatically convert keys to numbers if the primary key is an integer for one_to_many associations" do
|
|
215
|
+
@Album.db_schema[:id][:type] = :integer
|
|
216
|
+
@Artist.load(:id=>1).album_pks = %w'1 2'
|
|
217
|
+
@db.sqls.should == ["UPDATE albums SET artist_id = 1 WHERE (id IN (1, 2))",
|
|
218
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN (1, 2)))"]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
specify "should not automatically convert keys if the primary key is not an integer for one_to_many associations" do
|
|
222
|
+
@Album.db_schema[:id][:type] = :string
|
|
223
|
+
@Artist.load(:id=>1).album_pks = %w'1 2'
|
|
224
|
+
@db.sqls.should == ["UPDATE albums SET artist_id = 1 WHERE (id IN ('1', '2'))",
|
|
225
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN ('1', '2')))"]
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
specify "should automatically convert keys to numbers if the primary key is an integer for many_to_many associations" do
|
|
229
|
+
@Tag.db_schema[:id][:type] = :integer
|
|
230
|
+
@Album.load(:id=>2).tag_pks = %w'1 3'
|
|
231
|
+
sqls = @db.sqls
|
|
232
|
+
sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 3)))"
|
|
233
|
+
sqls[1].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
|
|
234
|
+
sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
|
|
235
|
+
sqls.length.should == 3
|
|
83
236
|
end
|
|
84
237
|
|
|
238
|
+
specify "should not automatically convert keys to numbers if the primary key is an integer for many_to_many associations" do
|
|
239
|
+
@Tag.db_schema[:id][:type] = :string
|
|
240
|
+
@Album.load(:id=>2).tag_pks = %w'1 3'
|
|
241
|
+
sqls = @db.sqls
|
|
242
|
+
sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN ('1', '3')))"
|
|
243
|
+
sqls[1].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
|
|
244
|
+
sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '1'|'1', 2)\)/
|
|
245
|
+
sqls[3].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '3'|'3', 2)\)/
|
|
246
|
+
sqls.length.should == 4
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
specify "should automatically convert keys to numbers for appropriate integer primary key for composite key associations" do
|
|
250
|
+
@Hit.db_schema[:year][:type] = :integer
|
|
251
|
+
@Hit.db_schema[:week][:type] = :integer
|
|
252
|
+
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week]
|
|
253
|
+
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks = [['1997', '1'], ['1997', '2']]
|
|
254
|
+
sqls = @db.sqls
|
|
255
|
+
sqls[0].should == "DELETE FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2') AND ((year, week) NOT IN ((1997, 1), (1997, 2))))"
|
|
256
|
+
sqls[1].should == "SELECT year, week FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2'))"
|
|
257
|
+
match = sqls[2].match(/INSERT INTO vocalists_hits \((.*)\) VALUES \((.*)\)/)
|
|
258
|
+
Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F2'", "last"=>"'L2'", "year"=>"1997", "week"=>"1"}
|
|
259
|
+
sqls.length.should == 3
|
|
260
|
+
|
|
261
|
+
@Vocalist.db_schema[:first][:type] = :integer
|
|
262
|
+
@Vocalist.db_schema[:last][:type] = :integer
|
|
263
|
+
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id
|
|
264
|
+
@Album.load(:id=>1).vocalist_pks = [["11", "11"], ["12", "12"]]
|
|
265
|
+
@db.sqls.should == ["UPDATE vocalists SET album_id = 1 WHERE ((first, last) IN ((11, 11), (12, 12)))",
|
|
266
|
+
"UPDATE vocalists SET album_id = NULL WHERE ((vocalists.album_id = 1) AND ((first, last) NOT IN ((11, 11), (12, 12))))"]
|
|
267
|
+
|
|
268
|
+
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last]
|
|
269
|
+
@Album.load(:id=>2).vocalist_pks = [["11", "11"], ["12", "12"]]
|
|
270
|
+
sqls = @db.sqls
|
|
271
|
+
sqls[0].should == "DELETE FROM albums_vocalists WHERE ((album_id = 2) AND ((first, last) NOT IN ((11, 11), (12, 12))))"
|
|
272
|
+
sqls[1].should == 'SELECT first, last FROM albums_vocalists WHERE (album_id = 2)'
|
|
273
|
+
match = sqls[2].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
|
|
274
|
+
Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"11", "last"=>"11", "album_id"=>"2"}
|
|
275
|
+
match = sqls[3].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
|
|
276
|
+
Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"12", "last"=>"12", "album_id"=>"2"}
|
|
277
|
+
sqls.length.should == 4
|
|
278
|
+
end
|
|
85
279
|
end
|
|
@@ -31,13 +31,13 @@ describe "Sequel::Plugins::AssociationProxies" do
|
|
|
31
31
|
|
|
32
32
|
it "should reload the cached association if sent an array method and the reload flag was given" do
|
|
33
33
|
@t.select{|x| false}.should == []
|
|
34
|
-
Item.db.sqls.length == 1
|
|
34
|
+
Item.db.sqls.length.should == 1
|
|
35
35
|
@t.select{|x| false}.should == []
|
|
36
|
-
Item.db.sqls.length ==
|
|
36
|
+
Item.db.sqls.length.should == 0
|
|
37
37
|
@i.tags(true).select{|x| false}.should == []
|
|
38
|
-
Item.db.sqls.length ==
|
|
38
|
+
Item.db.sqls.length.should == 1
|
|
39
39
|
@t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
|
|
40
|
-
Item.db.sqls.length ==
|
|
40
|
+
Item.db.sqls.length.should == 0
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "should not return a proxy object for associations that do not return an array" do
|