sequel 3.21.0 → 3.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- 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 +547 -0
- data/doc/opening_databases.rdoc +114 -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/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/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- 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 +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -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 +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -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 +7 -24
- 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 +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- 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 +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- 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/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- 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 +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- 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 +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- 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/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 +537 -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 +313 -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 +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -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 +22 -4
- 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 +58 -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 +167 -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 +5 -3
- 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/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 +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- 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 +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -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 +66 -32
- 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/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 +320 -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 +194 -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 +323 -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 +23 -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 +13 -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 +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -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 +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- 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 +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -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 +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Sequel::Plugins::DatasetAssociations" do
|
|
4
|
+
before do
|
|
5
|
+
@db = Sequel::Database.new
|
|
6
|
+
@Base = Class.new(Sequel::Model)
|
|
7
|
+
@Base.plugin :dataset_associations
|
|
8
|
+
|
|
9
|
+
@Artist = Class.new(@Base)
|
|
10
|
+
@Album = Class.new(@Base)
|
|
11
|
+
@Tag = Class.new(@Base)
|
|
12
|
+
|
|
13
|
+
@Artist.meta_def(:name){'Artist'}
|
|
14
|
+
@Album.meta_def(:name){'Album'}
|
|
15
|
+
@Tag.meta_def(:name){'Tag'}
|
|
16
|
+
|
|
17
|
+
@Artist.dataset = @db[:artists]
|
|
18
|
+
@Album.dataset = @db[:albums]
|
|
19
|
+
@Tag.dataset = @db[:tags]
|
|
20
|
+
|
|
21
|
+
@Artist.columns :id, :name
|
|
22
|
+
@Album.columns :id, :name, :artist_id
|
|
23
|
+
@Tag.columns :id, :name
|
|
24
|
+
|
|
25
|
+
@Artist.plugin :many_through_many
|
|
26
|
+
@Artist.one_to_many :albums, :class=>@Album
|
|
27
|
+
@Artist.one_to_one :first_album, :class=>@Album
|
|
28
|
+
@Album.many_to_one :artist, :class=>@Artist
|
|
29
|
+
@Album.many_to_many :tags, :class=>@Tag
|
|
30
|
+
@Tag.many_to_many :albums, :class=>@Album
|
|
31
|
+
@Artist.many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should work for many_to_one associations" do
|
|
35
|
+
ds = @Album.artists
|
|
36
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
37
|
+
ds.model.should == @Artist
|
|
38
|
+
ds.sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums.artist_id FROM albums))"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should work for one_to_many associations" do
|
|
42
|
+
ds = @Artist.albums
|
|
43
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
44
|
+
ds.model.should == @Album
|
|
45
|
+
ds.sql.should == "SELECT * FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists))"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should work for one_to_one associations" do
|
|
49
|
+
ds = @Artist.first_albums
|
|
50
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
51
|
+
ds.model.should == @Album
|
|
52
|
+
ds.sql.should == "SELECT * FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists))"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should work for many_to_many associations" do
|
|
56
|
+
ds = @Album.tags
|
|
57
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
58
|
+
ds.model.should == @Tag
|
|
59
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM albums INNER JOIN albums_tags ON (albums_tags.album_id = albums.id)))"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should work for many_through_many associations" do
|
|
63
|
+
ds = @Artist.tags
|
|
64
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
65
|
+
ds.model.should == @Tag
|
|
66
|
+
ds.sql.should == "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)))"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should have an associated method that takes an association symbol" do
|
|
70
|
+
ds = @Album.associated(:artist)
|
|
71
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
72
|
+
ds.model.should == @Artist
|
|
73
|
+
ds.sql.should == "SELECT * FROM artists WHERE (artists.id IN (SELECT albums.artist_id FROM albums))"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should raise an Error if an invalid association is given to associated" do
|
|
77
|
+
proc{@Album.associated(:foo)}.should raise_error(Sequel::Error)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should raise an Error if an unrecognized association type is used" do
|
|
81
|
+
@Album.association_reflection(:artist)[:type] = :foo
|
|
82
|
+
proc{@Album.artists}.should raise_error(Sequel::Error)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should work correctly when chaining" do
|
|
86
|
+
ds = @Artist.albums.tags
|
|
87
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
88
|
+
ds.model.should == @Tag
|
|
89
|
+
ds.sql.should == "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM albums INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE (albums.artist_id IN (SELECT artists.id FROM artists))))"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should deal correctly with filters before the association method" do
|
|
93
|
+
@Artist.filter(:id=>1).albums.sql.should == "SELECT * FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists WHERE (id = 1)))"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should deal correctly with filters after the association method" do
|
|
97
|
+
@Artist.albums.filter(:id=>1).sql.should == "SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (id = 1))"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "should deal correctly with block on the association" do
|
|
101
|
+
@Artist.one_to_many :albums, :clone=>:albums do |ds| ds.filter(:id=>1..100) end
|
|
102
|
+
@Artist.albums.sql.should == "SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (id >= 1) AND (id <= 100))"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should deal correctly with :conditions option on the association" do
|
|
106
|
+
@Artist.one_to_many :albums, :clone=>:albums, :conditions=>{:id=>1..100}
|
|
107
|
+
@Artist.albums.sql.should == "SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (id >= 1) AND (id <= 100))"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should deal correctly with :distinct option on the association" do
|
|
111
|
+
@Artist.one_to_many :albums, :clone=>:albums, :distinct=>true
|
|
112
|
+
@Artist.albums.sql.should == "SELECT DISTINCT * FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists))"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should deal correctly with :eager option on the association" do
|
|
116
|
+
@Artist.one_to_many :albums, :clone=>:albums, :eager=>:tags
|
|
117
|
+
@Artist.albums.opts[:eager].should == {:tags=>nil}
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should deal correctly with :eager_block option on the association, ignoring the association block" do
|
|
121
|
+
@Artist.one_to_many :albums, :clone=>:albums, :eager_block=>proc{|ds| ds.filter(:id=>1..100)} do |ds| ds.filter(:id=>2..200) end
|
|
122
|
+
@Artist.albums.sql.should == "SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (id >= 1) AND (id <= 100))"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should deal correctly with :extend option on the association" do
|
|
126
|
+
@Artist.one_to_many :albums, :clone=>:albums, :extend=>Module.new{def foo(x) filter(:id=>x) end}
|
|
127
|
+
@Artist.albums.foo(1).sql.should == "SELECT * FROM albums WHERE ((albums.artist_id IN (SELECT artists.id FROM artists)) AND (id = 1))"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "should deal correctly with :order option on the association" do
|
|
131
|
+
@Artist.one_to_many :albums, :clone=>:albums, :order=>:name
|
|
132
|
+
@Artist.albums.sql.should == "SELECT * FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists)) ORDER BY name"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "should deal correctly with :select option on the association" do
|
|
136
|
+
@Artist.one_to_many :albums, :clone=>:albums, :select=>[:id, :name]
|
|
137
|
+
@Artist.albums.sql.should == "SELECT id, name FROM albums WHERE (albums.artist_id IN (SELECT artists.id FROM artists))"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "Sequel::Plugins::DatasetAssociations with composite keys" do
|
|
142
|
+
before do
|
|
143
|
+
@db = Sequel::Database.new
|
|
144
|
+
@Base = Class.new(Sequel::Model)
|
|
145
|
+
@Base.plugin :dataset_associations
|
|
146
|
+
|
|
147
|
+
@Artist = Class.new(@Base)
|
|
148
|
+
@Album = Class.new(@Base)
|
|
149
|
+
@Tag = Class.new(@Base)
|
|
150
|
+
|
|
151
|
+
@Artist.meta_def(:name){'Artist'}
|
|
152
|
+
@Album.meta_def(:name){'Album'}
|
|
153
|
+
@Tag.meta_def(:name){'Tag'}
|
|
154
|
+
|
|
155
|
+
@Artist.dataset = @db[:artists]
|
|
156
|
+
@Album.dataset = @db[:albums]
|
|
157
|
+
@Tag.dataset = @db[:tags]
|
|
158
|
+
|
|
159
|
+
@Artist.set_primary_key([:id1, :id2])
|
|
160
|
+
@Album.set_primary_key([:id1, :id2])
|
|
161
|
+
@Tag.set_primary_key([:id1, :id2])
|
|
162
|
+
|
|
163
|
+
@Artist.columns :id1, :id2, :name
|
|
164
|
+
@Album.columns :id1, :id2, :name, :artist_id1, :artist_id2
|
|
165
|
+
@Tag.columns :id1, :id2, :name
|
|
166
|
+
|
|
167
|
+
@Artist.plugin :many_through_many
|
|
168
|
+
@Artist.one_to_many :albums, :class=>@Album, :key=>[:artist_id1, :artist_id2]
|
|
169
|
+
@Artist.one_to_one :first_album, :class=>@Album, :key=>[:artist_id1, :artist_id2]
|
|
170
|
+
@Album.many_to_one :artist, :class=>@Artist, :key=>[:artist_id1, :artist_id2]
|
|
171
|
+
@Album.many_to_many :tags, :class=>@Tag, :left_key=>[:album_id1, :album_id2], :right_key=>[:tag_id1, :tag_id2]
|
|
172
|
+
@Tag.many_to_many :albums, :class=>@Album, :right_key=>[:album_id1, :album_id2], :left_key=>[:tag_id1, :tag_id2]
|
|
173
|
+
@Artist.many_through_many :tags, [[:albums, [:artist_id1, :artist_id2], [:id1, :id2]], [:albums_tags, [:album_id1, :album_id2], [:tag_id1, :tag_id2]]], :class=>@Tag
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "should work for many_to_one associations" do
|
|
177
|
+
@Album.artists.sql.should == "SELECT * FROM artists WHERE ((artists.id1, artists.id2) IN (SELECT albums.artist_id1, albums.artist_id2 FROM albums))"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "should work for one_to_many associations" do
|
|
181
|
+
@Artist.albums.sql.should == "SELECT * FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists))"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should work for one_to_one associations" do
|
|
185
|
+
@Artist.first_albums.sql.should == "SELECT * FROM albums WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists))"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should work for many_to_many associations" do
|
|
189
|
+
@Album.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM albums INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2))))"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "should work for many_through_many associations" do
|
|
193
|
+
@Artist.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM artists INNER JOIN albums ON ((albums.artist_id1 = artists.id1) AND (albums.artist_id2 = artists.id2)) INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2))))"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "should work correctly when chaining" do
|
|
197
|
+
@Artist.albums.tags.sql.should == "SELECT tags.* FROM tags WHERE ((tags.id1, tags.id2) IN (SELECT albums_tags.tag_id1, albums_tags.tag_id2 FROM albums INNER JOIN albums_tags ON ((albums_tags.album_id1 = albums.id1) AND (albums_tags.album_id2 = albums.id2)) WHERE ((albums.artist_id1, albums.artist_id2) IN (SELECT artists.id1, artists.id2 FROM artists))))"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Sequel::Plugins::DefaultsSetter" do
|
|
4
|
+
before do
|
|
5
|
+
@db = db = Sequel::Database.new
|
|
6
|
+
@c = c = Class.new(Sequel::Model(db[:foo]))
|
|
7
|
+
@c.instance_variable_set(:@db_schema, {:a=>{}})
|
|
8
|
+
@c.plugin :defaults_setter
|
|
9
|
+
@c.columns :a
|
|
10
|
+
@pr = proc{|x| db.meta_def(:schema){|*| [[:a, {:ruby_default => x}]]}; c.dataset = c.dataset; c}
|
|
11
|
+
end
|
|
12
|
+
after do
|
|
13
|
+
Sequel.datetime_class = Time
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should set default value upon initialization" do
|
|
17
|
+
@pr.call(2).new.values.should == {:a=>2}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should not mark the column as modified" do
|
|
21
|
+
@pr.call(2).new.changed_columns.should == []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should not set a default of nil" do
|
|
25
|
+
@pr.call(nil).new.values.should == {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should set a default of false" do
|
|
29
|
+
@pr.call(false).new.values.should == {:a=>false}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should handle Sequel::CURRENT_DATE default by using the current Date" do
|
|
33
|
+
@pr.call(Sequel::CURRENT_DATE).new.a.should == Date.today
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should handle Sequel::CURRENT_TIMESTAMP default by using the current Time" do
|
|
37
|
+
t = @pr.call(Sequel::CURRENT_TIMESTAMP).new.a
|
|
38
|
+
t.should be_a_kind_of(Time)
|
|
39
|
+
(t - Time.now).should < 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should handle Sequel::CURRENT_TIMESTAMP default by using the current DateTime if Sequel.datetime_class is DateTime" do
|
|
43
|
+
Sequel.datetime_class = DateTime
|
|
44
|
+
t = @pr.call(Sequel::CURRENT_TIMESTAMP).new.a
|
|
45
|
+
t.should be_a_kind_of(DateTime)
|
|
46
|
+
(t - DateTime.now).should < 1/86400.0
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should not override a given value" do
|
|
50
|
+
@pr.call(2)
|
|
51
|
+
@c.new('a'=>3).values.should == {:a=>3}
|
|
52
|
+
@c.new('a'=>nil).values.should == {:a=>nil}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should work correctly when subclassing" do
|
|
56
|
+
Class.new(@pr.call(2)).new.values.should == {:a=>2}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should contain the default values in default_values" do
|
|
60
|
+
@pr.call(2).default_values.should == {:a=>2}
|
|
61
|
+
@pr.call(nil).default_values.should == {}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should allow modifications of default values" do
|
|
65
|
+
@pr.call(2)
|
|
66
|
+
@c.default_values[:a] = 3
|
|
67
|
+
@c.new.values.should == {:a => 3}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should allow proc default values" do
|
|
71
|
+
@pr.call(2)
|
|
72
|
+
@c.default_values[:a] = proc{3}
|
|
73
|
+
@c.new.values.should == {:a => 3}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should have procs that set default values set them to nil" do
|
|
77
|
+
@pr.call(2)
|
|
78
|
+
@c.default_values[:a] = proc{nil}
|
|
79
|
+
@c.new.values.should == {:a => nil}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should work correctly on a model without a dataset" do
|
|
83
|
+
@pr.call(2)
|
|
84
|
+
c = Class.new(Sequel::Model(@db[:bar]))
|
|
85
|
+
c.plugin :defaults_setter
|
|
86
|
+
c.default_values.should == {:a=>2}
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Sequel::Plugins::Dirty" do
|
|
4
|
+
before do
|
|
5
|
+
@db = Sequel.mock(:fetch=>{:initial=>'i', :initial_changed=>'ic'}, :numrows=>1)
|
|
6
|
+
@c = Class.new(Sequel::Model(@db[:c]))
|
|
7
|
+
@c.plugin :dirty
|
|
8
|
+
@c.columns :initial, :initial_changed, :missing, :missing_changed
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
shared_examples_for "dirty plugin" do
|
|
12
|
+
it "initial_value should be the current value if value has not changed" do
|
|
13
|
+
@o.initial_value(:initial).should == 'i'
|
|
14
|
+
@o.initial_value(:missing).should == nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "initial_value should be the intial value if value has changed" do
|
|
18
|
+
@o.initial_value(:initial_changed).should == 'ic'
|
|
19
|
+
@o.initial_value(:missing_changed).should == nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "initial_value should handle case where initial value is reassigned later" do
|
|
23
|
+
@o.initial_changed = 'ic'
|
|
24
|
+
@o.initial_value(:initial_changed).should == 'ic'
|
|
25
|
+
@o.missing_changed = nil
|
|
26
|
+
@o.initial_value(:missing_changed).should == nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "changed_columns should handle case where initial value is reassigned later" do
|
|
30
|
+
@o.changed_columns.should == [:initial_changed, :missing_changed]
|
|
31
|
+
@o.initial_changed = 'ic'
|
|
32
|
+
@o.changed_columns.should == [:missing_changed]
|
|
33
|
+
@o.missing_changed = nil
|
|
34
|
+
@o.changed_columns.should == [:missing_changed]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "column_change should give initial and current values if there has been a change made" do
|
|
38
|
+
@o.column_change(:initial_changed).should == ['ic', 'ic2']
|
|
39
|
+
@o.column_change(:missing_changed).should == [nil, 'mc2']
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "column_change should be nil if no change has been made" do
|
|
43
|
+
@o.column_change(:initial).should == nil
|
|
44
|
+
@o.column_change(:missing).should == nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "column_changed? should return whether the column has changed" do
|
|
48
|
+
@o.column_changed?(:initial).should == false
|
|
49
|
+
@o.column_changed?(:initial_changed).should == true
|
|
50
|
+
@o.column_changed?(:missing).should == false
|
|
51
|
+
@o.column_changed?(:missing_changed).should == true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "column_changed? should handle case where initial value is reassigned later" do
|
|
55
|
+
@o.initial_changed = 'ic'
|
|
56
|
+
@o.column_changed?(:initial_changed).should == false
|
|
57
|
+
@o.missing_changed = nil
|
|
58
|
+
@o.column_changed?(:missing_changed).should == false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "changed_columns should handle case where initial value is reassigned later" do
|
|
62
|
+
@o.changed_columns.should == [:initial_changed, :missing_changed]
|
|
63
|
+
@o.initial_changed = 'ic'
|
|
64
|
+
@o.changed_columns.should == [:missing_changed]
|
|
65
|
+
@o.missing_changed = nil
|
|
66
|
+
@o.changed_columns.should == [:missing_changed]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "column_changes should give initial and current values" do
|
|
70
|
+
@o.column_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "reset_column should reset the column to its initial value" do
|
|
74
|
+
@o.reset_column(:initial)
|
|
75
|
+
@o.initial.should == 'i'
|
|
76
|
+
@o.reset_column(:initial_changed)
|
|
77
|
+
@o.initial_changed.should == 'ic'
|
|
78
|
+
@o.reset_column(:missing)
|
|
79
|
+
@o.missing.should == nil
|
|
80
|
+
@o.reset_column(:missing_changed)
|
|
81
|
+
@o.missing_changed.should == nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "reset_column should remove missing values from the values" do
|
|
85
|
+
@o.reset_column(:missing)
|
|
86
|
+
@o.values.has_key?(:missing).should == false
|
|
87
|
+
@o.reset_column(:missing_changed)
|
|
88
|
+
@o.values.has_key?(:missing_changed).should == false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "refresh should clear the cached initial values" do
|
|
92
|
+
@o.refresh
|
|
93
|
+
@o.column_changes.should == {}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "will_change_column should be used to signal in-place modification to column" do
|
|
97
|
+
@o.will_change_column(:initial)
|
|
98
|
+
@o.initial << 'b'
|
|
99
|
+
@o.column_change(:initial).should == ['i', 'ib']
|
|
100
|
+
@o.will_change_column(:initial_changed)
|
|
101
|
+
@o.initial_changed << 'b'
|
|
102
|
+
@o.column_change(:initial_changed).should == ['ic', 'ic2b']
|
|
103
|
+
@o.will_change_column(:missing)
|
|
104
|
+
@o.values[:missing] = 'b'
|
|
105
|
+
@o.column_change(:missing).should == [nil, 'b']
|
|
106
|
+
@o.will_change_column(:missing_changed)
|
|
107
|
+
@o.missing_changed << 'b'
|
|
108
|
+
@o.column_change(:missing_changed).should == [nil, 'mc2b']
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "will_change_column should different types of existing objects" do
|
|
112
|
+
[nil, true, false, Class.new{undef_method :clone}.new, Class.new{def clone; raise TypeError; end}.new].each do |v|
|
|
113
|
+
o = @c.new(:initial=>v)
|
|
114
|
+
o.will_change_column(:initial)
|
|
115
|
+
o.initial = 'a'
|
|
116
|
+
o.column_change(:initial).should == [v, 'a']
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "save should clear the cached initial values" do
|
|
121
|
+
@o.save
|
|
122
|
+
@o.column_changes.should == {}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "save_changes should clear the cached initial values" do
|
|
126
|
+
@o.save_changes
|
|
127
|
+
@o.column_changes.should == {}
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe "with new instance" do
|
|
132
|
+
before do
|
|
133
|
+
@o = @c.new(:initial=>'i', :initial_changed=>'ic')
|
|
134
|
+
@o.initial_changed = 'ic2'
|
|
135
|
+
@o.missing_changed = 'mc2'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it_should_behave_like "dirty plugin"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "with existing instance" do
|
|
142
|
+
before do
|
|
143
|
+
@o = @c[1]
|
|
144
|
+
@o.initial_changed = 'ic2'
|
|
145
|
+
@o.missing_changed = 'mc2'
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it_should_behave_like "dirty plugin"
|
|
149
|
+
|
|
150
|
+
it "previous_changes should be the previous changes after saving" do
|
|
151
|
+
@o.save
|
|
152
|
+
@o.previous_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Sequel::Plugins::EagerEach" do
|
|
4
|
+
before do
|
|
5
|
+
@c = Class.new(Sequel::Model(:items))
|
|
6
|
+
@c.columns :id, :parent_id
|
|
7
|
+
@c.plugin :eager_each
|
|
8
|
+
@c.one_to_many :children, :class=>@c, :key=>:parent_id
|
|
9
|
+
@c.db.sqls
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should make #each on an eager dataset do eager loading" do
|
|
13
|
+
a = []
|
|
14
|
+
ds = @c.eager(:children)
|
|
15
|
+
ds._fetch = [{:id=>1, :parent_id=>nil}, {:id=>2, :parent_id=>nil}]
|
|
16
|
+
@c.dataset._fetch = [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}, {:id=>5, :parent_id=>2}, {:id=>6, :parent_id=>2}]
|
|
17
|
+
ds.each{|c| a << c}
|
|
18
|
+
a.should == [@c.load(:id=>1, :parent_id=>nil), @c.load(:id=>2, :parent_id=>nil)]
|
|
19
|
+
a.map{|c| c.associations[:children]}.should == [[@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)], [@c.load(:id=>5, :parent_id=>2), @c.load(:id=>6, :parent_id=>2)]]
|
|
20
|
+
@c.db.sqls.should == ['SELECT * FROM items', 'SELECT * FROM items WHERE (items.parent_id IN (1, 2))']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should make #each on an eager_graph dataset do eager loading" do
|
|
24
|
+
a = []
|
|
25
|
+
ds = @c.eager_graph(:children)
|
|
26
|
+
ds._fetch = []
|
|
27
|
+
ds._fetch = [{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}, {:id=>1, :parent_id=>nil, :children_id=>4, :children_parent_id=>1}, {:id=>2, :parent_id=>nil, :children_id=>5, :children_parent_id=>2}, {:id=>2, :parent_id=>nil, :children_id=>6, :children_parent_id=>2}]
|
|
28
|
+
ds.each{|c| a << c}
|
|
29
|
+
a.should == [@c.load(:id=>1, :parent_id=>nil), @c.load(:id=>2, :parent_id=>nil)]
|
|
30
|
+
a.map{|c| c.associations[:children]}.should == [[@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)], [@c.load(:id=>5, :parent_id=>2), @c.load(:id=>6, :parent_id=>2)]]
|
|
31
|
+
@c.db.sqls.should == ['SELECT items.id, items.parent_id, children.id AS children_id, children.parent_id AS children_parent_id FROM items LEFT OUTER JOIN items AS children ON (children.parent_id = items.id)']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "eval_inspect extension" do
|
|
4
|
+
before do
|
|
5
|
+
@ds = Sequel.mock.dataset
|
|
6
|
+
@ds.meta_def(:supports_window_functions?){true}
|
|
7
|
+
@ds.meta_def(:literal_blob_append){|sql, s| sql << "X'#{s}'"}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
specify "should make eval(obj.inspect) == obj for all Sequel::SQL::Expression subclasses" do
|
|
11
|
+
[
|
|
12
|
+
# Objects with components where eval(inspect) == self
|
|
13
|
+
Sequel::SQL::AliasedExpression.new(:b, :a),
|
|
14
|
+
Sequel::SQL::CaseExpression.new({:b=>:a}, :c),
|
|
15
|
+
Sequel::SQL::CaseExpression.new({:b=>:a}, :c, :d),
|
|
16
|
+
Sequel::SQL::Cast.new(:a, :b),
|
|
17
|
+
Sequel::SQL::ColumnAll.new(:a),
|
|
18
|
+
Sequel::SQL::ComplexExpression.new(:'=', :b, :a),
|
|
19
|
+
Sequel::SQL::Constant.new(:a),
|
|
20
|
+
Sequel::CURRENT_DATE,
|
|
21
|
+
Sequel::CURRENT_TIMESTAMP,
|
|
22
|
+
Sequel::CURRENT_TIME,
|
|
23
|
+
Sequel::SQLTRUE,
|
|
24
|
+
Sequel::SQLFALSE,
|
|
25
|
+
Sequel::NULL,
|
|
26
|
+
Sequel::NOTNULL,
|
|
27
|
+
Sequel::SQL::Function.new(:a, :b, :c),
|
|
28
|
+
Sequel::SQL::Identifier.new(:a),
|
|
29
|
+
Sequel::SQL::JoinClause.new(:inner, :b, :c),
|
|
30
|
+
Sequel::SQL::JoinOnClause.new({:d=>:a}, :inner, :b, :c),
|
|
31
|
+
Sequel::SQL::JoinUsingClause.new([:a], :inner, :b, :c),
|
|
32
|
+
Sequel::SQL::PlaceholderLiteralString.new('? = ?', [:a, :b]),
|
|
33
|
+
Sequel::SQL::PlaceholderLiteralString.new(':a = :b', [{:a=>:b, :b=>42}]),
|
|
34
|
+
Sequel::SQL::OrderedExpression.new(:a),
|
|
35
|
+
Sequel::SQL::OrderedExpression.new(:a, false),
|
|
36
|
+
Sequel::SQL::OrderedExpression.new(:a, false, :nulls=>:first),
|
|
37
|
+
Sequel::SQL::OrderedExpression.new(:a, false, :nulls=>:last),
|
|
38
|
+
Sequel::SQL::QualifiedIdentifier.new(:b, :a),
|
|
39
|
+
Sequel::SQL::Subscript.new(:a, [1, 2]),
|
|
40
|
+
Sequel::SQL::Window.new(:order=>:a, :partition=>:b),
|
|
41
|
+
Sequel::SQL::WindowFunction.new(Sequel::SQL::Function.new(:a, :b, :c), Sequel::SQL::Window.new(:order=>:a, :partition=>:b)),
|
|
42
|
+
Sequel::SQL::Wrapper.new(:a),
|
|
43
|
+
|
|
44
|
+
# Objects with components where eval(inspect) != self
|
|
45
|
+
Sequel::SQL::AliasedExpression.new(Sequel::SQL::Blob.new('s'), :a),
|
|
46
|
+
Sequel::SQL::AliasedExpression.new(Sequel::LiteralString.new('s'), :a),
|
|
47
|
+
Sequel::SQL::PlaceholderLiteralString.new('(a, b) IN ?', [Sequel::SQL::ValueList.new([[1, 2]])]),
|
|
48
|
+
Sequel::SQL::CaseExpression.new({{:d=>Sequel::LiteralString.new('e')}=>:a}, :c, :d),
|
|
49
|
+
Sequel::SQL::AliasedExpression.new(Date.new(2011, 10, 11), :a),
|
|
50
|
+
Sequel::SQL::AliasedExpression.new(Sequel::SQLTime.create(10, 20, 30, 500000.125), :a),
|
|
51
|
+
Sequel::SQL::AliasedExpression.new(DateTime.new(2011, 9, 11, 10, 20, 30), :a),
|
|
52
|
+
Sequel::SQL::AliasedExpression.new(DateTime.new(2011, 9, 11, 10, 20, 30, 0.25), :a),
|
|
53
|
+
Sequel::SQL::AliasedExpression.new(DateTime.new(2011, 9, 11, 10, 20, 30, -0.25), :a),
|
|
54
|
+
Sequel::SQL::AliasedExpression.new(Time.local(2011, 9, 11, 10, 20, 30), :a),
|
|
55
|
+
Sequel::SQL::AliasedExpression.new(Time.local(2011, 9, 11, 10, 20, 30, 500000.125), :a),
|
|
56
|
+
Sequel::SQL::AliasedExpression.new(Time.utc(2011, 9, 11, 10, 20, 30), :a),
|
|
57
|
+
Sequel::SQL::AliasedExpression.new(Time.utc(2011, 9, 11, 10, 20, 30, 500000.125), :a),
|
|
58
|
+
Sequel::SQL::AliasedExpression.new(BigDecimal.new('1.000000000000000000000000000000000000000000000001'), :a),
|
|
59
|
+
Sequel::SQL::AliasedExpression.new(Sequel::CURRENT_DATE, :a),
|
|
60
|
+
Sequel::SQL::AliasedExpression.new(Sequel::CURRENT_TIMESTAMP, :a),
|
|
61
|
+
].each do |o|
|
|
62
|
+
v = eval(o.inspect)
|
|
63
|
+
v.should == o
|
|
64
|
+
@ds.literal(v).should == @ds.literal(o)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -74,12 +74,13 @@ describe "force_encoding plugin" do
|
|
|
74
74
|
|
|
75
75
|
specify "should work when saving new model instances" do
|
|
76
76
|
o = @c.new
|
|
77
|
-
|
|
77
|
+
ds = MODEL_DB[:a]
|
|
78
78
|
def ds.first
|
|
79
79
|
s = 'blah'
|
|
80
80
|
s.force_encoding('US-ASCII')
|
|
81
81
|
{:id=>1, :x=>s}
|
|
82
82
|
end
|
|
83
|
+
@c.dataset = ds
|
|
83
84
|
o.save
|
|
84
85
|
o.x.should == 'blah'
|
|
85
86
|
o.x.encoding.should == @e1
|
|
@@ -87,12 +88,13 @@ describe "force_encoding plugin" do
|
|
|
87
88
|
|
|
88
89
|
specify "should work when refreshing model instances" do
|
|
89
90
|
o = @c.load(:id=>1, :x=>'as')
|
|
90
|
-
|
|
91
|
+
ds = MODEL_DB[:a]
|
|
91
92
|
def ds.first
|
|
92
93
|
s = 'blah'
|
|
93
94
|
s.force_encoding('US-ASCII')
|
|
94
95
|
{:id=>1, :x=>s}
|
|
95
96
|
end
|
|
97
|
+
@c.dataset = ds
|
|
96
98
|
o.refresh
|
|
97
99
|
o.x.should == 'blah'
|
|
98
100
|
o.x.encoding.should == @e1
|