class Sequence < App::Model
class Error < StandardError; end
ensure_index :name, :unique => true
def Sequence.cache
load_cache! unless defined?(@cache)
@cache
end
def Sequence.load_cache!
@cache = (
all.inject(Hash.new){|hash, sequence| hash.update(sequence.name => sequence)}
)
end
def Sequence.for(name)
name = name.to_s
record = cache[name] || first(:name => name)
return record if record
begin
record = new(:name => name, :value => 0)
record.save(:safe => true)
rescue
record = first(:name => name) or raise(Error, "no sequence for #{ name }!")
end
cache['name'] = record
end
def Sequence.[](name)
Sequence.for(name)
end
def Sequence.next(name)
Sequence.for(name).next
end
def next
result =
Sequence.find_and_modify(
'query' => { 'name' => name },
'update' => { '$inc' => {'value' => 1} },
'new' => true
)
self.value = result['value']
end
def Sequence.find_and_modify(options = {})
oh = OrderedHash.new
oh['findandmodify'] = collection.name
oh.merge!(options)
db = collection.db
result = db.command(oh)
unless result["ok"] == 1
raise(Error, "find_and_modify failed with: #{ result['errmsg'] }")
end
result['value']
end
end