1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
<html><head><title>The Bobo Persistent Object System, release 2.0</title>
</head><body>
<h1>The Bobo Persistent Object System, release 2.0</h1>
<p> This package includes a set of modules that together provide an
extensible persistent object system. </p>
<ul><li><p>Highly transparent database access,</p>
<li><p>Objects are saved and restored automatically as needed,</p>
<li><p>Transactional semantics.</p>
</ul>
<p> This is not a database system, although it can be extended to
provide database semantics.</p>
<p> For information on differences between BoboPOS 2 and BoboPOS 1 and
for infoprmation on recent releases, see the
<a href="release.html">release notes</a>.</p>
<p> Important notes on BoboPOS 2:</p>
<ul><li><p>Requires Python 1.5 (including cPickle and cStringIO)</p>
<li><p>Do not use ni. This version is designed to use the Python 1.5
default package support.</p>
<li><p>BoboPOS 1.x data files are automatically converted from the
SimpleDB V2 format to SimpleDB V3 format when they are opened by
BoboPOS 2.0. The old versions of the data files are retained
with a <code>.v2</code> suffix. Since this is an alpha release, you might
want to back up your data files before using BoboPOS 2.0.</p>
</ul>
<p> Note:</p>
<p> BoboPOS is not suitable for use with CGI. If you use BoboPOS,
you should use a long-running publishing mechanism like PCGI or
Medusa.</p>
<h2>Usage in a Nutshell</h2>
<p> import PickleDictionary and Persistence from the BoboPOS
package.</p>
<h3>Persistent Objects</h3>
<p> Persistent objects are objects that provide necessary behavior to
interact with the persistent object system. Each persistent object
is stored in a separate database record. </p>
<p> There is very little the application programmer must be aware of to
make application objects persistent. </p>
<ul><li><p>Persistent objects must provide the necessary persistence
interface (by subclassing BoboPOS.Persistent)</p>
<li><p>Persistent objects must be root objects (stored in a Pickle
Dictionary) or be sub-objects of persistent objects.</p>
<li><p>Persistent objects must be picklable.</p>
<li><p>Subobjects of persistent objects must be persistent or immutable.</p>
<p> If a subobject of a persistent object is not immutable, then it
must be used as if it was:</p>
<PRE>
def add_key(self, key, v):
d=self._d
d[key]=v
self._d=v
</PRE>
</ul>
<h3>Transactions</h3>
<p> The Bobo persistent-object system includes a simple transaction
manager. A transaction manager manages movement of objects
between memory and disk storage. It provides an important
property, atomicity. Atomicity assures that a changes made during
a transaction are made permanent if a transaction completes and
are undone if a transaction is aborted. Transaction boundaries
are defined by invoking transaction begin and commit operations. </p>
<p> When a transaction manager is installed, it installs a global
function, get_transaction() to retrieve a per-thread transaction
manager. The current Bobo release supports a single-threaded
transaction model so only one thread may have a transaction
model. </p>
<p> The get_transaction function is installed as a global variable so
that applications like Bobo can interact with it without making
assumptions about the transaction manager implementation. This
allows alternate transaction managers to be used without modifying
Bobo. </p>
<p> Application programs don't store or retrieve objects other than
root objects. It is the transaction managers job to decide when
objects most be loaded or saved. The only responsibility of the
application programmer is to:</p>
<ul><li><p>Manage root objects, and</p>
<li><p>Define transaction boundaries</p>
</ul>
<h4>Defining root objects</h4>
<p> To make objects persistent, we need to create a containment
hierarchy rooted in an object that is contained in a
PickleDictionary:</p>
<PRE>
db=PickleDictionary(lib+'/var/Data')
if db.has_key('Trinkets'):
trinkets=db['Trinkets']
else:
trinkets=db['Trinkets']=Trinkets()
get_transaction().commit()
</PRE>
<p> In this example, we have a root object trinkets that all other
persistent objects will be (posibly indirectly) contained by.</p>
<p> Note the use of the <code>get_transaction().commit()</code> to notify the
transaction system that objects may be saved.</p>
<h4>Defining Transaction Boundaries</h4>
<p> Transaction objects define three methods:</p>
<dl><dt> begin(info)<dd><p>define the beginning of a transaction.</p>
<p> The argument info provides transaction meta-data that is
currently ignored.</p>
<p> Note that begin implicitly aborts any changes made since the
last commit or abort.</p>
<dt> commit()<dd><p>Make changed performed in the transaction
permanent </p>
<dt> abort()<dd><p>Undo all changes made since the previous commit or
abort. </p>
</dl>
<p> In Bobo applications, Bobo automatically calls these methods
before and after processing HTTP requests.</p>
<h2>For additional information</h2>
<p> See the <a href="Persistence.html">Providing Persistence for World-Wide-Web Applications</a>.</p>
<p> And see the examples given in the Bobo tutorial.
</p>
</body></html>
|