module Sequel::Postgres::JSONDatabaseMethods

Methods enabling Database object integration with the json type.

Public Class Methods

db_parse_json(s) click to toggle source

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.

    # File lib/sequel/extensions/pg_json.rb
145 def self.db_parse_json(s)
146   parse_json(s)
147 rescue Sequel::InvalidValue
148   raise unless s.is_a?(String)
149   parse_json("[#{s}]").first
150 end
db_parse_jsonb(s) click to toggle source

Same as db_parse_json, but consider the input as jsonb.

    # File lib/sequel/extensions/pg_json.rb
153 def self.db_parse_jsonb(s)
154   parse_json(s, true)
155 rescue Sequel::InvalidValue
156   raise unless s.is_a?(String)
157   parse_json("[#{s}]").first
158 end
extended(db) click to toggle source
    # File lib/sequel/extensions/pg_json.rb
129 def self.extended(db)
130   db.instance_exec do
131     add_conversion_proc(114, JSONDatabaseMethods.method(:db_parse_json))
132     add_conversion_proc(3802, JSONDatabaseMethods.method(:db_parse_jsonb))
133     if respond_to?(:register_array_type)
134       register_array_type('json', :oid=>199, :scalar_oid=>114)
135       register_array_type('jsonb', :oid=>3807, :scalar_oid=>3802)
136     end
137     @schema_type_classes[:json] = [JSONHash, JSONArray]
138     @schema_type_classes[:jsonb] = [JSONBHash, JSONBArray]
139   end
140 end
parse_json(s, jsonb=false) click to toggle source

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.

    # File lib/sequel/extensions/pg_json.rb
164 def self.parse_json(s, jsonb=false)
165   begin
166     value = Sequel.parse_json(s)
167   rescue Sequel.json_parser_error_class => e
168     raise Sequel.convert_exception_class(e, Sequel::InvalidValue)
169   end
170 
171   case value
172   when Array
173     (jsonb ? JSONBArray : JSONArray).new(value)
174   when Hash 
175     (jsonb ? JSONBHash : JSONHash).new(value)
176   when String, Numeric, true, false, nil
177     value
178   else
179     raise Sequel::InvalidValue, "unhandled json value: #{value.inspect} (from #{s.inspect})"
180   end
181 end

Public Instance Methods

bound_variable_arg(arg, conn) click to toggle source

Handle json and jsonb types in bound variables

Calls superclass method
    # File lib/sequel/extensions/pg_json.rb
184 def bound_variable_arg(arg, conn)
185   case arg
186   when JSONArrayBase, JSONHashBase
187     Sequel.object_to_json(arg)
188   else
189     super
190   end
191 end

Private Instance Methods

bound_variable_array(a) click to toggle source

Handle json[] and jsonb[] types in bound variables.

Calls superclass method
    # File lib/sequel/extensions/pg_json.rb
196 def bound_variable_array(a)
197   case a
198   when JSONHashBase, JSONArrayBase
199     "\"#{Sequel.object_to_json(a).gsub('"', '\\"')}\""
200   else
201     super
202   end
203 end
schema_column_type(db_type) click to toggle source

Make the column type detection recognize the json types.

Calls superclass method
    # File lib/sequel/extensions/pg_json.rb
206 def schema_column_type(db_type)
207   case db_type
208   when 'json'
209     :json
210   when 'jsonb'
211     :jsonb
212   else
213     super
214   end
215 end
schema_post_process(_) click to toggle source

Set the :callable_default value if the default value is recognized as an empty json/jsonb array/hash.

Calls superclass method
    # File lib/sequel/extensions/pg_json.rb
218 def schema_post_process(_)
219   super.each do |a|
220     h = a[1]
221     if (h[:type] == :json || h[:type] == :jsonb) && h[:default] =~ /\A'(\{\}|\[\])'::jsonb?\z/
222       is_array = $1 == '[]'
223 
224       klass = if h[:type] == :json
225         if is_array
226           JSONArray
227         else
228           JSONHash
229         end
230       elsif is_array
231         JSONBArray
232       else
233         JSONBHash
234       end
235 
236       h[:callable_default] = lambda{klass.new(is_array ? [] : {})}
237     end
238   end
239 end
typecast_value_json(value) click to toggle source

Convert the value given to a JSONArray or JSONHash

    # File lib/sequel/extensions/pg_json.rb
242 def typecast_value_json(value)
243   case value
244   when JSONArray, JSONHash
245     value
246   when Array
247     JSONArray.new(value)
248   when Hash 
249     JSONHash.new(value)
250   when JSONBArray
251     JSONArray.new(value.to_a)
252   when JSONBHash
253     JSONHash.new(value.to_hash)
254   when String
255     JSONDatabaseMethods.parse_json(value)
256   else
257     raise Sequel::InvalidValue, "invalid value for json: #{value.inspect}"
258   end
259 end
typecast_value_jsonb(value) click to toggle source

Convert the value given to a JSONBArray or JSONBHash

    # File lib/sequel/extensions/pg_json.rb
262 def typecast_value_jsonb(value)
263   case value
264   when JSONBArray, JSONBHash
265     value
266   when Array
267     JSONBArray.new(value)
268   when Hash 
269     JSONBHash.new(value)
270   when JSONArray
271     JSONBArray.new(value.to_a)
272   when JSONHash
273     JSONBHash.new(value.to_hash)
274   when String
275     JSONDatabaseMethods.parse_json(value, true)
276   else
277     raise Sequel::InvalidValue, "invalid value for jsonb: #{value.inspect}"
278   end
279 end