[#6143] — Christophe Poucet <christophe.poucet@...>

Hello,

17 messages 2005/10/04
[#6147] Re: patch.tgz — nobu.nokada@... 2005/10/04

Hi,

[#6199] Kernel rdoc HTML file not being created when rdoc is run on 1.8.3 — James Britt <ruby@...>

When 1.8.3 came out, I grabbed the source and ran rdoc on it. After

9 messages 2005/10/08

[#6251] RubyGems, upstream releases and idempotence of packaging — Mauricio Fern疣dez <mfp@...>

[sorry for the very late reply; I left this message in +postponed and forgot

14 messages 2005/10/12

[#6282] Wilderness: Need Code to invoke ELTS_SHARED response — "Charles E. Thornton" <ruby-core@...>

Testing the My Object Dump and I am trying to cause creation

13 messages 2005/10/14
[#6283] Re: Wilderness: Need Code to invoke ELTS_SHARED response — Mauricio Fern疣dez <mfp@...> 2005/10/14

On Fri, Oct 14, 2005 at 05:04:59PM +0900, Charles E. Thornton wrote:

[#6288] Re: Wilderness: Need Code to invoke ELTS_SHARED response — "Charles E. Thornton" <ruby-core@...> 2005/10/14

Mauricio Fern疣dez wrote:

[#6365] Time for built-in Rational and Complex classes? — Gavin Sinclair <gsinclair@...>

There has been some support for, but no comment on, RCR #260 ("Make

12 messages 2005/10/24
[#6366] Re: Time for built-in Rational and Complex classes? — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/24

On Mon, 24 Oct 2005, Gavin Sinclair wrote:

[#6405] Re: [PATCH] Pathname.exists?() — "Berger, Daniel" <Daniel.Berger@...>

12 messages 2005/10/25
[#6406] Re: [PATCH] Pathname.exists?() — TRANS <transfire@...> 2005/10/25

On 10/25/05, Berger, Daniel <Daniel.Berger@qwest.com> wrote:

[#6408] Re: [PATCH] Pathname.exists?() — Gavin Sinclair <gsinclair@...> 2005/10/25

On 10/26/05, TRANS <transfire@gmail.com> wrote:

[#6442] Wilderness: I Have formatted README.EXT into an HTML Document — "Charles E. Thornton" <ruby-core@...>

I have taken README.EXT (English Version Only) and have reformatted

14 messages 2005/10/27

[#6469] csv.rb a start on refactoring. — Hugh Sasse <hgs@...>

For a database application I found using CSV to be rather slow.

50 messages 2005/10/28
[#6470] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/28

[#6471] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/28

On Oct 28, 2005, at 8:53 AM, Ara.T.Howard wrote:

[#6474] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/28

On Fri, 28 Oct 2005, James Edward Gray II wrote:

[#6484] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 9:58 AM, Ara.T.Howard wrote:

[#6485] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/29

On Sat, 29 Oct 2005, James Edward Gray II wrote:

[#6486] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 8:25 PM, Ara.T.Howard wrote:

[#6487] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/29

On Sat, 29 Oct 2005, James Edward Gray II wrote:

[#6491] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 8:43 PM, Ara.T.Howard wrote:

[#6493] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/29

On Oct 28, 2005, at 10:06 PM, James Edward Gray II wrote:

[#6496] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/29

On Sun, 30 Oct 2005, James Edward Gray II wrote:

[#6502] Re: csv.rb a start on refactoring. — James Edward Gray II <james@...> 2005/10/30

On Oct 29, 2005, at 12:11 PM, Ara.T.Howard wrote:

[#6505] Re: csv.rb a start on refactoring. — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/30

On Mon, 31 Oct 2005, James Edward Gray II wrote:

[#6511] Planning FasterCSV (was Re: csv.rb a start on refactoring.) — James Edward Gray II <james@...> 2005/10/30

I've decided to create a FasterCSV library, based on the code we

[#6516] Re: Planning FasterCSV (was Re: csv.rb a start on refactoring.) — "Ara.T.Howard" <Ara.T.Howard@...> 2005/10/31

On Mon, 31 Oct 2005, James Edward Gray II wrote:

[#6518] Re: Planning FasterCSV (was Re: csv.rb a start on refactoring.) — "NAKAMURA, Hiroshi" <nakahiro@...> 2005/10/31

-----BEGIN PGP SIGNED MESSAGE-----

[PATCH] PStore Documentation

From: James Edward Gray II <james@...>
Date: 2005-10-26 20:49:23 UTC
List: ruby-core #6430
The attached patch completely documents the PStore library.  Please  
let me know if there are any issues with it.  Otherwise, would some  
kind soul please apply this?

James Edward Gray II

Attachments (1)

pstore_docs.diff (10.1 KB, text/x-diff)
Index: lib/.document
===================================================================
RCS file: /src/ruby/lib/.document,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 .document
--- lib/.document	25 Oct 2005 06:38:26 -0000	1.1.2.7
+++ lib/.document	26 Oct 2005 20:45:39 -0000
@@ -25,6 +25,7 @@
 observer.rb
 optionparser.rb
 pathname.rb
+pstore.rb
 rational.rb
 set.rb
 shellwords.rb
Index: lib/pstore.rb
===================================================================
RCS file: /src/ruby/lib/pstore.rb,v
retrieving revision 1.17.2.3
diff -u -r1.17.2.3 pstore.rb
--- lib/pstore.rb	27 Oct 2004 09:16:20 -0000	1.17.2.3
+++ lib/pstore.rb	26 Oct 2005 20:45:39 -0000
@@ -1,24 +1,92 @@
+# = PStore -- Transactional File Storage for Ruby Objects
 #
-# How to use:
+# pstore.rb -
+#   by unknown
+#   documentation by Kev Jackson and James Edward Gray II
 #
-# db = PStore.new("/tmp/foo")
-# db.transaction do
-#   p db.roots
-#   ary = db["root"] = [1,2,3,4]
-#   ary[0] = [1,1.5]
-# end
-
-# db.transaction do
-#   p db["root"]
-# end
+# See PStore for documentation.
+
 
 require "fileutils"
 require "digest/md5"
 
+#
+# PStore implements a file based persistance mechanism based on a Hash.  User
+# code can store hierarchies of Ruby objects (values) into the data store file
+# by name (keys).  An object hierarchy may be just a single object, of course.
+# Then later user code may read values back from the data store or even update 
+# data, as needed.
+# 
+# The transactional behavior ensures that any changes succeed or fail together.
+# This can be used to ensure that the data store is not left in a transitory
+# state, where some values were upated but others were not.
+# 
+# Behind the seens, Ruby objects are stored to the data store file with Marhsal.
+# That carries the usual limitations.  Proc objects cannot be marshalled, for
+# example.
+#
+# == Usage example:
+# 
+#  require "pstore"
+#  
+#  # a mock wiki object...
+#  class WikiPage
+#    def initialize( page_name, author, contents )
+#      @page_name = page_name
+#      @revisions = Array.new
+#      
+#      add_revision(author, contents)
+#    end
+#    
+#    attr_reader :page_name
+#    
+#    def add_revision( author, contents )
+#      @revisions << { :created  => Time.now,
+#                      :author   => author,
+#                      :contents => contents }
+#    end
+#    
+#    def wiki_page_references
+#      [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/)
+#    end
+#    
+#    # ...
+#  end
+#  
+#  # create a new page...
+#  home_page = WikiPage.new( "HomePage", "James Edward Gray II",
+#                            "A page about the JoysOfDocumentation..." )
+#  
+#  # then we want to update page data and the index together, or not at all...
+#  wiki = PStore.new("wiki_pages.pstore")
+#  wiki.transaction do  # begin transaction; do all of this or none of it
+#    # store page...
+#    wiki[home_page.page_name] = home_page
+#    # ensure that an index has been created...
+#    wiki[:wiki_index]         ||= Array.new
+#    # update wiki index...
+#    wiki[:wiki_index].push(*home_page.wiki_page_references)
+#  end                   # commit changes to wiki data store file
+#  
+#  ### Some time later... ###
+#  
+#  # read wiki data...
+#  wiki.transaction(true) do  # begin read-only transaction, no changes allowed
+#    wiki.roots.each do |data_root_name|
+#      p data_root_name
+#      p wiki[data_root_name]
+#    end
+#  end
+#
 class PStore
+  # The error type thrown by all PStore methods.
   class Error < StandardError
   end
 
+  # 
+  # To construct a PStore object, simply pass in the _file_ path where you would
+  # like the data to be stored.
+  # 
   def initialize(file)
     dir = File::dirname(file)
     unless File::directory? dir
@@ -32,19 +100,41 @@
     @abort = false
   end
 
+  # Raises PStore::Error if the calling code is not in a PStore.transaction().
   def in_transaction
     raise PStore::Error, "not in transaction" unless @transaction
   end
+  # 
+  # Raises PStore::Error if the calling code is not in a PStore.transaction() or
+  # if the code is in a read-only PStore.transaction().
+  # 
   def in_transaction_wr()
     in_transaction()
     raise PStore::Error, "in read-only transaction" if @rdonly
   end
   private :in_transaction, :in_transaction_wr
 
+  #
+  # Retrieves a value from the PStore file data, by _name_.  The hierarchy of 
+  # Ruby objects stored under that root _name_ will be returned.
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction().  It will
+  # raise PStore::Error if called at any other time.
+  #
   def [](name)
     in_transaction
     @table[name]
   end
+  #
+  # This method is just like PStore.[](), save that you may also provide a 
+  # _default_ value for the object.  In the event the specified _name_ is not 
+  # found in the data store, your _default_ will be returned instead.  If you do 
+  # not specify a default, PStore::Error will be raised if the object is not 
+  # found.
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction().  It will
+  # raise PStore::Error if called at any other time.
+  #
   def fetch(name, default=PStore::Error)
     unless @table.key? name
       if default==PStore::Error
@@ -55,38 +145,137 @@
     end
     self[name]
   end
+  #
+  # Stores an individual Ruby object or a hierarchy of Ruby objects in the data
+  # store file under the root _name_.  Assigning to a _name_ already in the data
+  # store clobbers the old data.
+  # 
+  # == Example:
+  # 
+  #  require "pstore"
+  #  
+  #  store = PStore.new("data_file.pstore")
+  #  store.transaction do  # begin transaction
+  #    # load some data into the store...
+  #    store[:single_object] = "My data..."
+  #    store[:obj_heirarchy] = { "Kev Jackson" => ["rational.rb", "pstore.rb"],
+  #                              "James Gray"  => ["erb.rb", "pstore.rb"] }
+  #  end                   # commit changes to data store file
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction() and it cannot
+  # be read-only.  It will raise PStore::Error if called at any other time.
+  #
   def []=(name, value)
     in_transaction_wr()
     @table[name] = value
   end
+  #
+  # Removes an object hierarchy from the data store, by _name_.
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction() and it cannot
+  # be read-only.  It will raise PStore::Error if called at any other time.
+  #
   def delete(name)
     in_transaction_wr()
     @table.delete name
   end
 
+  #
+  # Returns the names of all object hierarchies currently in the store.
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction().  It will
+  # raise PStore::Error if called at any other time.
+  #
   def roots
     in_transaction
     @table.keys
   end
+  #
+  # Returns true if the supplied _name_ is currently in the data store.
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction().  It will
+  # raise PStore::Error if called at any other time.
+  #
   def root?(name)
     in_transaction
     @table.key? name
   end
+  # Returns the path to the data store file.
   def path
     @filename
   end
 
+  #
+  # Ends the current PStore.transaction(), committing any changes to the data
+  # store immediately.
+  # 
+  # == Example:
+  # 
+  #  require "pstore"
+  #   
+  #  store = PStore.new("data_file.pstore")
+  #  store.transaction do  # begin transaction
+  #    # load some data into the store...
+  #    store[:one] = 1
+  #    store[:two] = 2
+  #  
+  #    store.commit        # end transaction here, committing changes
+  #  
+  #    store[:three] = 3   # this change is never reached
+  #  end
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction().  It will
+  # raise PStore::Error if called at any other time.
+  #
   def commit
     in_transaction
     @abort = false
     throw :pstore_abort_transaction
   end
+  #
+  # Ends the current PStore.transaction(), discarding any changes to the data
+  # store.
+  # 
+  # == Example:
+  # 
+  #  require "pstore"
+  #   
+  #  store = PStore.new("data_file.pstore")
+  #  store.transaction do  # begin transaction
+  #    store[:one] = 1     # this change is not applied, see below...
+  #    store[:two] = 2     # this change is not applied, see below...
+  #  
+  #    store.abort         # end transaction here, dicard all changes
+  #  
+  #    store[:three] = 3   # this change is never reached
+  #  end
+  # 
+  # *WARNING*:  This method is only valid in a PStore.transaction().  It will
+  # raise PStore::Error if called at any other time.
+  #
   def abort
     in_transaction
     @abort = true
     throw :pstore_abort_transaction
   end
 
+  #
+  # Opens a new transaction for the data store.  Code executed inside a block
+  # passed to this method may read and write data to and from the data store 
+  # file.
+  # 
+  # At the end of the block, changes are committed to the data store
+  # automatically.  You may exit the transaction early with a call to either 
+  # PStore.commit() or PStore.abort().  See those methods for details about how
+  # changes are handled.  Raising an uncaught Exception in the block is 
+  # equivalent to calling PStore.abort().
+  # 
+  # If _read_only_ is set to +true+, you will only be allowed to read from the
+  # data store during the transaction and any attempts to change the data will
+  # raise a PStore::Error.
+  # 
+  # Note that PStore does not support nested transactions.
+  #
   def transaction(read_only=false)
     raise PStore::Error, "nested transaction" if @transaction
     begin
@@ -155,19 +344,23 @@
     value
   end
 
-  def dump(table)
+  # This method is just a wrapped around Marshal.dump().
+  def dump(table)  # :nodoc:
     Marshal::dump(table)
   end
 
-  def load(content)
+  # This method is just a wrapped around Marshal.load().
+  def load(content)  # :nodoc:
     Marshal::load(content)
   end
 
-  def load_file(file)
+  # This method is just a wrapped around Marshal.load().
+  def load_file(file)  # :nodoc:
     Marshal::load(file)
   end
 
   private
+  # Commits changes to the data store file.
   def commit_new(f)
     f.truncate(0)
     f.rewind
@@ -180,6 +373,8 @@
   end
 end
 
+# :enddoc:
+
 if __FILE__ == $0
   db = PStore.new("/tmp/foo")
   db.transaction do

In This Thread

Prev Next