Sha256: 2dd887781a3ad3d39f5489205efdae23a0535eb3d9131a304b7e700580c8de3e

Contents?: true

Size: 1.6 KB

Versions: 2

Compression:

Stored size: 1.6 KB

Contents

module HashPersistent
  module Resource
    def self.included(base)
      base.extend ClassMethods_Initial
    end

    module ClassMethods_Initial
      def persist_to(store, prefix)
        raise ArgumentError unless store.respond_to?(:has_key?) and prefix.respond_to?(:to_s)
        Class.new(self) do
          extend  ClassMethods
          include InstanceMethods

          @store  = store
          @prefix = prefix
        end
      end
    end
    
    module ClassMethods
      attr_reader :store, :prefix
      
      def find(key)
        @store[@prefix + key]
      end

      def on_save(&block)
        if block
          @on_save = block
        else
          @on_save
        end
      end

      def on_delete(&block)
        if block
          @on_delete = block
        else
          @on_delete
        end
      end          
    end
    
    module InstanceMethods
      attr_accessor :key

      def prefix_key
        self.class.prefix + key
      end

      def save
        raise RuntimeError unless key
        self.class.store[prefix_key] = self
        self.class.on_save.call(self) if self.class.on_save
      end

      def delete
        raise RuntimeError unless key
        return unless self.class.store.has_key?(prefix_key)
        # TODO concurrency here, the store's delete call should cope, but we don't want the callback if something else got in first?
        # Alternative: ensure that callback handles this case, which is true of HashPersistent::Collection
        self.class.store.delete(prefix_key)
        self.class.on_delete.call(self) if self.class.on_delete
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
kissifer-hash-persistent-0.3.1 lib/hash-persistent/resource.rb
kissifer-hash-persistent-0.3.2 lib/hash-persistent/resource.rb