Commit 56f1205e authored by Jim Fulton's avatar Jim Fulton

Integrated persistent metaclass with ZClasses and got basic ZClass

test to pass.
parent 5e1d9f08
...@@ -22,6 +22,7 @@ from ComputedAttribute import ComputedAttribute ...@@ -22,6 +22,7 @@ from ComputedAttribute import ComputedAttribute
from Products.PythonScripts.PythonScript import PythonScript from Products.PythonScripts.PythonScript import PythonScript
from zExceptions import BadRequest, Redirect from zExceptions import BadRequest, Redirect
import webdav.Collection import webdav.Collection
import ZClasses._pmc
import marshal import marshal
...@@ -91,7 +92,18 @@ from OFS.misc_ import p_ ...@@ -91,7 +92,18 @@ from OFS.misc_ import p_
p_.ZClass_Icon=Globals.ImageFile('class.gif', globals()) p_.ZClass_Icon=Globals.ImageFile('class.gif', globals())
class PersistentClass(Base, webdav.Collection.Collection ): class PersistentClass(Base, webdav.Collection.Collection ):
def __class_init__(self): pass
__metaclass__ = ZClasses._pmc.ZClassPersistentMetaClass
# We need this class to be treated as a normal global class, even
# though it is an instance of ZClassPersistentMetaClass.
# Subclasses should be stored in the database. See
# _pmc._p_DataDescr.__get__.
__global_persistent_class_not_stored_in_DB__ = True
def __class_init__(self):
pass
manage_addZClassForm=Globals.DTMLFile( manage_addZClassForm=Globals.DTMLFile(
'dtml/addZClass', globals(), 'dtml/addZClass', globals(),
......
...@@ -6,65 +6,86 @@ ZClasses were designed mainly to be used from the web. ...@@ -6,65 +6,86 @@ ZClasses were designed mainly to be used from the web.
To do anything, we need a working Zope object space: To do anything, we need a working Zope object space:
>>> from ZODB.DemoStorage import DemoStorage >>> conn = some_database.open()
>>> s = DemoStorage() >>> from OFS.Application import Application
>>> import ZODB.DB >>> app = Application()
>>> db = ZODB.DB(s) >>> conn.root()['Application'] = app
>>> conn = db.open() >>> from OFS.Application import initialize
>>> from OFS.Application import Application >>> initialize(app)
>>> app = Application()
>>> conn.root()['Application'] = app
>>> from OFS.Application import initialize
>>> initialize(app)
Once we have an object space, we need to create a product to hold the ZClass: Once we have an object space, we need to create a product to hold the ZClass:
>>> app.Control_Panel.Products.manage_addProduct('test', '') >>> app.Control_Panel.Products.manage_addProduct('test', '')
>>> test = app.Control_Panel.Products['test'] >>> test = app.Control_Panel.Products['test']
Then we can create the ZClass in the product: Then we can create the ZClass in the product:
>>> test.manage_addZClass('C', zope_object=True, CreateAFactory=True) >>> test.manage_addZClass('C', zope_object=True, CreateAFactory=True)
Having create a ZClass, we can create an instance: Having create a ZClass, we can create an instance:
>>> c = test.C() >>> c = test.C()
>>> c._setId('c') >>> c._setId('c')
>>> app._setObject('c', c) >>> app._setObject('c', c)
'c' 'c'
Now, ZClass instances aren't very interesting by themselves. We can Now, ZClass instances aren't very interesting by themselves. We can
give them data by defining property sheets: give them data by defining property sheets:
>>> test.C.propertysheets.common.manage_addCommonSheet('basic', '') >>> test.C.propertysheets.common.manage_addCommonSheet('basic', '')
>>> test.C.propertysheets.common['basic'].manage_addProperty( >>> test.C.propertysheets.common['basic'].manage_addProperty(
... 'x', 'hee ', 'string') ... 'x', 'hee ', 'string')
>>> app.c.x >>> app.c.x
'hee ' 'hee '
>>> test.C.propertysheets.common['basic'].manage_addProperty('y', 42, 'int') >>> test.C.propertysheets.common['basic'].manage_addProperty(
>>> app.c.y ... 'y', 42, 'int')
42 >>> app.c.y
42
Of course, we can change the data: Of course, we can change the data:
>>> app.c.x = 'hi ' >>> app.c.x = 'hi '
>>> app.c.y = 3 >>> app.c.y = 3
>>> app.c.x, app.c.y >>> app.c.x, app.c.y
('hi ', 3) ('hi ', 3)
We can also add methods, such as Python scripts: We can also add methods, such as Python scripts:
>>> test.C.propertysheets.methods.manage_addProduct[ >>> test.C.propertysheets.methods.manage_addProduct[
... 'PythonScripts'].manage_addPythonScript('eek') ... 'PythonScripts'].manage_addPythonScript('eek')
'' ''
>>> test.C.propertysheets.methods['eek'].ZPythonScript_edit('', >>> test.C.propertysheets.methods['eek'].ZPythonScript_edit('',
... 'return container.x * container.y') ... 'return container.x * container.y')
>>> app.c.eek() >>> app.c.eek()
'hi hi hi ' 'hi hi hi '
We're done, so clean up: Let's commit our changes:
>>> import transaction >>> import transaction
>>> transaction.commit() >>> transaction.commit()
>>> db.close()
We can access the class in another connection:
>>> import threading
>>> def run(func):
... thread = threading.Thread(target=func)
... thread.start()
... thread.join()
>>> def read_class():
... connection = some_database.open()
... app = connection.root()['Application']
... test = app.Control_Panel.Products['test']
... c2 = test.C()
... c2._setId('c')
... app._setObject('c2', c2)
... app.c2.x = '*'
... print app.c2.x, app.c2.y, app.c2.eek(), '!'
... print app.c.x, app.c.y, app.c.eek(), '!'
... connection.close()
... run(read_class)
hee 42 ****************************************** !
hi 3 hi hi hi !
...@@ -57,6 +57,9 @@ class _p_DataDescr(object): ...@@ -57,6 +57,9 @@ class _p_DataDescr(object):
def __get__(self, inst, cls): def __get__(self, inst, cls):
if inst is None: if inst is None:
return self return self
if '__global_persistent_class_not_stored_in_DB__' in inst.__dict__:
raise AttributeError, self.__name__
return inst._p_class_dict.get(self.__name__) return inst._p_class_dict.get(self.__name__)
def __set__(self, inst, v): def __set__(self, inst, v):
......
...@@ -44,11 +44,13 @@ def test_suite(): ...@@ -44,11 +44,13 @@ def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
# To do: # To do:
# - test integration: doctest.DocFileSuite("ZClass.txt"), # - Beef up basic test
# - Test working with old pickles # - Test working with old pickles
# - Test proper handling of __of__
# - Test export/import # - Test export/import
doctest.DocFileSuite("_pmc.txt", setUp=setUp, tearDown=tearDown), doctest.DocFileSuite("_pmc.txt", setUp=setUp, tearDown=tearDown),
doctest.DocFileSuite("ZClass.txt", setUp=setUp, tearDown=tearDown),
)) ))
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment