[Zope3-Users] Re: sqlos, sites and local utilities

2006-01-05 Thread Philipp von Weitershausen
Jeff Shell wrote:
 What about using zope.app.component.hooks.setSite? It sets the site on
 a zope.thread.local based object, and I believe most utility lookups
 fall back on that setting if context is not supplied.

All component look-ups *first* look at the closest site (which comes
from the thread local) and then cascade back to less local sites until
the global site is queried. Describing this as falling back on local
sites for most utility lookups is incorrect.

Now, the Component Architecture itself doesn't actually know about the
site in the thread local. It needs to be told to look there. That's
where the component hooks play a role. zope.app.component install those
to make zope.component look for the thread local. Unless these hooks
aren't installed, a site in the thread local won't be found. In Zope X3
3.0, these hooks were set via ZCML, in Zope 3.1+ you have to call
zope.app.component.hooks.setHooks(). That bit me at least twice when I
ported Five to Zope 3.2.

Philipp

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: sqlos, sites and local utilities

2005-11-16 Thread Andreas Elvers

Stephan Richter wrote:

On Tuesday 08 November 2005 05:38, Andreas Elvers wrote:

[...]

Has anyone yet tried sqlos with database connections created as local
utilities ? At one point sqlos tries to get the utility in connection.py
Line 88.

 newconn = zapi.queryUtility(IZopeDatabaseAdapter, name,
default=None,
context=context)

The context points to a sqlobject instance. The problem is that these
instances seem to have no parent and thus will fail the lookup my local
utility and will raise an 'NoneType' object is not callable error later
in the code when trying to adapt.

When you try the sqlos example everything is fine, since the database
connection is defined in configure.zcml as a global utility.

My current idea is to expose the enclosing folder as a context to query
utility. But I don't know if setting references in sqlobject instances
is such a great idea.



If the sqlobject instance does not have a parent, then that's bad. It probably 
does not have a parent, because it is usually wrapped using a location proxy, 
which is lost inside a method. I think the smart thing to do here would be 
what you suggested or to write a subclass of sqlobject that implements 
ILocation.


Hi,

While digging a bit depper into my problem I found out, that 
implementing ILocation
will not do the trick, since the mentioned exception is caused by a 
factory call, and

a factory will never have a __parent__ or am I totally wrong here ?

Anyway I have created a functional unit test to demonstrate the problem. 
In fact
the unit test shows that sqlos will always lookup global utilities and 
never local utilities.


Here is the test. It will fail in the last block on 
testsite['personcontainer'] = personcontainer.


Regards
- Andreas

First we need to set up some folder structure to set up a site.

 from zope.app import zapi
 from zope.app.folder import Folder
 from zope.app.container.contained import Contained
 from sqlos.testing.sampleperson import SamplePersonContainer, 
createTestingTables
 from zope.app.component import interfaces as componentInterfaces
 from zope.app.component.site import 
LocalSiteManager,SiteManagerContainer
 from sqlos.container import SQLObjectContainer

 class LocalSitePersonContainer(SamplePersonContainer, 
SiteManagerContainer, Contained):
...pass

 root = getRootFolder()
 testsite = Folder()
 root['testsite'] = testsite
 componentInterfaces.ISite.providedBy(testsite)
False

 sm = LocalSiteManager(testsite)
 testsite.setSiteManager(sm)
 componentInterfaces.ISite.providedBy(testsite)
True


Now we set up a local database utility

 from zope.app.rdb.interfaces import IZopeDatabaseAdapter
 from zope.app.component.interfaces.registration import 
ActiveStatus,InactiveStatus
 from sqlos.testing.testdb import SQLiteda
 from zope.app.utility import UtilityRegistration

 dbAdapter = SQLiteda(u'dbi://:memory:') 
 reg = UtilityRegistration('sqlite',IZopeDatabaseAdapter,dbAdapter)
 default = sm['default']
 key = default.registrationManager.addRegistration(reg)
 zapi.traverse(default.registrationManager, key).status = ActiveStatus

 localUtility = sm.queryUtility(IZopeDatabaseAdapter,'sqlite')
 localUtility
sqlos.testing.testdb.SQLiteda object at ...

 localUtility is dbAdapter
True

Ok. Now we have a site in root/testsite with a registered sqlite adapter.
We make sure that our localUtility is not identical to the global sqlite utility
that has been registered through ftesting.zcml.

 gsm = zapi.getGlobalSiteManager()
 globalUtility = gsm.queryUtility(IZopeDatabaseAdapter,'sqlite')
 globalUtility is not localUtility
True

Now we populate testsite with data. We do this by using direct SQL, because 
there is currently
no support for local sites in testcode.

 from zope.component.interfaces import ISiteManager

 cursor = localUtility().cursor()

 cursor.execute(
... '''create table dog (
...   id integer primary key,
...   fullname varchar(50) not null,
...   owner varchar(20) not null)''')
 cursor.execute(
... '''create table sample_isolated_person (
...   id integer primary key,
...   domains text,
...   fullname varchar(50) not null,
...   username varchar(20) not null,
...   password varchar(20) not null)''')
 cursor.execute(
... '''create table sample_person (
...   id integer primary key,
...   fullname varchar(50),
...   username varchar(20),
...   password varchar(20))''')

Now that we have setup database tables we should be able to create the