# PStore (Class)

In: | pstore.rb
Parent: | Object

## Methods

[] []= abort commit delete fetch new path root? roots transaction

## Classes and Modules

Class PStore::Error

## Public Class methods

new(file)

[Source]

    # File pstore.rb, line 22
      def initialize(file)
        dir = File::dirname(file)
        unless File::directory? dir
          raise PStore::Error, format("directory %s does not exist", dir)
        end
        if File::exist? file and not File::readable? file
          raise PStore::Error, format("file %s not readable", file)
        end
        @transaction = false
        @filename = file
        @abort = false
      end

## Public Instance methods

[](name)

[Source]

    # File pstore.rb, line 40
      def [](name)
        in_transaction
        @table[name]
      end

fetch(name, default=PStore::Error)

[Source]

    # File pstore.rb, line 44
      def fetch(name, default=PStore::Error)
        unless @table.key? name
          if default==PStore::Error
            raise PStore::Error, format("undefined root name `%s'", name)
          else
            default
          end
        end
        self[name]
      end

[]=(name, value)

[Source]

    # File pstore.rb, line 54
      def []=(name, value)
        in_transaction
        @table[name] = value
      end

delete(name)

[Source]

    # File pstore.rb, line 58
      def delete(name)
        in_transaction
        @table.delete name
      end

roots()

[Source]

    # File pstore.rb, line 63
      def roots
        in_transaction
        @table.keys
      end

root?(name)

[Source]

    # File pstore.rb, line 67
      def root?(name)
        in_transaction
        @table.key? name
      end

path()

[Source]

    # File pstore.rb, line 71
      def path
        @filename
      end

commit()

[Source]

    # File pstore.rb, line 75
      def commit
        in_transaction
        @abort = false
        throw :pstore_abort_transaction
      end

abort()

[Source]

    # File pstore.rb, line 80
      def abort
        in_transaction
        @abort = true
        throw :pstore_abort_transaction
      end

transaction(read_only=false) {|self| ...}

[Source]

    # File pstore.rb, line 86
      def transaction(read_only=false)
        raise PStore::Error, "nested transaction" if @transaction
        begin
          @transaction = true
          value = nil
          backup = @filename+"~"
          begin
            file = File::open(@filename, read_only ? "rb" : "rb+")
            orig = true
          rescue Errno::ENOENT
            raise if read_only
            file = File::open(@filename, "wb+")
          end
          file.flock(read_only ? File::LOCK_SH : File::LOCK_EX)
          if read_only
            @table = Marshal::load(file)
          elsif orig and (content = file.read) != ""
            @table = Marshal::load(content)
            size = content.size
            md5 = Digest::MD5.digest(content)
            content = nil          # unreference huge data

          else
            @table = {}
          end
          begin
            catch(:pstore_abort_transaction) do
              value = yield(self)
            end
          rescue Exception
            @abort = true
            raise
          ensure
            if !read_only and !@abort
              file.rewind
              content = Marshal::dump(@table)
              if !md5 || size != content.size || md5 != Digest::MD5.digest(content)
                File::copy @filename, backup
                begin
                  file.write(content)
                  file.truncate(file.pos)
                  content = nil            # unreference huge data

                rescue
                  File::rename backup, @filename if File::exist?(backup)
                  raise
                end
              end
            end
            if @abort and !orig
              File.unlink(@filename)
            end
            @abort = false
          end
        ensure
          @table = nil
          @transaction = false
          file.close if file
        end
        value
      end

[Validate]