module ROM::SQL::Postgres::Types::JSONMethods

@!parse

class SQL::Attribute
  # @!method contain(value)
  #   Check whether the JSON value includes a json value
  #   Translates to the @> operator
  #
  #   @example
  #     people.where { fields.contain(gender: 'Female') }
  #     people.where(people[:fields].contain([name: 'age']))
  #     people.select { fields.contain(gender: 'Female').as(:is_female) }
  #
  #   @param [Hash,Array,Object] value
  #
  #   @return [SQL::Attribute<Types::Bool>]
  #
  #   @api public

  # @!method contained_by(value)
  #   Check whether the JSON value is contained by other value
  #   Translates to the <@ operator
  #
  #   @example
  #     people.where { custom_values.contained_by(age: 25, foo: 'bar') }
  #
  #   @param [Hash,Array] value
  #
  #   @return [SQL::Attribute<Types::Bool>]
  #
  #   @api public

  # @!method get(*path)
  #   Extract the JSON value using at the specified path
  #   Translates to -> or #> depending on the number of arguments
  #
  #   @example
  #     people.select { data.get('age').as(:person_age) }
  #     people.select { fields.get(0).as(:first_field) }
  #     people.select { fields.get('0', 'value').as(:first_field_value) }
  #
  #   @param [Array<Integer>,Array<String>] path Path to extract
  #
  #   @return [SQL::Attribute<Types::PG::JSON>,SQL::Attribute<Types::PG::JSONB>]
  #
  #   @api public

  # @!method get_text(*path)
  #   Extract the JSON value as text using at the specified path
  #   Translates to ->> or #>> depending on the number of arguments
  #
  #   @example
  #     people.select { data.get('age').as(:person_age) }
  #     people.select { fields.get(0).as(:first_field) }
  #     people.select { fields.get('0', 'value').as(:first_field_value) }
  #
  #   @param [Array<Integer>,Array<String>] path Path to extract
  #
  #   @return [SQL::Attribute<Types::String>]
  #
  #   @api public

  # @!method has_key(key)
  #   Does the JSON value have the specified top-level key
  #   Translates to ?
  #
  #   @example
  #     people.where { data.has_key('age') }
  #
  #   @param [String] key
  #
  #   @return [SQL::Attribute<Types::Bool>]
  #
  #   @api public

  # @!method has_any_key(*keys)
  #   Does the JSON value have any of the specified top-level keys
  #   Translates to ?|
  #
  #   @example
  #     people.where { data.has_any_key('age', 'height') }
  #
  #   @param [Array<String>] keys
  #
  #   @return [SQL::Attribute<Types::Bool>]
  #
  #   @api public

  # @!method has_all_keys(*keys)
  #   Does the JSON value have all the specified top-level keys
  #   Translates to ?&
  #
  #   @example
  #     people.where { data.has_all_keys('age', 'height') }
  #
  #   @param [Array<String>] keys
  #
  #   @return [SQL::Attribute<Types::Bool>]
  #
  #   @api public

  # @!method merge(value)
  #   Concatenate two JSON values
  #   Translates to ||
  #
  #   @example
  #     people.select { data.merge(fetched_at: Time.now).as(:data) }
  #     people.select { (fields + [name: 'height', value: 165]).as(:fields) }
  #
  #   @param [Hash,Array] value
  #
  #   @return [SQL::Attribute<Types::PG::JSONB>]
  #
  #   @api public

  # @!method +(value)
  #   An alias for SQL::Attribute<JSONB>#merge
  #
  #   @api public

  # @!method delete(*path)
  #   Deletes the specified value by key, index, or path
  #   Translates to - or #- depending on the number of arguments
  #
  #   @example
  #     people.select { data.delete('age').as(:data_without_age) }
  #     people.select { fields.delete(0).as(:fields_without_first) }
  #     people.select { fields.delete(-1).as(:fields_without_last) }
  #     people.select { data.delete('deeply', 'nested', 'value').as(:data) }
  #     people.select { fields.delete('0', 'name').as(:data) }
  #
  #   @param [Array<String>] path
  #
  #   @return [SQL::Attribute<Types::PG::JSONB>]
  #
  #   @api public
end

Public Class Methods

[](type, wrap) click to toggle source
# File lib/rom/sql/extensions/postgres/types/json.rb, line 224
def self.[](type, wrap)
  parent = self
  Module.new do
    include parent
    define_method(:json_type) { type }
    define_method(:wrap, wrap)
  end
end

Public Instance Methods

get(_type, expr, *path) click to toggle source
# File lib/rom/sql/extensions/postgres/types/json.rb, line 233
def get(_type, expr, *path)
  Attribute[json_type].meta(sql_expr: wrap(expr)[path_args(path)])
end
get_text(_type, expr, *path) click to toggle source
# File lib/rom/sql/extensions/postgres/types/json.rb, line 237
def get_text(_type, expr, *path)
  Attribute[SQL::Types::String].meta(sql_expr: wrap(expr).get_text(path_args(path)))
end

Private Instance Methods

path_args(path) click to toggle source
# File lib/rom/sql/extensions/postgres/types/json.rb, line 243
def path_args(path)
  case path.size
  when 0 then raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)'
  when 1 then path[0]
  else path
  end
end