sequel 4.13.0 → 4.14.0

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