Permalink
Fetching contributors…
Cannot retrieve contributors at this time
226 lines (165 sloc) 4.8 KB
#--
# Copyright (c) 2005-2013, John Mettraux, jmettraux@gmail.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Made in Japan.
#++
require 'rufus/json'
require 'ruote/util/misc'
require 'ruote/storage/base'
require 'monitor'
module Ruote
#
# An in-memory storage.
#
# Useful for testing or for transient engines.
#
class HashStorage
include StorageBase
include MonitorMixin
attr_reader :h
def initialize(options={})
super()
# since were including MonitorMixin, this super() is necessary
@options = options
purge!
# which initializes @h
replace_engine_configuration(options)
end
def put(doc, opts={})
raise ArgumentError.new(
"document is missing key 'type' and/or '_id', cannot store it"
) if doc['type'] == nil || doc['_id'] == nil
synchronize do
pre = get(doc['type'], doc['_id'])
if pre && pre['_rev'] != doc['_rev']
return pre
end
if pre.nil? && doc['_rev']
return true
end
#puts caller unless doc.is_a?(Hash)
doc =
if opts[:update_rev]
doc.merge!('_rev' => pre ? pre['_rev'] : -1)
else
doc.merge('_rev' => doc['_rev'] || -1)
end
doc['put_at'] = Ruote.now_to_utc_s
doc['_rev'] = doc['_rev'] + 1
#doc = Ruote.keys_to_s(doc)
@h[doc['type']][doc['_id']] = Rufus::Json.dup(doc)
nil
end
#rescue => e
# puts "=" * 80
# File.open('doc.json', 'wb') do |f|
# f.puts Rufus::Json.pretty_encode(doc)
# end
# raise e
end
def get(type, key)
synchronize do
Ruote.fulldup(@h[type][key])
end
end
def delete(doc)
raise ArgumentError.new(
"document is missing key 'type' and/or '_id', cannot locate it"
) if doc['type'] == nil || doc['_id'] == nil
drev = doc['_rev']
raise ArgumentError.new("can't delete doc without _rev") unless drev
synchronize do
prev = get(doc['type'], doc['_id'])
return true if prev.nil?
doc['_rev'] ||= 0
return prev if prev['_rev'] != drev
@h[doc['type']].delete(doc['_id'])
nil # success
end
end
def get_many(type, key=nil, opts={})
# NOTE : no dup here for now
synchronize do
docs = if key
keys = Array(key).map { |k| k.is_a?(String) ? "!#{k}" : k }
@h[type].values.select { |doc| key_match?(type, keys, doc) }
else
@h[type].values
end
return docs.size if opts[:count]
docs = docs.sort_by { |d| d['_id'] }
docs = docs.reverse if opts[:descending]
skip = opts[:skip] || 0
limit = opts[:limit] || docs.size
docs[skip, limit]
end
end
# Returns a sorted list of all the ids for a given type.
#
def ids(type)
@h[type].keys.sort
end
#--
# keeping it commented out... using it for documentation efforts
#class NoisyHash < Hash
# def initialize(type)
# @type = type
# super()
# end
# def []=(k, v)
# puts " + #{@type}.put #{k} #{v['_rev']}"
# super
# end
# def delete(k)
# puts " - #{@type}.del #{k} "
# super
# end
#end
#++
# Purges the storage completely.
#
def purge!
@h = %w[
variables
msgs
expressions
errors
schedules
configurations
workitems
].each_with_object({}) { |k, h|
h[k] = {}
}
@h['configurations']['engine'] = @options
end
def add_type(type)
@h[type] = {}
end
def purge_type!(type)
@h[type] = {}
end
# Shuts this storage down.
#
def shutdown
# nothing to do
end
end
end