sequel 3.44.0 → 3.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +44 -0
- data/Rakefile +12 -4
- data/doc/reflection.rdoc +3 -3
- data/doc/release_notes/3.45.0.txt +179 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/transactions.rdoc +23 -0
- data/lib/sequel/adapters/db2.rb +1 -0
- data/lib/sequel/adapters/ibmdb.rb +19 -3
- data/lib/sequel/adapters/jdbc.rb +15 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -5
- data/lib/sequel/adapters/jdbc/h2.rb +1 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -1
- data/lib/sequel/adapters/jdbc/jtds.rb +5 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +5 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +7 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
- data/lib/sequel/adapters/jdbc/transactions.rb +28 -1
- data/lib/sequel/adapters/mysql.rb +4 -0
- data/lib/sequel/adapters/mysql2.rb +5 -1
- data/lib/sequel/adapters/oracle.rb +18 -0
- data/lib/sequel/adapters/postgres.rb +11 -1
- data/lib/sequel/adapters/shared/access.rb +14 -2
- data/lib/sequel/adapters/shared/cubrid.rb +1 -11
- data/lib/sequel/adapters/shared/db2.rb +11 -6
- data/lib/sequel/adapters/shared/mssql.rb +10 -10
- data/lib/sequel/adapters/shared/mysql.rb +11 -1
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +17 -1
- data/lib/sequel/adapters/shared/oracle.rb +16 -15
- data/lib/sequel/adapters/shared/postgres.rb +91 -59
- data/lib/sequel/adapters/shared/sqlite.rb +1 -4
- data/lib/sequel/adapters/tinytds.rb +15 -0
- data/lib/sequel/connection_pool/threaded.rb +1 -1
- data/lib/sequel/core.rb +10 -0
- data/lib/sequel/database/connecting.rb +2 -0
- data/lib/sequel/database/misc.rb +46 -4
- data/lib/sequel/database/query.rb +33 -14
- data/lib/sequel/database/schema_methods.rb +0 -5
- data/lib/sequel/dataset/misc.rb +9 -0
- data/lib/sequel/dataset/mutation.rb +9 -7
- data/lib/sequel/dataset/sql.rb +13 -0
- data/lib/sequel/exceptions.rb +3 -0
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/date_arithmetic.rb +0 -8
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/named_timezones.rb +18 -2
- data/lib/sequel/extensions/pg_array.rb +5 -1
- data/lib/sequel/extensions/pg_array_ops.rb +2 -0
- data/lib/sequel/extensions/pg_hstore.rb +2 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
- data/lib/sequel/extensions/pg_json.rb +3 -1
- data/lib/sequel/extensions/pg_range.rb +2 -0
- data/lib/sequel/extensions/pg_range_ops.rb +2 -0
- data/lib/sequel/extensions/pg_row.rb +2 -0
- data/lib/sequel/extensions/pg_row_ops.rb +2 -0
- data/lib/sequel/extensions/query.rb +18 -22
- data/lib/sequel/model/associations.rb +3 -4
- data/lib/sequel/model/base.rb +2 -0
- data/lib/sequel/plugins/force_encoding.rb +2 -0
- data/lib/sequel/plugins/json_serializer.rb +155 -39
- data/lib/sequel/plugins/serialization.rb +14 -2
- data/lib/sequel/plugins/unlimited_update.rb +31 -0
- data/lib/sequel/plugins/validation_class_methods.rb +6 -4
- data/lib/sequel/plugins/xml_serializer.rb +133 -30
- data/lib/sequel/sql.rb +2 -0
- data/lib/sequel/timezones.rb +4 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +0 -11
- data/spec/adapters/postgres_spec.rb +86 -54
- data/spec/adapters/spec_helper.rb +6 -0
- data/spec/core/connection_pool_spec.rb +16 -0
- data/spec/core/database_spec.rb +77 -1
- data/spec/core/dataset_spec.rb +30 -15
- data/spec/core/expression_filters_spec.rb +55 -13
- data/spec/core/mock_adapter_spec.rb +4 -0
- data/spec/core/schema_spec.rb +0 -2
- data/spec/core/spec_helper.rb +5 -0
- data/spec/core_extensions_spec.rb +33 -28
- data/spec/extensions/constraint_validations_spec.rb +2 -2
- data/spec/extensions/core_refinements_spec.rb +12 -12
- data/spec/extensions/json_serializer_spec.rb +137 -31
- data/spec/extensions/named_timezones_spec.rb +10 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +5 -0
- data/spec/extensions/pg_json_spec.rb +14 -0
- data/spec/extensions/pg_row_spec.rb +11 -0
- data/spec/extensions/pretty_table_spec.rb +2 -2
- data/spec/extensions/query_spec.rb +11 -8
- data/spec/extensions/serialization_spec.rb +20 -0
- data/spec/extensions/spec_helper.rb +8 -2
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +20 -0
- data/spec/extensions/xml_serializer_spec.rb +68 -16
- data/spec/integration/dataset_test.rb +28 -0
- data/spec/integration/spec_helper.rb +6 -0
- data/spec/integration/transaction_test.rb +39 -0
- data/spec/model/model_spec.rb +1 -1
- data/spec/sequel_coverage.rb +15 -0
- metadata +8 -3
@@ -98,7 +98,7 @@ module Sequel
|
|
98
98
|
# parsing does not yield an array or hash.
|
99
99
|
def self.parse_json(s)
|
100
100
|
begin
|
101
|
-
value =
|
101
|
+
value = Sequel.parse_json(s)
|
102
102
|
rescue JSON::ParserError=>e
|
103
103
|
raise Sequel.convert_exception_class(e, Sequel::InvalidValue)
|
104
104
|
end
|
@@ -192,6 +192,7 @@ module Sequel
|
|
192
192
|
Database.register_extension(:pg_json, Postgres::JSONDatabaseMethods)
|
193
193
|
end
|
194
194
|
|
195
|
+
# :nocov:
|
195
196
|
if Sequel.core_extensions?
|
196
197
|
class Array
|
197
198
|
# Return a Sequel::Postgres::JSONArray proxy to the receiver.
|
@@ -227,3 +228,4 @@ if defined?(Sequel::CoreRefinements)
|
|
227
228
|
end
|
228
229
|
end
|
229
230
|
end
|
231
|
+
# :nocov:
|
@@ -503,6 +503,7 @@ module Sequel
|
|
503
503
|
Database.register_extension(:pg_range, Postgres::PGRange::DatabaseMethods)
|
504
504
|
end
|
505
505
|
|
506
|
+
# :nocov:
|
506
507
|
if Sequel.core_extensions?
|
507
508
|
class Range
|
508
509
|
# Create a new PGRange using the receiver as the input range,
|
@@ -522,3 +523,4 @@ if defined?(Sequel::CoreRefinements)
|
|
522
523
|
end
|
523
524
|
end
|
524
525
|
end
|
526
|
+
# :nocov:
|
@@ -572,6 +572,7 @@ module Sequel
|
|
572
572
|
Database.register_extension(:pg_row, Postgres::PGRow::DatabaseMethods)
|
573
573
|
end
|
574
574
|
|
575
|
+
# :nocov:
|
575
576
|
if Sequel.core_extensions?
|
576
577
|
class Array
|
577
578
|
# Wraps the receiver in an anonymous Sequel::Postgres::PGRow::ArrayRow instance.
|
@@ -590,3 +591,4 @@ if defined?(Sequel::CoreRefinements)
|
|
590
591
|
end
|
591
592
|
end
|
592
593
|
end
|
594
|
+
# :nocov:
|
@@ -176,6 +176,7 @@ module Sequel
|
|
176
176
|
end
|
177
177
|
end
|
178
178
|
|
179
|
+
# :nocov:
|
179
180
|
if Sequel.core_extensions?
|
180
181
|
class Symbol
|
181
182
|
include Sequel::Postgres::PGRowOp::ExpressionMethods
|
@@ -189,3 +190,4 @@ if defined?(Sequel::CoreRefinements)
|
|
189
190
|
end
|
190
191
|
end
|
191
192
|
end
|
193
|
+
# :nocov:
|
@@ -1,12 +1,10 @@
|
|
1
1
|
# The query extension adds Sequel::Dataset#query which allows
|
2
2
|
# a different way to construct queries instead of the usual
|
3
|
-
# method chaining.
|
3
|
+
# method chaining. See Sequel::Dataset#query for details.
|
4
4
|
#
|
5
5
|
# To load the extension, do:
|
6
6
|
#
|
7
7
|
# Sequel.extension :query
|
8
|
-
#
|
9
|
-
# This extension uses Object#extend at runtime, which can hurt performance.
|
10
8
|
|
11
9
|
module Sequel
|
12
10
|
class Database
|
@@ -17,8 +15,9 @@ module Sequel
|
|
17
15
|
end
|
18
16
|
|
19
17
|
class Dataset
|
20
|
-
# Translates a query block into a dataset. Query blocks
|
21
|
-
#
|
18
|
+
# Translates a query block into a dataset. Query blocks are an
|
19
|
+
# alternative to Sequel's usual method chaining, by using
|
20
|
+
# instance_eval with a proxy object:
|
22
21
|
#
|
23
22
|
# dataset = DB[:items].query do
|
24
23
|
# select :x, :y, :z
|
@@ -29,28 +28,25 @@ module Sequel
|
|
29
28
|
# Which is the same as:
|
30
29
|
#
|
31
30
|
# dataset = DB[:items].select(:x, :y, :z).filter{(x > 1) & (y > 2)}.reverse(:z)
|
32
|
-
#
|
33
|
-
# Note that inside a call to query, you cannot call each, insert, update,
|
34
|
-
# or delete (or any method that calls those), or Sequel will raise an
|
35
|
-
# error.
|
36
31
|
def query(&block)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
clone(copy.opts)
|
32
|
+
query = Query.new(self)
|
33
|
+
query.instance_eval(&block)
|
34
|
+
query.dataset
|
41
35
|
end
|
42
36
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
# Proxy object used by Dataset#query.
|
38
|
+
class Query < Sequel::BasicObject
|
39
|
+
# The current dataset in the query. This changes on each method call.
|
40
|
+
attr_reader :dataset
|
41
|
+
|
42
|
+
def initialize(dataset)
|
43
|
+
@dataset = dataset
|
48
44
|
end
|
49
45
|
|
50
|
-
#
|
51
|
-
|
52
|
-
|
53
|
-
@
|
46
|
+
# Replace the query's dataset with dataset returned by the method call.
|
47
|
+
def method_missing(method, *args, &block)
|
48
|
+
@dataset = @dataset.send(method, *args, &block)
|
49
|
+
raise(Sequel::Error, "method #{method.inspect} did not return a dataset") unless @dataset.is_a?(Dataset)
|
54
50
|
self
|
55
51
|
end
|
56
52
|
end
|
@@ -254,6 +254,7 @@ module Sequel
|
|
254
254
|
private
|
255
255
|
|
256
256
|
if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'ruby'
|
257
|
+
# :nocov:
|
257
258
|
# On non-GVL rubies, assume the need to synchronize access. Store the key
|
258
259
|
# in a special sub-hash that always uses this method to synchronize access.
|
259
260
|
def cached_fetch(key)
|
@@ -270,6 +271,7 @@ module Sequel
|
|
270
271
|
h = self[:cache]
|
271
272
|
Sequel.synchronize{h[key] = value}
|
272
273
|
end
|
274
|
+
# :nocov:
|
273
275
|
else
|
274
276
|
# On MRI, use a plain fetch, since the GVL will synchronize access.
|
275
277
|
def cached_fetch(key)
|
@@ -1749,10 +1751,7 @@ module Sequel
|
|
1749
1751
|
#
|
1750
1752
|
# Artist.eager(:albums => {proc{|ds| ds.where{year > 1990}}=>{:tracks => :genre}})
|
1751
1753
|
module DatasetMethods
|
1752
|
-
|
1753
|
-
def self.extended(obj)
|
1754
|
-
obj.def_mutation_method(:eager, :eager_graph)
|
1755
|
-
end
|
1754
|
+
Sequel::Dataset.def_mutation_method(:eager, :eager_graph, :module=>self)
|
1756
1755
|
|
1757
1756
|
# If the expression is in the form <tt>x = y</tt> where +y+ is a <tt>Sequel::Model</tt>
|
1758
1757
|
# instance, array of <tt>Sequel::Model</tt> instances, or a <tt>Sequel::Model</tt> dataset,
|
data/lib/sequel/model/base.rb
CHANGED
@@ -36,30 +36,54 @@ module Sequel
|
|
36
36
|
# album.to_json(:root => true)
|
37
37
|
# # => '{"album":{"id":1,"name":"RF","artist_id":2}}'
|
38
38
|
#
|
39
|
+
# Additionally, +to_json+ also exists as a class and dataset method, both
|
40
|
+
# of which return all objects in the dataset:
|
41
|
+
#
|
42
|
+
# Album.to_json
|
43
|
+
# Album.filter(:artist_id=>1).to_json(:include=>:tags)
|
44
|
+
#
|
45
|
+
# If you have an existing array of model instances you want to convert to
|
46
|
+
# JSON, you can call the class to_json method with the :array option:
|
47
|
+
#
|
48
|
+
# Album.to_json(:array=>[Album[1], Album[2]])
|
49
|
+
#
|
39
50
|
# In addition to creating JSON, this plugin also enables Sequel::Model
|
40
|
-
#
|
51
|
+
# classes to create instances directly from JSON using the from_json class
|
52
|
+
# method:
|
41
53
|
#
|
42
54
|
# json = album.to_json
|
43
|
-
# album =
|
55
|
+
# album = Album.from_json(json)
|
56
|
+
#
|
57
|
+
# The array_from_json class method exists to parse arrays of model instances
|
58
|
+
# from json:
|
59
|
+
#
|
60
|
+
# json = Album.filter(:artist_id=>1).to_json
|
61
|
+
# albums = Album.array_from_json(json)
|
62
|
+
#
|
63
|
+
# These does not necessarily round trip, since doing so would let users
|
64
|
+
# create model objects with arbitrary values. By default, from_json will
|
65
|
+
# call set with the values in the hash. If you want to specify the allowed
|
66
|
+
# fields, you can use the :fields option, which will call set_fields with
|
67
|
+
# the given fields:
|
68
|
+
#
|
69
|
+
# Album.from_json(album.to_json, :fields=>%w'id name')
|
44
70
|
#
|
45
|
-
#
|
46
|
-
#
|
71
|
+
# If you want to update an existing instance, you can use the from_json
|
72
|
+
# instance method:
|
47
73
|
#
|
48
74
|
# album.from_json(json)
|
49
75
|
#
|
50
|
-
#
|
51
|
-
#
|
76
|
+
# Both of these allow creation of cached associated objects, if you provide
|
77
|
+
# the :associations option:
|
52
78
|
#
|
53
|
-
#
|
54
|
-
# of which return all objects in the dataset:
|
79
|
+
# album.from_json(json, :associations=>:artist)
|
55
80
|
#
|
56
|
-
#
|
57
|
-
# Album.filter(:artist_id=>1).to_json(:include=>:tags)
|
81
|
+
# You can even provide options when setting up the associated objects:
|
58
82
|
#
|
59
|
-
#
|
60
|
-
# JSON, you can call the class to_json method with the :array option:
|
83
|
+
# album.from_json(json, :associations=>{:artist=>{:fields=>%w'id name', :associations=>:tags}})
|
61
84
|
#
|
62
|
-
#
|
85
|
+
# If the json is trusted and should be allowed to set all column and association
|
86
|
+
# values, you can use the :all_columns and :all_associations options.
|
63
87
|
#
|
64
88
|
# Note that active_support/json makes incompatible changes to the to_json API,
|
65
89
|
# and breaks some aspects of the json_serializer plugin. You can undo the damage
|
@@ -116,29 +140,39 @@ module Sequel
|
|
116
140
|
# The default opts to use when serializing model objects to JSON.
|
117
141
|
attr_reader :json_serializer_opts
|
118
142
|
|
119
|
-
#
|
120
|
-
#
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
143
|
+
# Attempt to parse a single instance from the given JSON string,
|
144
|
+
# with options passed to InstanceMethods#from_json_node.
|
145
|
+
def from_json(json, opts={})
|
146
|
+
v = Sequel.parse_json(json)
|
147
|
+
case v
|
148
|
+
when self
|
149
|
+
v
|
150
|
+
when Hash
|
151
|
+
new.from_json_node(v, opts)
|
152
|
+
else
|
153
|
+
raise Error, "parsed json doesn't return a hash or instance of #{self}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Attempt to parse an array of instances from the given JSON string,
|
158
|
+
# with options passed to InstanceMethods#from_json_node.
|
159
|
+
def array_from_json(json, opts={})
|
160
|
+
v = Sequel.parse_json(json)
|
161
|
+
if v.is_a?(Array)
|
162
|
+
raise(Error, 'parsed json returned an array containing non-hashes') unless v.all?{|ve| ve.is_a?(Hash) || ve.is_a?(self)}
|
163
|
+
v.map{|ve| ve.is_a?(self) ? ve : new.from_json_node(ve, opts)}
|
164
|
+
else
|
165
|
+
raise(Error, 'parsed json did not return an array')
|
140
166
|
end
|
141
|
-
|
167
|
+
end
|
168
|
+
|
169
|
+
# Exists for compatibility with old json library which allows creation
|
170
|
+
# of arbitrary ruby objects by JSON.parse. Creates a new instance
|
171
|
+
# and populates it using InstanceMethods#from_json_node with the
|
172
|
+
# :all_columns and :all_associations options. Not recommended for usage
|
173
|
+
# in new code, consider calling the from_json method directly with the JSON string.
|
174
|
+
def json_create(hash, opts={})
|
175
|
+
new.from_json_node(hash, {:all_columns=>true, :all_associations=>true}.merge(opts))
|
142
176
|
end
|
143
177
|
|
144
178
|
# Call the dataset +to_json+ method.
|
@@ -157,14 +191,96 @@ module Sequel
|
|
157
191
|
|
158
192
|
module InstanceMethods
|
159
193
|
# Parse the provided JSON, which should return a hash,
|
160
|
-
# and
|
194
|
+
# and process the hash with from_json_node.
|
161
195
|
def from_json(json, opts={})
|
162
|
-
|
196
|
+
from_json_node(Sequel.parse_json(json), opts)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Using the provided hash, update the instance with data contained in the hash. By default, just
|
200
|
+
# calls set with the hash values.
|
201
|
+
#
|
202
|
+
# Options:
|
203
|
+
# :all_associations :: Indicates that all associations supported by the model should be tried.
|
204
|
+
# This option also cascades to associations if used. It is better to use the
|
205
|
+
# :associations option instead of this option. This option only exists for
|
206
|
+
# backwards compatibility.
|
207
|
+
# :all_columns :: Overrides the setting logic allowing all setter methods be used,
|
208
|
+
# even if access to the setter method is restricted.
|
209
|
+
# This option cascades to associations if used, and can be reset in those associations
|
210
|
+
# using the :all_columns=>false or :fields options. This option is considered a
|
211
|
+
# security risk, and only exists for backwards compatibility. It is better to use
|
212
|
+
# the :fields option appropriately instead of this option, or no option at all.
|
213
|
+
# :associations :: Indicates that the associations cache should be updated by creating
|
214
|
+
# a new associated object using data from the hash. Should be a Symbol
|
215
|
+
# for a single association, an array of symbols for multiple associations,
|
216
|
+
# or a hash with symbol keys and dependent association option hash values.
|
217
|
+
# :fields :: Changes the behavior to call set_fields using the provided fields, instead of calling set.
|
218
|
+
def from_json_node(hash, opts={})
|
219
|
+
unless hash.is_a?(Hash)
|
220
|
+
raise Error, "parsed json doesn't return a hash"
|
221
|
+
end
|
222
|
+
hash.delete(JSON.create_id)
|
223
|
+
|
224
|
+
unless assocs = opts[:associations]
|
225
|
+
if opts[:all_associations]
|
226
|
+
assocs = {}
|
227
|
+
model.associations.each{|v| assocs[v] = {:all_associations=>true}}
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
if assocs
|
232
|
+
assocs = case assocs
|
233
|
+
when Symbol
|
234
|
+
{assocs=>{}}
|
235
|
+
when Array
|
236
|
+
assocs_tmp = {}
|
237
|
+
assocs.each{|v| assocs_tmp[v] = {}}
|
238
|
+
assocs_tmp
|
239
|
+
when Hash
|
240
|
+
assocs
|
241
|
+
else
|
242
|
+
raise Error, ":associations should be Symbol, Array, or Hash if present"
|
243
|
+
end
|
244
|
+
|
245
|
+
if opts[:all_columns]
|
246
|
+
assocs.each_value do |assoc_opts|
|
247
|
+
assoc_opts[:all_columns] = true unless assoc_opts.has_key?(:fields) || assoc_opts.has_key?(:all_columns)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
assocs.each do |assoc, assoc_opts|
|
252
|
+
if assoc_values = hash.delete(assoc.to_s)
|
253
|
+
unless r = model.association_reflection(assoc)
|
254
|
+
raise Error, "Association #{assoc} is not defined for #{model}"
|
255
|
+
end
|
256
|
+
|
257
|
+
associations[assoc] = if r.returns_array?
|
258
|
+
raise Error, "Attempt to populate array association with a non-array" unless assoc_values.is_a?(Array)
|
259
|
+
assoc_values.map{|v| v.is_a?(r.associated_class) ? v : r.associated_class.new.from_json_node(v, assoc_opts)}
|
260
|
+
else
|
261
|
+
raise Error, "Attempt to populate non-array association with an array" if assoc_values.is_a?(Array)
|
262
|
+
assoc_values.is_a?(r.associated_class) ? assoc_values : r.associated_class.new.from_json_node(assoc_values, assoc_opts)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
163
268
|
if fields = opts[:fields]
|
164
|
-
set_fields(
|
269
|
+
set_fields(hash, fields, opts)
|
270
|
+
elsif opts[:all_columns]
|
271
|
+
meths = methods.collect{|x| x.to_s}.grep(Model::SETTER_METHOD_REGEXP) - Model::RESTRICTED_SETTER_METHODS
|
272
|
+
hash.each do |k, v|
|
273
|
+
if meths.include?(setter_meth = "#{k}=")
|
274
|
+
send(setter_meth, v)
|
275
|
+
else
|
276
|
+
raise Error, "Entry in JSON does not have a matching setter method: #{k}"
|
277
|
+
end
|
278
|
+
end
|
165
279
|
else
|
166
|
-
set(
|
280
|
+
set(hash)
|
167
281
|
end
|
282
|
+
|
283
|
+
self
|
168
284
|
end
|
169
285
|
|
170
286
|
# Return a string in JSON format. Accepts the following
|
@@ -82,9 +82,21 @@ module Sequel
|
|
82
82
|
def self.register_format(format, serializer, deserializer)
|
83
83
|
REGISTERED_FORMATS[format] = [serializer, deserializer]
|
84
84
|
end
|
85
|
-
register_format(:marshal, lambda{|v| [Marshal.dump(v)].pack('m')},
|
85
|
+
register_format(:marshal, lambda{|v| [Marshal.dump(v)].pack('m')},
|
86
|
+
lambda do |v|
|
87
|
+
begin
|
88
|
+
Marshal.load(v.unpack('m')[0])
|
89
|
+
rescue => e
|
90
|
+
begin
|
91
|
+
# Backwards compatibility for unpacked marshal output.
|
92
|
+
Marshal.load(v)
|
93
|
+
rescue
|
94
|
+
raise e
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end)
|
86
98
|
register_format(:yaml, lambda{|v| v.to_yaml}, lambda{|v| YAML.load(v)})
|
87
|
-
register_format(:json, lambda{|v| v.to_json}, lambda{|v|
|
99
|
+
register_format(:json, lambda{|v| v.to_json}, lambda{|v| Sequel.parse_json(v)})
|
88
100
|
|
89
101
|
module ClassMethods
|
90
102
|
# A hash with column name symbols and callable values, with the value
|