sequel 4.22.0 → 4.23.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.
- checksums.yaml +4 -4
- data/CHANGELOG +22 -0
- data/README.rdoc +6 -0
- data/Rakefile +59 -81
- data/doc/migration.rdoc +2 -0
- data/doc/release_notes/4.23.0.txt +65 -0
- data/doc/sharding.rdoc +16 -14
- data/doc/testing.rdoc +61 -77
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mock.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/postgresql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +9 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/transactions.rb +2 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +12 -12
- data/lib/sequel/extensions/date_arithmetic.rb +0 -4
- data/lib/sequel/extensions/pagination.rb +14 -2
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/delay_add_association.rb +50 -0
- data/lib/sequel/plugins/list.rb +2 -2
- data/lib/sequel/plugins/nested_attributes.rb +8 -28
- data/lib/sequel/plugins/update_refresh.rb +50 -0
- data/lib/sequel/plugins/validate_associated.rb +55 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +29 -29
- data/spec/adapters/firebird_spec.rb +97 -103
- data/spec/adapters/informix_spec.rb +25 -25
- data/spec/adapters/mssql_spec.rb +156 -172
- data/spec/adapters/mysql_spec.rb +334 -359
- data/spec/adapters/oracle_spec.rb +67 -69
- data/spec/adapters/postgres_spec.rb +1298 -1249
- data/spec/adapters/spec_helper.rb +2 -35
- data/spec/adapters/sqlanywhere_spec.rb +39 -39
- data/spec/adapters/sqlite_spec.rb +203 -200
- data/spec/bin_spec.rb +57 -59
- data/spec/core/connection_pool_spec.rb +402 -401
- data/spec/core/database_spec.rb +953 -944
- data/spec/core/dataset_spec.rb +2178 -2168
- data/spec/core/deprecated_spec.rb +19 -19
- data/spec/core/expression_filters_spec.rb +415 -415
- data/spec/core/mock_adapter_spec.rb +212 -212
- data/spec/core/object_graph_spec.rb +73 -73
- data/spec/core/placeholder_literalizer_spec.rb +71 -71
- data/spec/core/schema_generator_spec.rb +44 -44
- data/spec/core/schema_spec.rb +470 -472
- data/spec/core/spec_helper.rb +5 -20
- data/spec/core/version_spec.rb +2 -2
- data/spec/core_extensions_spec.rb +320 -320
- data/spec/extensions/accessed_columns_spec.rb +12 -12
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +2 -2
- data/spec/extensions/arbitrary_servers_spec.rb +23 -23
- data/spec/extensions/association_dependencies_spec.rb +34 -34
- data/spec/extensions/association_pks_spec.rb +98 -98
- data/spec/extensions/association_proxies_spec.rb +33 -33
- data/spec/extensions/auto_validations_spec.rb +46 -46
- data/spec/extensions/blacklist_security_spec.rb +19 -18
- data/spec/extensions/blank_spec.rb +36 -36
- data/spec/extensions/boolean_readers_spec.rb +36 -36
- data/spec/extensions/caching_spec.rb +82 -82
- data/spec/extensions/class_table_inheritance_spec.rb +72 -72
- data/spec/extensions/column_conflicts_spec.rb +19 -14
- data/spec/extensions/column_select_spec.rb +19 -19
- data/spec/extensions/columns_introspection_spec.rb +43 -43
- data/spec/extensions/composition_spec.rb +64 -64
- data/spec/extensions/connection_validator_spec.rb +92 -90
- data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
- data/spec/extensions/constraint_validations_spec.rb +80 -80
- data/spec/extensions/core_refinements_spec.rb +220 -220
- data/spec/extensions/csv_serializer_spec.rb +44 -44
- data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
- data/spec/extensions/dataset_associations_spec.rb +65 -65
- data/spec/extensions/dataset_source_alias_spec.rb +16 -16
- data/spec/extensions/date_arithmetic_spec.rb +51 -58
- data/spec/extensions/defaults_setter_spec.rb +19 -19
- data/spec/extensions/delay_add_association_spec.rb +52 -0
- data/spec/extensions/dirty_spec.rb +51 -51
- data/spec/extensions/eager_each_spec.rb +8 -8
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
- data/spec/extensions/error_splitter_spec.rb +2 -2
- data/spec/extensions/error_sql_spec.rb +4 -4
- data/spec/extensions/eval_inspect_spec.rb +3 -3
- data/spec/extensions/filter_having_spec.rb +8 -8
- data/spec/extensions/force_encoding_spec.rb +30 -30
- data/spec/extensions/from_block_spec.rb +7 -7
- data/spec/extensions/graph_each_spec.rb +19 -19
- data/spec/extensions/hash_aliases_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +100 -100
- data/spec/extensions/inflector_spec.rb +54 -54
- data/spec/extensions/input_transformer_spec.rb +10 -10
- data/spec/extensions/insert_returning_select_spec.rb +8 -8
- data/spec/extensions/instance_filters_spec.rb +26 -26
- data/spec/extensions/instance_hooks_spec.rb +85 -85
- data/spec/extensions/json_serializer_spec.rb +68 -68
- data/spec/extensions/lazy_attributes_spec.rb +49 -49
- data/spec/extensions/list_spec.rb +77 -75
- data/spec/extensions/looser_typecasting_spec.rb +16 -16
- data/spec/extensions/many_through_many_spec.rb +627 -627
- data/spec/extensions/meta_def_spec.rb +7 -7
- data/spec/extensions/migration_spec.rb +217 -217
- data/spec/extensions/modification_detection_spec.rb +20 -20
- data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
- data/spec/extensions/named_timezones_spec.rb +18 -18
- data/spec/extensions/nested_attributes_spec.rb +107 -107
- data/spec/extensions/null_dataset_spec.rb +24 -24
- data/spec/extensions/optimistic_locking_spec.rb +21 -21
- data/spec/extensions/pagination_spec.rb +52 -52
- data/spec/extensions/pg_array_associations_spec.rb +273 -273
- data/spec/extensions/pg_array_ops_spec.rb +52 -52
- data/spec/extensions/pg_array_spec.rb +152 -152
- data/spec/extensions/pg_enum_spec.rb +13 -13
- data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
- data/spec/extensions/pg_hstore_spec.rb +84 -84
- data/spec/extensions/pg_inet_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +29 -29
- data/spec/extensions/pg_json_ops_spec.rb +86 -84
- data/spec/extensions/pg_json_spec.rb +104 -104
- data/spec/extensions/pg_loose_count_spec.rb +6 -6
- data/spec/extensions/pg_range_ops_spec.rb +24 -24
- data/spec/extensions/pg_range_spec.rb +143 -143
- data/spec/extensions/pg_row_ops_spec.rb +14 -14
- data/spec/extensions/pg_row_plugin_spec.rb +12 -12
- data/spec/extensions/pg_row_spec.rb +118 -118
- data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
- data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
- data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
- data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
- data/spec/extensions/prepared_statements_spec.rb +28 -28
- data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
- data/spec/extensions/pretty_table_spec.rb +16 -16
- data/spec/extensions/query_literals_spec.rb +37 -37
- data/spec/extensions/query_spec.rb +32 -32
- data/spec/extensions/rcte_tree_spec.rb +141 -141
- data/spec/extensions/round_timestamps_spec.rb +21 -21
- data/spec/extensions/schema_caching_spec.rb +8 -8
- data/spec/extensions/schema_dumper_spec.rb +78 -78
- data/spec/extensions/schema_spec.rb +31 -27
- data/spec/extensions/scissors_spec.rb +3 -3
- data/spec/extensions/select_remove_spec.rb +14 -14
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
- data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
- data/spec/extensions/serialization_spec.rb +79 -78
- data/spec/extensions/server_block_spec.rb +17 -17
- data/spec/extensions/set_overrides_spec.rb +30 -30
- data/spec/extensions/sharding_spec.rb +65 -65
- data/spec/extensions/shared_caching_spec.rb +29 -29
- data/spec/extensions/single_table_inheritance_spec.rb +79 -79
- data/spec/extensions/skip_create_refresh_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +4 -29
- data/spec/extensions/split_array_nil_spec.rb +9 -9
- data/spec/extensions/split_values_spec.rb +7 -7
- data/spec/extensions/sql_expr_spec.rb +32 -32
- data/spec/extensions/static_cache_spec.rb +123 -123
- data/spec/extensions/string_date_time_spec.rb +34 -34
- data/spec/extensions/string_stripper_spec.rb +15 -15
- data/spec/extensions/subclasses_spec.rb +31 -31
- data/spec/extensions/table_select_spec.rb +15 -15
- data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
- data/spec/extensions/thread_local_timezones_spec.rb +13 -13
- data/spec/extensions/timestamps_spec.rb +40 -40
- data/spec/extensions/to_dot_spec.rb +34 -34
- data/spec/extensions/touch_spec.rb +52 -52
- data/spec/extensions/tree_spec.rb +72 -72
- data/spec/extensions/typecast_on_load_spec.rb +25 -25
- data/spec/extensions/unlimited_update_spec.rb +2 -2
- data/spec/extensions/update_or_create_spec.rb +36 -36
- data/spec/extensions/update_primary_key_spec.rb +35 -35
- data/spec/extensions/update_refresh_spec.rb +41 -0
- data/spec/extensions/validate_associated_spec.rb +52 -0
- data/spec/extensions/validation_class_methods_spec.rb +314 -317
- data/spec/extensions/validation_helpers_spec.rb +195 -195
- data/spec/extensions/xml_serializer_spec.rb +48 -48
- data/spec/guards_helper.rb +55 -0
- data/spec/integration/associations_test.rb +1089 -1088
- data/spec/integration/database_test.rb +29 -29
- data/spec/integration/dataset_test.rb +661 -661
- data/spec/integration/eager_loader_test.rb +147 -147
- data/spec/integration/migrator_test.rb +122 -122
- data/spec/integration/model_test.rb +70 -70
- data/spec/integration/plugin_test.rb +682 -640
- data/spec/integration/prepared_statement_test.rb +172 -172
- data/spec/integration/schema_test.rb +245 -245
- data/spec/integration/spec_helper.rb +1 -64
- data/spec/integration/timezone_test.rb +17 -17
- data/spec/integration/transaction_test.rb +87 -87
- data/spec/integration/type_test.rb +33 -33
- data/spec/model/association_reflection_spec.rb +130 -121
- data/spec/model/associations_spec.rb +1112 -1113
- data/spec/model/base_spec.rb +197 -196
- data/spec/model/class_dataset_methods_spec.rb +118 -118
- data/spec/model/dataset_methods_spec.rb +49 -49
- data/spec/model/eager_loading_spec.rb +705 -702
- data/spec/model/hooks_spec.rb +169 -168
- data/spec/model/inflector_spec.rb +5 -5
- data/spec/model/model_spec.rb +287 -297
- data/spec/model/plugins_spec.rb +47 -47
- data/spec/model/record_spec.rb +534 -535
- data/spec/model/spec_helper.rb +3 -21
- data/spec/model/validations_spec.rb +72 -70
- data/spec/spec_config.rb +8 -0
- metadata +41 -9
- data/lib/sequel/adapters/fdbsql.rb +0 -286
- data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
- data/lib/sequel/adapters/openbase.rb +0 -54
- data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
- data/spec/adapters/fdbsql_spec.rb +0 -429
- data/spec/rspec_helper.rb +0 -22
data/lib/sequel/adapters/jdbc.rb
CHANGED
data/lib/sequel/adapters/mock.rb
CHANGED
|
@@ -189,6 +189,7 @@ module Sequel
|
|
|
189
189
|
INFINITE_TIMESTAMP_STRINGS = ['infinity'.freeze, '-infinity'.freeze].freeze
|
|
190
190
|
INFINITE_DATETIME_VALUES = ([PLUS_INFINITY, MINUS_INFINITY] + INFINITE_TIMESTAMP_STRINGS).freeze
|
|
191
191
|
|
|
192
|
+
set_adapter_scheme :postgresql
|
|
192
193
|
set_adapter_scheme :postgres
|
|
193
194
|
|
|
194
195
|
# Whether infinite timestamps/dates should be converted on retrieval. By default, no
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Sequel.require 'adapters/postgres'
|
|
@@ -706,7 +706,7 @@ module Sequel
|
|
|
706
706
|
# Convert the hash of named conversion procs into a hash a oid conversion procs.
|
|
707
707
|
def convert_named_procs_to_procs(named_procs)
|
|
708
708
|
h = {}
|
|
709
|
-
from(:pg_type).where(:typtype=>'b', :typname=>named_procs.keys.map(&:to_s)).select_map([:oid, :typname]).each do |oid, name|
|
|
709
|
+
from(:pg_type).where(:typtype=>['b', 'e'], :typname=>named_procs.keys.map(&:to_s)).select_map([:oid, :typname]).each do |oid, name|
|
|
710
710
|
h[oid.to_i] = named_procs[name.untaint.to_sym]
|
|
711
711
|
end
|
|
712
712
|
h
|
|
@@ -1294,9 +1294,9 @@ module Sequel
|
|
|
1294
1294
|
# returned rows also include the exact phrase used.
|
|
1295
1295
|
# :rank :: Set to true to order by the rank, so that closer matches are returned first.
|
|
1296
1296
|
# :tsquery :: Specifies the terms argument is already a valid SQL expression returning a
|
|
1297
|
-
#
|
|
1297
|
+
# tsquery, and can be used directly in the query.
|
|
1298
1298
|
# :tsvector :: Specifies the cols argument is already a valid SQL expression returning a
|
|
1299
|
-
#
|
|
1299
|
+
# tsvector, and can be used directly in the query.
|
|
1300
1300
|
def full_text_search(cols, terms, opts = OPTS)
|
|
1301
1301
|
lang = Sequel.cast(opts[:language] || 'simple', :regconfig)
|
|
1302
1302
|
|
|
@@ -192,8 +192,13 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
|
192
192
|
deadline ||= time + @timeout
|
|
193
193
|
current_time = Time.now
|
|
194
194
|
raise(::Sequel::PoolTimeout, "timeout: #{@timeout}, elapsed: #{current_time - time}") if current_time > deadline
|
|
195
|
+
# :nocov:
|
|
196
|
+
# It's difficult to get to this point, it can only happen if there is a race condition
|
|
197
|
+
# where a connection cannot be acquired even after the thread is signalled by the condition
|
|
198
|
+
# variable that a connection is ready.
|
|
195
199
|
@waiters[server].wait(@mutex, deadline - current_time)
|
|
196
200
|
Thread.pass
|
|
201
|
+
# :nocov:
|
|
197
202
|
end
|
|
198
203
|
|
|
199
204
|
conn
|
|
@@ -4,7 +4,9 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
4
4
|
# Whether or not a ConditionVariable should be used to wait for connections.
|
|
5
5
|
# True except on ruby 1.8, where ConditionVariable#wait does not support a
|
|
6
6
|
# timeout.
|
|
7
|
-
USE_WAITER
|
|
7
|
+
unless defined?(USE_WAITER)
|
|
8
|
+
USE_WAITER = RUBY_VERSION >= '1.9'
|
|
9
|
+
end
|
|
8
10
|
|
|
9
11
|
# The maximum number of connections this pool will create (per shard/server
|
|
10
12
|
# if sharding).
|
|
@@ -40,7 +42,9 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
40
42
|
if USE_WAITER
|
|
41
43
|
@waiter = ConditionVariable.new
|
|
42
44
|
else
|
|
45
|
+
# :nocov:
|
|
43
46
|
@sleep_time = Float(opts[:pool_sleep_time] || 0.001)
|
|
47
|
+
# :nocov:
|
|
44
48
|
end
|
|
45
49
|
end
|
|
46
50
|
|
|
@@ -155,8 +159,12 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
155
159
|
deadline ||= time + @timeout
|
|
156
160
|
current_time = Time.now
|
|
157
161
|
raise(::Sequel::PoolTimeout, "timeout: #{@timeout}, elapsed: #{current_time - time}") if current_time > deadline
|
|
162
|
+
# :nocov:
|
|
163
|
+
# It's difficult to get to this point, it can only happen if there is a race condition
|
|
164
|
+
# where a connection cannot be acquired even after the thread is signalled by the condition
|
|
158
165
|
@waiter.wait(@mutex, deadline - current_time)
|
|
159
166
|
Thread.pass
|
|
167
|
+
# :nocov:
|
|
160
168
|
end
|
|
161
169
|
|
|
162
170
|
conn
|
|
@@ -6,7 +6,7 @@ module Sequel
|
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
8
8
|
# Array of supported database adapters
|
|
9
|
-
ADAPTERS = %w'ado amalgalite cubrid db2 dbi do
|
|
9
|
+
ADAPTERS = %w'ado amalgalite cubrid db2 dbi do firebird ibmdb informix jdbc mock mysql mysql2 odbc oracle postgres sqlanywhere sqlite swift tinytds'.collect(&:to_sym)
|
|
10
10
|
|
|
11
11
|
@single_threaded = false
|
|
12
12
|
|
|
@@ -124,7 +124,7 @@ module Sequel
|
|
|
124
124
|
begin_transaction(conn, opts)
|
|
125
125
|
if rollback == :always
|
|
126
126
|
begin
|
|
127
|
-
yield(conn)
|
|
127
|
+
ret = yield(conn)
|
|
128
128
|
rescue Exception => e1
|
|
129
129
|
raise e1
|
|
130
130
|
ensure
|
|
@@ -139,6 +139,7 @@ module Sequel
|
|
|
139
139
|
rescue Exception
|
|
140
140
|
end
|
|
141
141
|
transaction_error(e, :conn=>conn, :rollback=>rollback)
|
|
142
|
+
ret
|
|
142
143
|
ensure
|
|
143
144
|
begin
|
|
144
145
|
committed = commit_or_rollback_transaction(e, conn, opts)
|
|
@@ -224,6 +224,16 @@ module Sequel
|
|
|
224
224
|
end
|
|
225
225
|
end
|
|
226
226
|
|
|
227
|
+
# Modify the default create_table generator to include
|
|
228
|
+
# the constraint validation methods.
|
|
229
|
+
def create_table_generator(&block)
|
|
230
|
+
super do
|
|
231
|
+
extend CreateTableGeneratorMethods
|
|
232
|
+
@validations = []
|
|
233
|
+
instance_eval(&block) if block
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
227
237
|
# Drop the constraint validations table.
|
|
228
238
|
def drop_constraint_validations_table
|
|
229
239
|
drop_table(constraint_validations_table)
|
|
@@ -262,8 +272,6 @@ module Sequel
|
|
|
262
272
|
ds.delete
|
|
263
273
|
end
|
|
264
274
|
|
|
265
|
-
private
|
|
266
|
-
|
|
267
275
|
# Modify the default alter_table generator to include
|
|
268
276
|
# the constraint validation methods.
|
|
269
277
|
def alter_table_generator(&block)
|
|
@@ -274,6 +282,8 @@ module Sequel
|
|
|
274
282
|
end
|
|
275
283
|
end
|
|
276
284
|
|
|
285
|
+
private
|
|
286
|
+
|
|
277
287
|
# After running all of the table alteration statements,
|
|
278
288
|
# if there were any constraint validations, run table alteration
|
|
279
289
|
# statements to create related constraints. This is purposely
|
|
@@ -317,16 +327,6 @@ module Sequel
|
|
|
317
327
|
super
|
|
318
328
|
end
|
|
319
329
|
|
|
320
|
-
# Modify the default create_table generator to include
|
|
321
|
-
# the constraint validation methods.
|
|
322
|
-
def create_table_generator(&block)
|
|
323
|
-
super do
|
|
324
|
-
extend CreateTableGeneratorMethods
|
|
325
|
-
@validations = []
|
|
326
|
-
instance_eval(&block) if block
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
330
|
# For the given table, generator, and validations, add constraints
|
|
331
331
|
# to the generator for each of the validations, as well as adding
|
|
332
332
|
# validation metadata to the constraint validations table.
|
|
@@ -123,10 +123,6 @@ module Sequel
|
|
|
123
123
|
expr = Sequel.+(expr, Sequel.lit(["", " "], value, sql_unit))
|
|
124
124
|
end
|
|
125
125
|
false
|
|
126
|
-
when :fdbsql
|
|
127
|
-
each_valid_interval_unit(h, FDBSQL_DURATION_UNITS) do |value, sql_unit|
|
|
128
|
-
expr = Sequel.+(expr, Sequel.lit(["INTERVAL ", " "], value, sql_unit))
|
|
129
|
-
end
|
|
130
126
|
else
|
|
131
127
|
raise Error, "date arithmetic is not implemented on #{db.database_type}"
|
|
132
128
|
end
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# The pagination extension adds the Sequel::Dataset#paginate and #each_page methods,
|
|
2
|
-
# which return paginated (limited and offset) datasets with
|
|
3
|
-
# that make creating a paginated display easier
|
|
2
|
+
# which return paginated (limited and offset) datasets with the following methods
|
|
3
|
+
# added that make creating a paginated display easier:
|
|
4
|
+
#
|
|
5
|
+
# * +page_size+
|
|
6
|
+
# * +page_count+
|
|
7
|
+
# * +page_range+
|
|
8
|
+
# * +current_page+
|
|
9
|
+
# * +next_page+
|
|
10
|
+
# * +prev_page+
|
|
11
|
+
# * +first_page?+
|
|
12
|
+
# * +last_page?+
|
|
13
|
+
# * +pagination_record_count+
|
|
14
|
+
# * +current_page_record_count+
|
|
15
|
+
# * +current_page_record_range+
|
|
4
16
|
#
|
|
5
17
|
# This extension uses Object#extend at runtime, which can hurt performance.
|
|
6
18
|
#
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
# Just like any user-created type, after creating the type, you
|
|
19
19
|
# can create tables that have a column of that type:
|
|
20
20
|
#
|
|
21
|
-
# DB.create_table(:table_name)
|
|
21
|
+
# DB.create_table(:table_name) do
|
|
22
22
|
# enum_type_name :column_name
|
|
23
23
|
# end
|
|
24
24
|
#
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
# If the pg_array extension is used, arrays of enums are returned as a
|
|
32
32
|
# PGArray:
|
|
33
33
|
#
|
|
34
|
-
# DB.create_table(:table_name)
|
|
34
|
+
# DB.create_table(:table_name) do
|
|
35
35
|
# column :column_name, 'enum_type_name[]'
|
|
36
36
|
# end
|
|
37
37
|
# DB[:table_name].get(:column_name)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# as instances of Sequel::Postgres::HStore. HStore is
|
|
9
9
|
# a DelegateClass of Hash, so it mostly acts like a hash, but not
|
|
10
10
|
# completely (is_a?(Hash) is false). If you want the actual hash,
|
|
11
|
-
# you can call
|
|
11
|
+
# you can call HStore#to_hash. This is done so that Sequel does not
|
|
12
12
|
# treat a HStore like a Hash by default, which would cause issues.
|
|
13
13
|
#
|
|
14
14
|
# In addition to the parsers, this extension comes with literalizers
|
|
@@ -210,9 +210,9 @@ module Sequel
|
|
|
210
210
|
private
|
|
211
211
|
|
|
212
212
|
# Return a placeholder literal with the given str and args, wrapped
|
|
213
|
-
# in an JSONOp, used by operators that return json.
|
|
213
|
+
# in an JSONOp or JSONBOp, used by operators that return json or jsonb.
|
|
214
214
|
def json_op(str, args)
|
|
215
|
-
|
|
215
|
+
self.class.new(Sequel::SQL::PlaceholderLiteralString.new(str, [self, args]))
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
# Return a function with the given name, and the receiver as the first
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
module Plugins
|
|
3
|
+
# The delay_add_association plugin delays the adding of
|
|
4
|
+
# associated objects to a new (unsaved) object until after the new
|
|
5
|
+
# object is saved. By default, if you attempt to add
|
|
6
|
+
# associated objects to a new object, Sequel will raise
|
|
7
|
+
# an error, because you need to have a primary key before
|
|
8
|
+
# saving the objects.
|
|
9
|
+
#
|
|
10
|
+
# When delaying the add of an associated object, the object
|
|
11
|
+
# will be immediately added to the cached association array.
|
|
12
|
+
# When saving the current object, it will also attempt to
|
|
13
|
+
# validate any associated objects, and if the associated objects
|
|
14
|
+
# are not valid, the current object will also be considered
|
|
15
|
+
# not valid.
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
#
|
|
19
|
+
# # Make all model subclass delay add_association for new objects
|
|
20
|
+
# Sequel::Model.plugin :delay_add_association
|
|
21
|
+
#
|
|
22
|
+
# # Make the Album class delay add_association for new objects
|
|
23
|
+
# Album.plugin :delay_add_association
|
|
24
|
+
module DelayAddAssociation
|
|
25
|
+
# Depend on the validate_associated plugin.
|
|
26
|
+
def self.apply(mod)
|
|
27
|
+
mod.plugin :validate_associated
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module InstanceMethods
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# Delay the addition of the associated object till after
|
|
34
|
+
# saving the current object, if the current object is new
|
|
35
|
+
# and the associated dataset requires a primary key on the
|
|
36
|
+
# current object.
|
|
37
|
+
def add_associated_object(opts, o, *args)
|
|
38
|
+
if opts.dataset_need_primary_key? && new?
|
|
39
|
+
delay_validate_associated_object(opts, o)
|
|
40
|
+
send(opts[:name]) << o
|
|
41
|
+
after_create_hook{super(opts, o, *args)}
|
|
42
|
+
o
|
|
43
|
+
else
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/sequel/plugins/list.rb
CHANGED
|
@@ -129,11 +129,11 @@ module Sequel
|
|
|
129
129
|
checked_transaction do
|
|
130
130
|
ds = list_dataset
|
|
131
131
|
op, ds = if target < current
|
|
132
|
-
|
|
132
|
+
target = 1 if target < 1
|
|
133
133
|
[:+, ds.filter(position_field=>target...current)]
|
|
134
134
|
else
|
|
135
135
|
lp ||= last_position
|
|
136
|
-
|
|
136
|
+
target = lp if target > lp
|
|
137
137
|
[:-, ds.filter(position_field=>(current + 1)..target)]
|
|
138
138
|
end
|
|
139
139
|
ds.update(position_field => Sequel::SQL::NumericExpression.new(op, position_field, 1))
|
|
@@ -37,14 +37,16 @@ module Sequel
|
|
|
37
37
|
# of creating a new album.
|
|
38
38
|
#
|
|
39
39
|
# If you would like to delete the associated object instead of updating it, you add a _delete
|
|
40
|
-
# entry to the hash:
|
|
40
|
+
# entry to the hash, and also pass the :destroy option when calling +nested_attributes+:
|
|
41
41
|
#
|
|
42
|
+
# Artist.nested_attributes :albums, :destroy=>true
|
|
42
43
|
# a.update(:albums_attributes => [{:id=>1, :_delete=>true}])
|
|
43
44
|
#
|
|
44
45
|
# This will delete the related associated object from the database. If you want to leave the
|
|
45
46
|
# associated object in the database, but just remove it from the association, add a _remove
|
|
46
|
-
# entry in the hash:
|
|
47
|
+
# entry in the hash, and also pass the :remove option when calling +nested_attributes+:
|
|
47
48
|
#
|
|
49
|
+
# Artist.nested_attributes :albums, :remove=>true
|
|
48
50
|
# a.update(:albums_attributes => [{:id=>1, :_remove=>true}])
|
|
49
51
|
#
|
|
50
52
|
# The above example was for a one_to_many association, but the plugin also works similarly
|
|
@@ -71,9 +73,9 @@ module Sequel
|
|
|
71
73
|
# To save changes to the artist, create the first album and associate it to the artist,
|
|
72
74
|
# and update the other existing associated album.
|
|
73
75
|
module NestedAttributes
|
|
74
|
-
# Depend on the
|
|
76
|
+
# Depend on the validate_associated plugin.
|
|
75
77
|
def self.apply(model)
|
|
76
|
-
model.plugin(:
|
|
78
|
+
model.plugin(:validate_associated)
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
module ClassMethods
|
|
@@ -166,7 +168,7 @@ module Sequel
|
|
|
166
168
|
reflection = meta[:reflection]
|
|
167
169
|
obj = reflection.associated_class.new
|
|
168
170
|
nested_attributes_set_attributes(meta, obj, attributes)
|
|
169
|
-
|
|
171
|
+
delay_validate_associated_object(reflection, obj)
|
|
170
172
|
if reflection.returns_array?
|
|
171
173
|
send(reflection[:name]) << obj
|
|
172
174
|
after_save_hook{send(reflection.add_method, obj)}
|
|
@@ -282,7 +284,7 @@ module Sequel
|
|
|
282
284
|
# Returns the object updated.
|
|
283
285
|
def nested_attributes_update(meta, obj, attributes)
|
|
284
286
|
nested_attributes_update_attributes(meta, obj, attributes)
|
|
285
|
-
|
|
287
|
+
delay_validate_associated_object(meta[:reflection], obj)
|
|
286
288
|
# Don't need to validate the object twice if :validate association option is not false
|
|
287
289
|
# and don't want to validate it at all if it is false.
|
|
288
290
|
after_save_hook{obj.save_changes(:validate=>false)}
|
|
@@ -295,28 +297,6 @@ module Sequel
|
|
|
295
297
|
nested_attributes_set_attributes(meta, obj, attributes)
|
|
296
298
|
end
|
|
297
299
|
end
|
|
298
|
-
|
|
299
|
-
# Validate the given associated object, adding any validation error messages from the
|
|
300
|
-
# given object to the parent object.
|
|
301
|
-
def validate_associated_object(meta, obj)
|
|
302
|
-
reflection = meta[:reflection]
|
|
303
|
-
return if reflection[:validate] == false
|
|
304
|
-
association = reflection[:name]
|
|
305
|
-
if (reflection[:type] == :one_to_many || reflection[:type] == :one_to_one) && (key = reflection[:key]).is_a?(Symbol) && !(pk_val = obj.values[key])
|
|
306
|
-
# There could be a presence validation on the foreign key in the associated model,
|
|
307
|
-
# which will fail if we validate before saving the current object. If there is
|
|
308
|
-
# no value for the foreign key, set it to the current primary key value, or a dummy
|
|
309
|
-
# value of 0 if we haven't saved the current object.
|
|
310
|
-
p_key = pk unless pk.is_a?(Array)
|
|
311
|
-
obj.values[key] = p_key || 0
|
|
312
|
-
key = nil if p_key
|
|
313
|
-
end
|
|
314
|
-
obj.errors.full_messages.each{|m| errors.add(association, m)} unless obj.valid?
|
|
315
|
-
if key && !pk_val
|
|
316
|
-
# If we used a dummy value of 0, remove it so it doesn't accidently remain.
|
|
317
|
-
obj.values.delete(key)
|
|
318
|
-
end
|
|
319
|
-
end
|
|
320
300
|
end
|
|
321
301
|
end
|
|
322
302
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
module Plugins
|
|
3
|
+
# The update_refresh plugin makes the model class refresh
|
|
4
|
+
# the object after updating. By default, Sequel only
|
|
5
|
+
# refreshes automatically after inserting new rows, not
|
|
6
|
+
# after updating. However, if you are using triggers
|
|
7
|
+
# to modify the contents of updated rows, it can be
|
|
8
|
+
# helpful to immediately get the current data after
|
|
9
|
+
# updating.
|
|
10
|
+
#
|
|
11
|
+
# If the dataset supports UPDATE RETURNING, this
|
|
12
|
+
# plugin will use it so that it can retrieve the current
|
|
13
|
+
# data in the same query it uses for the update.
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
#
|
|
17
|
+
# # Make all model subclasses refresh after update
|
|
18
|
+
# Sequel::Model.plugin :update_refresh
|
|
19
|
+
#
|
|
20
|
+
# # Make the Album class refresh after update
|
|
21
|
+
# Album.plugin :update_refresh
|
|
22
|
+
module UpdateRefresh
|
|
23
|
+
module InstanceMethods
|
|
24
|
+
def after_update
|
|
25
|
+
super
|
|
26
|
+
unless this.supports_returning?(:update)
|
|
27
|
+
refresh
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def _update_without_checking(columns)
|
|
34
|
+
ds = _update_dataset
|
|
35
|
+
if ds.supports_returning?(:update)
|
|
36
|
+
ds = ds.opts[:returning] ? ds : ds.returning
|
|
37
|
+
rows = ds.update(columns)
|
|
38
|
+
n = rows.length
|
|
39
|
+
if n == 1
|
|
40
|
+
@values.merge!(rows.first)
|
|
41
|
+
end
|
|
42
|
+
n
|
|
43
|
+
else
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|