class Noid::Rails::Minter::Db
A minter backed by a database table. You would select this if you need to mint identifers on several distributed front-ends that do not share a common file system.
Public Instance Methods
# File lib/noid/rails/minter/db.rb, line 12 def read deserialize(instance) end
# File lib/noid/rails/minter/db.rb, line 16 def write!(minter) serialize(instance, minter) end
Protected Instance Methods
@param [MinterState] inst minter state to be converted @return [Hash{Symbol => String, Object}] minter state as a Hash, like read
@see read
, Noid::Rails::Minter::Base#read
# File lib/noid/rails/minter/db.rb, line 25 def deserialize(inst) filtered_hash = inst.as_json.slice('template', 'counters', 'seq', 'rand', 'namespace') if filtered_hash['counters'] filtered_hash['counters'] = JSON.parse(filtered_hash['counters'], symbolize_names: true) end filtered_hash.symbolize_keys end
@return [MinterState]
# File lib/noid/rails/minter/db.rb, line 68 def instance MinterState.lock.find_by!( namespace: Noid::Rails.config.namespace, template: Noid::Rails.config.template ) rescue ActiveRecord::RecordNotFound MinterState.seed!( namespace: Noid::Rails.config.namespace, template: Noid::Rails.config.template ) end
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 noid:rails:seed` or autofilled by instance below. If you want another namespace, edit your config initialzer to something like:
Noid::Rails.config.namespace = 'druid' Noid::Rails.config.template = '.reeedek'
and in your app run:
bundle exec rails generate noid:rails:seed
# File lib/noid/rails/minter/db.rb, line 56 def next_id id = nil MinterState.transaction do locked = instance minter = ::Noid::Minter.new(deserialize(locked)) id = minter.mint serialize(locked, minter) end id end
@param [MinterState] inst a locked row/object to be updated @param [::Noid::Minter] minter state containing the updates
# File lib/noid/rails/minter/db.rb, line 36 def serialize(inst, minter) # namespace and template are the same, now update the other attributes inst.update!( seq: minter.seq, counters: JSON.generate(minter.counters), rand: Marshal.dump(minter.instance_variable_get(:@rand)) ) end