sequel 4.13.0 → 4.14.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +24 -0
  3. data/doc/active_record.rdoc +4 -4
  4. data/doc/advanced_associations.rdoc +2 -2
  5. data/doc/association_basics.rdoc +11 -11
  6. data/doc/cheat_sheet.rdoc +7 -7
  7. data/doc/core_extensions.rdoc +1 -1
  8. data/doc/dataset_filtering.rdoc +1 -1
  9. data/doc/extensions.rdoc +1 -1
  10. data/doc/migration.rdoc +3 -3
  11. data/doc/model_hooks.rdoc +1 -1
  12. data/doc/opening_databases.rdoc +4 -0
  13. data/doc/postgresql.rdoc +2 -2
  14. data/doc/prepared_statements.rdoc +1 -1
  15. data/doc/querying.rdoc +31 -31
  16. data/doc/release_notes/4.13.0.txt +1 -1
  17. data/doc/release_notes/4.14.0.txt +68 -0
  18. data/doc/schema_modification.rdoc +1 -1
  19. data/doc/sharding.rdoc +2 -2
  20. data/doc/sql.rdoc +1 -1
  21. data/doc/virtual_rows.rdoc +2 -2
  22. data/lib/sequel/adapters/jdbc/jtds.rb +4 -0
  23. data/lib/sequel/adapters/mysql.rb +18 -18
  24. data/lib/sequel/adapters/mysql2.rb +7 -7
  25. data/lib/sequel/adapters/shared/mysql.rb +15 -5
  26. data/lib/sequel/adapters/shared/postgres.rb +71 -58
  27. data/lib/sequel/adapters/shared/sqlite.rb +2 -2
  28. data/lib/sequel/ast_transformer.rb +1 -1
  29. data/lib/sequel/connection_pool/sharded_single.rb +8 -8
  30. data/lib/sequel/connection_pool/sharded_threaded.rb +8 -8
  31. data/lib/sequel/database/connecting.rb +1 -1
  32. data/lib/sequel/database/schema_generator.rb +12 -0
  33. data/lib/sequel/database/schema_methods.rb +8 -7
  34. data/lib/sequel/database/transactions.rb +1 -2
  35. data/lib/sequel/dataset/actions.rb +4 -4
  36. data/lib/sequel/dataset/graph.rb +4 -0
  37. data/lib/sequel/dataset/query.rb +18 -18
  38. data/lib/sequel/dataset/sql.rb +3 -3
  39. data/lib/sequel/extensions/_pretty_table.rb +1 -0
  40. data/lib/sequel/extensions/arbitrary_servers.rb +3 -2
  41. data/lib/sequel/extensions/columns_introspection.rb +1 -0
  42. data/lib/sequel/extensions/connection_validator.rb +1 -0
  43. data/lib/sequel/extensions/constraint_validations.rb +1 -0
  44. data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -0
  45. data/lib/sequel/extensions/dataset_source_alias.rb +1 -0
  46. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  47. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +1 -0
  48. data/lib/sequel/extensions/error_sql.rb +1 -0
  49. data/lib/sequel/extensions/eval_inspect.rb +1 -0
  50. data/lib/sequel/extensions/filter_having.rb +1 -0
  51. data/lib/sequel/extensions/from_block.rb +1 -0
  52. data/lib/sequel/extensions/graph_each.rb +1 -0
  53. data/lib/sequel/extensions/hash_aliases.rb +1 -0
  54. data/lib/sequel/extensions/looser_typecasting.rb +1 -0
  55. data/lib/sequel/extensions/meta_def.rb +1 -0
  56. data/lib/sequel/extensions/migration.rb +1 -0
  57. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +1 -0
  58. data/lib/sequel/extensions/named_timezones.rb +1 -0
  59. data/lib/sequel/extensions/null_dataset.rb +1 -0
  60. data/lib/sequel/extensions/pagination.rb +1 -0
  61. data/lib/sequel/extensions/pg_array.rb +2 -2
  62. data/lib/sequel/extensions/pg_array_ops.rb +1 -0
  63. data/lib/sequel/extensions/pg_enum.rb +1 -0
  64. data/lib/sequel/extensions/pg_hstore_ops.rb +1 -0
  65. data/lib/sequel/extensions/pg_json_ops.rb +1 -0
  66. data/lib/sequel/extensions/pg_loose_count.rb +1 -0
  67. data/lib/sequel/extensions/pg_range_ops.rb +1 -0
  68. data/lib/sequel/extensions/pg_row_ops.rb +1 -0
  69. data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -0
  70. data/lib/sequel/extensions/pretty_table.rb +1 -0
  71. data/lib/sequel/extensions/query.rb +1 -0
  72. data/lib/sequel/extensions/query_literals.rb +1 -0
  73. data/lib/sequel/extensions/schema_caching.rb +1 -0
  74. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  75. data/lib/sequel/extensions/select_remove.rb +1 -0
  76. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +1 -0
  77. data/lib/sequel/extensions/server_block.rb +1 -0
  78. data/lib/sequel/extensions/set_overrides.rb +1 -0
  79. data/lib/sequel/extensions/split_array_nil.rb +1 -0
  80. data/lib/sequel/extensions/thread_local_timezones.rb +1 -0
  81. data/lib/sequel/extensions/to_dot.rb +1 -0
  82. data/lib/sequel/model/associations.rb +5 -5
  83. data/lib/sequel/model/base.rb +3 -3
  84. data/lib/sequel/plugins/association_proxies.rb +1 -1
  85. data/lib/sequel/plugins/caching.rb +8 -3
  86. data/lib/sequel/plugins/class_table_inheritance.rb +20 -11
  87. data/lib/sequel/plugins/composition.rb +18 -18
  88. data/lib/sequel/plugins/json_serializer.rb +3 -3
  89. data/lib/sequel/plugins/lazy_attributes.rb +23 -9
  90. data/lib/sequel/plugins/many_through_many.rb +21 -21
  91. data/lib/sequel/plugins/nested_attributes.rb +7 -3
  92. data/lib/sequel/plugins/pg_row.rb +1 -1
  93. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  94. data/lib/sequel/plugins/sharding.rb +6 -6
  95. data/lib/sequel/plugins/timestamps.rb +4 -4
  96. data/lib/sequel/plugins/touch.rb +7 -7
  97. data/lib/sequel/plugins/tree.rb +1 -1
  98. data/lib/sequel/plugins/validation_class_methods.rb +36 -36
  99. data/lib/sequel/plugins/validation_helpers.rb +3 -4
  100. data/lib/sequel/plugins/xml_serializer.rb +29 -29
  101. data/lib/sequel/sql.rb +22 -11
  102. data/lib/sequel/version.rb +1 -1
  103. data/spec/adapters/postgres_spec.rb +10 -0
  104. data/spec/core/database_spec.rb +3 -4
  105. data/spec/core/dataset_spec.rb +16 -1
  106. data/spec/core/expression_filters_spec.rb +12 -0
  107. data/spec/core/object_graph_spec.rb +5 -0
  108. data/spec/core/placeholder_literalizer_spec.rb +8 -0
  109. data/spec/extensions/caching_spec.rb +18 -0
  110. data/spec/extensions/class_table_inheritance_spec.rb +34 -0
  111. data/spec/extensions/many_through_many_spec.rb +4 -0
  112. data/spec/extensions/nested_attributes_spec.rb +59 -4
  113. data/spec/extensions/pg_array_associations_spec.rb +5 -0
  114. data/spec/extensions/single_table_inheritance_spec.rb +23 -1
  115. data/spec/integration/plugin_test.rb +17 -0
  116. data/spec/model/eager_loading_spec.rb +8 -0
  117. metadata +4 -2
@@ -14,6 +14,7 @@
14
14
  #
15
15
  # DB.extension(:hash_aliases)
16
16
 
17
+ #
17
18
  module Sequel
18
19
  module HashAliases
19
20
  def from(*source)
@@ -10,6 +10,7 @@
10
10
  #
11
11
  # DB.extension :looser_typecasting
12
12
 
13
+ #
13
14
  module Sequel
14
15
  module LooserTypecasting
15
16
  # Typecast the value to a Float using to_f instead of Kernel.Float
@@ -5,6 +5,7 @@
5
5
  #
6
6
  # Sequel.extension :meta_def
7
7
 
8
+ #
8
9
  module Sequel
9
10
  # Contains meta_def method for adding methods to objects via blocks.
10
11
  # Only recommended for backwards compatibility with existing code.
@@ -6,6 +6,7 @@
6
6
  #
7
7
  # Sequel.extension :migration
8
8
 
9
+ #
9
10
  module Sequel
10
11
  # Sequel's older migration class, available for backward compatibility.
11
12
  # Uses subclasses with up and down instance methods for each migration:
@@ -22,6 +22,7 @@
22
22
  #
23
23
  # DB.extension(:mssql_emulate_lateral_with_apply)
24
24
 
25
+ #
25
26
  module Sequel
26
27
  module MSSQL
27
28
  module EmulateLateralWithApply
@@ -39,6 +39,7 @@
39
39
 
40
40
  require 'tzinfo'
41
41
 
42
+ #
42
43
  module Sequel
43
44
  self.datetime_class = DateTime
44
45
 
@@ -31,6 +31,7 @@
31
31
  #
32
32
  # DB.extension(:null_dataset)
33
33
 
34
+ #
34
35
  module Sequel
35
36
  class Dataset
36
37
  module Nullifiable
@@ -14,6 +14,7 @@
14
14
  #
15
15
  # DB.extension(:pagination)
16
16
 
17
+ #
17
18
  module Sequel
18
19
  module DatasetPagination
19
20
  # Returns a paginated dataset. The returned dataset is limited to
@@ -52,7 +52,7 @@
52
52
  # conversion_procs usingthe appropriate type OID. For user defined
53
53
  # types, you can do this via:
54
54
  #
55
- # DB.conversion_procs[scalar_type_oid] = lambda{|string| ...}
55
+ # DB.conversion_procs[scalar_type_oid] = lambda{|string| }
56
56
  #
57
57
  # Then you can call
58
58
  # Sequel::Postgres::PGArray::DatabaseMethods#register_array_type
@@ -66,7 +66,7 @@
66
66
  # Sequel::Postgres::PGArray.register. In this case, you'll have
67
67
  # to specify the type oids:
68
68
  #
69
- # Sequel::Postgres::PG_TYPES[1234] = lambda{|string| ...}
69
+ # Sequel::Postgres::PG_TYPES[1234] = lambda{|string| }
70
70
  # Sequel::Postgres::PGArray.register('foo', :oid=>4321, :scalar_oid=>1234)
71
71
  #
72
72
  # Both Sequel::Postgres::PGArray::DatabaseMethods#register_array_type
@@ -65,6 +65,7 @@
65
65
  # In order for #hstore to automatically wrap the returned value correctly in
66
66
  # an HStoreOp, you need to load the pg_hstore_ops extension.
67
67
 
68
+ #
68
69
  module Sequel
69
70
  module Postgres
70
71
  # The ArrayOp class is a simple container for a single object that
@@ -42,6 +42,7 @@
42
42
  # the enum values as symbols when creating enums using create_enum or
43
43
  # add_enum_value.
44
44
 
45
+ #
45
46
  module Sequel
46
47
  module Postgres
47
48
  # Methods enabling Database object integration with enum types.
@@ -66,6 +66,7 @@
66
66
  # PostgreSQL arrays will have the returned expression automatically wrapped in a
67
67
  # Postgres::ArrayOp if the pg_array_ops extension is loaded.
68
68
 
69
+ #
69
70
  module Sequel
70
71
  module Postgres
71
72
  # The HStoreOp class is a simple container for a single object that
@@ -65,6 +65,7 @@
65
65
  # (as shown in the #[] and #get_text examples above), you need to load the pg_array
66
66
  # extension.
67
67
 
68
+ #
68
69
  module Sequel
69
70
  module Postgres
70
71
  # The JSONBaseOp class is a simple container for a single object that
@@ -16,6 +16,7 @@
16
16
  #
17
17
  # DB.extension :pg_loose_count
18
18
 
19
+ #
19
20
  module Sequel
20
21
  module Postgres
21
22
  module LooseCount
@@ -52,6 +52,7 @@
52
52
  # loading this extension. Doing so will allow you to use PGArray#op to get
53
53
  # an RangeOp, allowing you to perform range operations on range literals.
54
54
 
55
+ #
55
56
  module Sequel
56
57
  module Postgres
57
58
  # The RangeOp class is a simple container for a single object that
@@ -79,6 +79,7 @@
79
79
  # # SELECT (a.*)::a, (b.*)::b FROM a INNER JOIN b ON (b.id = a.b_id)
80
80
  # # => {:a=>{:id=>1, :b_id=>2}, :b=>{:id=>2}}
81
81
 
82
+ #
82
83
  module Sequel
83
84
  module Postgres
84
85
  # This class represents a composite type expression reference.
@@ -62,6 +62,7 @@
62
62
  # use the same Database).
63
63
  # * Must be using a thread-safe connection pool (the default).
64
64
 
65
+ #
65
66
  module Sequel
66
67
  module Postgres
67
68
  module StaticCacheUpdater
@@ -19,6 +19,7 @@
19
19
  #
20
20
  # DB.extension(:pretty_table)
21
21
 
22
+ #
22
23
  module Sequel
23
24
  extension :_pretty_table
24
25
 
@@ -18,6 +18,7 @@
18
18
  #
19
19
  # DB.extension(:query)
20
20
 
21
+ #
21
22
  module Sequel
22
23
  module DatabaseQuery
23
24
  def self.extended(db)
@@ -31,6 +31,7 @@
31
31
  #
32
32
  # DB.extension(:query_literals)
33
33
 
34
+ #
34
35
  module Sequel
35
36
  # The QueryLiterals module can be used to make select, group, and
36
37
  # order methods operate similar to the filter methods if the first
@@ -42,6 +42,7 @@
42
42
  # and it handles all ruby objects used in the schema hash. Because of this,
43
43
  # you should not attempt to load the schema from a untrusted file.
44
44
 
45
+ #
45
46
  module Sequel
46
47
  module SchemaCaching
47
48
  # Dump the cached schema to the filename given in Marshal format.
@@ -105,7 +105,7 @@ END_MIG
105
105
  # will yield the same type. Without this set, types that aren't
106
106
  # recognized will be translated to a string-like type.
107
107
  # :foreign_keys :: If set to false, don't dump foreign_keys (they can be
108
- # added later via #dump_foreign_key_migration)
108
+ # added later via #dump_foreign_key_migration)
109
109
  # :indexes :: If set to false, don't dump indexes (they can be added
110
110
  # later via #dump_index_migration).
111
111
  # :index_names :: If set to false, don't record names of indexes. If
@@ -12,6 +12,7 @@
12
12
  #
13
13
  # DB.extension(:select_remove)
14
14
 
15
+ #
15
16
  module Sequel
16
17
  module SelectRemove
17
18
  # Remove columns from the list of selected columns. If any of the currently selected
@@ -19,6 +19,7 @@
19
19
  #
20
20
  # DB.extension(:sequel_3_dataset_methods)
21
21
 
22
+ #
22
23
  module Sequel
23
24
  module Sequel3DatasetMethods
24
25
  COMMA = Dataset::COMMA
@@ -37,6 +37,7 @@
37
37
  # DB[:a].server(:read_only).all # Uses shard1
38
38
  # end
39
39
 
40
+ #
40
41
  module Sequel
41
42
  module ServerBlock
42
43
  # Enable the server block on the connection pool, choosing the correct
@@ -14,6 +14,7 @@
14
14
  #
15
15
  # DB.extension(:set_overrides)
16
16
 
17
+ #
17
18
  module Sequel
18
19
  module SetOverrides
19
20
  Dataset::NON_SQL_OPTIONS.concat([:defaults, :overrides])
@@ -31,6 +31,7 @@
31
31
  #
32
32
  # DB.extension(:split_array_nil)
33
33
 
34
+ #
34
35
  module Sequel
35
36
  class Dataset
36
37
  module SplitArrayNil
@@ -34,6 +34,7 @@
34
34
  # Sequel.thread_application_timezone = :nil
35
35
  # Sequel.application_timezone # => nil
36
36
 
37
+ #
37
38
  module Sequel
38
39
  module ThreadLocalTimezones
39
40
  %w'application database typecast'.each do |t|
@@ -7,6 +7,7 @@
7
7
  #
8
8
  # Sequel.extension :to_dot
9
9
 
10
+ #
10
11
  module Sequel
11
12
  class ToDot
12
13
  module DatasetMethods
@@ -1791,10 +1791,10 @@ module Sequel
1791
1791
  select_all(egds.first_source).
1792
1792
  select_append(*associated_key_array)
1793
1793
  egds = opts.apply_eager_graph_limit_strategy(egls, egds)
1794
- ds.graph(egds, associated_key_array.map{|v| v.alias}.zip(lpkcs) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>eo[:implicit_qualifier], :join_type=>eo[:join_type]||join_type, :from_self_alias=>eo[:from_self_alias], :select=>select||orig_egds.columns, &graph_block)
1794
+ ds.graph(egds, associated_key_array.map{|v| v.alias}.zip(lpkcs) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>eo[:implicit_qualifier], :join_type=>eo[:join_type]||join_type, :from_self_alias=>eo[:from_self_alias], :join_only=>eo[:join_only], :select=>select||orig_egds.columns, &graph_block)
1795
1795
  else
1796
- ds = ds.graph(join_table, use_jt_only_conditions ? jt_only_conditions : lcks.zip(lpkcs) + graph_jt_conds, :select=>false, :table_alias=>ds.unused_table_alias(join_table, [eo[:table_alias]]), :join_type=>eo[:join_type]||jt_join_type, :implicit_qualifier=>eo[:implicit_qualifier], :qualify=>:deep, :from_self_alias=>eo[:from_self_alias], &jt_graph_block)
1797
- ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : opts.right_primary_keys.zip(rcks) + conditions, :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, &graph_block)
1796
+ ds = ds.graph(join_table, use_jt_only_conditions ? jt_only_conditions : lcks.zip(lpkcs) + graph_jt_conds, :select=>false, :table_alias=>ds.unused_table_alias(join_table, [eo[:table_alias]]), :join_type=>eo[:join_type]||jt_join_type, :join_only=>eo[:join_only], :implicit_qualifier=>eo[:implicit_qualifier], :qualify=>:deep, :from_self_alias=>eo[:from_self_alias], &jt_graph_block)
1797
+ ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : opts.right_primary_keys.zip(rcks) + conditions, :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
1798
1798
  end
1799
1799
  end
1800
1800
 
@@ -2561,7 +2561,7 @@ END
2561
2561
  end
2562
2562
  local_opts = ds.opts[:eager_graph][:local]
2563
2563
  limit_strategy = r.eager_graph_limit_strategy(local_opts[:limit_strategy])
2564
- ds = loader.call(:self=>ds, :table_alias=>assoc_table_alias, :implicit_qualifier=>(ta == ds.opts[:eager_graph][:master]) ? first_source : qualifier_from_alias_symbol(ta, first_source), :callback=>callback, :join_type=>local_opts[:join_type], :limit_strategy=>limit_strategy, :from_self_alias=>ds.opts[:eager_graph][:master])
2564
+ ds = loader.call(:self=>ds, :table_alias=>assoc_table_alias, :implicit_qualifier=>(ta == ds.opts[:eager_graph][:master]) ? first_source : qualifier_from_alias_symbol(ta, first_source), :callback=>callback, :join_type=>local_opts[:join_type], :join_only=>local_opts[:join_only], :limit_strategy=>limit_strategy, :from_self_alias=>ds.opts[:eager_graph][:master])
2565
2565
  if r[:order_eager_graph] && (order = r.fetch(:graph_order, r[:order]))
2566
2566
  ds = ds.order_more(*qualified_expression(order, assoc_table_alias))
2567
2567
  end
@@ -2614,7 +2614,7 @@ END
2614
2614
  # Return a new dataset with JOINs of the given type added, using the tables and
2615
2615
  # conditions specified by the associations.
2616
2616
  def _association_join(type, associations)
2617
- clone(:join=>clone(:graph_from_self=>false).eager_graph_with_options(associations, :join_type=>type).opts[:join])
2617
+ clone(:join=>clone(:graph_from_self=>false).eager_graph_with_options(associations, :join_type=>type, :join_only=>true).opts[:join])
2618
2618
  end
2619
2619
 
2620
2620
  # If the association has conditions itself, then it requires additional filters be
@@ -1351,7 +1351,7 @@ module Sequel
1351
1351
  # a = Artist[1]
1352
1352
  # Artist.db.transaction do
1353
1353
  # a.lock!
1354
- # a.update(...)
1354
+ # a.update(:name=>'A')
1355
1355
  # end
1356
1356
  def lock!
1357
1357
  _refresh(this.for_update) unless new?
@@ -2091,7 +2091,7 @@ module Sequel
2091
2091
  # Returns all methods that can be used for attribute assignment (those that end with =),
2092
2092
  # depending on the type:
2093
2093
  #
2094
- # :default :: Use the default methods allowed in th model class.
2094
+ # :default :: Use the default methods allowed in the model class.
2095
2095
  # :all :: Allow setting all setters, except those specifically restricted (such as ==).
2096
2096
  # Array :: Only allow setting of columns in the given array.
2097
2097
  def setter_methods(type)
@@ -2249,7 +2249,7 @@ module Sequel
2249
2249
  # If there is no order already defined on this dataset, order it by
2250
2250
  # the primary key and call paged_each.
2251
2251
  #
2252
- # Album.paged_each{|row| ...}
2252
+ # Album.paged_each{|row| }
2253
2253
  # # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 0
2254
2254
  # # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 1000
2255
2255
  # # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 2000
@@ -35,7 +35,7 @@ module Sequel
35
35
  # :arguments => [2],
36
36
  # :block => {|x| 3},
37
37
  # :instance => artist,
38
- # :reflection => {:name=>:albums, ...},
38
+ # :reflection => {:name=>:albums} # AssociationReflection instance
39
39
  # :proxy_argument => 1,
40
40
  # :proxy_block => {|ds| ds}
41
41
  # }
@@ -7,8 +7,8 @@ module Sequel
7
7
  # cache_store.set(key, obj, time) # Associate the obj with the given key
8
8
  # # in the cache for the time (specified
9
9
  # # in seconds).
10
- # cache_store.get(key) => obj # Returns object set with same key.
11
- # cache_store.get(key2) => nil # nil returned if there isn't an object
10
+ # cache_store.get(key) # => obj # Returns object set with same key.
11
+ # cache_store.get(key2) # => nil # nil returned if there isn't an object
12
12
  # # currently in the cache with that key.
13
13
  # cache_store.delete(key) # Remove key from cache
14
14
  #
@@ -64,10 +64,15 @@ module Sequel
64
64
  cache_get(cache_key(pk))
65
65
  end
66
66
 
67
+ # Returns the prefix used to namespace this class in the cache.
68
+ def cache_key_prefix
69
+ "#{self}"
70
+ end
71
+
67
72
  # Return a key string for the given primary key.
68
73
  def cache_key(pk)
69
74
  raise(Error, 'no primary key for this record') unless pk.is_a?(Array) ? pk.all? : pk
70
- "#{self}:#{Array(pk).join(',')}"
75
+ "#{cache_key_prefix}:#{Array(pk).join(',')}"
71
76
  end
72
77
 
73
78
  Plugins.inherited_instance_variables(self, :@cache_store=>nil, :@cache_ttl=>nil, :@cache_ignore_exceptions=>nil)
@@ -13,20 +13,20 @@ module Sequel
13
13
  #
14
14
  # the following database schema may be used (table - columns):
15
15
  #
16
- # * employees - id, name, kind
17
- # * staff - id, manager_id
18
- # * managers - id, num_staff
19
- # * executives - id, num_managers
16
+ # employees :: id, name, kind
17
+ # staff :: id, manager_id
18
+ # managers :: id, num_staff
19
+ # executives :: id, num_managers
20
20
  #
21
21
  # The class_table_inheritance plugin assumes that the main table
22
22
  # (e.g. employees) has a primary key field (usually autoincrementing),
23
23
  # and all other tables have a foreign key of the same name that points
24
24
  # to the same key in their superclass's table. For example:
25
25
  #
26
- # * employees.id - primary key, autoincrementing
27
- # * staff.id - foreign key referencing employees(id)
28
- # * managers.id - foreign key referencing employees(id)
29
- # * executives.id - foreign key referencing managers(id)
26
+ # employees.id :: primary key, autoincrementing
27
+ # staff.id :: foreign key referencing employees(id)
28
+ # managers.id :: foreign key referencing employees(id)
29
+ # executives.id :: foreign key referencing managers(id)
30
30
  #
31
31
  # When using the class_table_inheritance plugin, subclasses use joined
32
32
  # datasets:
@@ -62,6 +62,13 @@ module Sequel
62
62
  # a = Employee.all # [<#Staff>, <#Manager>, <#Executive>]
63
63
  # a.first.values # {:id=>1, name=>'S', :kind=>'Staff'}
64
64
  # a.first.manager_id # Loads the manager_id attribute from the database
65
+ #
66
+ # If you want to get all columns in a subclass instance after loading
67
+ # via the superclass, call Model#refresh.
68
+ #
69
+ # a = Employee.first
70
+ # a.values # {:id=>1, name=>'S', :kind=>'Executive'}
71
+ # a.refresh.values # {:id=>1, name=>'S', :kind=>'Executive', :num_staff=>4, :num_managers=>2}
65
72
  #
66
73
  # Usage:
67
74
  #
@@ -159,6 +166,8 @@ module Sequel
159
166
  cmm = cti_model_map
160
167
  pk = primary_key
161
168
  ds = dataset
169
+ table = nil
170
+ columns = nil
162
171
  subclass.instance_eval do
163
172
  raise(Error, "cannot create anonymous subclass for model class using class_table_inheritance") if !(n = name) || n.empty?
164
173
  table = ctm[n.to_sym] || implicit_table_name
@@ -178,9 +187,9 @@ module Sequel
178
187
  super
179
188
  subclass.instance_eval do
180
189
  set_dataset_cti_row_proc
181
- (columns - [cbm.primary_key]).each{|a| define_lazy_attribute_getter(a)}
182
- cti_tables.reverse.each do |table|
183
- db.schema(table).each{|k,v| db_schema[k] = v}
190
+ (columns - [cbm.primary_key]).each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>table)}
191
+ cti_tables.reverse.each do |t|
192
+ db.schema(t).each{|k,v| db_schema[k] = v}
184
193
  end
185
194
  end
186
195
  end
@@ -72,24 +72,24 @@ module Sequel
72
72
  # You must provide either a :mapping option or both the :composer and :decomposer options.
73
73
  #
74
74
  # Options:
75
- # * :class - if using the :mapping option, the class to use, as a Class, String or Symbol.
76
- # * :composer - A proc that is instance evaled when the composition getter method is called
77
- # to create the composition.
78
- # * :decomposer - A proc that is instance evaled before saving the model object,
79
- # if the composition object exists, which sets the columns in the model object
80
- # based on the value of the composition object.
81
- # * :mapping - An array where each element is either a symbol or an array of two symbols.
82
- # A symbol is treated like an array of two symbols where both symbols are the same.
83
- # The first symbol represents the getter method in the model, and the second symbol
84
- # represents the getter method in the composition object. Example:
85
- # # Uses columns year, month, and day in the current model
86
- # # Uses year, month, and day methods in the composition object
87
- # :mapping=>[:year, :month, :day]
88
- # # Uses columns year, month, and day in the current model
89
- # # Uses y, m, and d methods in the composition object where
90
- # # for example y in the composition object represents year
91
- # # in the model object.
92
- # :mapping=>[[:year, :y], [:month, :m], [:day, :d]]
75
+ # :class :: if using the :mapping option, the class to use, as a Class, String or Symbol.
76
+ # :composer :: A proc that is instance evaled when the composition getter method is called
77
+ # to create the composition.
78
+ # :decomposer :: A proc that is instance evaled before saving the model object,
79
+ # if the composition object exists, which sets the columns in the model object
80
+ # based on the value of the composition object.
81
+ # :mapping :: An array where each element is either a symbol or an array of two symbols.
82
+ # A symbol is treated like an array of two symbols where both symbols are the same.
83
+ # The first symbol represents the getter method in the model, and the second symbol
84
+ # represents the getter method in the composition object. Example:
85
+ # # Uses columns year, month, and day in the current model
86
+ # # Uses year, month, and day methods in the composition object
87
+ # {:mapping=>[:year, :month, :day]}
88
+ # # Uses columns year, month, and day in the current model
89
+ # # Uses y, m, and d methods in the composition object where
90
+ # # for example y in the composition object represents year
91
+ # # in the model object.
92
+ # {:mapping=>[[:year, :y], [:month, :m], [:day, :d]]}
93
93
  def composition(name, opts=OPTS)
94
94
  opts = opts.dup
95
95
  compositions[name] = opts