class AttrPouch::Pouch

Constants

VALID_FIELD_NAME_REGEXP

Public Class Methods

new(host, storage_field) click to toggle source
# File lib/attr_pouch.rb, line 257
def initialize(host, storage_field)
  @host = host
  @storage_field = storage_field.to_sym
  @fields = {}
end

Public Instance Methods

either_json?() click to toggle source
# File lib/attr_pouch.rb, line 279
def either_json?
  json? || jsonb?
end
field(name, opts={}) click to toggle source
# File lib/attr_pouch.rb, line 311
def field(name, opts={})
  unless VALID_FIELD_NAME_REGEXP.match(name)
    raise InvalidFieldError, "Field name must match #{VALID_FIELD_NAME_REGEXP}"
  end

  field = Field.new(self, name, opts)
  @fields[name.to_s] = field

  storage_field = @storage_field
  default_store = wrap({})

  @host.class_eval do
    define_method(name) do
      store = self[storage_field]
      field.read(store)
    end

    define_method("#{name.to_s.sub(/\?\z/, '')}=") do |value|
      store = self[storage_field]
      was_nil = store.nil?
      store = default_store.dup if was_nil
      changed = field.write(store, value)
      if was_nil
        self[storage_field] = store
      else
        modified! storage_field if changed
      end
    end

    if field.deletable?
      delete_method = "delete_#{name.to_s.sub(/\?\z/, '')}"
      define_method(delete_method) do
        store = self[storage_field]
        unless store.nil?
          field.all_names.each { |a| store.delete(a) }
          modified! storage_field
        end
      end

      define_method("#{delete_method}!") do
        self.public_send(delete_method)
        save_changes
      end
    end

    if opts.has_key?(:raw_field)
      raw_name = opts[:raw_field]

      define_method(raw_name) do
        store = self[storage_field]
        field.read(store, decode: false)
      end

      define_method("#{raw_name.to_s.sub(/\?\z/, '')}=") do |value|
        store = self[storage_field]
        was_nil = store.nil?
        store = default_store.dup if was_nil
        changed = field.write(store, value, encode: false)
        if was_nil
          self[storage_field] = store
        else
          modified! storage_field if changed
        end
      end
    end
  end
end
field_definition(name) click to toggle source
# File lib/attr_pouch.rb, line 263
def field_definition(name)
  @fields[name.to_s]
end
hstore?() click to toggle source
# File lib/attr_pouch.rb, line 267
def hstore?
  pouch_column_info.fetch(:db_type) == 'hstore'
end
json?() click to toggle source
# File lib/attr_pouch.rb, line 271
def json?
  pouch_column_info.fetch(:db_type) == 'json'
end
jsonb?() click to toggle source
# File lib/attr_pouch.rb, line 275
def jsonb?
  pouch_column_info.fetch(:db_type) == 'jsonb'
end
pouch_column_info() click to toggle source
# File lib/attr_pouch.rb, line 283
def pouch_column_info
  @host.db_schema.find { |k,_| k == @storage_field }.last
end
store() click to toggle source
# File lib/attr_pouch.rb, line 299
def store
  if hstore?
    Sequel.hstore(@storage_field)
  elsif json?
    Sequel.pg_json_op(@storage_field)
  elsif jsonb?
    Sequel.pg_jsonb_op(@storage_field)
  else
    raise InvalidPouchError, "Pouch must use hstore, json, or jsonb column"
  end
end
wrap(hash) click to toggle source
# File lib/attr_pouch.rb, line 287
def wrap(hash)
  if hstore?
    Sequel.hstore(hash)
  elsif json?
    Sequel.pg_json(hash)
  elsif jsonb?
    Sequel.pg_jsonb(hash)
  else
    raise InvalidPouchError, "Pouch must use hstore, json, or jsonb column"
  end
end