Created
September 18, 2009 17:30
-
-
Save machu/189180 to your computer and use it in GitHub Desktop.
appengine-pstore.rb - A PStore compatible interface using the Datastore.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# = 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