class Sequel::Postgres::JSONBOp

jsonb_op = Sequel.pg_jsonb(:jsonb)
In the method documentation examples, assume that:
JSONBaseOp subclass for the jsonb type.

def -(other)

jsonb_op - "a" # (jsonb - 'a')

current jsonb.
jsonb expression for deletion of the given argument from the
def -(other)
  self.class.new(super)
end

def [](key)

Support subscript syntax for JSONB.
def [](key)
  if is_array?(key)
    super
  else
    case @value
    when Symbol, SQL::Identifier, SQL::QualifiedIdentifier, JSONBSubscriptOp
      # Only use subscripts for identifiers.  In other cases, switching from
      # the -> operator to [] for subscripts causes SQL syntax issues.  You
      # only need the [] for subscripting when doing assignment, and
      # assignment is generally done on identifiers.
      self.class.new(JSONBSubscriptOp.new(self, key))
    else
      super
    end
  end
end

def _path_function(func, path, vars, silent)

Internals of the jsonb SQL/JSON path functions.
def _path_function(func, path, vars, silent)
  args = []
  if vars
    if vars.is_a?(Hash)
      vars = vars.to_json
    end
    args << vars
    unless silent.nil?
      args << silent
    end
  end
  SQL::Function.new(func, self, path, *args)
end

def bool_op(str, other)

in a boolean expression, used by operators that return booleans.
Return a placeholder literal with the given str and args, wrapped
def bool_op(str, other)
  Sequel::SQL::BooleanExpression.new(:NOOP, Sequel::SQL::PlaceholderLiteralString.new(str, [value, other]))
end

def concat(other)

jsonb_op.concat(:h) # (jsonb || h)

the current jsonb.
jsonb expression for concatenation of the given jsonb into
def concat(other)
  json_op(CONCAT, wrap_input_jsonb(other))
end

def contain_all(other)

jsonb_op.contain_all(:a) # (jsonb ?& a)

Check if the receiver contains all of the keys in the given array:
def contain_all(other)
  bool_op(CONTAIN_ALL, wrap_input_array(other))
end

def contain_any(other)

jsonb_op.contain_any(:a) # (jsonb ?| a)

Check if the receiver contains any of the keys in the given array:
def contain_any(other)
  bool_op(CONTAIN_ANY, wrap_input_array(other))
end

def contained_by(other)

jsonb_op.contained_by(:h) # (jsonb <@ h)

Check if the other jsonb contains all entries in the receiver:
def contained_by(other)
  bool_op(CONTAINED_BY, wrap_input_jsonb(other))
end

def contains(other)

jsonb_op.contains(:h) # (jsonb @> h)

Check if the receiver contains all entries in the other jsonb:
def contains(other)
  bool_op(CONTAINS, wrap_input_jsonb(other))
end

def delete_path(other)

jsonb_op.delete_path(:h) # (jsonb #- h)

Removes the given path from the receiver.
def delete_path(other)
  json_op(DELETE_PATH, wrap_input_array(other))
end

def function_name(name)

The jsonb type functions are prefixed with jsonb_
def function_name(name)
  "jsonb_#{name}"
end

def has_key?(key)

jsonb_op.has_key?('a') # (jsonb ? 'a')

Check if the receiver contains the given key:
def has_key?(key)
  bool_op(HAS_KEY, key)
end

def insert(path, other, insert_after=false)

jsonb_op.insert(['a', 'b'], h, true) # jsonb_insert(jsonb, ARRAY['a', 'b'], h, true)
jsonb_op.insert(['a', 'b'], h) # jsonb_insert(jsonb, ARRAY['a', 'b'], h, false)

insert_after can be set to true to insert it after the given path.
The default is to insert the value before the given path, but
Inserts the given jsonb value at the given path in the receiver.
def insert(path, other, insert_after=false)
  self.class.new(function(:insert, wrap_input_array(path), wrap_input_jsonb(other), insert_after))
end

def path_exists(path)

json_op.path_exists("$.foo") # (json @? '$.foo')

Returns whether the JSON path returns any item for the json object.
def path_exists(path)
  bool_op(PATH_EXISTS, path)
end

def path_exists!(path, vars=nil, silent=nil)

# jsonb_path_exists(json, '$.foo ? ($ > $x)', '{"x":2}', true)
json_op.path_exists!("$.foo ? ($ > $x)", {x: 2}, true)

# jsonb_path_exists(json, '$.foo ? ($ > $x)', '{"x":2}')
json_op.path_exists!("$.foo ? ($ > $x)", x: 2)

# jsonb_path_exists(json, '$.foo')
json_op.path_exists!("$.foo")

Returns whether the JSON path returns any item for the json object.
def path_exists!(path, vars=nil, silent=nil)
  Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_exists, path, vars, silent))
end

def path_exists_tz!(path, vars=nil, silent=nil)

The same as #path_exists!, except that timezone-aware conversions are used for date/time values.
def path_exists_tz!(path, vars=nil, silent=nil)
  Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_exists_tz, path, vars, silent))
end

def path_match(path)

json_op.path_match("$.foo") # (json @@ '$.foo')

Returns nil if the first item is not true or false.
Returns the first item of the result of JSON path predicate check for the json object.
def path_match(path)
  bool_op(PATH_MATCH, path)
end

def path_match!(path, vars=nil, silent=nil)

# jsonb_path_match(json, '$.foo ? ($ > $x)', '{"x":2}', true)
json_op.path_match!("$.foo ? ($ > $x)", {x: 2}, true)

# jsonb_path_match(json, '$.foo ? ($ > $x)', '{"x":2}')
json_op.path_match!("$.foo ? ($ > $x)", x: 2)

# jsonb_path_match(json, '$.foo')
json_op.path_match!("$.foo")

Returns nil if the first item is not true or false and silent is true.
Returns the first item of the result of JSON path predicate check for the json object.
def path_match!(path, vars=nil, silent=nil)
  Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_match, path, vars, silent))
end

def path_match_tz!(path, vars=nil, silent=nil)

The same as #path_match!, except that timezone-aware conversions are used for date/time values.
def path_match_tz!(path, vars=nil, silent=nil)
  Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_match_tz, path, vars, silent))
end

def path_query(path, vars=nil, silent=nil)

# jsonb_path_query(json, '$.foo ? ($ > $x)', '{"x":2}', true)
json_op.path_query("$.foo ? ($ > $x)", {x: 2}, true)

# jsonb_path_query(json, '$.foo ? ($ > $x)', '{"x":2}')
json_op.path_query("$.foo ? ($ > $x)", x: 2)

# jsonb_path_query(json, '$.foo')
json_op.path_query("$.foo")

for the json object.
Returns a set of all jsonb values specified by the JSON path
def path_query(path, vars=nil, silent=nil)
  _path_function(:jsonb_path_query, path, vars, silent)
end

def path_query_array(path, vars=nil, silent=nil)

# jsonb_path_query_array(json, '$.foo ? ($ > $x)', '{"x":2}', true)
json_op.path_query_array("$.foo ? ($ > $x)", {x: 2}, true)

# jsonb_path_query_array(json, '$.foo ? ($ > $x)', '{"x":2}')
json_op.path_query_array("$.foo ? ($ > $x)", x: 2)

# jsonb_path_query_array(json, '$.foo')
json_op.path_query_array("$.foo")

for the json object.
Returns a jsonb array of all values specified by the JSON path
def path_query_array(path, vars=nil, silent=nil)
  JSONBOp.new(_path_function(:jsonb_path_query_array, path, vars, silent))
end

def path_query_array_tz(path, vars=nil, silent=nil)

The same as #path_query_array, except that timezone-aware conversions are used for date/time values.
def path_query_array_tz(path, vars=nil, silent=nil)
  JSONBOp.new(_path_function(:jsonb_path_query_array_tz, path, vars, silent))
end

def path_query_first(path, vars=nil, silent=nil)

# jsonb_path_query_first(json, '$.foo ? ($ > $x)', '{"x":2}', true)
json_op.path_query_first("$.foo ? ($ > $x)", {x: 2}, true)

# jsonb_path_query_first(json, '$.foo ? ($ > $x)', '{"x":2}')
json_op.path_query_first("$.foo ? ($ > $x)", x: 2)

# jsonb_path_query_first(json, '$.foo')
json_op.path_query_first("$.foo")

for the json object.
Returns the first item of the result specified by the JSON path
def path_query_first(path, vars=nil, silent=nil)
  JSONBOp.new(_path_function(:jsonb_path_query_first, path, vars, silent))
end

def path_query_first_tz(path, vars=nil, silent=nil)

The same as #path_query_first, except that timezone-aware conversions are used for date/time values.
def path_query_first_tz(path, vars=nil, silent=nil)
  JSONBOp.new(_path_function(:jsonb_path_query_first_tz, path, vars, silent))
end

def path_query_tz(path, vars=nil, silent=nil)

The same as #path_query, except that timezone-aware conversions are used for date/time values.
def path_query_tz(path, vars=nil, silent=nil)
  _path_function(:jsonb_path_query_tz, path, vars, silent)
end

def pg_jsonb

Return the receiver, since it is already a JSONBOp.
def pg_jsonb
  self
end

def pretty

jsonb_op.pretty # jsonb_pretty(jsonb)

Return a pretty printed version of the receiver as a string expression.
def pretty
  Sequel::SQL::StringExpression.new(:NOOP, function(:pretty))
end

def set(path, other, create_missing=true)

jsonb_op.set(['a', 'b'], h, false) # jsonb_set(jsonb, ARRAY['a', 'b'], h, false)
jsonb_op.set(['a', 'b'], h) # jsonb_set(jsonb, ARRAY['a', 'b'], h, true)

create_missing can be set to false to not create a new value.
By default, this will create the value if it does not exist, but
Set the given jsonb value at the given path in the receiver.
def set(path, other, create_missing=true)
  self.class.new(function(:set, wrap_input_array(path), wrap_input_jsonb(other), create_missing))
end

def set_lax(path, other, create_missing=true, null_value_treatment='use_json_null')

which can be one of 'raise_exception', 'use_json_null' (default), 'delete_key', or 'return_target'.
The same as #set, except if +other+ is +nil+, then behaves according to +null_value_treatment+,
def set_lax(path, other, create_missing=true, null_value_treatment='use_json_null')
  self.class.new(function(:set_lax, wrap_input_array(path), wrap_input_jsonb(other), create_missing, null_value_treatment))
end

def wrap_input_array(obj)

Wrap argument in a PGArray if it is an array
def wrap_input_array(obj)
  if obj.is_a?(Array) && Sequel.respond_to?(:pg_array) 
    Sequel.pg_array(obj)
  else
    obj
  end
end

def wrap_input_jsonb(obj)

Wrap argument in a JSONBArray or JSONBHash if it is an array or hash.
def wrap_input_jsonb(obj)
  if Sequel.respond_to?(:pg_jsonb) && (obj.is_a?(Array) || obj.is_a?(Hash))
    Sequel.pg_jsonb(obj)
  else
    obj
  end
end