class ActiveFedora::Noid::Minter::Db

Public Instance Methods

read() click to toggle source
# File lib/active_fedora/noid/minter/db.rb, line 8
def read
  deserialize(instance)
end
write!(minter) click to toggle source
# File lib/active_fedora/noid/minter/db.rb, line 12
def write!(minter)
  serialize(instance, minter)
end

Protected Instance Methods

deserialize(inst) click to toggle source

@param [MinterState] inst minter state to be converted @return [Hash{Symbol => String, Object}] minter state as a Hash, like read @see read, ActiveFedora::Noid::Minter::Base#read

# File lib/active_fedora/noid/minter/db.rb, line 21
def deserialize(inst)
  filtered_hash = inst.as_json.slice(*%w(template counters seq rand namespace))
  filtered_hash['counters'] = JSON.parse(filtered_hash['counters'], symbolize_names: true) if filtered_hash['counters']
  filtered_hash.symbolize_keys
end
instance() click to toggle source

@return [MinterState]

# File lib/active_fedora/noid/minter/db.rb, line 60
def instance
  MinterState.lock.find_by!(
    namespace: ActiveFedora::Noid.config.namespace,
    template: ActiveFedora::Noid.config.template
  )
rescue ActiveRecord::RecordNotFound
  MinterState.seed!(
    namespace: ActiveFedora::Noid.config.namespace,
    template: ActiveFedora::Noid.config.template
  )
end
next_id() click to toggle source

Uses pessimistic lock to ensure the record fetched is the same one updated. Should be fast enough to avoid terrible deadlock. Must lock because of multi-connection context! (transaction is per connection – not enough) The DB table will only ever have at most one row per namespace. The 'default' namespace row is inserted by `rails generate active_fedora:noid:seed` or autofilled by instance below. If you want another namespace, edit your config initialzer to something like:

ActiveFedora::Noid.config.namespace = 'druid'
ActiveFedora::Noid.config.template = '.reeedek'

and in your app run:

bundle exec rails generate active_fedora:noid:seed
# File lib/active_fedora/noid/minter/db.rb, line 48
def next_id
  id = nil
  MinterState.transaction do
    locked = instance
    minter = ::Noid::Minter.new(deserialize(locked))
    id = minter.mint
    serialize(locked, minter)
  end # transaction
  id
end
serialize(inst, minter) click to toggle source

@param [MinterState] inst a locked row/object to be updated @param [::Noid::Minter] minter state containing the updates

# File lib/active_fedora/noid/minter/db.rb, line 29
def serialize(inst, minter)
  # namespace and template are the same, now update the other attributes
  inst.update_attributes!(
    seq: minter.seq,
    counters: JSON.generate(minter.counters),
    rand: Marshal.dump(minter.instance_variable_get(:@rand))
  )
end