sequel 3.48.0 → 4.0.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 (267) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +114 -0
  3. data/Rakefile +10 -7
  4. data/doc/association_basics.rdoc +25 -23
  5. data/doc/code_order.rdoc +7 -0
  6. data/doc/core_extensions.rdoc +0 -10
  7. data/doc/object_model.rdoc +4 -1
  8. data/doc/querying.rdoc +3 -3
  9. data/doc/release_notes/4.0.0.txt +262 -0
  10. data/doc/security.rdoc +0 -28
  11. data/doc/testing.rdoc +8 -14
  12. data/lib/sequel/adapters/ado.rb +7 -11
  13. data/lib/sequel/adapters/ado/access.rb +8 -8
  14. data/lib/sequel/adapters/ado/mssql.rb +4 -4
  15. data/lib/sequel/adapters/amalgalite.rb +6 -6
  16. data/lib/sequel/adapters/cubrid.rb +7 -7
  17. data/lib/sequel/adapters/db2.rb +5 -9
  18. data/lib/sequel/adapters/dbi.rb +2 -6
  19. data/lib/sequel/adapters/do.rb +4 -4
  20. data/lib/sequel/adapters/firebird.rb +4 -4
  21. data/lib/sequel/adapters/ibmdb.rb +8 -8
  22. data/lib/sequel/adapters/informix.rb +2 -10
  23. data/lib/sequel/adapters/jdbc.rb +17 -17
  24. data/lib/sequel/adapters/jdbc/as400.rb +2 -2
  25. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
  26. data/lib/sequel/adapters/jdbc/db2.rb +1 -1
  27. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  28. data/lib/sequel/adapters/jdbc/h2.rb +2 -2
  29. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
  30. data/lib/sequel/adapters/jdbc/informix.rb +1 -1
  31. data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
  32. data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
  33. data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
  35. data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
  36. data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
  37. data/lib/sequel/adapters/mock.rb +7 -7
  38. data/lib/sequel/adapters/mysql.rb +3 -3
  39. data/lib/sequel/adapters/mysql2.rb +4 -4
  40. data/lib/sequel/adapters/odbc.rb +2 -6
  41. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  42. data/lib/sequel/adapters/openbase.rb +1 -5
  43. data/lib/sequel/adapters/oracle.rb +13 -17
  44. data/lib/sequel/adapters/postgres.rb +20 -25
  45. data/lib/sequel/adapters/shared/cubrid.rb +3 -3
  46. data/lib/sequel/adapters/shared/db2.rb +2 -2
  47. data/lib/sequel/adapters/shared/firebird.rb +7 -7
  48. data/lib/sequel/adapters/shared/mssql.rb +9 -9
  49. data/lib/sequel/adapters/shared/mysql.rb +29 -13
  50. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
  51. data/lib/sequel/adapters/shared/oracle.rb +22 -13
  52. data/lib/sequel/adapters/shared/postgres.rb +61 -46
  53. data/lib/sequel/adapters/shared/sqlite.rb +9 -9
  54. data/lib/sequel/adapters/sqlite.rb +17 -11
  55. data/lib/sequel/adapters/swift.rb +3 -3
  56. data/lib/sequel/adapters/swift/mysql.rb +1 -1
  57. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  58. data/lib/sequel/adapters/tinytds.rb +8 -8
  59. data/lib/sequel/ast_transformer.rb +3 -1
  60. data/lib/sequel/connection_pool.rb +4 -2
  61. data/lib/sequel/connection_pool/sharded_single.rb +2 -2
  62. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
  63. data/lib/sequel/connection_pool/threaded.rb +7 -7
  64. data/lib/sequel/core.rb +4 -67
  65. data/lib/sequel/database.rb +1 -0
  66. data/lib/sequel/database/connecting.rb +2 -8
  67. data/lib/sequel/database/dataset.rb +2 -7
  68. data/lib/sequel/database/dataset_defaults.rb +0 -18
  69. data/lib/sequel/database/features.rb +4 -4
  70. data/lib/sequel/database/misc.rb +6 -8
  71. data/lib/sequel/database/query.rb +5 -61
  72. data/lib/sequel/database/schema_generator.rb +22 -20
  73. data/lib/sequel/database/schema_methods.rb +48 -20
  74. data/lib/sequel/database/transactions.rb +7 -17
  75. data/lib/sequel/dataset.rb +2 -0
  76. data/lib/sequel/dataset/actions.rb +23 -91
  77. data/lib/sequel/dataset/features.rb +1 -4
  78. data/lib/sequel/dataset/graph.rb +3 -47
  79. data/lib/sequel/dataset/misc.rb +4 -33
  80. data/lib/sequel/dataset/prepared_statements.rb +3 -1
  81. data/lib/sequel/dataset/query.rb +116 -240
  82. data/lib/sequel/dataset/sql.rb +19 -97
  83. data/lib/sequel/deprecated.rb +0 -16
  84. data/lib/sequel/exceptions.rb +0 -3
  85. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  86. data/lib/sequel/extensions/columns_introspection.rb +1 -12
  87. data/lib/sequel/extensions/constraint_validations.rb +3 -3
  88. data/lib/sequel/extensions/core_extensions.rb +0 -9
  89. data/lib/sequel/extensions/date_arithmetic.rb +1 -2
  90. data/lib/sequel/extensions/graph_each.rb +11 -0
  91. data/lib/sequel/extensions/migration.rb +5 -5
  92. data/lib/sequel/extensions/null_dataset.rb +11 -13
  93. data/lib/sequel/extensions/pagination.rb +3 -6
  94. data/lib/sequel/extensions/pg_array.rb +6 -4
  95. data/lib/sequel/extensions/pg_array_ops.rb +35 -1
  96. data/lib/sequel/extensions/pg_json.rb +12 -2
  97. data/lib/sequel/extensions/pg_json_ops.rb +266 -0
  98. data/lib/sequel/extensions/pg_range.rb +2 -2
  99. data/lib/sequel/extensions/pg_range_ops.rb +0 -8
  100. data/lib/sequel/extensions/pg_row.rb +2 -2
  101. data/lib/sequel/extensions/pretty_table.rb +0 -4
  102. data/lib/sequel/extensions/query.rb +3 -8
  103. data/lib/sequel/extensions/schema_caching.rb +0 -7
  104. data/lib/sequel/extensions/schema_dumper.rb +10 -17
  105. data/lib/sequel/extensions/select_remove.rb +0 -4
  106. data/lib/sequel/extensions/set_overrides.rb +28 -0
  107. data/lib/sequel/extensions/to_dot.rb +6 -10
  108. data/lib/sequel/model.rb +6 -7
  109. data/lib/sequel/model/associations.rb +127 -182
  110. data/lib/sequel/model/base.rb +88 -211
  111. data/lib/sequel/model/errors.rb +0 -13
  112. data/lib/sequel/model/plugins.rb +2 -2
  113. data/lib/sequel/no_core_ext.rb +0 -1
  114. data/lib/sequel/plugins/after_initialize.rb +11 -17
  115. data/lib/sequel/plugins/association_autoreloading.rb +1 -47
  116. data/lib/sequel/plugins/association_dependencies.rb +2 -2
  117. data/lib/sequel/plugins/auto_validations.rb +2 -8
  118. data/lib/sequel/plugins/blacklist_security.rb +32 -2
  119. data/lib/sequel/plugins/caching.rb +1 -1
  120. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  121. data/lib/sequel/plugins/composition.rb +10 -8
  122. data/lib/sequel/plugins/constraint_validations.rb +2 -2
  123. data/lib/sequel/plugins/dataset_associations.rb +4 -0
  124. data/lib/sequel/plugins/defaults_setter.rb +8 -6
  125. data/lib/sequel/plugins/dirty.rb +6 -6
  126. data/lib/sequel/plugins/force_encoding.rb +13 -8
  127. data/lib/sequel/plugins/hook_class_methods.rb +1 -7
  128. data/lib/sequel/plugins/json_serializer.rb +13 -74
  129. data/lib/sequel/plugins/lazy_attributes.rb +2 -4
  130. data/lib/sequel/plugins/list.rb +1 -1
  131. data/lib/sequel/plugins/many_through_many.rb +4 -11
  132. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
  133. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  134. data/lib/sequel/plugins/optimistic_locking.rb +3 -5
  135. data/lib/sequel/plugins/pg_array_associations.rb +453 -0
  136. data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
  137. data/lib/sequel/plugins/prepared_statements.rb +1 -1
  138. data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
  139. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
  140. data/lib/sequel/plugins/rcte_tree.rb +1 -1
  141. data/lib/sequel/plugins/serialization.rb +5 -4
  142. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  143. data/lib/sequel/plugins/sharding.rb +7 -1
  144. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  145. data/lib/sequel/plugins/timestamps.rb +1 -1
  146. data/lib/sequel/plugins/touch.rb +2 -2
  147. data/lib/sequel/plugins/tree.rb +1 -1
  148. data/lib/sequel/plugins/typecast_on_load.rb +19 -4
  149. data/lib/sequel/plugins/validation_class_methods.rb +0 -30
  150. data/lib/sequel/plugins/validation_helpers.rb +13 -31
  151. data/lib/sequel/plugins/xml_serializer.rb +18 -57
  152. data/lib/sequel/sql.rb +20 -22
  153. data/lib/sequel/version.rb +2 -2
  154. data/spec/adapters/db2_spec.rb +14 -23
  155. data/spec/adapters/firebird_spec.rb +25 -29
  156. data/spec/adapters/informix_spec.rb +11 -14
  157. data/spec/adapters/mssql_spec.rb +71 -77
  158. data/spec/adapters/mysql_spec.rb +165 -172
  159. data/spec/adapters/oracle_spec.rb +36 -39
  160. data/spec/adapters/postgres_spec.rb +175 -100
  161. data/spec/adapters/spec_helper.rb +13 -11
  162. data/spec/adapters/sqlite_spec.rb +36 -44
  163. data/spec/core/connection_pool_spec.rb +2 -1
  164. data/spec/core/database_spec.rb +55 -55
  165. data/spec/core/dataset_spec.rb +45 -249
  166. data/spec/core/deprecated_spec.rb +0 -8
  167. data/spec/core/expression_filters_spec.rb +23 -5
  168. data/spec/core/object_graph_spec.rb +4 -66
  169. data/spec/core/schema_spec.rb +35 -12
  170. data/spec/core/spec_helper.rb +3 -2
  171. data/spec/core_extensions_spec.rb +17 -19
  172. data/spec/extensions/arbitrary_servers_spec.rb +2 -3
  173. data/spec/extensions/association_dependencies_spec.rb +14 -14
  174. data/spec/extensions/auto_validations_spec.rb +7 -0
  175. data/spec/extensions/blacklist_security_spec.rb +5 -5
  176. data/spec/extensions/blank_spec.rb +2 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +2 -2
  178. data/spec/extensions/columns_introspection_spec.rb +2 -29
  179. data/spec/extensions/composition_spec.rb +10 -17
  180. data/spec/extensions/core_refinements_spec.rb +5 -1
  181. data/spec/extensions/dataset_associations_spec.rb +18 -0
  182. data/spec/extensions/date_arithmetic_spec.rb +2 -2
  183. data/spec/extensions/defaults_setter_spec.rb +9 -9
  184. data/spec/extensions/dirty_spec.rb +0 -5
  185. data/spec/extensions/eval_inspect_spec.rb +2 -0
  186. data/spec/extensions/force_encoding_spec.rb +2 -18
  187. data/spec/extensions/hash_aliases_spec.rb +8 -0
  188. data/spec/extensions/hook_class_methods_spec.rb +39 -58
  189. data/spec/extensions/inflector_spec.rb +2 -0
  190. data/spec/extensions/instance_filters_spec.rb +8 -8
  191. data/spec/extensions/json_serializer_spec.rb +1 -41
  192. data/spec/extensions/list_spec.rb +1 -1
  193. data/spec/extensions/many_through_many_spec.rb +106 -109
  194. data/spec/extensions/migration_spec.rb +2 -0
  195. data/spec/extensions/named_timezones_spec.rb +1 -0
  196. data/spec/extensions/pg_array_associations_spec.rb +603 -0
  197. data/spec/extensions/pg_array_ops_spec.rb +25 -0
  198. data/spec/extensions/pg_array_spec.rb +9 -1
  199. data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
  200. data/spec/extensions/pg_hstore_spec.rb +1 -0
  201. data/spec/extensions/pg_json_ops_spec.rb +131 -0
  202. data/spec/extensions/pg_json_spec.rb +10 -4
  203. data/spec/extensions/pg_range_ops_spec.rb +2 -5
  204. data/spec/extensions/pg_range_spec.rb +6 -2
  205. data/spec/extensions/pg_row_ops_spec.rb +2 -0
  206. data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
  207. data/spec/extensions/rcte_tree_spec.rb +15 -15
  208. data/spec/extensions/schema_dumper_spec.rb +0 -1
  209. data/spec/extensions/schema_spec.rb +9 -9
  210. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  211. data/spec/extensions/serialization_spec.rb +18 -29
  212. data/spec/extensions/set_overrides_spec.rb +4 -0
  213. data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
  214. data/spec/extensions/single_table_inheritance_spec.rb +4 -4
  215. data/spec/extensions/spec_helper.rb +8 -9
  216. data/spec/extensions/sql_expr_spec.rb +2 -0
  217. data/spec/extensions/string_date_time_spec.rb +2 -0
  218. data/spec/extensions/string_stripper_spec.rb +2 -0
  219. data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
  220. data/spec/extensions/thread_local_timezones_spec.rb +2 -0
  221. data/spec/extensions/timestamps_spec.rb +1 -1
  222. data/spec/extensions/to_dot_spec.rb +1 -1
  223. data/spec/extensions/touch_spec.rb +24 -24
  224. data/spec/extensions/tree_spec.rb +7 -7
  225. data/spec/extensions/typecast_on_load_spec.rb +8 -1
  226. data/spec/extensions/update_primary_key_spec.rb +10 -10
  227. data/spec/extensions/validation_class_methods_spec.rb +10 -39
  228. data/spec/extensions/validation_helpers_spec.rb +29 -47
  229. data/spec/extensions/xml_serializer_spec.rb +1 -23
  230. data/spec/integration/associations_test.rb +231 -40
  231. data/spec/integration/database_test.rb +1 -1
  232. data/spec/integration/dataset_test.rb +64 -64
  233. data/spec/integration/eager_loader_test.rb +28 -28
  234. data/spec/integration/migrator_test.rb +1 -1
  235. data/spec/integration/model_test.rb +2 -2
  236. data/spec/integration/plugin_test.rb +21 -21
  237. data/spec/integration/prepared_statement_test.rb +7 -7
  238. data/spec/integration/schema_test.rb +115 -110
  239. data/spec/integration/spec_helper.rb +17 -27
  240. data/spec/integration/timezone_test.rb +1 -1
  241. data/spec/integration/transaction_test.rb +10 -10
  242. data/spec/integration/type_test.rb +2 -2
  243. data/spec/model/association_reflection_spec.rb +2 -28
  244. data/spec/model/associations_spec.rb +239 -188
  245. data/spec/model/base_spec.rb +27 -68
  246. data/spec/model/dataset_methods_spec.rb +4 -4
  247. data/spec/model/eager_loading_spec.rb +160 -172
  248. data/spec/model/hooks_spec.rb +62 -79
  249. data/spec/model/model_spec.rb +36 -51
  250. data/spec/model/plugins_spec.rb +5 -19
  251. data/spec/model/record_spec.rb +125 -151
  252. data/spec/model/spec_helper.rb +8 -6
  253. data/spec/model/validations_spec.rb +4 -17
  254. data/spec/spec_config.rb +2 -10
  255. metadata +50 -56
  256. data/lib/sequel/deprecated_core_extensions.rb +0 -135
  257. data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
  258. data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
  259. data/lib/sequel/plugins/identity_map.rb +0 -260
  260. data/lib/sequel_core.rb +0 -2
  261. data/lib/sequel_model.rb +0 -2
  262. data/spec/extensions/association_autoreloading_spec.rb +0 -102
  263. data/spec/extensions/identity_map_spec.rb +0 -337
  264. data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
  265. data/spec/extensions/pg_statement_cache_spec.rb +0 -208
  266. data/spec/rcov.opts +0 -8
  267. data/spec/spec_config.rb.example +0 -10
@@ -7,7 +7,7 @@ module Sequel
7
7
  # the additional support that the pg_* extensions add for advanced PostgreSQL
8
8
  # types such as arrays.
9
9
  #
10
- # This plugin modifies Model#set_values to do the same conversion that the
10
+ # This plugin makes model loading to do the same conversion that the
11
11
  # native postgres adapter would do for all columns given. You can either
12
12
  # specify the columns to typecast on load in the plugin call itself, or
13
13
  # afterwards using add_pg_typecast_on_load_columns:
@@ -41,19 +41,35 @@ module Sequel
41
41
  @pg_typecast_on_load_columns.concat(columns)
42
42
  end
43
43
 
44
- Plugins.inherited_instance_variables(self, :@pg_typecast_on_load_columns=>:dup)
45
- end
44
+ def call(values)
45
+ super(load_typecast_pg(values))
46
+ end
46
47
 
47
- module InstanceMethods
48
48
  # Lookup the conversion proc for the column's oid in the Database
49
49
  # object, and use it to convert the value.
50
- def set_values(values)
51
- model.pg_typecast_on_load_columns.each do |c|
50
+ def load_typecast_pg(values)
51
+ pg_typecast_on_load_columns.each do |c|
52
52
  if (v = values[c]).is_a?(String) && (oid = db_schema[c][:oid]) && (pr = db.conversion_procs[oid])
53
53
  values[c] = pr.call(v)
54
54
  end
55
55
  end
56
- super
56
+ values
57
+ end
58
+
59
+ Plugins.inherited_instance_variables(self, :@pg_typecast_on_load_columns=>:dup)
60
+ end
61
+
62
+ module InstanceMethods
63
+ private
64
+
65
+ # Typecast specific columns using the conversion procs when manually refreshing.
66
+ def _refresh_set_values(values)
67
+ super(model.load_typecast_pg(values))
68
+ end
69
+
70
+ # Typecast specific columns using the conversion procs when refreshing after save.
71
+ def _save_set_values(values)
72
+ super(model.load_typecast_pg(values))
57
73
  end
58
74
  end
59
75
  end
@@ -42,7 +42,7 @@ module Sequel
42
42
 
43
43
  # Create a prepared statement based on the given dataset with a unique name for the given
44
44
  # type of query and values.
45
- def prepare_statement(ds, type, vals={})
45
+ def prepare_statement(ds, type, vals=OPTS)
46
46
  ps = ds.prepare(type, :"smpsp_#{NEXT.call}", vals)
47
47
  ps.log_sql = true
48
48
  ps
@@ -25,8 +25,8 @@ module Sequel
25
25
  module ClassMethods
26
26
  # Disable prepared statement use if a block is given, or the :dataset or :conditions
27
27
  # options are used, or you are cloning an association.
28
- def associate(type, name, opts = {}, &block)
29
- if block || opts[:dataset] || opts[:conditions] || (opts[:clone] && association_reflection(opts[:clone])[:prepared_statement] == false)
28
+ def associate(type, name, opts = OPTS, &block)
29
+ if block || opts[:dataset] || (opts[:clone] && association_reflection(opts[:clone])[:prepared_statement] == false)
30
30
  opts = opts.merge(:prepared_statement=>false)
31
31
  end
32
32
  super(type, name, opts, &block)
@@ -48,7 +48,7 @@ module Sequel
48
48
  case opts[:type]
49
49
  when :many_to_one
50
50
  association_bound_variable_hash(opts.associated_class.table_name, opts.primary_keys, opts[:keys])
51
- when :one_to_many
51
+ when :one_to_many, :one_to_one
52
52
  association_bound_variable_hash(opts.associated_class.table_name, opts[:keys], opts[:primary_keys])
53
53
  when :many_to_many
54
54
  association_bound_variable_hash(opts.join_table_alias, opts[:left_keys], opts[:left_primary_keys])
@@ -59,10 +59,18 @@ module Sequel
59
59
 
60
60
  # Given an association reflection, return and cache a prepared statement for this association such
61
61
  # that, given appropriate bound variables, the prepared statement will work correctly for any
62
- # instance.
63
- def association_prepared_statement(opts)
62
+ # instance. Return false if such a prepared statement cannot be created.
63
+ def association_prepared_statement(opts, assoc_bv)
64
64
  opts.send(:cached_fetch, :prepared_statement) do
65
- ps = _associated_dataset(opts, {}).unbind.first.prepare(opts.returns_array? ? :select : :first, :"smpsap_#{NEXT.call}")
65
+ ds, bv = _associated_dataset(opts, {}).unbind
66
+ if bv.length != assoc_bv.length
67
+ h = {}
68
+ bv.each do |k,v|
69
+ h[k] = v unless assoc_bv.has_key?(k)
70
+ end
71
+ ds = ds.bind(h)
72
+ end
73
+ ps = ds.prepare(opts.returns_array? ? :select : :first, :"smpsap_#{NEXT.call}")
66
74
  ps.log_sql = true
67
75
  ps
68
76
  end
@@ -70,15 +78,13 @@ module Sequel
70
78
 
71
79
  # If a prepared statement can be used to load the associated objects, execute it to retrieve them. Otherwise,
72
80
  # fall back to the default implementation.
73
- def _load_associated_objects(opts, dynamic_opts={})
74
- if !opts.can_have_associated_objects?(self) || dynamic_opts[:callback] || (ps = opts[:prepared_statement]) == false
81
+ def _load_associated_objects(opts, dynamic_opts=OPTS)
82
+ if !opts.can_have_associated_objects?(self) || dynamic_opts[:callback] || (load_with_primary_key_lookup?(opts, dynamic_opts) && opts.associated_class.respond_to?(:cache_get_pk))
83
+ super
84
+ elsif (bv = association_bound_variables(opts)) && (ps ||= association_prepared_statement(opts, bv))
85
+ ps.call(bv)
86
+ else
75
87
  super
76
- else
77
- if bv = association_bound_variables(opts)
78
- (ps || association_prepared_statement(opts)).call(bv)
79
- else
80
- super
81
- end
82
88
  end
83
89
  end
84
90
  end
@@ -57,14 +57,14 @@ module Sequel
57
57
  # of free columns.
58
58
  def before_create
59
59
  if v = model.prepared_statements_column_defaults
60
- set_values(v.merge(values))
60
+ @values = v.merge(values)
61
61
  end
62
62
  super
63
63
  end
64
64
 
65
65
  # Always do a full save of all columns to reduce the number of prepared
66
66
  # statements that can be used.
67
- def save_changes(opts={})
67
+ def save_changes(opts=OPTS)
68
68
  save(opts) || false if modified?
69
69
  end
70
70
  end
@@ -92,7 +92,7 @@ module Sequel
92
92
  module RcteTree
93
93
  # Create the appropriate parent, children, ancestors, and descendants
94
94
  # associations for the model.
95
- def self.apply(model, opts={})
95
+ def self.apply(model, opts=OPTS)
96
96
  model.plugin :tree, opts
97
97
 
98
98
  opts = opts.dup
@@ -172,19 +172,20 @@ module Sequel
172
172
  @deserialized_values ||= {}
173
173
  end
174
174
 
175
+ # Freeze the deserialized values
175
176
  def freeze
176
177
  deserialized_values.freeze
177
178
  super
178
179
  end
179
180
 
180
- # Initialization the deserialized values for objects retrieved from the database.
181
- def set_values(hash)
181
+ private
182
+
183
+ # Clear any cached deserialized values when doing a manual refresh.
184
+ def _refresh_set_values(hash)
182
185
  @deserialized_values.clear if @deserialized_values
183
186
  super
184
187
  end
185
188
 
186
- private
187
-
188
189
  # Deserialize the column value. Called when the model column accessor is called to
189
190
  # return a deserialized value.
190
191
  def deserialize_value(column, v)
@@ -34,7 +34,7 @@ module Sequel
34
34
  # show the column is modified after saving.
35
35
  def after_save
36
36
  super
37
- @original_deserialized_values = {}
37
+ @original_deserialized_values = @deserialized_values
38
38
  end
39
39
 
40
40
  # Detect which serialized columns have changed.
@@ -27,7 +27,7 @@ module Sequel
27
27
  # When eagerly loading, if the current dataset has a defined shard and the
28
28
  # dataset that you will be using to get the associated records does not,
29
29
  # use the current dataset's shard for the associated dataset.
30
- def eager_loading_dataset(opts, ds, select, associations, eager_options={})
30
+ def eager_loading_dataset(opts, ds, select, associations, eager_options=OPTS)
31
31
  ds = super(opts, ds, select, associations, eager_options)
32
32
  if !ds.opts[:server] and s = eager_options[:self] and server = s.opts[:server]
33
33
  ds = ds.server(server)
@@ -82,6 +82,12 @@ module Sequel
82
82
  o.set_server?(@server) if o.respond_to?(:set_server?)
83
83
  super
84
84
  end
85
+
86
+ # Don't use primary key lookup to load associated objects, since that will not
87
+ # respect the current object's server.
88
+ def load_with_primary_key_lookup?(opts, dynamic_opts)
89
+ false
90
+ end
85
91
  end
86
92
 
87
93
  module DatasetMethods
@@ -69,7 +69,7 @@ module Sequel
69
69
  # as keys.
70
70
  module SingleTableInheritance
71
71
  # Setup the necessary STI variables, see the module RDoc for SingleTableInheritance
72
- def self.configure(model, key, opts={})
72
+ def self.configure(model, key, opts=OPTS)
73
73
  model.instance_eval do
74
74
  @sti_key_array = nil
75
75
  @sti_key = key
@@ -26,7 +26,7 @@ module Sequel
26
26
  # * :force - Whether to overwrite an existing create timestamp (default: false)
27
27
  # * :update - The field to hold the update timestamp (default: :updated_at)
28
28
  # * :update_on_create - Whether to set the update timestamp to the create timestamp when creating (default: false)
29
- def self.configure(model, opts={})
29
+ def self.configure(model, opts=OPTS)
30
30
  model.instance_eval do
31
31
  @create_timestamp_field = opts[:create]||:created_at
32
32
  @update_timestamp_field = opts[:update]||:updated_at
@@ -30,7 +30,7 @@ module Sequel
30
30
  # The default column to update when touching
31
31
  TOUCH_COLUMN_DEFAULT = :updated_at
32
32
 
33
- def self.apply(model, opts={})
33
+ def self.apply(model, opts=OPTS)
34
34
  model.instance_variable_set(:@touched_associations, {})
35
35
  end
36
36
 
@@ -43,7 +43,7 @@ module Sequel
43
43
  # when updating the associated objects is the model's touch_column.
44
44
  # If a hash is used, the value is used as the column to update.
45
45
  # * :column - The column to modify when touching a model instance.
46
- def self.configure(model, opts={})
46
+ def self.configure(model, opts=OPTS)
47
47
  model.touch_column = opts[:column] || TOUCH_COLUMN_DEFAULT if opts[:column] || !model.touch_column
48
48
  model.touch_associations(opts[:associations]) if opts[:associations]
49
49
  end
@@ -27,7 +27,7 @@ module Sequel
27
27
  # specify options to use for the parent association
28
28
  # using a :parent option, and options to use for the
29
29
  # children association using a :children option.
30
- def self.apply(model, opts={})
30
+ def self.apply(model, opts=OPTS)
31
31
  opts = opts.dup
32
32
  opts[:class] = model
33
33
 
@@ -5,7 +5,7 @@ module Sequel
5
5
  # typecast correctly (with correct being defined as how the model object
6
6
  # would typecast the same column values).
7
7
  #
8
- # This plugin modifies Model#set_values to call the setter methods (which typecast
8
+ # This plugin makes model loading call the setter methods (which typecast
9
9
  # by default) for all columns given. You can either specify the columns to
10
10
  # typecast on load in the plugin call itself, or afterwards using
11
11
  # add_typecast_on_load_columns:
@@ -36,6 +36,12 @@ module Sequel
36
36
  @typecast_on_load_columns.concat(columns)
37
37
  end
38
38
 
39
+ # Typecast values using #load_typecast when the values are retrieved
40
+ # from the database.
41
+ def call(values)
42
+ super.load_typecast
43
+ end
44
+
39
45
  Plugins.inherited_instance_variables(self, :@typecast_on_load_columns=>:dup)
40
46
  end
41
47
 
@@ -52,9 +58,18 @@ module Sequel
52
58
  self
53
59
  end
54
60
 
55
- # Typecast values using #load_typecast when the values are retrieved from
56
- # the database.
57
- def set_values(values)
61
+ private
62
+
63
+ # Typecast values using #load_typecast when the values are refreshed manually.
64
+ def _refresh_set_values(values)
65
+ ret = super
66
+ load_typecast
67
+ ret
68
+ end
69
+
70
+ # Typecast values using #load_typecast when the values are refreshed
71
+ # automatically after a save.
72
+ def _save_set_values(values)
58
73
  ret = super
59
74
  load_typecast
60
75
  ret
@@ -264,36 +264,6 @@ module Sequel
264
264
  end
265
265
  end
266
266
 
267
- # Validates whether an attribute is not a string. This is generally useful
268
- # in conjunction with raise_on_typecast_failure = false, where you are
269
- # passing in string values for non-string attributes (such as numbers and dates).
270
- # If typecasting fails (invalid number or date), the value of the attribute will
271
- # be a string in an invalid format, and if typecasting succeeds, the value will
272
- # not be a string.
273
- #
274
- # Possible Options:
275
- # * :message - The message to use (default: 'is a string' or 'is not a valid (integer|datetime|etc.)' if the type is known)
276
- def validates_not_string(*atts)
277
- Sequel::Deprecation.deprecate('validates_not_string', "Please switch to validates_schema_type")
278
- opts = {
279
- :tag => :not_string,
280
- }.merge!(extract_options!(atts))
281
- reflect_validation(:not_string, opts, atts)
282
- atts << opts
283
- validates_each(*atts) do |o, a, v|
284
- if v.is_a?(String)
285
- unless message = opts[:message]
286
- message = if sch = o.db_schema[a] and typ = sch[:type]
287
- "is not a valid #{typ}"
288
- else
289
- "is a string"
290
- end
291
- end
292
- o.errors.add(a, message)
293
- end
294
- end
295
- end
296
-
297
267
  # Validates whether an attribute is a number.
298
268
  #
299
269
  # Possible Options:
@@ -32,9 +32,7 @@ module Sequel
32
32
  # :allow_nil :: Whether to skip the validation if the value is nil.
33
33
  # :message :: The message to use. Can be a string which is used directly, or a
34
34
  # proc which is called. If the validation method takes a argument before the array of attributes,
35
- # that argument is passed as an argument to the proc. The exception is the
36
- # validates_not_string method, which doesn't take an argument, but passes
37
- # the schema type symbol as the argument to the proc.
35
+ # that argument is passed as an argument to the proc.
38
36
  #
39
37
  # The default validation options for all models can be modified by
40
38
  # changing the values of the Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS hash. You
@@ -84,7 +82,6 @@ module Sequel
84
82
  :max_length=>{:message=>lambda{|max| "is longer than #{max} characters"}, :nil_message=>lambda{"is not present"}},
85
83
  :min_length=>{:message=>lambda{|min| "is shorter than #{min} characters"}},
86
84
  :not_null=>{:message=>lambda{"is not present"}},
87
- :not_string=>{:message=>lambda{|type| type ? "is not a valid #{type}" : "is a string"}},
88
85
  :numeric=>{:message=>lambda{"is not a number"}},
89
86
  :type=>{:message=>lambda{|klass| klass.is_a?(Array) ? "is not a valid #{klass.join(" or ").downcase}" : "is not a valid #{klass.to_s.downcase}"}},
90
87
  :presence=>{:message=>lambda{"is not present"}},
@@ -93,22 +90,22 @@ module Sequel
93
90
 
94
91
  module InstanceMethods
95
92
  # Check that the attribute values are the given exact length.
96
- def validates_exact_length(exact, atts, opts={})
93
+ def validates_exact_length(exact, atts, opts=OPTS)
97
94
  validatable_attributes_for_type(:exact_length, atts, opts){|a,v,m| validation_error_message(m, exact) if v.nil? || v.length != exact}
98
95
  end
99
96
 
100
97
  # Check the string representation of the attribute value(s) against the regular expression with.
101
- def validates_format(with, atts, opts={})
98
+ def validates_format(with, atts, opts=OPTS)
102
99
  validatable_attributes_for_type(:format, atts, opts){|a,v,m| validation_error_message(m, with) unless v.to_s =~ with}
103
100
  end
104
101
 
105
102
  # Check attribute value(s) is included in the given set.
106
- def validates_includes(set, atts, opts={})
103
+ def validates_includes(set, atts, opts=OPTS)
107
104
  validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.send(set.respond_to?(:cover?) ? :cover? : :include?, v)}
108
105
  end
109
106
 
110
107
  # Check attribute value(s) string representation is a valid integer.
111
- def validates_integer(atts, opts={})
108
+ def validates_integer(atts, opts=OPTS)
112
109
  validatable_attributes_for_type(:integer, atts, opts) do |a,v,m|
113
110
  begin
114
111
  Kernel.Integer(v.to_s)
@@ -120,7 +117,7 @@ module Sequel
120
117
  end
121
118
 
122
119
  # Check that the attribute values length is in the specified range.
123
- def validates_length_range(range, atts, opts={})
120
+ def validates_length_range(range, atts, opts=OPTS)
124
121
  validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.send(range.respond_to?(:cover?) ? :cover? : :include?, v.length)}
125
122
  end
126
123
 
@@ -128,33 +125,22 @@ module Sequel
128
125
  #
129
126
  # Accepts a :nil_message option that is the error message to use when the
130
127
  # value is nil instead of being too long.
131
- def validates_max_length(max, atts, opts={})
128
+ def validates_max_length(max, atts, opts=OPTS)
132
129
  validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| v ? validation_error_message(m, max) : validation_error_message(opts[:nil_message] || DEFAULT_OPTIONS[:max_length][:nil_message]) if v.nil? || v.length > max}
133
130
  end
134
131
 
135
132
  # Check that the attribute values are not shorter than the given min length.
136
- def validates_min_length(min, atts, opts={})
133
+ def validates_min_length(min, atts, opts=OPTS)
137
134
  validatable_attributes_for_type(:min_length, atts, opts){|a,v,m| validation_error_message(m, min) if v.nil? || v.length < min}
138
135
  end
139
136
 
140
137
  # Check attribute value(s) are not NULL/nil.
141
- def validates_not_null(atts, opts={})
138
+ def validates_not_null(atts, opts=OPTS)
142
139
  validatable_attributes_for_type(:not_null, atts, opts){|a,v,m| validation_error_message(m) if v.nil?}
143
140
  end
144
141
 
145
- # Check that the attribute value(s) is not a string. This is generally useful
146
- # in conjunction with raise_on_typecast_failure = false, where you are
147
- # passing in string values for non-string attributes (such as numbers and dates).
148
- # If typecasting fails (invalid number or date), the value of the attribute will
149
- # be a string in an invalid format, and if typecasting succeeds, the value will
150
- # not be a string.
151
- def validates_not_string(atts, opts={})
152
- Sequel::Deprecation.deprecate('validates_not_string', "Please switch to validates_schema_types")
153
- validatable_attributes_for_type(:not_string, atts, opts){|a,v,m| validation_error_message(m, (db_schema[a]||{})[:type]) if v.is_a?(String)}
154
- end
155
-
156
142
  # Check attribute value(s) string representation is a valid float.
157
- def validates_numeric(atts, opts={})
143
+ def validates_numeric(atts, opts=OPTS)
158
144
  validatable_attributes_for_type(:numeric, atts, opts) do |a,v,m|
159
145
  begin
160
146
  Kernel.Float(v.to_s)
@@ -168,7 +154,7 @@ module Sequel
168
154
  # Validates for all of the model columns (or just the given columns)
169
155
  # that the column value is an instance of the expected class based on
170
156
  # the column's schema type.
171
- def validates_schema_types(atts=keys, opts={})
157
+ def validates_schema_types(atts=keys, opts=OPTS)
172
158
  Array(atts).each do |k|
173
159
  if type = schema_type_class(k)
174
160
  validates_type(type, k, {:allow_nil=>true}.merge(opts))
@@ -178,13 +164,9 @@ module Sequel
178
164
 
179
165
  # Check if value is an instance of a class. If +klass+ is an array,
180
166
  # the value must be an instance of one of the classes in the array.
181
- def validates_type(klass, atts, opts={})
167
+ def validates_type(klass, atts, opts=OPTS)
182
168
  klass = klass.to_s.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
183
169
  validatable_attributes_for_type(:type, atts, opts) do |a,v,m|
184
- if v.nil?
185
- Sequel::Deprecation.deprecate('validates_type will no longer allow nil values by default in Sequel 4. Use the :allow_nil=>true option to allow nil values.')
186
- next
187
- end
188
170
  if klass.is_a?(Array) ? !klass.any?{|kls| v.is_a?(kls)} : !v.is_a?(klass)
189
171
  validation_error_message(m, klass)
190
172
  end
@@ -192,7 +174,7 @@ module Sequel
192
174
  end
193
175
 
194
176
  # Check attribute value(s) is not considered blank by the database, but allow false values.
195
- def validates_presence(atts, opts={})
177
+ def validates_presence(atts, opts=OPTS)
196
178
  validatable_attributes_for_type(:presence, atts, opts){|a,v,m| validation_error_message(m) if model.db.send(:blank_object?, v) && v != false}
197
179
  end
198
180