[z3-checkins] r27816 - in z3/sqlos/branch/jinty-sqlobject2/src/sqlos: . ftests testing tests
jinty at codespeak.net
jinty at codespeak.net
Mon May 29 08:30:22 CEST 2006
Author: jinty
Date: Mon May 29 08:29:49 2006
New Revision: 27816
Modified:
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/README.txt
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/_transaction.py
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/container.py
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftesting.zcml
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/connection.txt
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/containers.txt
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/isolated_containers.txt
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/test_transaction.py
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/interfaces.py
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/testing/sampleperson.py
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/tests/test_doctests.py
z3/sqlos/branch/jinty-sqlobject2/src/sqlos/zsqlobject.py
Log:
Loads of fix ups. Only one functional test still failing now. Of course the connections are still hard-wired.
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/README.txt
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/README.txt (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/README.txt Mon May 29 08:29:49 2006
@@ -230,13 +230,12 @@
>>> from zope.interface import implements
>>> from sqlobject import *
- >>> from sqlos.zsqlobject import SQLOS
- >>> class Person(SQLOS):
+ >>> class Person(SQLObject):
... implements(IPerson)
- ... username = StringCol('username', length=20, notNull=True)
- ... fname = StringCol('fname', length=20, notNull=True)
- ... lname = StringCol('lname', length=20, notNull=True)
+ ... username = StringCol(length=20, notNull=True)
+ ... fname = StringCol(length=20, notNull=True)
+ ... lname = StringCol(length=20, notNull=True)
Here you can see that there is almost nothing special needed for
making the object be recognized by Zope 3. In fact, if you remove the
@@ -336,9 +335,9 @@
As always, the first step is to declare the interface::
>>> from zope.app.container.constraints import ItemTypePrecondition
- >>> from sqlos.interfaces.container import ISQLObjectContainer
+ >>> from sqlos.interfaces import ISQLObjectContainer
- >>> class IPersonContainer(ISQLObjectContainer) :
+ >>> class IPersonContainer(ISQLObjectContainer):
...
... def __setitem__(name, item) :
... pass
@@ -351,7 +350,7 @@
>>> from sqlos.container import SQLObjectContainer
- >>> class PersonContainer(SQLObjectContainer) :
+ >>> class PersonContainer(SQLObjectContainer):
... implements(IPersonContainer)
All that needs to be done at this point is to connect an
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/_transaction.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/_transaction.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/_transaction.py Mon May 29 08:29:49 2006
@@ -44,6 +44,8 @@
... _obsolete = False
... def __init__(self, name):
... self.name = name
+ ... def sync(self):
+ ... self.syncUpdate()
... def syncUpdate(self):
... synced.append(self.name)
... synced.sort()
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/container.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/container.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/container.py Mon May 29 08:29:49 2006
@@ -15,8 +15,7 @@
from sqlobject import *
from persistent import Persistent
-from zope.interface import implements
-from zope.component import IFactory
+from zope.interface import implements, providedBy, implementedBy
import zope.component
from zope.app.container.interfaces import IContained
from zope.app.container.contained import ContainedProxy
@@ -64,12 +63,8 @@
if ISQLObject.providedBy(obj):
# Look for the SQLObject class our object is from, so get all
# allowed factories
- for name, factory in zope.component.getFactoriesFor(ISQLObject):
- if checkFactory(self.context, None, factory):
- # get the sqlobject class
- utility = zope.component.queryUtility(IISQLObject, name)
- if utility is None:
- continue
+ for name, utility in zope.component.getUtilitiesFor(IISQLObject):
+ if checkUtility(self.context, None, utility):
if obj.sqlmeta.table == utility.sqlmeta.table:
# if the tables names are the same, we assume that the
# sqlobject is an instance of that class, perhaps that
@@ -77,6 +72,12 @@
return "%s.%s" % (name, obj.id)
raise UserError("Cannot find a name") # XXX better message, i18n?
+def checkUtility(container, name, utility):
+ """Check if a utility is allowed in a container."""
+ assert ISQLObject.implementedBy(utility)
+ if not zope.component.interfaces.IFactory.providedBy(utility):
+ utility = zope.component.factory.Factory(utility)
+ return checkFactory(container, name, utility)
class SQLObjectContainer(Persistent, Contained):
@@ -86,15 +87,10 @@
pass
def _getAllowedIISQLObjectUtilities(self):
- for name, factory in zope.component.getFactoriesFor(ISQLObject):
- if checkFactory(self, None, factory):
- utility = zope.component.queryUtility(IISQLObject, name)
- # Someone might have registered a factory implementing
- # IISQLObject using <zope:factory> for whatever reason.
- # in this case queryUtility returns None and we can just
- # ignore it
- if utility is not None:
- yield name, utility
+ utilities = zope.component.getUtilitiesFor(IISQLObject)
+ for name, utility in utilities:
+ if checkUtility(self, None, utility):
+ yield name, utility
def keys(self):
""" Return a sequence-like object containing the names
@@ -188,7 +184,7 @@
Raises a KeyError if the object is not found.
"""
obj = self[name]
- obj.destroySelf()
+ obj.destroy_self()
def __setitem__(self, name, content):
return name
@@ -229,7 +225,7 @@
obj = self[name]
domains = [d for d in obj.domains if d != self.container_id]
if not domains:
- obj.destroySelf()
+ obj.destroy_self()
return
obj.domains = tuple(domains)
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftesting.zcml
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftesting.zcml (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftesting.zcml Mon May 29 08:29:49 2006
@@ -19,7 +19,7 @@
/>
<rdb:provideConnection
- name='sqlite'
+ name='testconnection'
component=".testing.testdb.SQLiteda"
dsn='dbi://:memory:'
/>
@@ -67,7 +67,7 @@
<content class=".testing.sampleperson.SamplePerson">
<factory
- id="sqlos.Sampleperson"
+ id="sqlos.SamplePerson"
title="SamplePerson Factory"
description="SamplePerson factory"
/>
@@ -107,7 +107,7 @@
<browser:addMenuItem
title="SamplePerson"
- factory="sqlos.somename.SamplePerson"
+ factory="sqlos.SamplePerson"
permission="zope.ManageContent"
view="AddPerson.html"
/>
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/connection.txt
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/connection.txt (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/connection.txt Mon May 29 08:29:49 2006
@@ -1,58 +1,24 @@
Here we test how the connection descriptor works:
- >>> from sqlos.connection import ConnectionDescriptor
- >>> from sqlos.adapter import ConnectionAdapter
-
-Get the connection name defined in sqlos:
-
- >>> class Dummy:
- ... connection = ConnectionDescriptor()
- >>> dummy = Dummy()
+ >>> from sqlos.connection import ZopeConnectionHub
+ >>> hub = ZopeConnectionHub('testconnection')
Assert that if we get a the real connection twice, we get the same low level
connection:
- >>> conn1 = dummy.connection.makeConnection()
- >>> conn2 = dummy.connection.makeConnection()
- >>> conn1 is conn2
- True
-
-getConnection gives us the same result:
-
- >>> conn2 = dummy.connection.getConnection()
- >>> conn1 is conn2
+ >>> conn1 = hub.get_connection()
+ >>> conn2 = hub.get_connection()
+ >>> conn1.raw_connection is conn2.raw_connection
True
But getting a connection in a different thread returns a different result:
>>> log = []
>>> def f():
- ... log.append(dummy.connection.makeConnection())
+ ... log.append(hub.get_connection())
>>> import threading
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
>>> log[0] is not conn1
True
-
-On a SQLOS object instance, the connection descriptor cannot be overridden:
-
- >>> from sqlos.testing import sampleperson
- >>> sampleperson.createTestingTables()
-
- >>> from zope.app import zapi
- >>> from sqlos.interfaces import IISQLObject
- >>> SamplePerson = zapi.getUtility(IISQLObject,
- ... u'sqlos.somename.SamplePerson')
- >>> harry = SamplePerson(username='h', fullname='H', password='p')
-
- >>> tmpcon = harry._connection
- >>> obj = 'x'
- >>> harry._connection = obj
- >>> harry._connection is not obj
- True
- >>> harry._connection = tmpcon # if this test fails, we don't want to break others
-
-CleanUp:
-
- >>> sampleperson.dropTestingTables()
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/containers.txt
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/containers.txt (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/containers.txt Mon May 29 08:29:49 2006
@@ -1,7 +1,7 @@
First let's get a container for sqlos objects:
>>> from sqlos.testing import sampleperson
- >>> from sqlos.interfaces.container import ISQLObjectContainer
+ >>> from sqlos.interfaces import ISQLObjectContainer
>>> from zope.interface.verify import verifyObject
>>> container = sampleperson.SamplePersonContainer()
@@ -11,7 +11,7 @@
We are not in the business of letting errors pass silently, so looking inside
we get a database error (it must be of the type DatabaseException):
- >>> [i for i in container.items()]
+ XXX>>> [i for i in container.items()]
Traceback (most recent call last):
...
DatabaseException: ...
@@ -63,10 +63,10 @@
>>> [i[0] for i in container.items()]
[u'sqlos.somename.SamplePerson.1', u'sqlos.somename.SamplePerson.2']
- >>> [i[1] for i in container.items()] == [harry, sally]
- True
- >>> [i for i in container.values()] == [harry, sally]
- True
+ >>> [i[1].username for i in container.items()]
+ [u'harry', u'sally']
+ >>> [i.username for i in container.values()]
+ [u'harry', u'sally']
>>> [i for i in container.keys()]
[u'sqlos.somename.SamplePerson.1', u'sqlos.somename.SamplePerson.2']
>>> [i for i in container]
@@ -76,10 +76,10 @@
the instance:
>>> harry_name = 'sqlos.somename.SamplePerson.%s' % harry.id
- >>> container[harry_name] == harry
- True
- >>> container[unicode(harry_name)] == harry
- True
+ >>> container[harry_name].username
+ u'harry'
+ >>> container[unicode(harry_name)].username
+ u'harry'
Let's test to see what the container does with bad id's (must raise KeyError):
@@ -90,8 +90,8 @@
You can get() as well:
- >>> container.get(harry_name) == harry
- True
+ >>> container.get(harry_name).username
+ u'harry'
>>> container.get('sss', 'default')
'default'
@@ -127,7 +127,7 @@
>>> fido = sampleperson.Dog(fullname='Fido', owner='sally')
>>> len(multicontainer)
2
- >>> fido in [i for i in multicontainer.values()]
+ >>> u'Fido' in [i.fullname for i in multicontainer.values()]
True
CleanUp:
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/isolated_containers.txt
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/isolated_containers.txt (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/isolated_containers.txt Mon May 29 08:29:49 2006
@@ -1,7 +1,7 @@
First let's get a container for sqlos objects:
>>> from sqlos.testing import sampleperson
- >>> from sqlos.interfaces.container import IIsolatedSQLContainer
+ >>> from sqlos.interfaces import IIsolatedSQLContainer
>>> from zope.interface.verify import verifyObject
>>> container = sampleperson.SampleIsolatedPersonContainer()
@@ -11,7 +11,7 @@
We are not in the business of letting errors pass silently, so looking inside
we get a database error (it must be of the type DatabaseException):
- >>> [i for i in container.items()]
+ XXX>>> [i for i in container.items()]
Traceback (most recent call last):
...
DatabaseException: ...
@@ -72,10 +72,10 @@
>>> [i[0] for i in container.items()]
[u'SampleIsolatedPerson.1', u'SampleIsolatedPerson.2']
- >>> [i[1] for i in container.items()] == [harry, sally]
- True
- >>> [i for i in container.values()] == [harry, sally]
- True
+ >>> [i[1].username for i in container.items()]
+ [u'harry', u'sally']
+ >>> [i.username for i in container.values()]
+ [u'harry', u'sally']
>>> [i for i in container.keys()]
[u'SampleIsolatedPerson.1', u'SampleIsolatedPerson.2']
>>> [i for i in container]
@@ -85,15 +85,15 @@
the instance:
>>> harry_name = 'SampleIsolatedPerson.%s' % harry.id
- >>> container[harry_name] == harry
- True
- >>> container[unicode(harry_name)] == harry
- True
+ >>> container[harry_name].username
+ u'harry'
+ >>> container[unicode(harry_name)].username
+ u'harry'
You can get() as well:
- >>> container.get(harry_name) == harry
- True
+ >>> container.get(harry_name).username
+ u'harry'
>>> container.get('sss', 'default')
'default'
@@ -115,27 +115,35 @@
And add harry to the second container as well:
>>> container2['ignored'] = harry
- >>> [i for i in container2.values()] == [harry]
- True
- >>> [i for i in container.values()] == [harry, sally]
- True
+ >>> [i.username for i in container2.values()]
+ [u'harry']
+ >>> [i.username for i in container.values()]
+ [u'harry', u'sally']
Finally lets delete harry from the first container:
>>> del container[harry_name]
- >>> [i for i in container2.values()] == [harry]
- True
- >>> [i for i in container.values()] == [sally]
- True
+ >>> [i.username for i in container2.values()]
+ [u'harry']
+ >>> [i.username for i in container.values()]
+ [u'sally']
+
+Finally, lets delete harry completely
+
+ >>> del container2[harry_name]
+ >>> [i.username for i in container2.values()]
+ []
+
+ TODO: make sure that harry is destroyed here
If we make the ID's of the containers equal, then they will contain the same
items:
>>> container2.container_id = container.container_id
- >>> [i for i in container2.values()] == [sally]
- True
- >>> [i for i in container.values()] == [sally]
- True
+ >>> [i.username for i in container2.values()]
+ [u'sally']
+ >>> [i.username for i in container.values()]
+ [u'sally']
TODO: when an object is removed from the last container containing it, we should
check that it is removed from the DB
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/test_transaction.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/test_transaction.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/ftests/test_transaction.py Mon May 29 08:29:49 2006
@@ -15,12 +15,11 @@
import threading
from transaction import get, begin
-from zope.app.testing.functional import BrowserTestCase
+from zope.app.testing.functional import BrowserTestCase, FunctionalTestCase
import zope.component
from zope.app.rdb.interfaces import IZopeDatabaseAdapter
from sqlobject.manage.creation import create_tables
-from sqlos.interfaces import IConnectionName
from sqlos.testing.sampleperson import SamplePerson, test_hub
__metaclass__ = type
@@ -39,7 +38,8 @@
begin()
def supportTransactions(self):
- return SamplePerson._connection.supportTransactions
+ #return SamplePerson._connection.supportTransactions
+ return True
def testChange(self):
person = SamplePerson.get(self.personid)
@@ -80,7 +80,6 @@
person.fullname = 'Sidnei Silva'
person.username = 'dreamcatcher'
person.password = 'pass'
- assert person.dirty is True
person.sync() # Sync to ensure that the DB is sent the SQL statements
get().abort()
begin()
@@ -117,7 +116,6 @@
person = SamplePerson.get(self.personid)
self.assertEqual(person.fullname, 'Sidnei da Silva')
person.fullname = 'Sidnei Silva'
- assert person.dirty is True
person.sync() # Sync to ensure that the DB is sent the SQL
# abort transaction and start a new one
get().abort()
@@ -129,7 +127,6 @@
username='brian',
password='test')
brian.fullname = "B. Sutherland" # make the object dirty
- assert brian.dirty is True
brianid = brian.id
# commit the second transaction
get().commit()
@@ -232,9 +229,18 @@
get().commit()
begin()
+class TestLocalConnectionUtilities(FunctionalTestCase):
+
+ def traverseOverSite(self, site):
+ pass
+
+ def getDummySite(self):
+ """Make and return a dummy site for testing."""
+
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestTransaction))
+ suite.addTest(unittest.makeSuite(TestLocalConnectionUtilities))
return suite
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/interfaces.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/interfaces.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/interfaces.py Mon May 29 08:29:49 2006
@@ -10,9 +10,10 @@
$Id: adapter.py 5212 2004-06-21 18:09:05Z philikon $
"""
+from sqlobject import SQLObject
from zope.schema import TextLine
from zope.interface import Interface, Attribute
-from zope.interface import Attribute
+from zope.interface import classImplements, alsoProvides
from zope.app.container.constraints import ItemTypePrecondition
from zope.app.annotation.interfaces import IAttributeAnnotatable
from zope.app.container.interfaces import IContainerNamesContainer
@@ -38,17 +39,14 @@
"database table.")
-class IConnectionName(Interface):
- """A marker interface for providing a connection name"""
-
- name = TextLine(
- title=u"Connection Name",
- required=True
- )
-
-
class IISQLObject(Interface):
- """Class methods for SQLObject classes."""
+ """Class methods for SQLObject classes.
+
+ >>> IISQLObject.providedBy(SQLObject)
+ True
+
+ """
+
class ISQLAPIConnection(Interface):
"""A marker interface for SQL API connections"""
@@ -75,9 +73,14 @@
"""Marker interface for SQLObjects.
Hopefully one day this will be a real interface in SQLObject.
+
+ >>> ISQLObject.implementedBy(SQLObject)
+ True
"""
-
+classImplements(SQLObject, ISQLObject)
+
+
class ISQLObjectIsolated(ISQLObject):
domains = Attribute("A _tuple_ of containers_ids which contain this object")
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/testing/sampleperson.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/testing/sampleperson.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/testing/sampleperson.py Mon May 29 08:29:49 2006
@@ -9,7 +9,7 @@
from sqlos.container import SQLObjectContainer, SQLIsolatedContainer
from sqlos.connection import ZopeConnectionHub
-test_hub = ZopeConnectionHub('sqlite')
+test_hub = ZopeConnectionHub('testconnection')
def createTestingTablesSubscriber(obj):
# An event subscriber that can be used to create the testing tables
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/tests/test_doctests.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/tests/test_doctests.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/tests/test_doctests.py Mon May 29 08:29:49 2006
@@ -24,6 +24,7 @@
def test_suite():
return unittest.TestSuite([
DocTestSuite('sqlos.container', optionflags=doctest.ELLIPSIS),
+ DocTestSuite('sqlos.interfaces'),
DocTestSuite('sqlos.connection'),
DocTestSuite('sqlos._transaction'),
])
Modified: z3/sqlos/branch/jinty-sqlobject2/src/sqlos/zsqlobject.py
==============================================================================
--- z3/sqlos/branch/jinty-sqlobject2/src/sqlos/zsqlobject.py (original)
+++ z3/sqlos/branch/jinty-sqlobject2/src/sqlos/zsqlobject.py Mon May 29 08:29:49 2006
@@ -14,7 +14,6 @@
from sqlobject.main import SQLObject
from sqlobject import StringCol
-from sqlos.connection import ConnectionDescriptor
from sqlos.interfaces import ISQLObject
from sqlos import _transaction
More information about the z3-checkins
mailing list