module Sequel::Postgres::JSONDatabaseMethods
Methods enabling Database
object integration with the json type.
Attributes
Whether to typecast strings for json/jsonb types as JSON strings, instead of trying to parse the string as JSON. False by default.
Whether to wrap JSON primitives instead of using Ruby objects. Wrapping the primitives allows the primitive values to roundtrip, but it can cause problems, especially as false/null JSON values will be treated as truthy in Ruby due to the wrapping. False by default.
Public Class Methods
Source
# File lib/sequel/extensions/pg_json.rb 314 def self.db_parse_json(s) 315 # SEQUEL6: Remove 316 parse_json(s) 317 rescue Sequel::InvalidValue 318 raise unless s.is_a?(String) 319 parse_json("[#{s}]").first 320 end
Deprecated
Source
# File lib/sequel/extensions/pg_json.rb 323 def self.db_parse_jsonb(s) 324 # SEQUEL6: Remove 325 parse_json(s, true) 326 rescue Sequel::InvalidValue 327 raise unless s.is_a?(String) 328 parse_json("[#{s}]").first 329 end
Deprecated
Source
# File lib/sequel/extensions/pg_json.rb 236 def self.extended(db) 237 db.instance_exec do 238 add_conversion_proc(114, method(:_db_parse_json)) 239 add_conversion_proc(3802, method(:_db_parse_jsonb)) 240 if respond_to?(:register_array_type) 241 register_array_type('json', :oid=>199, :scalar_oid=>114) 242 register_array_type('jsonb', :oid=>3807, :scalar_oid=>3802) 243 end 244 @schema_type_classes[:json] = [JSONObject] 245 @schema_type_classes[:jsonb] = [JSONBObject] 246 end 247 end
Source
# File lib/sequel/extensions/pg_json.rb 270 def self.json_primitive_wrapper(value) 271 case value 272 when ::Hash 273 JSONHash 274 when ::Array 275 JSONArray 276 when ::String 277 JSONString 278 when ::Integer 279 JSONInteger 280 when ::Float 281 JSONFloat 282 when ::NilClass 283 JSONNull 284 when ::TrueClass 285 JSONTrue 286 when ::FalseClass 287 JSONFalse 288 end 289 end
Return the wrapper class for the json type if value is a supported type.
Source
Source
# File lib/sequel/extensions/pg_json.rb 292 def self.jsonb_primitive_wrapper(value) 293 case value 294 when ::Hash 295 JSONBHash 296 when ::Array 297 JSONBArray 298 when ::String 299 JSONBString 300 when ::Integer 301 JSONBInteger 302 when ::Float 303 JSONBFloat 304 when ::NilClass 305 JSONBNull 306 when ::TrueClass 307 JSONBTrue 308 when ::FalseClass 309 JSONBFalse 310 end 311 end
Return the wrapper class for the jsonb type if value is a supported type.
Source
Source
# File lib/sequel/extensions/pg_json.rb 332 def self.parse_json(s, jsonb=false) 333 # SEQUEL6: Remove 334 Sequel::Deprecation.deprecate("Sequel::Postgres::JSONDatabaseMethods.{parse_json,db_parse_json,db_parse_jsonb} are deprecated and will be removed in Sequel 6.") 335 begin 336 value = Sequel.parse_json(s) 337 rescue Sequel.json_parser_error_class => e 338 raise Sequel.convert_exception_class(e, Sequel::InvalidValue) 339 end 340 341 case value 342 when Array 343 (jsonb ? JSONBArray : JSONArray).new(value) 344 when Hash 345 (jsonb ? JSONBHash : JSONHash).new(value) 346 when String, Numeric, true, false, nil 347 value 348 else 349 raise Sequel::InvalidValue, "unhandled json value: #{value.inspect} (from #{s.inspect})" 350 end 351 end
Deprecated
Public Instance Methods
Source
# File lib/sequel/extensions/pg_json.rb 366 def bound_variable_arg(arg, conn) 367 case arg 368 when JSONObject, JSONBObject 369 Sequel.object_to_json(arg) 370 else 371 super 372 end 373 end
Handle json and jsonb types in bound variables
Private Instance Methods
Source
# File lib/sequel/extensions/pg_json.rb 380 def _db_parse_json(s) 381 _wrap_json(_parse_json(s)) 382 rescue Sequel::InvalidValue 383 raise unless s.is_a?(String) 384 _wrap_json(_parse_json("[#{s}]").first) 385 end
Parse JSON data coming from the database. Since PostgreSQL allows non JSON data in JSON fields (such as plain numbers and strings), we don’t want to raise an exception for that.
Source
# File lib/sequel/extensions/pg_json.rb 388 def _db_parse_jsonb(s) 389 _wrap_jsonb(_parse_json(s)) 390 rescue Sequel::InvalidValue 391 raise unless s.is_a?(String) 392 _wrap_jsonb(_parse_json("[#{s}]").first) 393 end
Same as _db_parse_json
, but consider the input as jsonb.
Source
# File lib/sequel/extensions/pg_json.rb 399 def _parse_json(s) 400 Sequel.parse_json(s) 401 rescue Sequel.json_parser_error_class => e 402 raise Sequel.convert_exception_class(e, Sequel::InvalidValue) 403 end
Parse the given string as json, returning either a JSONArray
or JSONHash
instance (or JSONBArray
or JSONBHash
instance if jsonb argument is true), or a String
, Numeric
, true, false, or nil if the json library used supports that.
Source
# File lib/sequel/extensions/pg_json.rb 407 def _wrap_json(value) 408 if klass = JSONDatabaseMethods.json_wrapper(value) 409 klass.new(value) 410 elsif klass = JSONDatabaseMethods.json_primitive_wrapper(value) 411 if wrap_json_primitives 412 klass.new(value) 413 else 414 value 415 end 416 else 417 raise Sequel::InvalidValue, "unhandled json value: #{value.inspect}" 418 end 419 end
Wrap the parsed JSON value in the appropriate JSON wrapper class. Only wrap primitive values if wrap_json_primitives
is set.
Source
# File lib/sequel/extensions/pg_json.rb 423 def _wrap_jsonb(value) 424 if klass = JSONDatabaseMethods.jsonb_wrapper(value) 425 klass.new(value) 426 elsif klass = JSONDatabaseMethods.jsonb_primitive_wrapper(value) 427 if wrap_json_primitives 428 klass.new(value) 429 else 430 value 431 end 432 else 433 raise Sequel::InvalidValue, "unhandled jsonb value: #{value.inspect}" 434 end 435 end
Wrap the parsed JSON value in the appropriate JSONB wrapper class. Only wrap primitive values if wrap_json_primitives
is set.
Source
# File lib/sequel/extensions/pg_json.rb 438 def schema_column_type(db_type) 439 case db_type 440 when 'json' 441 :json 442 when 'jsonb' 443 :jsonb 444 else 445 super 446 end 447 end
Make the column type detection recognize the json types.
Source
# File lib/sequel/extensions/pg_json.rb 450 def schema_post_process(_) 451 super.each do |a| 452 h = a[1] 453 if (h[:type] == :json || h[:type] == :jsonb) && h[:default] =~ /\A'(\{\}|\[\])'::jsonb?\z/ 454 is_array = $1 == '[]' 455 456 klass = if h[:type] == :json 457 if is_array 458 JSONArray 459 else 460 JSONHash 461 end 462 elsif is_array 463 JSONBArray 464 else 465 JSONBHash 466 end 467 468 h[:callable_default] = lambda{klass.new(is_array ? [] : {})} 469 end 470 end 471 end
Set the :callable_default value if the default value is recognized as an empty json/jsonb array/hash.
Source
# File lib/sequel/extensions/pg_json.rb 474 def typecast_value_json(value) 475 case value 476 when JSONObject 477 value 478 when String 479 if typecast_json_strings 480 JSONString.new(value) 481 else 482 _wrap_json(_parse_json(value)) 483 end 484 when *JSON_WRAP_CLASSES 485 JSONDatabaseMethods.json_primitive_wrapper(value).new(value) 486 when JSONBObject 487 value = value.__getobj__ 488 JSONDatabaseMethods.json_primitive_wrapper(value).new(value) 489 else 490 raise Sequel::InvalidValue, "invalid value for json: #{value.inspect}" 491 end 492 end
Convert the value given to a JSON wrapper object.
Source
# File lib/sequel/extensions/pg_json.rb 495 def typecast_value_jsonb(value) 496 case value 497 when JSONBObject 498 value 499 when String 500 if typecast_json_strings 501 JSONBString.new(value) 502 else 503 _wrap_jsonb(_parse_json(value)) 504 end 505 when *JSON_WRAP_CLASSES 506 JSONDatabaseMethods.jsonb_primitive_wrapper(value).new(value) 507 when JSONObject 508 value = value.__getobj__ 509 JSONDatabaseMethods.jsonb_primitive_wrapper(value).new(value) 510 else 511 raise Sequel::InvalidValue, "invalid value for jsonb: #{value.inspect}" 512 end 513 end
Convert the value given to a JSONB wrapper object.