Skip to content

Instantly share code, notes, and snippets.

@machu
Created September 18, 2009 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save machu/189180 to your computer and use it in GitHub Desktop.
Save machu/189180 to your computer and use it in GitHub Desktop.
appengine-pstore.rb - A PStore compatible interface using the Datastore.
# = AppEngine::PStore --
#
# A PStore compatible interface using the Datastore.
# This module is based on pstore.rb written by matz.
#
require 'pstore'
require 'digest/md5'
require 'rubygems'
require 'appengine-apis/datastore'
module AppEngine; end
# AppEngine::PStore is compatible with PStore interface.
# It uses the Datastore to privide a persistance mechanism.
class AppEngine::PStore < PStore
# call-seq:
# db = AppEngine::PStore.new('foo/bar.pstore')
#
# Creates a new database identified by filename
#
# Args:
# - filename: String. A key to identify database.
#
def initialize(filename)
@kind = self.class.name
@transaction = false
@filename = filename
@abort = false
end
# call-seq:
# db.transaction do |db|
# db[:somekey] = somevalue
# puts db[:anotherkey]
# end
#
# Opens a new transaction for the data store.
#
# Args:
# - read_only: Boolean.
#
def transaction(read_only = false)
raise PStore::Error, "nested transaction" if @transaction
begin
@rdonly = read_only
@abort = false
@transaction = true
value = nil
key = AppEngine::Datastore::Key.from_path(@kind, @filename)
begin
entity = AppEngine::Datastore.get(key)
if !read_only
size = entity[:content].size
md5 = Digest::MD5.digest(entity[:content])
end
@table = load(entity[:content])
rescue AppEngine::Datastore::EntityNotFound
@table = {}
end
begin
catch(:pstore_abort_transaction) do
value = yield(self)
end
rescue Exception
@abort = true
raise
ensure
if !read_only and !@abort
content = dump(@table)
if !md5 || size != content.size || md5 != Digest::MD5.digest(content)
entity = AppEngine::Datastore::Entity.new(key)
entity[:content] = content
AppEngine::Datastore.put(entity)
end
end
end
ensure
@table = nil
@transaction = false
end
value
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment