[Zope-dev] Re: [Zope3-dev] Re: How To run current Zope 2 3 from CVS on Windows

2004-05-12 Thread Phillip J. Eby
At 06:12 PM 5/12/04 +0800, Choo Zhi Min wrote:
What does import os; print os.name return in Cygwin, nt or posix?
Python 2.3.2 (#1, Oct  9 2003, 12:03:29)
[GCC 3.3.1 (cygming special)] on cygwin
Type help, copyright, credits or license for more information.
 import os
 os.name
'posix'



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )


[Zope-dev] Re: [Zope3-dev] ZConfig: Section type datatype inheritance

2003-12-29 Thread Phillip J. Eby
At 12:04 PM 12/29/03 -0500, Barry Warsaw wrote:

This is how I'm using extended section types in my code currently.  The
proposed change won't affect me because I explicitly specify the data
types in derived section types.  It seems to me unlikely that you'd have
a base section type with a non-default data type, with derived section
types that rely on the default data type.
Yes, it would only be useful if you could also override existing attribute 
or key definitions in the derived section type.  Adding new attributes, but 
leaving the section's datatype alone wouldn't make much sense.


+0
Agreed, unless there's also a way to override/replace existing attributes, 
as opposed to merely adding new ones.

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )


[Zope-dev] Re: [Zope3-dev] ZConfig: Keytype and section type extension

2003-12-29 Thread Phillip J. Eby
At 01:53 PM 12/29/03 -0500, Fred L. Drake, Jr. wrote:

Phillip J. Eby writes:
  That reminds me...  is there any way for section *names* to be
  case-sensitive, or at least case-preserving?  For example, if one were
  simulating Apache-style configuration like:
There isn't, but there was at some point.  Nobody here at ZC seemed to
think it useful at the time, so it was removed as a simplification.
What we had was a nametype attribute for sectiontype elements; it
was just another datatype function.
I'd be happy to have that back if there's a real use for it.  The
current situation, where the conversion is coded directly in
ZConfig.cfgparser, isn't very flexible.
Agreed.  :)


Would it suit your requirements if the name type were associated with
the section type, and inherited from the base type if not specified?
Yep.


  Currently, IIRC, the '_name' attribute of the resulting section will be
  '/foo/bar/baz'.
The _name attribute is an implementation detail; use the
getSectionName() method instead.  I'm likely to change the _name
detail just to be facetious.  ;-)
Well, in that case, can we have a 'getItems()' that returns only the 
key-value pairs for actual attributes, and does *not* include keys for 
values that weren't explicitly specified in the configuration file and 
don't have defaults?

In PEAK, the binding.Component class has this constructor currently:

def fromZConfig(klass, section):

Classmethod: Create an instance from a ZConfig 'section'

# ZConfig uses unicode for keys and defaults unsupplied values to None
data = dict([(str(k),v) for k,v in section.__dict__.items()
if v is not None])
if not hasattr(klass,'_name') and '_name' in data:
del data['_name']
if not hasattr(klass,'_matcher') and '_matcher' in data:
del data['_matcher']
return klass(**data)

As you can see, I'm doing a fair amount of work in order to extract a 
mapping I can use as keyword arguments for the regular constructor.  The 
standard way in PEAK to make a component configurable by ZConfig is simply 
to specify whatevertype.fromZConfig as the datatype in the ZConfig schema.

If there were a 'getMapping' method available, the above would become 
something like:

def fromZConfig(klass, section):

Classmethod: Create an instance from a ZConfig 'section'

data = dict([(str(k),v) for k,v in section.getItems()]
data['_name'] = section.getSectionName()
return klass(**data)
Unless of course the keys were strings rather than Unicode, in which case 
it'd be even simpler.  (The issue here is that Python requires keyword 
arguments to be strings rather than Unicode, even though attribute names 
can be Unicode.  ZConfig sets attributes using unicode because ZConfig 
schemas are XML, and therefore Unicode.)

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] PHP vs Zope cost benefit

2002-04-24 Thread Phillip J. Eby

At 04:55 PM 4/24/02 -0300, Leonardo Rochael Almeida wrote:

As for multiple DB rollback, yes, that works as advertised, and is
actually really easy to believe if you explain them how it works. Truth
is, Two-Phase-Commit was INVENTED (a long time ago, and not in Zope) to
make it possible to commit or rollback multiple transactional entities
at the same time. Zope is just an implementation of a TPC coordinator (I
think, and I hope I got the vocabulary right).

Note that this only guaranteed to work if all the database adapters 
involved in the transaction support two-phase-commit.  Many do not, and 
thus may commit too early or too late in the course of a multi-database 
transaction.

If you need multi-database commit, you'll need to verify that the adapter 
in question actually implements tpc_vote() as something other than 'pass'.  :)



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Future of ZPatterns

2002-04-20 Thread Phillip J. Eby

At 08:22 PM 4/15/02 -0500, Steve Spicklemire wrote:
Hi Marcello,

 Wow.. sounds like a neat book. ;-) Seriously, Phil Eby has 
 suggested that there will be some sort of migration helpers to move from 
 ZPatterns to

There probably will not be any migration tools written by me or Ty; we are 
likely to port our own ZPatterns apps by hand, as the benefits of rewriting 
specifically for TransWarp far exceed any potential labor savings from an 
automated port, at least for our projects.



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Re: [Zope3-dev] Are there Graphic Designers?

2002-04-05 Thread Phillip J. Eby

Folks, can we please stop the zope-dev/zope3-dev crossposts and direct this 
thread to zope3-dev only?  You're doubling the volume of posts I have to 
read.  :)  Thanks.



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Defining Interfaces

2002-01-29 Thread Phillip J. Eby

At 03:17 PM 1/28/02 +, Chris Withers wrote:
Jeffrey P Shell wrote:
 
  On 1/27/02 11:25 AM, Steve Alexander [EMAIL PROTECTED] wrote:
 
   Hi folks,
  
   When I define an Interface, are the methods of the interface supposed to
   have self as the first argument?
 
  No.

Can you expand on this a little?

It doesn't make sense to me to exclude 'self'...

Because when you *call* the methods, you don't pass 'self', it's 
implied.  Since an interface is supposed to document the call signature, it 
actually doesn't make sense for it to include 'self', since it's not part 
of the call signature.  Make sense?


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] im_self of methods accessed via non trivial acquisition

2002-01-19 Thread Phillip J. Eby

At 01:12 PM 1/18/02 +0100, Stefan Bund wrote:
Phillip J. Eby [EMAIL PROTECTED] writes:
 
  Method rebinding is done only when an item is retrieved from the aq_self
  side, and only if im_self points to aq_self.  If these conditions are met,
  a new binding is created which points to the acquisition wrapper.
 
  This is a feature, not a bug.  If you rebind im_self on the aq_parent side,
  and your method assigns a value to an attribute of self, it will be
  assigned to the wrong object!  It is safe in your example to bind m.im_self
  to B, because B.aq_base is f, the true self of m.  But it is not safe to
  bind m.im_self to A, because A.aq_base is g -- another object altogether.
 
  I guess another way to look at it is that a method retrieved from an
  acquisition-wrapped object will always meet the condition that
  method.im_self.aq_base is the original object the method was retrieved
  from.  This ensures that the method simply works with an
  acquisition-wrapped version of its original self.

Of course, im_self cannot be A, that would be wrong, but as far as I
understand, it could be a *new* acquisition wrapper, something like /B
o A/ or even /[f] o A/:

C--A--O--[a]
|  |  |
|  |  [b]
|  |
|  O--B--O--[c]
|  |  |  |
|  |  |  [d]
|  |  |
|  |  O--[e]
|  |  |
|  |  [f]
|  |
|  [g]
|
B--O--[c]
|  |
|  [d]
|
O--[e]
|
[f]

(that's what I refer to in the definition of /C/). So if /C/ is one of
the aforementioned new wrappers, /C.aq_base/ is indeed [f] and
therefore, /C/ would be safe as im_self?

Hmm. Is there another reasun, why method rebinding works the way it
does (returning a subtree and not a new acquisitionwrapper like
described above) or am I completely amiss?

Beats me.  I guess nobody's asked for the feature, and in any event it 
requires global knowledge of the tree structure that would be very 
difficult to code.  The current behavior is a rule that is applied locally 
at each acquisition wrapper, and the wrappers don't know what wrapper is 
pointing to them, so it's really not practical for them to try and do 
something that smart.

It may also be that what you're asking for is a bad idea, in which case Jim 
Fulton can probably explain why.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Security Gurus Wanted

2002-01-19 Thread Phillip J. Eby

At 10:43 AM 1/19/02 -0500, vio wrote:
* vio [EMAIL PROTECTED] [020119 09:56]:

So Globals.InitializeClass(your_class) finds the declaration
'security.declareSomething()' inside a class, but 'security' being
a reference to a ClassSecurityInfo object AT THE MODULE LEVEL somehow has
no effect at the class level (while I wrongly thought that by declaring it
at the module level like that, it will behave more or less like a 'global'
variable). I wonder what was carried at the class level, but something
definitely was, else Python would have thrown something ugly at me.

Check the Python reference manual -- not the library reference, but the 
language definition.  You'll find that Python has two primary scopes: 
local and global.  When a class statement is executing, the local 
namespace is the future __dict__ of the class, and the global namespace is 
the module __dict__.  If security.Foo() is in the body of a class, and 
security is not in the *local* namespace (i.e. already defined in the 
class body), then it will be looked up in the global namespace.  Thus, your 
calls went to the module-level security, but no security object was 
present in the resulting class (because there was no statement placing one 
there).

IMHO, you don't want to share a security object between more than one 
class, since presumably they will have different declarations and thus each 
require their own.  So there's no reason to create a ClassSecurityInfo 
object at the module level, anyway.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] im_self of methods accessed via non trivial acquisition

2002-01-18 Thread Phillip J. Eby

At 09:42 AM 1/18/02 +0100, Stefan Bund wrote:

A--O--[a]
|  |
|  [b]
|
O--B--O--[c]
|  |  |
|  |  [d]
|  |
|  O--[e]
|  |
|  [f]
|
[g]

...

let /m/ be a method of the objekt /f/. The expression of interest is

 x := A.m

I would expect /x.im_self/ to be an acquisition wrapper C

 C := A.f

where (as far as i understand the rules of acquisition)
/C.aq_parent == A/

But instead displaying  /x.im_self/ yields the acquisition tree rooted
at /B/ !!

I find this a bit disturbing. My question: 'Is it a *bug* or a
*feature*?'. I hope, I made my point clear.

Method rebinding is done only when an item is retrieved from the aq_self 
side, and only if im_self points to aq_self.  If these conditions are met, 
a new binding is created which points to the acquisition wrapper.

This is a feature, not a bug.  If you rebind im_self on the aq_parent side, 
and your method assigns a value to an attribute of self, it will be 
assigned to the wrong object!  It is safe in your example to bind m.im_self 
to B, because B.aq_base is f, the true self of m.  But it is not safe to 
bind m.im_self to A, because A.aq_base is g -- another object altogether.

I guess another way to look at it is that a method retrieved from an 
acquisition-wrapped object will always meet the condition that 
method.im_self.aq_base is the original object the method was retrieved 
from.  This ensures that the method simply works with an 
acquisition-wrapped version of its original self.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] separate mailing list for ZPublisher-only apps (ZPub + cgi + apache)

2002-01-06 Thread Phillip J. Eby

At 10:06 AM 1/6/02 -0800, Michael Olivier wrote:
I'd like to form (or join) a separate mailing list for ZPublisher-only 
apps.  I know there are zope developers like me who use ZPublisher + 
FastCGI (or whatever) + apache (or whatever) to run a web site.  I know we 
would not have the benefit of some of the expertise here, but the flip 
side is we would get more discussion for our flavor of zope use.  Most of 
the discussion here is about the full Zope which is a lot to wade through 
for the occasional helpful tidbit.

I'd be interested, and if ZC doesn't want to make it a zope.org list, I'm 
sure we could set it up at eby-sarna.com easily enough.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] References, persistence, BTrees

2002-01-03 Thread Phillip J. Eby

At 05:49 PM 1/3/02 -0700, Jeffrey P Shell wrote:

'subscriber' is a reference to the subscribing object, and it's very 
likely to be to an object in the ZODB.  Is it wise to have more than one 
persistent reference to a single persistent object?
I swear that I had once heard Jim say (vocally) that you could do 
references like this in the ZODB now.  I'm trying to avoid using Paths 
because objects have a tendency to move around[*], and I have performance 
concerns for a single event service object to have to call 
'unrestrictedTraverse' to every subscriber.

Unfortunately, you can't take this shortcut.  Not because you can't store 
or retrieve references in this way, but because you can't get an 
acquisition context this way, which means security is shot, not to mention 
things like objects knowing their URLs.  So although it's perfectly safe to 
point to objects in the ZODB from more than one place, it's almost always 
useless to do so with respect to an arbitrary Zope object.  :(

I don't know if this is changing in Z3, but I'm rather curious about the 
possibility, myself.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPublisher Q about obj having both __bobo_traverse__ and index_html

2001-12-24 Thread Phillip J. Eby

At 10:18 PM 12/23/01 -0800, Michael Olivier wrote:
I'm using ZPublisher + PCGI w/o the full Zope environment.  Is it possible 
to have an object that defines a __bobo_traverse__ method and also has an 
index_html method?  In the example below, I would want it to traverse if 
the URL path had more elements on it, and otherwise to call 
index_html().  Unless I comment out the __bobo_traverse__, the index_html 
method doesn't work.  I also tried returning None in traversal if key was 
None, but that didn't work either.  (I am running 2.0.1, so maybe I'm 
hitting a bug that's since been fixed.)

class MsgDirList:
 message directory list

 def __init__(self):
 pass

 def __bobo_traverse__(self, REQUEST, key):
 # traverse if there is more in the URL path...

Try putting this in right here:

  if key=='index_html': return self.index_html

 return CitiesMsgs(key)

index_html is *added* onto the URL for traversal, so your __bobo_traverse__ 
should get asked for it.  Note that you return self.index_html *without* 
calling it, as ZPublisher will do that for you.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] 100k+ objects, or...Improving Performance of BTreeFolder...

2001-12-10 Thread Phillip J. Eby

I'm not sure if this is taken into consideration in your work so far/future 
plans...  but just in case you were unaware, it is not necessary for you to 
persistently store objects in the ZODB that you intend to index in a 
ZCatalog.  All that is required is that the object to be cataloged is 
accessible via a URL path.  ZSQL methods can be set up to be 
URL-traversable, and to wrap a class around the returned row.  To load the 
items into the catalog, you can use a PythonScript or similar to loop over 
a multi-row query, passing the objects directly to the catalog along with a 
path that matches the one they'll be retrievable from.  This approach would 
eliminate the need for BTreeFolder altogether, although of course it 
requires access to the RDBMS for retrievals.  This should reduce the number 
of writes and allow for bigger subtransactions in a given quantity of memory.


At 07:36 PM 12/9/01 -0800, [EMAIL PROTECTED] wrote:
Interesting FYI for those looking to support lots of cataloged objects in
ZODB and Zope (Chris W., et al)... I'm working on a project to put ~350k
Cataloged objects (customer database) in a single BTreeFolder-derived
container; these objects are 'proxy' objects which each expose a single
record in a relational dataset, and allow about 8 fields to be indexed (2 of
which, TextIndexes).

...

- Also, I want to make it clear that if I had a data access API that needed
more than simple information about my datasets (i.e. I was trying to do
reporting on patterns, like CRM-ish types of applications), I would likely
wrap a function around indexes done in the RDB, not in Catalog.  My requires
no reporting functionality, and thus really needs no indexes, other than for
finding a record for customer service purposes and account validation
purposes.  The reason, however, that I chose ZCatalog was for full text
indexing that I could control/hack/customize easily.  My slightly uninformed
belief now is that for big datasets or enterprise applications (whatever
that means), I would use a hybrid set of (faster) indexes using the RDB's
indexes where appropriate (heavily queried fields), and ZCatalog for
TextIndexes (convenient).   I'm sure inevitable improvements to ZCatalog
(there seems to be community interest in such) will help here.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] 100k+ objects, or...Improving Performance of BTreeFolder...

2001-12-10 Thread Phillip J. Eby

At 04:08 PM 12/10/01 +, Tony McDonald wrote:
On 10/12/01 2:54 pm, Phillip J. Eby [EMAIL PROTECTED] wrote:

  I'm not sure if this is taken into consideration in your work so far/future
  plans...  but just in case you were unaware, it is not necessary for you to
  persistently store objects in the ZODB that you intend to index in a
  ZCatalog.  All that is required is that the object to be cataloged is
  accessible via a URL path.  ZSQL methods can be set up to be
  URL-traversable, and to wrap a class around the returned row.  To load the
  items into the catalog, you can use a PythonScript or similar to loop over
  a multi-row query, passing the objects directly to the catalog along with a
  path that matches the one they'll be retrievable from.  This approach would
  eliminate the need for BTreeFolder altogether, although of course it
  requires access to the RDBMS for retrievals.  This should reduce the number
  of writes and allow for bigger subtransactions in a given quantity of 
 memory.

Gad! - are you saying you don't need to store a 1Mb .doc file into the ZODB,
but can still index the thing, store the index information in the Zcatalog
(presumably a lot smaller than 1Mb) and have the actual file accessible from
a file system URL? If so, that's really neat!

Yep.  By URL path, though, I meant a *Zope* path.  However it would be 
straightforward to create a Zope object that represents a filesystem path 
and does traversal/retrieval, assuming that one of the 'FS'-products out 
there doesn't already do this for you.

Chris Withers has pointed out that technically you don't even need the path 
string to be valid, it just has to be unique.  However, the standard tools 
and the method for getting the real object referred to by the catalog 
record do expect it to be a valid path IIRC.  I personally find it most 
convenient, therefore, to use a real Zope path.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPT Plain Text

2001-12-04 Thread Phillip J. Eby

At 05:58 PM 12/4/01 +, Chris Withers wrote:
Phillip J. Eby wrote:
 
  I personally would like to see ZPT support plain text at some point, and it
  already has some of the things necessary to do it.  But that's a separate
  issue from Zope 3X or Zope 3 itself.

It already can:

[example snipped]

Last I looked, there were still certain constructs that could not have the 
tag opted-out-of.  But that was a month or two ago and TAL moves fast... 
:)  I don't remember seeing tal:omit-tag before, so maybe that was the last 
piece of the puzzle.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ComputedAttribute, Persitent and too many datafull base classes

2001-10-21 Thread Phillip J. Eby


At 03:44 PM 10/20/01 +0200, Godefroid Chapelle wrote:
Hi,

In a product I am writing, I am trying to add a ComputedAttribute to an 
instance of a Folder descendant class.

This is the code I use:

 def addComputedAttribute(self, attributeName, sourceCode):
 methodName = '_ca_get%s' % attributeName
 self.addMethod(methodName, sourceCode)
 setattr(self, attributeName, 
 ContextComputedAttribute(self.__class__.__dict__[methodName]))

I think the problem you're having is that the method object being used in 
the last line (i.e., self.__class__.__dict__[methodName]) is not 
persistent.  If it is a Python function, it will not be saved persistently 
within the computed attribute.  This is probably why the Zope instance 
crashes at a later time.

This doesn't have anything to do with whether ComputedAttribute is 
Persistent.  It doesn't need to be, which is a good thing because you can't 
derive a class from both (as you've discovered).  You can write a Python 
version of ComputedAttribute by deriving only from Persistent, but as I 
said there is really no need to do that.  You need the function to be 
persistent, not the ComputedAttribute itself.  If the function is currently 
a pure-Python function, you need to replace it with some kind of callable 
object that can be pickled, such as a PythonScript.  You could also write 
your own class to do this, but again it is not the ComputedAttribute part 
that would cause a problem.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPublisher/ZServer interaction (was Re: A modest proposal)

2001-10-13 Thread Phillip J. Eby

At 10:23 AM 10/12/01 -0400, Paul Everitt wrote:

Wow, this is one hell of a thread. :^)

FWIW, Grisha put a Bobo publisher in mod_python a couple of years ago. 
Thus, if you like ZPublisher-style processing, you can do it in Apache via 
mod_python.

Personally, I prefer to keep a process boundary between Apache and my apps, 
for both safety and security.  Usually they're running as different users, 
for one thing.  We've been very pleased with FastCGI performance using 
mod_fcgi, so I don't see a whole lot to be gained by using mod_python.

Another interesting factor that can affect performance is that we usually 
run many pre-forked Apache child processes, but rarely have more than 2 or 
3 application processes.  Using mod_python would probably impact memory 
usage adversely, since there would then be in effect a larger application 
pool.

A somewhat simplistic analysis of memory usage in the different approaches:

O = Fixed application overhead (e.g. Python modules)
D = Application dynamic data
A = size of an Apache process
P = Memory used for a python interpreter (if the OS shares executable 
segments, ignore the code size, as it will be a constant for all approaches 
and thus irrelevant for comparison purposes.  In that case consider P will 
be the interpreter's data size)

n = Number of threads or processes in the app server pool
s = Number of Apache servers


Zope w/Apache frontend = P + O + D*n + A*s
mod_python = (P+O+D)*s   + A*s
ZLite  = (P+O+D)*n   + A*s

Since n is usually smaller than s, the ZLite approach uses considerably 
less memory than the mod_python approach, but can be faster than the 
Zope+Apache combination on multi-processor machines when the Python 
interpreter lock is an issue, at an extra cost of only (P+O)*(n-1).  In our 
situations, that usually amounts to at most 2 or 3 times P+O, which is a 
small price to pay for also being able to ignore all threading issues.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] RE: Component Architecture / A modest proposal: Replace medusa with Twisted

2001-10-11 Thread Phillip J. Eby

At 01:52 PM 10/11/01 +0200, Jean Jordaan wrote:
Hi all

I don't know if you're all familiar with this already, but reading
about Twisted didn't immediately bring to mind Medusa, but rather
certain aspects (specifically, *aspects*) of TransWarp, and of the
Component Architecture (interfaces).

I'm including a bite from
   http://twistedmatrix.com/page.epy/twistedphil.html

Interesting?

What they're doing is more of a design pattern ala JavaBeans to create 
interface definitions using method signatures which can be recognized using 
introspection.  However, a major point of the Component architecture is to 
get *away* from this style of doing things in Zope, because it makes it 
harder to use objects off the shelf, as one is required to code objects 
from the ground up for Zope use.  Whereas, in the New Religion, you can 
just stick an __implements__ attribute on them, and set up some adapters.

(Also, what Twisted is doing is entirely orthogonal to what TransWarp does, 
but I covered that in my reply to your post on the TransWarp mailing list. :) )


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] ZPublisher/ZServer interaction (was Re: A modest proposal)

2001-10-10 Thread Phillip J. Eby

At 08:00 AM 10/10/01 -0700, kapil thangavelu wrote:

sadly the distinction between zpublisher and zserver is nowhere near as
clean, i spent some time looking at it this morning trying to get my server
of choice using zope. i thought it would be a mid morning hack, but the rabit
hole follows the class heirarchy deeper and deeper:).  all i have to show for
my results is zope's output dumped to the server logs. its a start though...

hopefully we get some new religion in the publisher, please...

Hmm...   Check out:

http://cvs.eby-sarna.com/pylib/ZLite/

Specifically, the ZPlumbing module, for several examples of ZPublisher run 
loops using CGI and two different FastCGI modules.  I don't know anything 
about Twisted, so I couldn't tell you how easy it'd be to use the ZLite 
framework for this.

ZLite is the beginnings of my work on a Zope Lite distribution.  It's 
sort of the Standalone ZODB distribution's evil twin - intended if you 
want to use almost anything *but* the ZODB and ZMI parts of Zope.  That is, 
when you just want the app server without the IDE and application 
framework.  Architecturally, it's intended for multi-process, single thread 
setups using Apache as a front-end, with FastCGI.

This shouldn't be considered an announcement or a release, btw.  The code 
in CVS is production-hardened by years of service (many millions of hits 
served), but is utterly without documentation, nor has everything I've 
written been checked into CVS yet.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Stored Procedures with Sybase and the Sybase DA

2001-10-01 Thread Phillip J. Eby

At 01:50 PM 10/1/01 +0200, [EMAIL PROTECTED] wrote:

Does anybody know of any development going on regarding Sybase and stored
procedures? Christopher Petrilli declared them a future goal, but I urgently
need them by now. So if anybody has a workarround, please let me know.

Ty did some work on this for Zope 2.2 which you can find at:

http://cvs.eby-sarna.com/ZProducts/SybaseStoredProcedure/


There's no docs to speak of.  Feel free to use it if you can get it to 
work.  I think that to get this to work, we also had to patch the Sybase DA 
to handle status result codes, but that patch might have been incorporated 
into Zope.  I'm not positive about any of this.  :(  All I can tell you is 
that the code above is in actual use in a production application that 
needed stored-procedure support.

Note that it does not support returning SELECT results from procedures; 
only non-negative status returns.  It assumes a negative status is an 
error, and if it's one of the standard Sybase status error codes (e.g. -3 
for a deadlock), it throws a SybaseProcError with an explanation and the 
original query text.

The return value from calling a StoredProcedure object is always an integer 
0 or greater, unless the status return is negative, in which case an 
exception is raised.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Stored Procedures with Sybase and the Sybase DA

2001-10-01 Thread Phillip J. Eby

At 03:33 PM 10/1/01 +0200, [EMAIL PROTECTED] wrote:

I use the newest version of the Sybase DA, but it doesn't seem to work. 
Can you
help me finding the appropriate patches, etc? Are they available anywhere in
that CVS-tree?`

I don't think so.  Ty was going to submit them to ZC for inclusion; I don't 
know if he did or not.  It had to do with a Sybase discriminator code that 
the existing DA didn't handle.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Re: [ZPatterns] HowTo: Make an Image/File a DataSkin ???

2001-07-11 Thread Phillip J. Eby

At 08:03 AM 7/11/01 +0100, Steve Alexander wrote:
Steve Spicklemire wrote:

Hi Ulrich,
 Hmm.. can you just call DataSkin.__init__(self, id) in the 
 File's constructor?


You might need to do it like this:

   DataSkin.inheritedAttribute('__init__')(self, id)

Actually, I'm not sure you need to do anything special at all.  If you use 
the File DataSkin in a Folder w/Customizer Support, you shouldn't need to 
do anything special, because in that mode the 'id' attribute is never used 
by ZPatterns.  If you need to use these File DataSkins in a Rack, though, 
you'll need to include a SkinScript that says::

  WITH SELF COMPUTE id=getId()

Racks still use the id attribute directly, I'm afraid.  Your '__init__' 
method will still need to accept an 'id' parameter, also, and you'd need to 
set the __name__ attribute instead of id.  Ugh.

Anyway, I will take a look at Rack and see if it can be made to use the 
'getId()' and 'setId()' methods.  Of course, you can also subclass Rack and 
replace the '_getClientID(client)' method with one that uses 'getId()', but 
it might be that I could do this safely in the base Rack class.

The SkinScript examples should also probably be changed to use 'getId()' 
instead of 'id' so that people don't use them as a justification for 
continuing to indulge in deprecated behavior.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] UML and XMI support now available in TransWarp CVS

2001-06-29 Thread Phillip J. Eby

Recently, there has been much interest (on Zope-Dev and elsewhere) in
creating Zope and Python applications from UML diagrams.  Since to my
knowledge there are no other Python libraries currently available for
UML/XMI processing, I decided to get busy and release a version of
TransWarp with support for querying/manipulating UML models and reading XMI
files.  That version is now available at cvs.eby-sarna.com, for brave UML
hackers to experiment with.

I say release, but if you've ever heard the jokes about Klingon
programmers, you'll know that Klingon programmers do not *release* code.
Their code escapes, leaving the bloody corpses of testers, users, and
documentation writers in its wake.  This is pretty much the case for this
rough draft of UML/XMI support.  It is functional, but the interfaces are
subject to future upheaval as I continue refactoring.  This release is
ONLY for people who have a good understanding of UML, and aren't afraid to
UTSL (Use The Source, Luke).

Current Features:

* Load an XMI file into a UML Model object 

* Query UML model using full StructuralModel features and querying interface

* Create your own custom classes for UML elements - e.g. you could redefine
ModelElement to include a method to print out a nice report on the
element's features.  You could also implement executable UML with this
approach.

Current Limitations:

* **ALL** model attributes are strings, rather than their correct type, so
booleans for example are represented as the strings true and false.
Note that this doesn't mean you can't manipulate a UML model which
*defines* non-string attributes.  It's the attributes of the model *itself*
(like the 'isRoot' attribute of a 'GeneralizableElement') which are
currently all strings.  (This will be fixed when I finish refactoring to
the full Service-Element-Feature pattern, and every element class has a
corresponding Service object responsible for marshalling to/from strings.)

* Only the InMemory StructuralModel implementation can currently be used,
mainly because there aren't any other implementations of the StructuralModel.


Example of use (note, this is *all* subject to interface upheaval in future):


# begin example code

from TW.UML import UMLRecipe
from TW.StructuralModel.Queries import Type, ANY

# if you have your own specs for classes, add them to UMLRecipe first
UMLModel = UMLRecipe(name='UMLModel')  

myModel = UMLModel()
myModel.importFromXMI('someXMIfile.xml')

# print the names of all classes
print myModel.Where(Type('Foundation.Core.Class')).Get('name')

# Shortcut to get a type name if you only know the short form...  But
# it's better to just do this manually once to find out the name for
# future use; I'm not guaranteeing that _XMINames will always exist in
# its present form!
Package = UMLModel.Package._XMINames[0]

isPackage = Type(Package)

# print the names of all packages which contain other packages
print myModel.Where( isPackage  ANY('ownedElements',isPackage) ).Get('name')

# end example code


I'm willing to answer questions about the TW parts of this (how-to's,
problems, etc.), but can't provide handholding for anything else.  For
example, me explaining XMI or the UML metamodel in general is out of scope.
 So if for example, the code barfs in the 'xml' package because it can't
parse your XMI file, it's probably a problem with the program that
generated the XMI.  If it barfs in the 'TW' package, it's probably
something to do with my code, unless you just have a very nastily malformed
XMI file (in which case I'll want to see the smallest version you can send
me that still produces the error).

Feedback from UML/XMI hackers is welcomed and encouraged.  Please direct
all responses to the TransWarp list, [EMAIL PROTECTED]  To subscribe
to the TransWarp list, visit:


http://www.eby-sarna.com/mailman/listinfo/TransWarp

Thanks.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] Re: [ZPatterns] Best Free UML, XMI, Zope/Transwarp tools

2001-06-28 Thread Phillip J. Eby

At 10:35 AM 6/28/01 -0700, jimbo wrote:
I've been  looking for a standard *FREE* tool that I can use to design
Zope apps.  I think my search is over.  It seems to be a good tool for
students because it's free and comes with support for Java, Persistence and
XMI, Full and partial exchange.

  I wonder if Transwarp is at the point of being able to use UML/XMI stuff.

Well, the current CVS has a full UML metamodel in it, and the test suite
actually performs some operations such as creating a UML model, adding
items to a package, and so on.  But I still haven't rewritten the XMI
support.  I expect it to be another month or so before that shows up in CVS.

(By the way, the best place for discussion regarding TransWarp is the
mailing list [EMAIL PROTECTED], and the zope-dev list generally
frowns on crosspostings for discussion.  If you reply to this message, be
sure to only reply to [EMAIL PROTECTED]  Thanks!)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] ZPatterns DATA LOSS BUG and FIX (0.4.3p1 patch release)

2001-06-26 Thread Phillip J. Eby

ZPatterns 0.4.3final contains a serious bug which deletes all ZODB-stored
contents of a Rack when you use the manage_pack method.  This bug only
affects you if you store Rack-mounted objects or attributes in the ZODB,
and does not affect you if your objects are entirely contained in an RDBMS
or other mechanism external to the rack.  If you've upgraded to 0.4.3,
please do not use manage_pack!

I have uploaded new versions of ZPatterns and PlugIns to fix the problem
with packing racks, and to provide experimental support for Zope 2.4b1.
(Specifically the problems reported below with expr_globals and ts_regex
have been fixed.)  Please upgrade to 0.4.3p1 before using manage_pack, or
if you wish to experiment with ZPatterns on Zope 2.4b1.  Thanks.

Thanks too, to Juan Palomar and Itai Tavor for providing information and
patches.


At 11:01 AM 6/26/01 +0200, Juan David Ibáñez Palomar wrote:


With Zope 2.4b1 and ZPatterns 0.4.3, the following error raises when
starting Zope:

2001-06-26T08:24:40 ERROR(200) Zope Could not import Products.ZPatterns
Traceback (innermost last):
  File
/home/jdavid/Zope-2.4.0b1/lib/python/Products/ZPatterns/Expressions.py,
line 38, in ?
(Object: ComputedAttribute)
ImportError: cannot import name expr_globals

expr_globals is not available in Zope 2.4, the fix is:

...

Besides this error, there're some warnings:

/home/jdavid/Zope-2.4.0b1/lib/python/ts_regex.py:87: DeprecationWarning:
the regex module is deprecated; please use the re module
  import regex, regsub #, Sync
/home/jdavid/Zope-2.4.0b1/lib/python2.1/regsub.py:15: DeprecationWarning:
the regsub module is deprecated; please use re.sub()
  DeprecationWarning)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Bulletproof ZCatalog proposal

2001-06-08 Thread Phillip J. Eby

At 04:58 PM 6/8/01 -0400, Shane Hathaway wrote:
On Thursday 07 June 2001 21:28, Phillip J. Eby wrote:
  Upon being told to perform a transaction or subtransaction commit,
  the transaction would notify all the ruleAgents, and then all the
  indexingAgents.  Objects could still subscribe to either queue while
  this notifying is taking place.  (So that triggered actions could
  cause indexish objects to register as indexingAgents, not to mention
  causing updated objects to fire additional triggers.)
 
  Once all agents in a queue are notified, that queue should be cleared
  so that notifications are on a per-subtransaction basis.  Once both
  queues are cleared, normal transaction behavior goes forward.

Would you say this would occur before tpc_begin() messages or just
after?

Before.  I'm saying this would take place immediately at the start of the 
existing Transaction.commit() method.


  Hm.  That's simpler than I thought it was going to be.  Shoot, I can
  even see how to implement it as a runtime patch, that would've been
  simpler than all the shenanigans ZPatterns goes through to fake out
  the transaction machinery...  and it's a better
  implementation.  Ah well.  At the time I wanted to avoid trying to
  convince Jim to add machinery to transactions just for ZPatterns,
  given that ZPatterns wasn't a particularly established product at the
  time.
 
  Let me know if you guys put something like this in, though, and I'll
  definitely look at reworking ZPatterns to use the mechanism.  It
  could potentially cut a lot of code out and improve the robustness at
  the same time.

I don't foresee us adding this capability right away since we need to
understand it better and it only applies to one working product and a
hypothetical product.  I'd suggest you go ahead with the runtime patch.

I think I'll wait until ZPatterns works with Zope 2.4, unless it becomes 
necessary otherwise.  Replacing what I've got now is a pretty significant 
undertaking, and risk-prone to boot, so I don't want to delay the finishing 
of ZPatterns' support for Zope 2.3.x.

Basically, the runtime patch would be to replace 
ZODB.Transaction.Transaction with a subclass that implemented the 
notification queues in the commit() method.  There'd be a few other little 
extensions needed, like clearing the queues on any abort operation, and 
adding registerIndex() and registerRule() or some such methods.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Bulletproof ZCatalog proposal

2001-06-07 Thread Phillip J. Eby

At 02:07 PM 6/7/01 -0400, Shane Hathaway wrote:
On Thursday 07 June 2001 12:17, Phillip J. Eby wrote:

 The
 only catch was that this would still produce conflicts at the head
 end of the linked list.  :(  Of course, that was in the days before
 ZODB conflict resolution.  Nowadays, you could probably implement it
 as a simple sequence object with the conflict resolution method
 implemented.  But then there'd be the question of how to resolve
 conflicts if more than one thread or ZEO client decided to apply the
 queued changes...  a 100 conflicts vs 1 situation.  Ugh.

I was thinking the queue would only last the duration of a transaction 
and that the queue would be thread-specific.

That's not hard to do - you could just toss an object into the transaction
queue to do it during transaction commit, similar to what ZPatterns does in
a more general way.  (Note that ZPatterns users can already get the
benefits of deferring catalog changes until the end of a (sub)transaction,
by using triggers to implement automatic cataloging).


 Anyway, I'd be really interested in seeing a solution for all the
 issues in conflict resolution.

I was thinking that certain types of objects would be committed by the 
transaction manager before all others.  In this case, the catalog (or a 
special object in the catalog) would be committed first.  It would 
resolve all conflicts in the contained indices before they occur by 
replaying the changes in the persisted queues from the transaction 
history, then setting the _p_serial attributes to convince the storage 
that the conflicts have already been resolved.


Hm.  Sounds to me like what you actually want is for the transaction
manager to do this *after* everything else, rather than before.  Thus, you
would catch any changes which occur *during* transaction commit - such as
commit-phase cataloging (as some folks do with ZPatterns currently).

That is, in ZPatterns one can specify triggers such as:

WHEN OBJECT DELETED, CHANGED CALL
someCatalog.manage_uncatalog(self.absolute_url(1))
WHEN OBJECT ADDED, CHANGED CALL
someCatalog.manage_catalog(self,self.absolute_url(1))

Which will be executed during transaction commit if the conditions apply.
If you have the catalog process its queue *before* other objects commit, it
will not have received these calls yet.  This will end up making the
catalog try to commit itself a second time, which will fail with a conflict
error - 100% of the time.  (And retry won't help, because the transaction
is conflicting with itself.)

Of course, this issue could be fixed by minor adjustment to the ZODB API
and implementation such that it is permissible to store() an object more
than once during a transaction's commit phase without creating a
ConflictError.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Property Storage

2001-06-07 Thread Phillip J. Eby

At 09:29 PM 6/7/01 +0100, Chris Withers wrote:

If I change one property on, say, a DTML Document, does that store a whole
new copy of the document in the ZODB?

It updates the object in the ZODB.  Whether that causes a copy to be made,
depends on the underlying storage.  FileStorage makes copies,
BerkeleyStorage (at least Ty's first implementation thereof) does not.


Is so, then how about storing properties in their own mini-class that just
subclassed Persistent, so each property got its own pickle jar?

There are a lot of things you'd have to tinker with to get that behavior.
You would probably be better off just using a storage that doesn't make
copies, or using ZPatterns to store selected attributes in such a storage
(such as a differently-backed ZODB, the filesystem, or an SQL or LDAP
database).


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Bulletproof ZCatalog proposal

2001-06-07 Thread Phillip J. Eby

At 07:07 PM 6/7/01 -0400, Shane Hathaway wrote:
Phillip J. Eby wrote:
 That is, in ZPatterns one can specify triggers such as:
 
 WHEN OBJECT DELETED, CHANGED CALL
 someCatalog.manage_uncatalog(self.absolute_url(1))
 WHEN OBJECT ADDED, CHANGED CALL
 someCatalog.manage_catalog(self,self.absolute_url(1))

After I read this again I realized what you were saying.  This
capability of ZPatterns is very brittle, don't you think?

Yep.  That's why I've previously described ZPatterns as a hack.  :)


If the
catalog is updated manually before the special ZPatterns object is added
to the queue, the behavior is undefined AFAIK--either the later changes
to the catalog will be ignored, will cause a conflict, or some objects
will be written twice in the same transaction.

True.  But this behavior is avoidable through the use of subtransaction
commits, in the event that someone has to have transactions which update a
ZCatalog directly.  Usually, when someone is using catalogs with ZPatterns,
they use triggers to do all the updates and don't touch the catalog manually.

Note that I'm not saying this still isn't a hack.  But it's the best I
could do without either fixing the multi-commit issue in ZODB, or with some
kind of priority scheme.


However, if we could specify transaction commit priorities, and the
ZPatterns update came first, auto-indexing came second, and everything
else followed, I think it would work.  Or perhaps ZPatterns should be
able to register things that occur *before* the two-phase commit
protocol.

Yep.  One of the last two times I spoke with Jim in person (either the
January DC visit or IPC 8, I forget which), he said something about it
maybe being a good idea to have some kind of priority system like that.
I'd love to see something like it exist, if it would make some of
ZPatterns' hackery unnecessary.

The implementation could consist of two subscription queues: ruleAgents and
indexingAgents.  ZCatalog would register in indexingAgents, and ZPatterns
objects would register in one or the other, usually ruleAgents.  (I can
think of some circumstances where it would be nice to use the
indexingAgents queue, but right now ZPatterns apps have to work around this
by defining their rules in execution priority order.)

Upon being told to perform a transaction or subtransaction commit, the
transaction would notify all the ruleAgents, and then all the
indexingAgents.  Objects could still subscribe to either queue while this
notifying is taking place.  (So that triggered actions could cause indexish
objects to register as indexingAgents, not to mention causing updated
objects to fire additional triggers.)

Once all agents in a queue are notified, that queue should be cleared so
that notifications are on a per-subtransaction basis.  Once both queues are
cleared, normal transaction behavior goes forward.

Hm.  That's simpler than I thought it was going to be.  Shoot, I can even
see how to implement it as a runtime patch, that would've been simpler than
all the shenanigans ZPatterns goes through to fake out the transaction
machinery...  and it's a better
implementation.  Ah well.  At the time I wanted to avoid trying to convince
Jim to add machinery to transactions just for ZPatterns, given that
ZPatterns wasn't a particularly established product at the time.

Let me know if you guys put something like this in, though, and I'll
definitely look at reworking ZPatterns to use the mechanism.  It could
potentially cut a lot of code out and improve the robustness at the same time.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] getPersistentItemIDs not cooperating?

2001-05-23 Thread Phillip J. Eby

At 05:48 PM 5/23/01 +0200, Christian Scholz wrote:
Hi!

  It works.. partially. For some reason it looks like getPersistentItemIDs
  does not always return a *complete* list. I need to run this method
  several times to completely exhaust the Rack's storage. Thoughts? The
  only way I ever create Track objects is via a different method that is
  only accessed once (a long time ago!)

Well, I experiences something similar when changing a Racks storage
from persistent to non-persistent. The included objects are marked
as orphaned then and should be deleted with the Clear-Button. This
also works, but only the half of them gets deleted every time I click
on that button.. So I also have to press it several times.. Sounds like
the same problem..

I just thought of how this happens...  if you delete an object from the 
Rack, it's being removed from the virtual list of keys your loop is 
traversing.  So as you iterate from 0..n, and you delete  items from the 
rack, they are removed from the keys list too, the list shortens, and every 
other item in the list is skipped!  This is why you get half the list every 
time.

The fix would probably be:

foo = getPersisentItemIDs()

while foo:
 foo[0].manage_delete()

I should probably do this in ZPatterns too.  I'm working on upgrading it 
for 2.3.2 right now anyway.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] getPersistentItemIDs not cooperating?

2001-05-23 Thread Phillip J. Eby

At 12:33 PM 5/23/01 -0500, Steve Spicklemire wrote:
Hi Phil,

FYI.. this doesn't work in a PythonScript since indexing into a BTreeItems 
is (apparently) not allowed by the Security Machinery. So... a simple 
list is looking better and better! ;-)

Hmmm.  Good point.  I'll have to think about that one.  I just hate to load 
all those keys if they're not really needed.  I suppose if you call 
getPersistentItemIDs(), you usually want them all...  It's just that if you 
use the BTreeItems object, it can toss out keys that aren't needed.

Maybe what I'll do is implement a wrapper over BTreeItems that fixes this 
somehow.  I'll also have to look at how this works with the new BTrees 
trees, because I *know* they don't implement indexing the same way, and may 
not have this problem!


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Experiments with ORMapping

2001-05-14 Thread Phillip J. Eby

At 12:26 PM 5/14/01 -0400, Shane Hathaway wrote:
Chris Withers wrote:
 
  Shane Hathaway wrote:
  
   One would define an ObjectMappingSchema whose job it is to store and
   retrieve objects of a specific type and in a specific location.  It
   would usually grab a database connection object to do its work.  When
   loading, it would perform a query then manually put attributes into a
   persistent object.  When storing, it would grab specific attributes from
   the persistent object and execute a statement to store those attributes.
 
  How does this differ from ZPatterns? Phil?

ZPatterns implements storage logic on the application level.
Applications have to be aware of (in fact they have to be centered
around) ZPatterns.  This alternate approach keeps storage logic
independent of application logic.  It lets you take any code written for
the ZODB and move it to your RDBMS schema without changing the code
(most of the time :-) ).

I am reminded of a passage from Dirk Gently's Holistic Detective Agency, 
wherein Dirk decides to cut to the heart of the problem, and simply writes 
down the answer.  Now, he declares, he is faced with only a relatively much 
easier problem: What strange language did he write the answer down in?

While I'm not saying that what you're doing isn't possible, I *will* say 
that I believe you are replacing a small amount of API-specificity in the 
code with a similar amount of specificity, coupled with a much larger 
complexity in the mapping layers.  It is, IMHO, much harder to write 
generic mappings at the schema layer where you propose, than to do so at 
the domain logic layer where ZPatterns operates.  Ty and I spent many weeks 
chewing over designs in the space you're talking about, back before 
ZPatterns existed, after consulting at length with Jim Fulton and Michel 
Pelletier.  Our conclusion was that yes, it was *possible* to do the 
mapping you're talking about, but that it was very high impedance for the 
kinds of applications we had in mind.

I'll give a simple example to show what I'm talking about.  Consider a task 
framework where TaskPerformers are assigned Tasks, in a simple one-to-many 
relationship.  TaskPerformers, in this framework, perform up to hundreds of 
tasks per day, thousands per month.  Assuming an RDBMS backend, how do you 
propose to map this in your storage model?

My thought on this, is that you will be forced to explicitly consider the 
nature of this relationship and its storage at the application level.  If 
you write explicitly for ZODB, you might use a BTree, for example.  Or 
perhaps you'd have some kind of global container for the Tasks, with a 
Catalog to index them, and a method on TaskPerformer to query the Catalog.

How would you propose to map this to an RDMS?  Well, substituting catalog 
queries might be relatively straightforward, but perhaps rather time 
consuming to develop in a generic way.  The BTree might give you a bit more 
trouble.  Probably you'd have to end up using some sort of generic 
queryable containers that translated to BTrees or Catalogs or RDBMS tables, 
depending...

And lo!  You now have an application framework.  Oops.

We haven't even addressed performance issues yet, which are the real 
killer.  The only way (again IMHO) to get reasonably high performance that 
is portable across different databases is to be able to write code that 
is optimized based on the back-end.  The only way you can push this code 
under the hood is to create an all-purpose query mechanism.  Otherwise, 
you must expose enough of the inner workings to the application developer 
that they can include platform-specific code for each circumstance.

All this is of course just my opinion, and quite possibly wrong.  But I 
think that an application developer would get more mileage out of your 
DBAPI product (coupled with some utility classes to replace Racks) or from 
ZPatterns than they would from this approach to O-R mapping.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Experiments with ORMapping

2001-05-12 Thread Phillip J. Eby

At 05:42 PM 5/11/01 -0400, Shane Hathaway wrote:
Phillip J. Eby wrote:
 I'm not quite clear on how exactly you suggest mapping from RDMBS -
 ZODB.  There's a *significant* (IMHO) impedance mismatch between ZODB's
 arbitrarily identified variably structured single records and SQL's
 content-identified fixed-structure record sets.  This is what application
 frameworks/toolkits (such as your own DBAPI product) are needed for.

If you implement this at the Storage level, yes, there is a major
mismatch.  But at the Connection level it makes a lot of sense. 
Connection basically exposes a pile of pickles as objects; an OR mapping
exposes a complex schema as objects.

I think that understanding will change the rest of your response. :-)


Nope.  As far as I can see, all that does is leverage ZODB Connections as a
crude sort of Rack that only provides a mapping-like interface for
retrieving objects, without helping any of the higher-order needs of an
application.  I guess if you define O-R mapping as can you store and
retrieve an object's properties from a database, then I guess you've
succeeded at that point.  But if that was all my O-R apps needed, there
would've been no reason to use the RDBMS; I could've just used ZODB and a
BTree with less bother.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Experiments with ORMapping

2001-05-11 Thread Phillip J. Eby

At 11:01 AM 5/11/01 -0400, Shane Hathaway wrote:
Joachim Werner wrote:
 
  The current design plans of SmartObjects are mainly based on the assumption
  that we will not be able to change Zope itself. This is not a dogma for us,
  however. I guess doing OR-mapping in the Zope core would be fine with 
 us ;-)

FYI by replacing I don't mean changing anything in the Zope core.  I
mean using a different class in place of Connection, which you can do
just by creating a custom_zodb.py.

Hm.  So you're suggesting creation of a Storage class that returns a 
special root object which emulates the standard ZODB root 
PersistentMapping, and contains another object that emulates a folder, with 
a bunch of other foldoids that are actually tables, or something of that 
sort?  And maybe exposes some query methods ala ZCatalog?

I'm not quite clear on how exactly you suggest mapping from RDMBS - 
ZODB.  There's a *significant* (IMHO) impedance mismatch between ZODB's 
arbitrarily identified variably structured single records and SQL's 
content-identified fixed-structure record sets.  This is what application 
frameworks/toolkits (such as your own DBAPI product) are needed for.


  But the more important one for us is that we still believe that even with
  ZCatalog Zope can not really do efficient croos-tree queries in all 
 cases.
  A query like Give me all users who have bought this and that product and
  are aged 20 or above can not be handled by the catalog, I think.

Yes it can. :-)  That's not to say that it has as much flexibility as a
SQL query, but it can do most of the things people usually do with one
table at a time.

Here's the goal I envision for OR mapping: to be able to move between
OODBMS and RDBMS seamlessly.  It makes sense to develop on top of ZODB
then move to an RDBMS for testing and deployment.

Unfortunately, I think that this requirement can *only* be met through a 
common API or access pattern/framework/what-have-you, be it DBAPI, 
ZPatterns, SmartObjects, or TransWarp.  The ZODB is both too powerful (in 
its flexibility) and too weak (in lack of any ZODB-level notions of 
record sets, schemas, and indexing) to be useful as a 
cross-database-platform API.  That's not to denigrate any of the value of 
ZODB itself - an explicit goal of both ZP and TW is to leverage ZODB's 
flexibility in combination with other kinds of databases.  (And, recently, 
I have been speculatively eyeing the ZODB for some mortgage-industry 
related projects which involve complex variable data structures, 
distribution requirements ala ZEO, and local data stores on 
intermittently-connected laptops.)



  SmartObjects is more of a programming framework than just adding OR-Mapping
  to Zope. So if we can solve the storage and query parts more efficiently by
  just having Zope itself extended a bit, this would be very cool ...

You see, I think it is not necessary to create a programming framework
if the goal is OR mapping.  The framework is already defined, and it's
Python / ZODB.  But SmartObjects seems to have many loosely related
goals, making it difficult to assist.


I think the goal for SO, and all the other frameworks that have been 
created or are being created, is to *make application development 
easier*.  OR mapping is just a means to that end.  LDAP connectivity, or 
other types of non-ZODB data access are important to many of us, as 
well.  This boils down to abstraction of how data attributes are 
represented.  For example, if I am an ISP, and I want to implement an 
active flag on an account object, I would like changing it to 
automatically go out and add or remove routing entries and password entries 
on my servers when I update the record through my Zope interface (web, 
SOAP, or whatever).  Could you make a ZODB Storage object that supported 
this?  Maybe.  But from an architectural standpoint it would be rather 
messy - akin to writing OO code with giant switch statements.

The Java (and CORBA, actually) solution to this, is to use a property 
pattern, where a property is a non-real thing that actually only has 
setters and getters.  An object's users always go through these accessor 
methods, so the implementation can be anything you like.  (Notice, btw, how 
the solution is once again a framework pattern...)

ZPatterns was an effort to produce a Pythonic emulation of this concept 
that didn't need actual methods.  It unfortunately inherits some of the 
flaws of __getattr__ hooks, such as forced semi-centralization of 
implementations. TransWarp does away with that and instead introduces 
property (feature) objects which themselves have methods, but are not 
data.  This provides a bit more extensibility than the Java approach, since 
it is conceivable one could add an observable interface to a property 
object and thus subscribe to it, for example.

Anyway, all I'm really trying to say is, if you want implementation 
independence, you have to have implementation hiding.  ZODB makes it easy 
to store 

Re: [Zope-dev] ZPatterns Rack question..

2001-04-28 Thread Phillip J. Eby

At 06:00 PM 4/28/01 +0200, Christian Scholz wrote:
Hi!

First of all one note to the sql attribute provider: My problem seems to
be solved
now. Actually it was quite easy.. dunno why it took the long way.. thanks
anyway
to Phillip and Steve!

But I have another problem now: I have some rack with persistent objects
in it.
Now I want to migrate my site to production. Problem: If I do this more often
and the objects are within some Rack, then also these get copied to the
production
site and the old objects will get deleted there.

Is there any way to first backup the contents of some rack? Or do I need to
construct it all as external storage? (basically most things are in an sql
db already, I just put image data etc. into the rack directly as I don't need
relational access to it..)

Actually I know how to read the objects from the BTree but I dunno how to
store them again into another rack (which has the same storage attribs of
course). Can I simply use _setRack()? I guess not, eh? :)


My suggestion would be to copy the Rack using normal Zope copy/paste
(assuming that works), and then from Python poke the old rack's BTree
into the new Rack.  Then delete the old rack.  This really sucks as a
mechanism, however.

The way I originally intended to solve this issue was to allow the Rack's
persistent data to be stored outside itself somewhere.  That's why some
versions of ZPatterns have a little dropdown on the Storage tab which only
has one selection - stored inside the rack.  The idea was that maybe
someone would create storage providers which could be kept external to
the Rack and then acquired.  This could still be done, if somebody wanted
to take up the coding.  Then you could upgrade/replace a rack without
damaging data stored in it.  Ty and I never got around to doing it because
so far, all our ZPatterns apps have not had any ZODB-based data, only SQL
and LDAP.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] Re: hack for refused authorization with virtual dataskin

2001-04-23 Thread Phillip J. Eby

At 01:37 PM 4/23/01 +0200, Godefroid Chapelle wrote:
Hello,


After rereading the ZopeSecurityPolicy source code, I tried the
following hack.

I add in the skinscript :

WITH 1 COMPUTE __allow_access_to_unprotected_subobjects__=RESULT

which does work : it fools the security mechanism.

I can live with it but feel that there is only a slight problem which
could allow me to avoid the hack.

I hope this can hint some of you to help me to understand what is badly
settled in my installation.

It sounds to me like you need to be using the getId() method instead of the 
.id attribute.  I think that the id attribute is being phased out in favor 
of getId().

I'm somewhat reluctant to enable access to unprotected subobjects in the 
DataSkin base class; it seems a little too broad of an access level.  The 
other alternative would be to allow SkinScript expressions free rein as 
regards security - but that's too broad also.  The optimum would be to 
allow SkinScript expressions full access to the targeted DataSkin's direct 
attributes, but normal (validated) access to everything else, but I'm not 
sure how to do this safely.

This is an example of why I consider ZPatterns a hack - too many places 
where it depends on Zope innards like this.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Phillip J. Eby

At 03:07 PM 4/22/01 +0100, Steve Alexander wrote:

   As a simpler workaround, you can use 
your_object.commitSubtransaction() instead of redirecting to a new page. 

Um, this shouldn't be the issue here.  _SetAttributeFor() should be called
when the attribute is set; it's not transaction-driven.  Something weird is
happening with Christian's situation that I haven't investigated yet.


   You really should be able to create a new object and set its 
attributes in the same transaction. The status of the object (_v_status 
in DataSkin.py) will be ChangedStatus, if you're adding and changing in 
the same transaction. That's a good place to look for where the problem is.

Actually, the status should be AddedStatus, and it should stay that way
throughout the transaction, unless the object gets deleted in the same
transaction.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Phillip J. Eby

At 08:29 PM 4/22/01 +0200, Christian Scholz wrote:
Hi!

A little update..

Actually I was mistaken and SetAttributeFor() is called. Just
_objectChanged()
is not called in that case.. and thus my attributes are not stored to the
database.

When an object is newly added, only _objectAdded() is called.
_objectAdded(), _objectChanged(), and _objectDeleted() are mutually
exclusive within a given transaction.  That is, only one of them occurs in
a given transaction.  See more below.


Maybe some more code will help (just the important pieces):

def _objectAdded(self,client):
""" store cached data in database """

   ... here we do an sql query to insert things in database ...

def _objectChanged(self,client):
""" store cached data in database """

   ... here we do an sql query to update things in database ...

def _objectAdding(self,client,
_tmap={ None:AddedStatus,
DeletedStatus:ChangedStatus,
ChangedStatus:AddedStatus
}
):
t = client._getTokenFor(self)
s = t.status
t.status = _tmap.get(s,s)

# we need to do a commit here in order to store the record into
the database!
   # and we need to have it stored as an AttributeFor() of the primary key will
   # return None otherwise (as this also just makes a query).
client.commitSubtransaction()

This is broken.  Don't do this!  commitSubtransaction() is an
application-level operation.  Only.  If you have to use it inside of
provider-level code or code called from SkinScript, chances are that you
are doing something horribly wrong.  You run the risk of causing a
recursive commit operation in the Zope transaction machinery.  Don't do this!



def _SetAttributeFor(self,client,name,value):
"""Set the attribute and return true if successful"""
   # attribs stores the attributes we care about
if name in self._attribs.keys():
client._getCache()[name]=value
client.__dict__[name]=value; 
   client._p_changed = 1
return 1
return None

This also looks broken to me.  Why are you changing both the cache and the
persistent state?  There's no reason to do both.



So _objectChanging() is not overridden, the rest I have ommitted..

So as you also can see I already do a subtransaction commit but it does
not seem to help for this problem.. 


I think you're seriously over-engineering this.  I don't see anything that
you're doing here that couldn't be done more easily with SkinScript
statements.  If all you want to do is store the data in an SQL database, a
few SkinScript triggers would suffice.

Now, if you're trying to get a row to be inserted in an SQL database at the
actual time of the newItem() call, there is a trick you can use to do that
from SkinScript also.  Do this:

INITIALIZE OBJECT WITH someAttr1=default1,
someAttr2=default2,...,dummyAttributeName=myInsertQuery(primaryKey=self.id)

Where myInsertQuery() is an SQL insert query that takes primaryKey as a
parameter, and dummyAttributeName is some attribute name you don't care
about.  You should also set any default values for fields that will be
inserted.  Your insert query will be called, initializing the row in the
database, and then use something like this:

WHEN OBJECT ADDED,CHANGED STORE foo,bar,baz USING
UpdateMethod(widget_id=self.id, foo_field=self.foo, wbar=self.bar)


To update the data at transaction commit time.  Voila.  No need to make any
custom attribute providers just to do this.

Just to clarify the event sequence that should take place:

1. newItem() is called, which fires an _objectCreating() event

1.1. The SkinScript INITIALIZE OBJECT statement is triggered by the
_objectCreating() event, and calls myInsertQuery() to insert a row in the
database, with default values for everything but the primary key.

1.2. newItem() fires an _objectAdding() event, which does nothing except
flag the object as "AddedStatus" and pass the event back to the DataManager
(Rack).

1.3. The Rack passes the _objectAdding() event to all appropriately
registered providers.  The WHEN OBJECT ADDED,CHANGED statement is such a
provider, so it receives the message and notes that the DataSkin was added,
but does not act on it yet.  Instead, it registers a proxy for itself with
the Zope transaction object so that it will be notified of transaction commit.

2. newItem() returns a new DataSkin to your application, bearing the
contents set up by the INITIALIZE OBJECT WITH statement.

3. Your application calls manage_changeProperties, to change an attribute.

3.1. The DataSkin fires an _objectChanging() event, which flags the object
as "ChangedStatus", and the event is propagated to all registered providers
in the Rack.  (Such as the WHEN OBJECT statement)

3.2. The WHEN OBJECT statement ignores the _objectChanging() event, because
from its point of view the object is in AddedStatus.

3.3. The DataSkin calls 

Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Phillip J. Eby

At 08:29 PM 4/22/01 +0200, Christian Scholz wrote:
Hi!

A little update..

Actually I was mistaken and SetAttributeFor() is called. Just
_objectChanged()
is not called in that case.. and thus my attributes are not stored to the
database.

When an object is newly added, only _objectAdded() is called.
_objectAdded(), _objectChanged(), and _objectDeleted() are mutually
exclusive within a given transaction.  That is, only one of them occurs in
a given transaction.  See more below.


Maybe some more code will help (just the important pieces):

def _objectAdded(self,client):
""" store cached data in database """

   ... here we do an sql query to insert things in database ...

def _objectChanged(self,client):
""" store cached data in database """

   ... here we do an sql query to update things in database ...

def _objectAdding(self,client,
_tmap={ None:AddedStatus,
DeletedStatus:ChangedStatus,
ChangedStatus:AddedStatus
}
):
t = client._getTokenFor(self)
s = t.status
t.status = _tmap.get(s,s)

# we need to do a commit here in order to store the record into
the database!
   # and we need to have it stored as an AttributeFor() of the primary key will
   # return None otherwise (as this also just makes a query).
client.commitSubtransaction()

This is broken.  Don't do this!  commitSubtransaction() is an
application-level operation.  Only.  If you have to use it inside of
provider-level code or code called from SkinScript, chances are that you
are doing something horribly wrong.  You run the risk of causing a
recursive commit operation in the Zope transaction machinery.  Don't do this!



def _SetAttributeFor(self,client,name,value):
"""Set the attribute and return true if successful"""
   # attribs stores the attributes we care about
if name in self._attribs.keys():
client._getCache()[name]=value
client.__dict__[name]=value; 
   client._p_changed = 1
return 1
return None

This also looks broken to me.  Why are you changing both the cache and the
persistent state?  There's no reason to do both.



So _objectChanging() is not overridden, the rest I have ommitted..

So as you also can see I already do a subtransaction commit but it does
not seem to help for this problem.. 


I think you're seriously over-engineering this.  I don't see anything that
you're doing here that couldn't be done more easily with SkinScript
statements.  If all you want to do is store the data in an SQL database, a
few SkinScript triggers would suffice.

Now, if you're trying to get a row to be inserted in an SQL database at the
actual time of the newItem() call, there is a trick you can use to do that
from SkinScript also.  Do this:

INITIALIZE OBJECT WITH someAttr1=default1,
someAttr2=default2,...,dummyAttributeName=myInsertQuery(primaryKey=self.id)

Where myInsertQuery() is an SQL insert query that takes primaryKey as a
parameter, and dummyAttributeName is some attribute name you don't care
about.  You should also set any default values for fields that will be
inserted.  Your insert query will be called, initializing the row in the
database, and then use something like this:

WHEN OBJECT ADDED,CHANGED STORE foo,bar,baz USING
UpdateMethod(widget_id=self.id, foo_field=self.foo, wbar=self.bar)


To update the data at transaction commit time.  Voila.  No need to make any
custom attribute providers just to do this.

Just to clarify the event sequence that should take place:

1. newItem() is called, which fires an _objectCreating() event

1.1. The SkinScript INITIALIZE OBJECT statement is triggered by the
_objectCreating() event, and calls myInsertQuery() to insert a row in the
database, with default values for everything but the primary key.

1.2. newItem() fires an _objectAdding() event, which does nothing except
flag the object as "AddedStatus" and pass the event back to the DataManager
(Rack).

1.3. The Rack passes the _objectAdding() event to all appropriately
registered providers.  The WHEN OBJECT ADDED,CHANGED statement is such a
provider, so it receives the message and notes that the DataSkin was added,
but does not act on it yet.  Instead, it registers a proxy for itself with
the Zope transaction object so that it will be notified of transaction commit.

2. newItem() returns a new DataSkin to your application, bearing the
contents set up by the INITIALIZE OBJECT WITH statement.

3. Your application calls manage_changeProperties, to change an attribute.

3.1. The DataSkin fires an _objectChanging() event, which flags the object
as "ChangedStatus", and the event is propagated to all registered providers
in the Rack.  (Such as the WHEN OBJECT statement)

3.2. The WHEN OBJECT statement ignores the _objectChanging() event, because
from its point of view the object is in AddedStatus.

3.3. The DataSkin calls 

Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-21 Thread Phillip J. Eby

At 08:18 PM 4/21/01 +0200, Christian Scholz wrote:
Hi!

  Good evening everybody!
  
  I have some question regarding attribute and agent programming for
ZPatterns.
  
  I have some provider which is registered for the "handlers" and
"attributes"
  methods and some attributes.
  
  My problem is when trying to create a new object and directly editing
it, e.g.
  
  obj=newItem()
  obj.propertysheets.data.manage_changeProperties(foobar=13)
  
  the propertysheet is defined and my provider is also registered for
  handling the property "foobar". Unfortunately my SetAttributeFor() method
  is never called.
 
 
 Have you defined a namesForRegistration method in your provider?

Yes, as said above it registers for handlers and attributes. Also
_objectChanged and _SetAttributeFor() etc. are called. They're just not
called 
directly after creating the object (when being in the same request that is).

_objectChanged() is a transaction-commit message.  You'll only get it when
the (sub)transaction commits.  You'll receive _objectChanging() just
*before* the object changes.

As for _SetAttributeFor(), it should be called at the time
manage_changeProperties executes, not at object creation.  Are you sure
that you have it properly named and that it isn't still being defined by
one of your ancestor classes instead?  The "AttributeProvider" and
"GTMixin" base classes in ZPatterns implement _SetAttributeFor() by simply
noting the change for later.  If you don't override this behavior, your
class won't see _SetAttributFor() itself.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] SkinScript Questions

2001-04-02 Thread Phillip J. Eby

At 10:59 PM 4/1/01 -0700, Michael R. Bernstein wrote:

1) Are there any naming conventions for SkinScripts?

Not that I'm aware of.  I think Ty names all of his methods "SkinScript",
but then, he tends to name all his working/temporary files "x", so what
does he know?  ;)


2) Is there any reason (other than factoring) to split
SkinScripts up, or is putting all your declarations in one
SkinScript ok?

The compiler creates a seperate attribute provider or agent for each
declaration anyway, so there's no reason not to put them all in one if you
don't need to interleave non-SkinScript providers/agents into the priority
order.



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns Image Archive Project

2001-04-02 Thread Phillip J. Eby

At 01:45 PM 4/1/01 -0700, Michael R. Bernstein wrote:

It seems as though the manage_upload method is supposed to
hand off the image data to RenderingKinds, which in turn
either replaces the image data in existing Renderings, or
creates new ones, by iterating through the rows in the
TinyTable.

[shudder].  No, not at *all*.  The calling pattern goes like this:

anArchiveImage.upload:
for kind in RenderingKinds.getKindsFor(self):
Renderings.setRenderingFor(self,kind,data)

The ArchiveImage is responsible for knowing the image data.  The
RenderingKinds specialist is responsible for knowing what renderings should
be made for an ArchiveImage.  The Renderings specialist is responsible for
creating and storing a rendering, given an image and a kind of rendering to
be made.  However, it may ask the kind object for dimensions or other
assistance in actually creating the rendering.  

Don't think "iterating through rows in the TinyTable".  Outside
RenderingKinds, nobody knows there's a TinyTable.  *You* don't know there's
a TinyTable, because the application integrator might decide to do it with
a table in an SQL database or a ZODB folder.

Don't think "RenderingKinds replaces the image data in existing
Renderings", because that's "meddleware" - objects meddling in each others'
business.  Renderings is responsible for renderings.  RenderingKinds is
only responsible for knowing about *kinds*.

This is probably the hardest part of ZPatterns design for people to learn.
Ironically, it's nothing more than the most fundamental of O-O design
principles.  Everybody thinks they know O-O, incredibly few do.  I was
doing O-O for almost *fifteen years* before I realized I wasn't even close
to doing it right at this level of design!


In turn, are RenderingKinds *also* responsible for returning
the appropriate Rendering based on a 'size' attribute? 

No.  RenderingKinds are responsible only for knowing about *kinds*, not the
details of a particular image.  Thus, it makes sense for RenderingKinds to
implement rules about what renderings an image *should* have, but the ones
it *does* have are the domain of the image itself (but delegated to the
Renderings specialist for actual implementation).


are ArchiveImages supposed to access Renderings directly to
find whatever Renderings exist for them?  Which SPecialist
now has a getRenderingFor(archiveImage,imageKind) method?

Renderings.  ArchiveImage should have getRendering(imageKind) which then
calls Renderings.getRenderingFor(self,imageKind).


I can also see a problem with the following situation: after
several Archive images are created along with their
appropriate Renderings, the configuration information in the
TinyTable is changed, with new sizes added, and existing
sizes deleted or edited.

I would not expect the entire image database to be resized
and new sizes created automatically, so the data in the
Renderings Specialist would be out of sync with the sizing
meta-data, with Renderings possibly 'orphaned', and other
Renderings 'missing'

I *think* that these problems can be avoided, if the
Renderings Specialist is still responsible for reporting
what Renderings an ArchiveImage *has* (and possibly what
their dimensions are), and the RenderingKinds Specialist is

responsible for removing orphan renderings and creating
missing Renderings when the Image is either uploaded again
or 'refreshed'.

How would you reccomend handling this?

That depends on what the requirements are.  If you need to implement this,
then the sensible place to do it is probably in the RenderingKind objects
and RenderingKinds specialist.  That is, adding a RenderingKind might
include the option to go through and create the missing renderings, and
deleting or altering one might similarly prompt for updates.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns Image Archive Project

2001-04-01 Thread Phillip J. Eby

At 08:59 PM 3/30/01 -0800, Michael R. Bernstein wrote:
"Phillip J. Eby" wrote:
 
 Aha.  I think I understand what you're doing now.  You have an "Image" and
 you have a "Rendering".  Two classes, different behaviors.  I'm assuming
 that originals and thumbnails and whatever other renderings exist have no
 real behavioral differences and can be implemented with the same class and
 storage characteristics.

The terminology I'm using is ArchiveImage (for the 'Image'
class) and RackImage (for the 'Rendering' class).

I'd recommend a name change for RackImage, at least at the Specialist
level.  If you don't like Renderings, then maybe RenderedImages,
ActualImages, or some such.  Specialist names should reflect the *purpose*
of a thing in the application rather than the nature of the thing itself.


I think that different sizes would have the same behavioural
characteristics (simply an image file, really), but am less
sure about storage. My application will attempt to store all
the renderings in the ZODB, but if I want this to be
reusable, I have to assume that someone (including me) might
want to store the image data on the FS instead. If it's
going to be stored on the FS, it would be natural to dump
different sizes into separate directories, or even separate
partitions. Two years from now, this web application could
contain around 300 Gb of images (current prices on that much
storage are about $1,000 for ten 30 Gb hard-drives, so I'm
not too worried on that score).

This can still be accomplished with a single specialist, if your 'id'
format contains the necessary information to distinguish between image
sizes/types.  If a user of your framework wants to seperate the storage,
they can create more than one rack and have the specialist distinguish
between them using the contents of the 'id'.  It's best to keep
implementation simple in the reference implementation of a framework.


 That's what I meant, sorry. The RackImages need to appear to
 be attributes of the ZClass, and I'll use SkinScripts to
 accomplish that.
 
 That's really only practical if you have a fixed set of rendering types and
 names, but it'll work for retrieval.  It won't really help you with
 creation and assignment, though.  I'd suggest specialized methods on Image
 which delegate to the Renderings specialist.

I was thinking of a manage_upload method on the
ArchiveImage, that iterated through a list of sizes and used
an external method that imports PIL to resize the image
data, then passes the resized image data into the RackImage
manage_upload method.

Does that seem reasonable?

It seems to me that sizing renderings should be the responsibility of the
Renderings specialist.  That is, the ArchiveImage upload method would look
something like this:

for imageKind in ('fullsize','thumbnail'):
Renderings.setRenderingFor(self,imageKind,imageData)


The setRenderingFor method would take the ArchiveImage's id, tack the
imagekind onto it, and either retrieve the current image or create a new
one, then re-size the image according to your rules for what size fullsize
or thumbnail is, and pass it to the current or new rendered image object.
(A counterpart method, getRenderingFor(archiveImage,imageKind) would do a
similar id transformation to retrieve a rendering when called by the
ArchiveImage's getRendering() method.)


Of course, this means that the Renderings specialist has to know what
sizes different size names mean, and that ArchiveImages have to know the
possible sizes.  Such knowledge being spread across two specialists means
there's a specialist missing: RenderingKinds.  This may be a sub-specialist
of Renderings, or a peer of Renderings within ArchiveImages.  If a
sub-specialist of Renderings, Renderings must expose a method to retrieve
the sizes, and the upload method above would look like this instead:

for imageKind in Renderings.getRenderingKindsFor(self):
Renderings.setRenderingFor(self,imageKind,imageData)

Although, it may be in your framework that ArchiveImages are responsible
for knowing which kinds of renderings they should have, and the
RenderingKinds specialist will simply deal with implementation details such
as how each kind is sized and which rack they're stored in within the
Renderings specialist.

By the way, RenderingKinds is a sort of specialist that hasn't been
discussed much outside of the apps Ty and I work with - the "constant"
Specialist, one which contains application configuration or metadata rather
than "content".  Oftentimes it's handy to simply base a Specialist on a
TinyTable or similar product in order to set up configuration of constant
items like RenderingKinds.  Consider the TinyTable data below:

Columns: name:string scaling:float width:int height:int rackname:string

"fullsize",1.0,0,0,"bigimages"
"halfsize",0.5,0,0,"bigimages"
"thumbnail",0.0,64,64,"thumbnails"

The Re

Re: [Zope-dev] (ZPatterns) Speeding up Skinscripts

2001-03-29 Thread Phillip J. Eby

At 01:57 PM 3/29/01 -0800, John Eikenberry wrote:

We have a fairly large and complex app framework built on ZPatterns. It
uses MySQL for storage and the standard Specialist/Rack/DataSkin setup with
skinscripts for attributes and triggers.

We've found that the speed of getItem is a bit slower than we need. For
instance retrieving 200 dataskins takes about 8 seconds on a P2-300. After
profiling and digging around I think I've found the primary bottleneck.
Its the
running of eval() on the skinscript's python expression (stored in the
Compute
class as _fromex and Triggers as callexpr).

Congratulations, you're the first person (that I know of, anyway) to hit a
wall here.  However, I think you may be barking up the wrong tree on your
profiling.  See below.  

The optimization I've been looking at is changing the code from storing a
string and eval()ing the string to using compile() at save time and exec()
when
evaluated.

Profiling these 2 ways in little test programs seems to indicate about a 2.5x
speedup. Not huge, but combined with better hardware should be enough.

But I'm curious why this avenue wasn't taken to begin with. Seems like the
way
to do it to me. Am I missing something? 

Yes, as your later message mentions, ZPatterns already does that caching.
I think what's more likely to be taking up time is either:

1) Zope security checks on the expressions, or
2) DTML execution of your SQL queries

Or perhaps something else altogether.  First a few comments on the above,
then I'll ask some more probing questions regarding your setup.

SkinScript expressions execute using Zope security checking.  If you're
using a "WITH QUERY SQLmethod() COMPUTE attributelist" statement, security
checks are applied to both the query expression and to every name
referenced in 'attributelist'.  So the longer the attribute list, the
slower the execution.  Although, now that I think of it, eval() is not used
if you use a pure attribute name list like "name1,name2,name3", so the
problem probably isn't on the attribute list side.  This makes it much less
likely that the security machinery is to blame (unless you have a very slow
user folder which also doesn't cache well, and you haven't given your
SkinScript proxy roles to shortcut the security checks.)


Now, for your SQL query...  is it by any chance dynamically generated in a
complex way?  I mean, more complex than an sqlvar or two?  Keep in mind
that when Zope caches SQL queries it does it by generating the text of the
query and using it as a cache key.  That means any DTML in your query will
be executed each time.  It'd have to be pretty complex, or else there'd
need to be lots of slow security lookups, to get the kind of poor
performance you're seeing, though.

Okay.  Here are a few things to look at in your app:

1. If you're not using LoginManager as your user folder, and maybe even if
you are, your SkinScripts should have proxy roles.  Proxy roles can slash
the overhead of performing security checks, and are usually appropriate for
SkinScripts because SkinScript is "internal" to the object and Zope
security will apply to the results of the SkinScripts as well.

2. Why are you retrieving 200 dataskins?  Is this all in one transaction?
If so, you may have a design issue.  Multi-object operations should
generally be implemented as domain-specific methods on the Specialist, so
they can be implementation-specific (and thereby take advantage of speedups
like a ZCatalog index or specialized SQL queries).  In other words, you
probably want to iterate directly over a 200-row query result from an
SQLMethod, rather than retrieiving 200 DataSkins.  (You're accessing over
10 times as many DataSkins in one transaction as our most complex ZPatterns
application touches in its most complex type of transaction, which involves
about 4 or 5 Specialists at once!)  Pretty much, if you're displaying a
list or report or doing some kind of summary analysis or mass update, it
belongs in an implementation-specific method in the Specialist.

3. If you *really* need 200 dataskins in one transaction, and the overhead
is *really* in SkinScript, then you can bypass the overhead by writing an
AttributeProvider of your own in Python.  I'm guessing, however, that
SkinScript per se is not the source of the slowdown, and you need to look
more closely at the things the SkinScript is calling.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] LoginManager question

2001-03-27 Thread Phillip J. Eby

At 12:19 PM 3/27/01 +0200, Bertrand Croq wrote:
Hi,
  I am currently using LoginManager to authenticate users from a MySQL 
database. I followed the tutorials and it works quite well; but there are 
other data associated with users in the database that I would like to use in 
Zope. I have found a solution but I think it is quite complicated:

- first, I added SQL_id_user (ZSQL-method) in the acl_users:

select id_user
from user
where dtml-sqltest username column=user_name type=string

- then, I added id_user (DTML-method) in the acl_users:

dtml-in expr="SQL_id_user(username=username)"
  dtml-return id_user 
/dtml-in

- now, when I want to get the id_user value associated with the current
user, 
I need to do:

dtml-with REQUEST
 dtml-var
  expr = "AUTHENTICATED_USER.id_user(
   AUTHENTICATED_USER,
   username=AUTHENTICATED_USER
  )"
 
/dtml-with

Isn't there an easier way to get the id_user value?


Yes, there is.  Get rid of the "id_user" DTML method and add the following
to a SkinScript method inside your UserSource:

WITH QUERY SQL_id_user(username=self.id) COMPUTE id_user

You should then be able to do "AUTHENTICATED_USER.id_user" to retrieve the
attribute.  


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] FYI: TransWarp talk slides posted

2001-03-11 Thread Phillip J. Eby

HTML Version (frames  JavaScript required):

http://telecommunity.com/TransWarp/IPC9Talk.htm 

PowerPoint Version:

http://telecommunity.com/TransWarp/IPC9Talk.ppt


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns: External Attribute Provider question

2001-03-11 Thread Phillip J. Eby

At 07:48 PM 3/11/01 +, Steve Alexander wrote:

Is there a good reason that ExternalAttributeProvider sets up a 
dictionary to put its attributes into, rather than a PersistentMapping?

It's mainly to avoid a proliferation of persistent objects, based on the
assumption that if you're using a PEAP, you probably don't have that much
else in the PersistentMapping.


If an External Attribute Provider instead set up a new PersistentMapping 
in its slot, only that PersistentMapping would change in the ZODB on 
updates.

Do you think this is a reasonable change for the External Attribute 
Provider class? Or, should I write my own provider, derived from 
External Attribute Provider, that uses a PersistentMapping instead of a 
dict?

I would suggest creating your own provider(s).


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] State of ZPatterns

2001-03-10 Thread Phillip J. Eby

At 10:16 AM 3/11/01 +1100, Itai Tavor wrote:

I'm wondering where TransWarp leaves ZPatterns users. Until a couple 
of weeks ago ZPatterns was the best thing to happen in the Zope world 
since, well, Zope. Now it's described as a 'hack', 

Those things aren't mutually exclusive, you know.  :)


demoted into 
'maintenance only' mode, and superceded by something that is 
described as being as much better than ZPatterns as ZPatterns was 
better than standard Zope development.

It hasn't been superceded.  TransWarp has several layers of functionality
planned; only one of those layers has been released to date.  (By the way,
I also don't recall ever saying even that TransWarp was "better" than
ZPatterns, let alone that it was some giant leap forward.  I did say that
it expanded further on the model which was the basis for ZPatterns, however.) 

As for "maintenance only", ZPatterns hasn't had any changes in months,
except for patches provided by its users.  That's largely because it hasn't
needed any.  There's not much you can *add* to ZPatterns, without a major
upheaval.  I figure, let the major upheaval be directed at making something
completely different, rather than have major reworking to make something
only marginally better.


So what do we do now? Wrap up current ZPatterns work, writing it off 
as a loss for future reuse? Or can we count on 'maintenance only' 
being sufficient to support continued reused of ZPatterns efforts 
long enough to justify the original development effort?

Someone asked a similar question of me at the conference.  I told them that
if I needed to develop a web-based application today, I would use ZPatterns
with Zope.  It works, it's stable, it gets the job done.

Also, recall that the RIPP model concept was introduced to the Zope
community last January, and it was many months before ZPatterns' first
release, then many more before it was stable enough to be ready for
production use.  Expect the same to be true of TransWarp.  The tools
released so far are rock solid, but there isn't anywhere near enough there
to compete with ZPatterns yet.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Designing ZPatterns/Python-product-based, reusable applications - take 2

2001-03-10 Thread Phillip J. Eby

At 10:24 AM 3/11/01 +1100, Itai Tavor wrote:

Then I need Specialists to manage collections of PD classes. I think 
that these would also benefit from being product-based, so I subclass 
Specialist to create a manager for each role in the application. Now, 
since an existing application might be expanded, the Specialists all 
need factory methods and will all show up in Zope's Add New Object 
menu.

Or you may want to just create one factory method that creates an entire
family of related Specialists.  Specialists do support TTW overriding of
their methods, if you set up the methods properly in your Python code.  (I
forget how this works, though, you'll probably need to check the source code.)


-  Many of the classes will also have web user UI, and since this has 
to be designed to fit the design of the web site in which the 
application is used, the UI methods will have to be located where 
designers can modify them - in the ZODB. For the Specialists, I can 
install a default set of UI methods when an instance of the 
Specialist is installed. But where do I store PD class UI methods? 
EMarket's solution is to store them in the Specialist, but this not 
only breaks O-O rules, it can also be very ugly. Say I have a 
Specialist managing 3 PD classes. Instead of an index_html method for 
each class, I'll need class1index_html, class2index_html, 
class3index_html in the Specialist. And each class would have to 
define:

 def index_html(self, REQUEST, RESPONSE, **kw):
 return self.class1index_html(REQUEST, RESPONSE, kw)

This is unacceptably ugly. But the only other thing I can think of 
doing is creating a ZClass for each PD class and store the UI methods 
there. But that's also pretty unacceptable. Is there a better 
solution?

Yes.  Use "class_default_for_X" methods.  (e.g. "def
class_default_for_index_html").  This will make them capable of being
overridden with a Class Extender in the Rack or Specialist.



Next, I need object connections - these are created using 
SkinScripts. And as far as I can tell, I can't manage SkinScript in 
the product - they have to be in the ZODB. Which is ok in O-O land as 
they're not strictly part of the PD classes, but this means that PD 
classes don't actually work at all until someone comes and fills in 
the SkinScripts - so the class actually misses a lot of the code it 
requires to function. Also, it means SkinScript code can't be reused 

with the rest of the application's components (except by cutting and 
pasting code pieces from an existing application).

Your factory code can set this up, although I admit it's ugly.


Finally, I need to wrap the whole thing up as an application. So I 
create a Folderish class which installs instances of all Specialists, 
and add application-wide utility methods. Or do I simply place all 
Specialists in a Folder?

Placing them in a folder would be fine.  Actually, it would suffice simply
to install a meta type which creates all the Specialists in the selected
folder.  Note that Zope does not require that a meta type correspond to
some physical class, or that an add operation result in a single object
being added to a container; you can add as many objects as you want in the
same operation.


Now, about reuse. O-O reuse, as far as I understand it, takes place 
at the class level. So how do I start a new application? Do I 
subclass its main container class and and my own init method that 
adds any added or subclassed Specialists I use? Or do I create my own 
application class and import PD classes from the old application? Do 
I copy the old classes into my new product, or do I import them from 
the old product, which then would require that the old product is 
kept on the server, even if the application that product defines 
isn't used on this server?

If I understand you correctly, then you'd just instantiate another instance
of the application metatype, and then customize whatever needed to be
customized.


And, as mentioned above, how do I reuse SkinScripts, Rack methods and 
SQL methods? Copy and paste? It seems funny that if I create a new 
instance of the product, I don't get a new copy of a working 
application...

If your factory methods set this stuff up, then you're okay.


On the other hand, considering that ZPatterns is now being superceded 
before it even had a chance to mature, maybe nobody cares to hear 
about it anymore :-( But more on that in a separate post.

IMHO, ZPatterns is actually pretty mature - in terms of its code.  By that
I mean, it has gone about as far in capabilities as its internal
architecture will allow.  There are many minor improvements that could be
made, but they would be costly compared to their benefit.  I would rather
invest the effort in something that will produce a greater gain for me and
the rest of the community.  TransWarp will be much better for
filesystem-based, Python products than ZPatterns, which is almost 100%
through-the-web focused.

The key phrase, though, is 

Re: [Zope-dev] TransWarp preview release (AOP tools only)

2001-03-08 Thread Phillip J. Eby

At 10:52 AM 3/6/01 -0500, Shane Hathaway wrote:
"Phillip J. Eby" wrote:
 
 There's actually a simpler way.  Aspect objects can be pickled as long as
 all the objects in them can be pickled.  Which means that as long as all
 their methods are Zope objects, and all the nested classes are also Aspect
 objects, you can save an aspect into the ZODB, and load it at a future
 time.  Further, since adding aspects together makes new aspects, you can
 save the combined aspects, so you only have to perform one call to
 transform the aspect into a family of classes.  That still means some
 load-time complexity, however.

Perhaps... but as I see it, pickling the aspect weaving information into
each object makes it harder to vary the aspect weaving after objects
have been created.

That's not what I said.  *Aspect objects* can be pickled.  You're talking
about *instances* of *classes* created by weaving the aspects, and that's a
whole different kettle of fish.  Check out the "AOPTutorial" in the Wiki,
which sorts out the differences between the three.



I would want to be able to create a portal, add some
content, then change the aspects that apply to the content after it has
been created.

Of course, just as you can currently upgrade a class that has instances in
the ZODB.  Regenerating the class from different aspects would have exactly
the same pros and cons as upgrading a .py module containing a class that's
used in the ZODB.


I'm also planning outside the ZODB.  The goal is to design apps using
pure and simple ZODB and not be required to do anything special to make
it work later with other forms of storage.  Other databases will not be
able to store aspect information.

Again, this is a confusion of instance and class.  Aspect information is
*not* per-instance - heck, even *classes* in TW don't know what Aspects
they were woven from.  The aspects are like flour and eggs that go into
making a cake (class or set of classes).  Once it's baked, the ingredients
are no longer visible.  :)


That's actually the kind of functionality we have now, but we're using
subobjects rather than tabs and we achieve many of the things AOP would
give us through simple delegation.  You should check out the CMF as soon
as the beta is released.

One of the interesting things I learned at the Python conference this year
(through some of the papers, like the Virtual Worlds and Thin Client
projects) was where the best trade-offs between a delegation approach and
an AOP-style approach are.  The spectrum seems to be that if your instances
need to make lots of different choices, or if they need to be able to add
and remove aspects on an ongoing basis, then some type of delegation is
probably the way to go.  If your choices are more about *configuration*
that applies to *multiple classes*, then aspects are probably more
appropriate.

By the way, I have never tried to promote AOP as even being relevant to the
CMF.  :)  AOP is mostly about *reuse*, so any single run-time environment
(such as CMF or even Zope as a whole) will not see much benefit that you
can't get through delegation.  ZPatterns, for another example, is one
gigantic web of delegation internally.  AOP is of more relevance to the
developer who has a piece of code they would like to use for the CMF, *and*
for a command line tool, *and* a testing tool, *and*  And thus they
need to be able to assemble their code into a variety of useful
configurations.

After Michel's presentation the other day, I understand a lot better how
Zope will address this issue with "adapters", and that will help *a lot*
with a lot of things.  However, people may also have other environments
besides Zope to use their code in, or other configuration choices to be
addressed that are not exposed to Zope (such as the database schema), and
having AOP available will presumably be helpful to them.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] TransWarp preview release (AOP tools only)

2001-03-02 Thread Phillip J. Eby

At 03:53 PM 3/2/01 -0500, R. David Murray wrote:
On Fri, 2 Mar 2001, Shane Hathaway wrote:
 "Phillip J. Eby" wrote:
  One reason I've been racing like mad to get the preview release out is so
  that, after seeing the usefulness of TW for the Zope 3 component
  architecture, y'all might be interested in considering implementations
for
  module persistence besides proxying.  :)  IMHO, a "rollback importer"
  approach ala unittest might be better suited for TW-ish components, and
  have fewer weird side effects for persistent modules generally.  I don't
  like unittest's mechanism for *doing* the rollback, and Zope would need a
  thread-specific version of sys.modules, as well as a mechanism to
purge the
  cache of any objects which were loaded after any of the purged
modules, but
  I think the basic idea is sound.
 
 Hmm.  I'm afraid I don't see how TW helps with module persistence.

I could be wrong, but I didn't read what Phillip wrote as saying he was
suggesting TransWarp as a player in the Module Persistence implementation,
but rather that he wanted people to see the value of TransWarp first hand
so that they would want to make sure that Module Persistence and TransWarp
could play together


Yes, that's exactly what I meant.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] TransWarp preview release (AOP tools only)

2001-03-02 Thread Phillip J. Eby

At 12:39 PM 3/2/01 -0500, Shane Hathaway wrote:

We've been separating concerns in the PTK/CMF for the last year now. 
We've been moving as many responsibilities of the content objects as
possible into per-portal "service" objects.  The services provide user
interface, discussion capability, workflow integration, etc.

In doing so, IMHO we've lost a little simplicity.  In the current way of
doing things, content objects should not know about their own workflow,
instead they should be associated with a portal-specific type object and
the type object is associated with a set of workflows.  And the user
interface depends heavily on acquisition now.

Now, let's say that instead everything were reintegrated into the
content objects using aspects.  To retain flexibility, different portals
would weave the content objects in different ways because of variations
in user interface, workflow, etc.  Would this be a good application for
TW?

Absolutely.  And as you've probably guessed, you can insert the
implementations at whatever level of the class hierarchy - insert global
policies into a base ContentObject, override them at a more detailed level,
whatever.


This could be achieved by generating a new Python module for each portal
instance, but that would mean sys.modules would have to be pre-loaded
with the information about each portal instance and that's not the ZODB
way.  It would be better to create a new class loader that can weave a
new class on the fly based on persisted component metadata.  Note that
class loading is currently quite simple; see
lib/python/Zope/ClassLoader.py (sp?).  It could bear some complexity.
:-)

There's actually a simpler way.  Aspect objects can be pickled as long as
all the objects in them can be pickled.  Which means that as long as all
their methods are Zope objects, and all the nested classes are also Aspect
objects, you can save an aspect into the ZODB, and load it at a future
time.  Further, since adding aspects together makes new aspects, you can
save the combined aspects, so you only have to perform one call to
transform the aspect into a family of classes.  That still means some
load-time complexity, however.

I haven't given a whole lot of though to through-the-web use of TransWarp's
AOP stuff; I've mainly thought of it as being a "Product"-level tool.  But
I imagine you could perhaps make some sort of "ZAspects" (ala ZClasses)
that wrap through-the-webness onto aspects.  (Of course, if you can do
through-the-web modules, no special magic is required.)

Actually, any Python class or ExtensionClass can be used as part of a TW
aspect, so you could in fact use ZClasses as part of an aspect right now,
if you wanted to.  Handling the class hierarchy of a ZClass could be
tricky, though, if you wanted to be able to deal with them as a class
family.  ZClasses have so many parent classes by default.

It would be interesting if you could take an arbitrary Zope service object
(like a portal), and go to its "Aspects" tab, and add or remove aspects to
be woven with its class family.  But I suspect it will be a long time
before I'll have a need for that personally or professionally, as I am
focused primarily on TransWarp as a CASE tool and Python application
toolkit at present.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] TransWarp preview release (AOP tools only)

2001-03-01 Thread Phillip J. Eby

At 09:37 AM 3/1/01 -0500, Shane Hathaway wrote:
This looks very interesting, Phillip.  I haven't downloaded the package
yet, but I read the wiki and it finally made sense once I understood the
goal (I think): TW lets you set up the class inheritance hierarchy at
runtime.  In normal OO methodology, you can only extend classes.  With
TW, you can also slip your own version of a base class into a class
hierarchy (without actually modifying the Python class hierarchy, of
course.)

That's a good way of describing the *function* of the AOP part of
TransWarp.  The goal is not so much to set up the inheritance hierarchy at
runtime, as to allow you to configure various versions of the same
component, and to write seperately-managed "aspects" for different areas of
concern.  The targeted time is not really "runtime" so much as "build
time".  Runtime is a side-effect of how it's done, and it can be useful for
things like selecting an OS-specific or other environment-sensitive aspect
at application startup.  But the main goals of the AOP portion are being
able to instantiate customized versions of "third-party" components, and to
be able to mix-and-match implementations for different areas of concern.
For example, wxPython vs. Tkinter vs. Win32, SQL vs LDAP vs ZODB, and so on.

TransWarp in the larger picture will also deal with generative programming;
the UML-driven parts will generate aspects that contain structural
information (inheritance, associations, aggregations, attributes, etc.)
that can then be merged with non-structural aspects.  The ability to "set
up the class inheritance hierarchy at runtime" provided by the AOP tools
will then allow you to define what an "attribute" is, and give it
publishability, security permissions, or a GUI rendering.

There is actually code in the preview release to do this structural
generation for the UML metamodel (if loaded from MMX format), and it's even
rudimentarily tested (one unit test that just makes sure it doesn't blow up
altogether) but the "StructuralModel" aspects that implement attributes and
associations are currently broken, not yet updated for the true AOP model.
Earlier versions of TransWarp did class generation as an integral part of
the GP system, not as a GP+AOP system, and I'm still adapting a lot of
stuff to take advantage of AOP and to use a cleaner metadata mechanism.


What is your vision of integrating AOP into a persistent object system? 
Would one drop in an object that modifies the class loading mechanism so
that the classes come from a TW component rather than Python modules?

Not necessary.  If you dig into the TransWarpFAQ page in the Wiki, you'll
see a question that explains how to make TW-generated classes work with
pickle and cPickle.  It just requires one additional argument at
aspect-weaving time, to specify the module which the generated classes
should be registered with.  This means that TW's AOP features are
functional right now, today, with ZODB.  (As long as the classes are
generated in good ol' Python module files.)

Now, as to whether TW will be fully compatible with Zope 3 "persistent
modules", that's a different question.  In the conversation I had with Jim
in January, based on his description of the module refresh mechanism and of
import proxies, I would say that TW-generated classes would not properly
refresh when a persistent module that they were dependent on changed.
(Because TW will generate new class objects from the imported classes
rather than referencing them via the proxy.)  But that's based on a very
early notion of how Z3 persistent modules would work.

One reason I've been racing like mad to get the preview release out is so
that, after seeing the usefulness of TW for the Zope 3 component
architecture, y'all might be interested in considering implementations for
module persistence besides proxying.  :)  IMHO, a "rollback importer"
approach ala unittest might be better suited for TW-ish components, and
have fewer weird side effects for persistent modules generally.  I don't
like unittest's mechanism for *doing* the rollback, and Zope would need a
thread-specific version of sys.modules, as well as a mechanism to purge the
cache of any objects which were loaded after any of the purged modules, but
I think the basic idea is sound.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns goes crazy after ZClass change

2001-02-20 Thread Phillip J. Eby

At 10:29 AM 2/21/01 +1100, Itai Tavor wrote:

I think I've severely misunderstood how Racks work. I thought 
persistent Racks just store properties, and then use the ZClass set 
in the Storage tab to wrap that data when providing it. Which means 
that I can change the class set for storage and all the objects in 
the Rack will be provided as the new class. But if changing the 
storage class doesn't change the object provided by the Rack, it 
means the actual ZClass instance is stored. Is this right?

Yes... unless you use a Persistent External Attribute Provider, and set the
"load attribute" so that the rack is virtual.  The "store objects
persistently" option stores the actual ZClass instances.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns and SQL

2001-02-19 Thread Phillip J. Eby

At 05:29 PM 2/19/01 +0100, Christian Scholz wrote:
 
 You need to use an attribute which the object has *if and only if* it
 exists in the database.  If the class has the attribute defined, all
 instances exist, and you can't even load it with SkinScript because
 ZPatterns uses __getattr__ to redefine attributes, and that doesn't work if
 the attribute already exists in the class.

So I shouldn't define it inside the ZClass propertysheet? 
Do I understand this right?
(I remember having problems when using properties not defined in a
sheet somewhere.. or am I mistaken completely somehow? ;-)

You can't do this with a load attribute, because a default value will
exist.  The easiest way to deal with this is simply to have a seperate
attribute name just for loading, or use an attribute that isn't on a
property sheet.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns and SQL

2001-02-19 Thread Phillip J. Eby

At 05:50 PM 2/19/01 +0100, Christian Scholz wrote:

(though I am still confused a little, as I tried one non-existing
attribute and it didn't work. But this one also was not defined inside
the SkinScript and the database).

As I said, the attribute must exist if and only if the row is in the
database.  Thus, it must *not* exist on the propertysheet, and it *must*
exist in your SkinScript.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Waaagh! Python Script won't allow __setitem__

2001-02-19 Thread Phillip J. Eby

At 05:25 PM 2/19/01 +, Chris Withers wrote:

Hmmm arguably a bug in ExtensionClass, but not one I'm gonna try and
fix ;-)


It's not a bug, it's a feature -- the feature that is the reason for the
very existence of ExtensionClasses in the first place: merging of the
notion of type and class.

Of course, type() could always be replaced with a safe_type function that
checked whether the type() was an ExtensionClass and returned something inert.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Python Product as DataSkin

2001-02-18 Thread Phillip J. Eby

At 12:51 PM 2/18/01 -0800, Michael R. Bernstein wrote:
I have an existing Python Product that I would like to use
as a DataSkin in a Rack.

What do I need to change (import/subclass) in order to use
it in this way?


from ZPatterns.DataSkins import DataSkin

class MyClass(DataSkin,...all other bases...):
...


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Python Product as DataSkin

2001-02-18 Thread Phillip J. Eby

At 09:49 PM 2/18/01 -0800, Michael R. Bernstein wrote:

Ok, assuming that the 'normal' instantiation is either
solved or a non-issue, do I need to do anything special to
get the newItem() method to call my products manage_add
method?

newItem() will not do that.  A Rack's newItem() method always takes only an
'id' method.  You'll need a method on the object itself that can be given
anything else you want to give it, which you'll call from a method you
create on the specialist, e.g. a "myAdd" method that takes all four
parameters and then does something like:

newObject = self.newItem(id)
newObject.setup(extraParm1,extraParm2,...)
return newObject


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Python Product as DataSkin

2001-02-18 Thread Phillip J. Eby

At 10:47 PM 2/18/01 -0800, Michael R. Bernstein wrote:

Hmm. So I need to refactor the 'manage_add' method inside
the python product into two methods, 'manage_add' which
would be used by the 'normal' object creation process and
that would also call a second 'setup' method which could be
called by the specialists 'myadd' method directly, bypassing
the 'manage_add' method entirely.

Is that correct?

Pretty much


Is there anything else I would need to change?

Anything that carries any assumptions about the normal Zope management
creation process.  For example, manage_afterAdd is only called when a
DataSkin is added to a Folder, not a Rack.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Q: Specialists, Racks, and ZCatalogs?

2001-02-04 Thread Phillip J. Eby

At 08:38 AM 2/4/01 -0800, Michael Bernstein wrote:

On that subject, does anyone know why SkinScripts don't
support cut-n-paste or copy-n-paste?


'cause I never thought of implementing it, probably because I've never yet
needed to move a SkinScript.  Patches cheerfully accepted.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] Specialist/Rack scalability

2001-01-21 Thread Phillip J. Eby

At 07:12 PM 1/21/01 +, Steve Alexander wrote:

So, storing things in a Rack happens in a number of stages:

   Your application interacts with the Rack
   The Rack (perhaps) stores the object persistently in its BTree
   The BTree is a collection of persistent ZODB objects
   The ZODB objects are stored as Python Pickles in a FileStorage

We can consider what the effect of storing 60 000 objects is at each of 
these interfaces.

The Rack shouldn't have a problem with 60 000 objects.

I doubt a BTree would have a problem.

The ZODB might not like accessing many large objects during a single 
transaction, as all those objects need to be in memory at once.

A FileStorage should have no problem reading 60 000 stored objects. 
However, if these objects are changing much, your Data.fs will grow 
fast. In any case, you may find undo and history screens take a long 
time to appear.

However, if you are using a Rack, you have a lot of choice about where 
you put your data. You can put frequently changed aspects of your data 
on the filesystem, and the rest in FileStorage for example.

Just to expand a little on the abov...  Racks should scale at least as
well, if not larger than a ZCatalog, given the same storage backing for the
ZODB.  This is because ZCatalog has to manage a minimum of one forward and
reverse BTree for *each* index, plus another few BTrees for overall storage
and housekeeping.  Also, keyword and full text indexes store multiple BTree
entries per object, so that's a factor as well.

So don't worry about the Rack.  If you're using a Rack, you can store the
data anywhere, and you can index it in an RDBMS, LDAP directory, ZCatalog,
or some combination thereof, using triggers to keep the data in sync.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] LoginManger: multiple LoginMethods

2001-01-20 Thread Phillip J. Eby

At 06:38 PM 1/7/01 -0800, John Eikenberry wrote:

Anyways... I want to be able to support both cookie based auth and basic
auth. With cookie based auth being the default unless they don't have
cookies (either because they have them turned off, behind a proxy filter,
etc), in which case they should use basic auth. The problem is I'm not sure
how to get it to use something other than cookie based auth. The default
setup tries to use cookie auth whether or not cookies are in use.

Any tips on how to get this working? I know there is no great way of
detecting cookies, besides setting one and testing for it. But even if I
did this, how do I say I want basic auth if the test cookie isn't found.


Doing a: raise "Unauthorized" or RESPONSE.setStatus(401) will tell the
browser to pop up an authorization dialog.  Note that if you do this, you
won't be able to also display a login form for cookies.

For all practical purposes, you need a seperate login page for cookies vs.
basic auth.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] skinscript and URL traversal question

2001-01-19 Thread Phillip J. Eby

At 09:41 AM 1/19/01 -0500, Aaron Payne wrote:
At 09:38 AM 1/19/01 -0500, Phillip J. Eby wrote:

 Thus, your
 SkinScript is running as anonymous, and probably doesn't have rights to
 access the SQL method.
 You might need to change the proxy roles setting on
 the SkinScript method so that when the SkinScript runs it always has
 appropriate roles to do what it needs to do.
 
 I gave the skinscript trigger a proxy role of manager.  Actually, I gave
 all methods involved a proxy of manager. The same error was produced.

What version of Zope are you using?


Zope version: Zope 2.2.1
Platform: freebsd4


Hmm.  You've got me, then.  Have you tried taking the Python Method out of
the mix and using the SQL method directly, like this:

WITH QUERY searchBy_Name(name=self.id)

Also, have you tried running Zope with logging ("STUPID_LOG_FILE") enabled?
 What gets added to the log when you try to access the object via
bobo_traverse?


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




RE: [Zope-dev] Specialists and __bobo_traverse__

2001-01-17 Thread Phillip J. Eby

At 04:41 PM 1/17/01 +0200, Roch'e Compaan wrote:


 I don't have the slightest idea what you're trying to accomplish here - I
 probably missed the beginning of this thread.  Do you want to change the
 way the specialist processes the string "dataskin1", or the way dataskin1
 processes the URL component that comes next?  Each requires a different
 approach.

I want to process the way dataskin1 processes the URL component that comes
next.  Just to make sure I communicate some sense :)


Okay, then your SkinScript *should* work, so long as your dataskins don't
already inherit a __bobo_traverse__ method.  If your DataSkin inherits from
ObjectManager or any of its derivatives, for example, then it won't work.
Of course, the bobo_traverse you're supplying has to be able to be bound to
the DataSkin.  Not all types of Zope "method" objects can do this binding
correctly.  ZPublisher will call the method with two arguments, but your
method will (presumably) need three: one of which is "self" - the DataSkin
itself.  I'm pretty sure DTML methods *won't* work.  "Python Methods"
might.  I don't know about external methods, python scripts, etc.

If I was trying to solve your problem, I would just write a
__bobo_traverse__ in a Python base for my class.  If I needed it to be
replaceable on the fly, I'd write it so that it looked for another
attribute, maybe __skin_traverse__, and called it if it existed.  But I'd
have it pass three parameters, including self, so that I could use almost
any kind of Zope method and make it work.  Then if I needed to customize it
I could use SkinScript or a Class Extender to add the method in.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Specialists and __bobo_traverse__

2001-01-16 Thread Phillip J. Eby

It sounds to me like you're trying to have SkinScript supply a
bobo_traverse for the Specialist itself, and this you cannot do.  (There
are other ways to change a Specialist's bobo_traverse behavior, but
SkinScript is not one of them.)  The SkinScript you're doing is meaningful
only if you want to go to specialist/skin1/something, in which case your
traversal_method should be called to process "something".

I don't have the slightest idea what you're trying to accomplish here - I
probably missed the beginning of this thread.  Do you want to change the
way the specialist processes the string "dataskin1", or the way dataskin1
processes the URL component that comes next?  Each requires a different
approach.


At 07:28 PM 1/16/01 +0200, Roch'e Compaan wrote:
I'm still lost as to when __bobo_traverse__ is checked for object traversal
and when not.

I have very simple piece of SkinScript:  WITH SELF COMPUTE __bobo_traverse__
= traversal_method.  Looking at the traverse method in BaseRequest.py it
looks to me as if an object is always checked if it has a __bobo_traverse__
method but this is not what is happening.

If I manually type in a url, say path.to.specialist/dataskin1, where
dataskin1 exists, my traversal_method is not called.  When I type in
path.to.specialist/dataskin2, where dataskin2 does not exist then my
traversal_method is called.  Noticing that the traversal_method is called
when an object can not be found I tried
path.to.specialist/dataskin1/dataskin2, where dataskin1 is in the
specialist's rack but dataskin2 is in another specialist's rack and will
therefor not be found.  In this case my traversal_method was not called.  If
it was then I could retrieve it from the appropriate specialist.

I hope the above is clear because I'm somewhat desperate at the moment.  If
I'm trying the impossible, a simple "forget about it" will also do.



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: catching exceptions raised by triggers

2001-01-05 Thread Phillip J. Eby

At 12:49 AM 1/6/01 +, Steve Alexander wrote:

WHEN OBJECT ADDED, CHANGED CALL self.ensure_conditions_hold()

I write the ensure_conditions_hold method so that it returns None if 
everything is ok, but raises an exception if there is a problem with the 
new state of the object.

That's all fine. However, I want to catch this exception in my 
application, and handle it in a friendly way. However, I've tried using 
dtml-try blocks and try: except: blocks from Python Scripts, and either 
way, I cannot catch the exception. It still causes Zope to return the 
standard_error_message screen.

I can only speculate that this is all due to the way that triggers get 
executed at the end of transaction. I guess I'll have to validate the 
data twice if I want to provide helpful feedback to the user.

How do I catch an error raised by a Trigger?

What Ty and I usually do is raise user-friendly error messages (in HTML) to
begin with, so there's no need to trap them in an except block; Zope's
normal handling works okay then.  This is the "as designed/intended"
solution to your overall problem.  (We often use dtml-raise for this, as it
makes it easier to create a full-screen HTML error page.)

But to answer the question you asked, you can do it by performing a
subtransaction commit, wrapped in a try or dtml-try block.  This will fire
the triggers in a context where you can trap the exception.  We suggest you
only use this trick when you really need it, however, and in your situation
as described I don't think you really need it.  Even if
"ensure_conditions_hold" can't be changed to raise friendly exceptions, you
can always put a wrapper routine around it that catches and re-raises them.

The key idea here is that it's perfectly okay to let an exception propagate
to the user, if formatted properly.  You probably *want* it to happen, to
ensure that *everything* gets rolled back.  Even if you do the
subtransaction trick and trap the error, you still want to make sure the
transaction as a whole aborts, since SQL (for example) might already have
been sent to a database.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns; possible bug?

2001-01-04 Thread Phillip J. Eby

At 06:03 PM 1/4/01 +, Steve Alexander wrote:

I think what is happening in the broken example is that when the zope 
security machinery asks for __roles__, name is also computed. The 
machinery must request __roles__ before changing anything.


The behavior is as documented, though I'm not sure I'd call it "intended",
exactly.  :)  You can fix this with either a seperate statement, as you've
noticed, OR by placing the __roles__ computation *first* in the WITH SELF
statement.  This will ensure that it is already computed before the other
items execute.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Objects with multiple parents and storage flexibility, ZPatterns?

2001-01-03 Thread Phillip J. Eby

At 05:15 PM 1/3/01 +, Chris Withers wrote:

What I'd like:
'Zope' objects of type 'X', which can have multiple parents and can
contain other objects of type 'X', where storage isn't necessarily tied
to the ZODB but where the objects have a normal properties page (in
terms of use, again, it'd be nice if it could be stored anywhere) and
participate in all the normal Zope security and management interface
processes, and they need to be catalogable.

This sounds like ZPatterns to me, am I right?

If so, it appears there are two choices:
1. Folder w/Customiser Support (FwCS ;-) and DataSkins
2. Specialist with one or more Racks and DataSkins

Which one of these would be most appropriate?
FwCS containg DataSkins that also mix in the Folder class sound like
they'd give a closer approximation to 'real Zope objects', but Racks
sound like the only way that objects of the same metatype can come from
different sources (eg, some objects of type 'X' from ZODB, some from
SQL, some from LDAP ,etc) and seem to be more flexible in general, but
can I have DataSkins that nest stored in a specialists' rack, eg:

http://server:8080/specialist/dataskin1/dataskin2

How about doing something like:

http://server:8080/specialist/dataskin1/dataskin2/manage


You can't really "nest" DataSkins inside each other in a rack, and you
really don't want to, anyway.  But there's nothing that says you can't
create a DataSkin subclass whose __bobo_traverse__ looks up related
objects.  You just can't "really" store the DataSkins inside each other.
Note that if your __bobo_traverse__ uses a specialist "getXforY()" call,
you can "store" objects from different databases (racks) "inside" each
other.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns example update....

2001-01-02 Thread Phillip J. Eby

At 03:08 PM 1/2/01 +1100, Itai Tavor wrote:
Hi Steve,

Steve Spicklemire wrote:

   "Itai" == Itai Tavor [EMAIL PROTECTED] writes:

 Itai Maybe with this
 Itai SkinScript: WITH Doers.getItem(self.doerID) CALCULATE
 Itai self.doerID=RESULT.id or '' ?  But I'm not really sure about
 Itai this...

Ahh.. I think my brain just imploded in a recursive death spiral,
but I get intent of the idea. This would work I think:

WITH Doers.getItem(self.doerID) COMPUTE self.myDoer=RESULT or 
Doers.getItem('doNothing')

where there is a default 'doer' named 'doNothing' in one of the Doers
Racks.  This guy would 'fill in' for the ToDo's doer when no 'real'
doer can be found... I like that. ;-)

Yeah, this looks good... whether it's appropriate or not depends on 
how you expect the case where there's no Doer to behave - if you 
needed to know explicitly that a Doer doesn't exist, returning a 
'nothing' doer could confuse things. BTW, I can't see the recursion 
in my script... but maybe my brain is still in vacation mode :)

Your script uses an attribute (doerID) in the WITH clause that is provided
by the COMPUTE clause.  This is infinitely recursive in theory.  In
practice, it will result in the non-existence of the doerID attribute, as
ZPatterns treats recursive attribute references as non-existence of the
attribute.  The WITH clause will fail with an AttributeError.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns, ZClasses, Specialists: Assigning responsibilities

2000-12-21 Thread Phillip J. Eby

At 05:13 PM 12/21/00 +1100, Itai Tavor wrote:

I think you're right about this being an OrderLineItem.  A couple of fine
points, however...  First, I don't think there needs to be an
"OrderLineItemsWithGraphic" specialist, since there is nothing else that
would talk to it.  It's fine in this case to have the line item classes
(either with graphic or without) handle their own UI snippets.  UI
delegation is for when an object needs to display UI for some *other*
object than itself, since you can always use class extenders and other
techniques to reshape the apparent class of an object retrieved from a
specialist.  The interface which other objects deal with is
"OrderLineItem", and they simply expect a portion of the form to be
rendered, and it's okay for the class to handle that.

I got a bit confused here... the UI snippet for uploading a graphic 
actually comes from the Graphics Specialist.

That's fine, but it should be by way of an object that's filling the
OrderLineItem role, yes?

Or I could 
eliminate the problem by uploading the graphic from a form displayed 
by the order line item after it has been added.

That's actually what I thought you were doing/intending.


Here's the question...  how many behaviors are different in the order line
item itself?  Are you also using fulfillment line items?  If the only
difference to the order line item is that it references some additional
data, then I'd say a single class would be fine.  Most of the behavior
probably comes in on the fulfillment line item, yes?  Again, you can ask
your FulfillmentLineItems specialist to create
"newLineItemFor(orderLineItem)" and let it decide what kind of
implementation to hand back.  In this case, it probably will be a different
class, while for the order line items, it may or may not buy you anything.

I haven't thought of using fulfillment line items... not sure what 
they are for? An order is considered fulfilled once all items have 
been shipped, so order line items are responsible for tracking 
everything that happens until a ShipmentLineItem is created. The 
order line item for a customizable product tracks the product using 
state values like 'sent to factory', 'received from factory', etc. So 
it needs a new set of state values, as well as methods like 
'sendManufacturingOrderToFactory'.

What exactly does the fulfillment role you're referring to do? Does 
it do more than a shipment role?

Fulfillment would be between ordering and shipping, covering such things as
pulling items from the warehouse to customizing them with the graphic.  I
assumed that an order line item was only meaningful until you have a
completed order.  You may not need the complexity, but to me it seems like
a seperate phase with a very different set of behaviors than what I would
think of as an order line item.  If I were doing an app like this, I'd at
least have some sort of state/status objects to delegate these different
behaviors to.  But I'd say this could be left to the taste of the chef.  :)

P.S.  By the way, I'm off on vacation later today, and won't be active on
the list again for a little over a week.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns, ZClasses, Specialists: Assigning responsibilities

2000-12-18 Thread Phillip J. Eby

At 04:21 PM 12/18/00 +1100, Itai Tavor wrote:

This is how I see it:

- Products Specialist
 productRack
 customizableProductRack

- OrderLineItem Specialist
 lineItemRack
 lineItemWithGraphicRack

- product.addMeToOrder():
 order.addLineItem(product_id=id, add='lineItem')

- custimazable_product.addMeToOrder():
 order.addLineItem(product_id=id, add='lineItemWithGraphic')

This should probably be more like:

product.addMeToOrder():
  item = OrderLineItems.newLineItemFor(self)
item.setQuantity(...)
  etc.
  order.addLineItem(item)

customizable_product.addMeToOrder():
  item = OrderLineItems.newLineItemFor(self)
  item.setGraphic(...)
item.setQuantity(...)
  etc.
  order.addLineItem(item)

This approach makes things more declarative.  The product classes can have
properties or interfaces that the OrderLineItems specialist can use to
decide what kind of line item would serve them best.  You can then change
your line item assignment rules without necessarily requiring changes to
the product classes.



I imagine, then, that the UI for uploading the graphic would be 
included in product.addMeToOrderForm, using a UI snippet from the 
OrderLineItemsWithGraphic Specialist. Then I could pass REQUEST on to 
order.addLineItem and to OrderLineItemsWithGraphic.add, which would 
then upload the file?

I think you're right about this being an OrderLineItem.  A couple of fine
points, however...  First, I don't think there needs to be an
"OrderLineItemsWithGraphic" specialist, since there is nothing else that
would talk to it.  It's fine in this case to have the line item classes
(either with graphic or without) handle their own UI snippets.  UI
delegation is for when an object needs to display UI for some *other*
object than itself, since you can always use class extenders and other
techniques to reshape the apparent class of an object retrieved from a
specialist.  The interface which other objects deal with is
"OrderLineItem", and they simply expect a portion of the form to be
rendered, and it's okay for the class to handle that.

Second, you need to define that interface so that the Order can give the
line item constraints on how it does that UI, so it can share the screen
and REQUEST with other objects/data that the Order needs.  One easy way to
do this is to use a namespace parameter, that simply gives the line item a
name prefix to use on its fields.  Alternatively, you can use the "record"
approach, like this:

INPUT TYPE="TEXT" NAME="lineitem1.desiredSize:record:int" VALUE="4"
INPUT TYPE="FILE" NAME="lineitem1.imageFile:record:file"
...

The resulting REQUEST object from submitting the form will contain a single
object, "lineitem1", with "desiredSize" and "imageFile" attributes, so
you'll only have to pass a single parameter back to the line item.  I've
never tried doing a record with a file in it before, so I don't really know
how well that works.


Woof... so long. I'd appreciate any comments on this - especially on 
the question on whether it's better to have a specialized type of 
OrderLineItem, or to link the standard OrderLineItem to a Product 
object in case of a standard product, or, in the case of a 
customizable product, to a new object which stores the graphic and 
tracks the fabrication of the customized item.

Here's the question...  how many behaviors are different in the order line
item itself?  Are you also using fulfillment line items?  If the only
difference to the order line item is that it references some additional
data, then I'd say a single class would be fine.  Most of the behavior
probably comes in on the fulfillment line item, yes?  Again, you can ask
your FulfillmentLineItems specialist to create
"newLineItemFor(orderLineItem)" and let it decide what kind of
implementation to hand back.  In this case, it probably will be a different
class, while for the order line items, it may or may not buy you anything.

Anyway...  remember that Specialists are there to hide implementation
decisions like what classes are being used.  If you look at the ZPatterns
Wiki you'll see references to some of the design patterns which Specialists
are an instance of, which will give you some hints as to the many kinds of
things they can "hide" for you (and which therefore you should avoid
revealing in other code).  One of those patterns is that as an object
"trader" or "broker", Specialists can be used to create new instances of
objects that meet a certain interface, but whose implementation has been
selected on the basis of declarative criteria by the requesters.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: persistant objects hold DataSkin-Items - KeyError: _v_dm_

2000-12-14 Thread Phillip J. Eby

At 02:49 PM 12/14/00 +0100, Ulrich Eck wrote:

after a while I think I got it now.

I use a FcWS as a Folder like usual in Zope and if i create an object
of a type which is "customized" certain attributes will be set through
the customizer. 

Yes.


so for a database app that handles multiple tables
it isnt useful to handle with a FwCS.

Um, not necessarily.  You can create regular Folders under the FwCS if you
want to keep them seperate.  You can even use BTreeFolders or other
ObjectManagers, if you like.  All that's required is that they support the
ObjectManager protocol.  So you can have a folder for each meta_type.  Of
course, the primary storage of the object has to be the ZODB.


First I thought there is the same "magic" as if i ..getItem() with a
specialist .. in a FwCS

No.  The FwCS is to allow more "traditional" Zope objects to blend in data
from other sources, and/or to have trigger support.


Due to the Folders Rules, there can only by one object with the same id
at a time in one FwCS ..

Yes.   But you don't have to place the DataSkins directly under the FwCS,
they can be any number of nesting levels below it.


I'll switch back to a Specialist which has many racks as data-providers
which i can choose the right one with a method that has a "meta-type"
parameter.

is this right so far ??

Pretty much, although I'm not sure why you want to pick by meta type, since
one of the major reasons for having a Specialist is for the rest of the
application not to know about specific meta types.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: General Design Question

2000-12-14 Thread Phillip J. Eby

At 02:42 PM 12/14/00 +0200, Roch'e Compaan wrote:
As part of a Customer Relationship Management system our company is
developing, we have a Licenses specialist which manages product licenses.
All license objects do not have the same attributes however.  The various
attributes relating to different licence types are not known attributes from
the outset.

My first reaction to this is that I would use a different class for each
type of license, and a rack in the specialist for each class.  This would
allow maximum behavioral flexibility, since each class can have its own
methods for inputting or displaying data.

However, if your application needs to have end-user (as opposed to
integrator-user) definition of license types, then you need to add
LicenseType to your domain model and create a specialist for it (possibly
nested inside the Licenses specialist).  


As I see it one can take two approaches to this:
a) either add a single dictionary property for both license and licensetypes
which holds user defined attributes
   or
b) explicityly call manage_addProperty per instance to add properties.


Option "b" will make your application ZODB-dependent, since there is no way
to map arbitrary attributes to an SQL database, for example.  Option "a" is
better, since a dictionary attribute can be handled with WITH/COMPUTEs and
triggers, with a little work.

There is also an option "c", which would be to model
LicensePropertyDefinition and LicenseProperty objects in your domain model.
 This approach leads to a bit more work defining your model, as well as in
setting up the specialists and their interactions, but the payoff is in
better documentation of what your app is doing and easier re-mapping from
one database type to another.

Ty and I recently experienced something similar, in an application where we
were using a dictionary attribute to represent something that was better
modelled as a seperate object.  The complexity of the associated SkinScript
and DTML/Python/SQL methods went down after we bit the bullet and added a
nested Specialist.  (When a role in a domain model is only accessed from
one other role, it is reasonable to nest that role's Specialist inside the
other's, as it keeps the higher-level app namespace cleaner.  Usually there
is some clustering to domain models that puts a small number of supporting
classes in a position to do this for each major class.)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: persistant objects hold DataSkin-Items - KeyError: _v_dm_

2000-12-13 Thread Phillip J. Eby

At 06:31 PM 12/13/00 +0100, Ulrich Eck wrote:
after one more day of source-code-reading i got that far:

When I want to use a Folder /w Customizer (FwCS) I cannot/don't need to use
Specialists.

Not to store your objects, no.  You can still use Specialists to
concentrate search methods, constructors, UI snippets, and the like.
Typically, in that configuration some of your Specialists may contain (or
be) ZCatalogs which index selected objects from your FwCS hierarchy.


i create a FwCS and put my 'Framework' in it.
if i want to access (get/new) an object handled by a customizer
i can ask FwCS._getDataManagerFor(client,default) for my datamanager (DM)

Not necessary.  If you retrieve your DataSkin as an attribute of its
container, the DataSkin __of__ method will automatically find and bind the
DataManager (assuming you're not using some class that overrides __of__).


Do I need to implement methods like
createItem/retrieveItem/_v_itemConstructor as well
or how do i "get" my objects ??

Just retrieve the objects from their containers in the normal Zope way.
Ditto for creation - use the standard way of constructing objects in an
ObjectManager.


If I have an object whose metatype is handled via
customizer/skinscript/sqlmethod it'll
probably work managing attributes ..

Yes, it should.  Likewise triggers, if you want to set up cataloging triggers.


I'm searching for something that handles a newItem(meta_type,key) function
that is provided
from the FwCS who decides which object-type is created and gets those
attributes from the customizer

Just use the normal Zope "add list" to create one manually, or call the
appropriate constructors (e.g. SomeZClass.createInObjectManager()).


is there an example those newItem(meta_type,key) -
getItem(meta_type,key) ??

You want examples?  You forget, this is ZPatterns.  ;)  Seriously, look for
examples of how to create an object by meta_type in a Zope ObjectManager.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] [ZPatterns] DataSkin object ownership

2000-12-12 Thread Phillip J. Eby

At 08:04 PM 12/12/00 -0500, BS wrote:
Do DataSkins have ownership? I want to give multiple users the ability to
add objects to a rack and only allow the 'owner' to view/edit the object.
When a user adds a DataSkin to a rack does he get ownership of the object?
I can't seem to get the ownership information for these objects. Is there a
way to do this?

DataSkins stored in Racks do not participate in the Zope ownership
mechanism, nor the creation of the 'Owner' role.  This is because they are
not being stored via the normal ObjectManager protocols.  If you want this
behavior, you'll need to use Folders w/Customizer support, which let you
use most of DataSkins' dynamic features with "almost ordinary" Zope objects.

BTW - I'm talking about virtual object that totally live in MySQL.

Folders w/Customizer Support require the DataSkins' primary storage to be
in the ZODB.



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] FW: ZPatterns, ObjectDomain, UML and all that.....

2000-12-05 Thread Phillip J. Eby

At 09:44 PM 12/5/00 +0200, Roch'e Compaan wrote:
 If you want to store one DataSkin inside another, where either one of them
 is stored in a Rack, you will have to create appropriate SkinScript or
 custom attribute providers to do so.

But what if I always store dataskins in there own racks but simply assign
an attribute of one 
Dataskin to the instance of another Dataskin?  I simply want to be able to
say 
Customer.Address.Street...


As implied above, you cannot, unless you do so with an appropriate
provider.  Just like ZODB-stored objects, ZPatterns objects cannot function
if you break the rules that govern their behavior.  (E.g. if you change a
mutable value of a ZODB object, it has no way to know it should be saved to
the database.)  This is a "by design" limitation of ZPatterns.  Also, it's
not that bad of a limitation.  You can easily work around it with
SkinScript or an attribute provider, and more commonly, this is done by
delegation to another specialist.

Specifically, rather than breaking encapsulation by having application code
write to an attribute directly, you use a method which delegates to the
foreign specialist, asking it to link or create an associated object.  You
can then still use SkinScript to retrieve your "Address" attribute, again
by delegation to the other Specialist.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] changing/storing Properties with ZPatterns

2000-12-01 Thread Phillip J. Eby

At 10:07 AM 12/1/00 +0100, Joachim Schmitz wrote:

this works fine. Now I wanted to have attributes which I don't want to
display in the form, for example complete attribute. I therefore created
another dataskin propersheet Internal in AZ with a property complete
and tried to set it with:

dtml-call
"ni.propertysheets.Internal.manage_changeProperties(REQUEST,complete='1')"

But I don't manage to store retrieve this attribute.
All attributes in the Basic propertysheet I can store and retrieve.

what is the magic behind this ?


Beats me.  I know that we use a variety of DataSkin propertysheets in our
apps with no problems, although we are not using persistent storage at the
present time.

What happens when you try to store "complete"?  Is it simply not saved, or
do you get some kind of error?  Have you tried other values?  Have you
checked your permissions to ensure your code has rights to change the
"Internal" sheet?


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] OracleStorage, and possibly others

2000-11-30 Thread Phillip J. Eby

At 08:10 AM 11/30/00 -0500, Jim Fulton wrote:

I don't think Data.fs will go away.  I do expect it to be relagated to
initial evaluation and development projects. Use of Berkely DB in

transactional mode requires a significant andminstration commitment.
Log files need to be purged. Backup and recovery processes need to be in 
place.

FWIW, Ty and I talked about using a daemonic thread in BerkeleyStorage to
run periodic checkpoints and purge logfiles.  AFAIK, backups of BerkeleyDB
require only that you make a copy of all the associated files.  Recovery's
a bit trickier, of course.  (We never got around to implementing it because
our tests showed that BerkeleyDB didn't solve the performance issue we were
trying to solve.  So we quit working on it at that point.)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: using PythonMethods from Skinscript

2000-11-30 Thread Phillip J. Eby
At 04:39 PM 11/30/00 +0100, Ulrich Eck wrote: 

I've a db_sequence specialist who serves the Framework with
db_id's for new Records like:


May I suggest calling your Specialist "Sequences" or "Counters" since it appears that it returns objects which produce sequential integer  values?



>>> newid = db_sequence.getItem('sequence_name>').nextid
  
The Attribute nextid is provided by a Skinscript-Method:

WITH getNextId(seq_name=self.id) 
COMPUTE seq_name=seq_name,nextid=_.int(nextid)



I would not suggest using nextid as an attribute.  This should really be a method, e.g. getNextId().  The method should then return the result of calling Counters.getNextId(seq_name=self.id).

However, if you insist on using the above approach, your SkinScript should read:

WITH 
getNextId(seq_name=self.id)
COMPUTE 
nextid=RESULT['nextid'], seq_name=RESULT['seq_name']

Notice that since your Python method returns a dictionary, RESULT is a dictionary, not an object, so you have to retrieve the elements you want in your expressions that way.  Of course, you could just have getNextId() return an integer result, and use:

WITH getNextId(seq_name=self.id) COMPUTE nextid=RESULT
WITH SELF COMPUTE seq_name=id

to achieve the same effects.


  

My Second "little" Problem:


i'm not the first one who had problems to manage data with rdbms and zpatterns. i can get Attributes through SSMethods
easily and now tried to setup ADD/CHANGE/DELETED Rules to manage data.




Here my SSMethod for this(getEventById/insertEvent/updateEvent are ZSQL-Methods):


WITH QUERY getEventById(id=self.id) COMPUTE sid=_.int(id),name,time_start
WHEN OBJECT ADDED CALL insertEvent(id=self.sid)
WHEN OBJECT ADDED,CHANGED STORE sid,name,time_start 
USING  updateEvent(id=self.sid,name=self.name,time_start=self.time_start)
  


I access the Item through loadAttribute: "sid"
I set up a ZClass derived from Dataskin which acts as Storage-Class.
  
I call  
  
dtml-let ni="newItem(key=db.getItem('data_event').nextid)" nips="ni.propertysheets.get('Basic')">
dtml-var "nips.manage_changeProperties(REQUEST=REQUEST)">
/dtml-let>
and get back an empty object without any attributes (propertysheet-problem??)
the record in the database is created (but only because I reduced the ZSQL-Insert Method to id-parm only)
this again seems to be a Problem of the namespace I'm in while the _objectAdded() ... method.


Here's what you're missing.  There is no "sid" attribute when you add an object.  You need to add this to your SkinScript (assuming I'm guessing correctly what sid is supposed to be):

INITIALIZE OBJECT WITH sid=_.int(self.id)

Otherwise, your two ADDED triggers will execute with no value for the sid attribute.



- Do I need a PropertySheet when I only want to access/change/create/delete Items/Attributes from a RDBMS ??
If yes: Which one (CommonInterfaceProp/DataSkinProp)
If no: how do i Access/Change my Properties ??


Yes.  DataSkin Property sheets would be the ones you need to use.



- and another Question related to this:
Which object fires the Trigger-Event (ADDED/CHANGED/DELETED)  ..
is it the PropertySheet itself ???


When you change the attributes of the object, the action is logged for the trigger to fire at transaction commit time.  The Property Sheet is just a way to change the attributes.


___ Zope-Dev maillist  -  [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev **  No cross posts or HTML encoding!  ** (Related lists -  http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] ZPetterns implementation qustions

2000-11-29 Thread Phillip J. Eby

At 06:19 PM 11/29/00 +1100, Itai Tavor wrote:
Hi,

I'm trying to figure out the right way to implement a set of classes 
and roles in ZPatterns. I asked some questions about this a while 
ago, and then went away and did some learning, but I'm stuck again 
and I'm afraid I need to ask more questions.

I have two types of actors - Person (with properties name, phone, 
email, password) and Organization (with properties name, phone, fax, 
business_number).

I also have two participants - Customer and Reseller. Each 
participant can be either a Person or an Organization.

The participants can fill several roles, like OrderingEntities, 
BillableEntities, etc.

Starting from the bottom, I create a Specialist for each role, each 
one with two virtual Racks - customerRack and ResellerRack, so I can 
refer to an OrderingEntity without caring if it's a Reseller or 
Customer.

My problem is in implementing the Participant Specialists and storing 
Participant and Actor classes. Do I create Specialists for the 
Actors? It seems to me that since there is either one Person or one 
Organization per Customer, then the actor object should be created in 
the Customers Specialist. So Customers will have 3 Racks - 
defaultRack (using Customer object), personRack (using Person object) 
and organizationRack (using Organization object). Does this make 
sense?

I think what you want is to have an Actors specialist containing a
personRack and organizationRack.  That 
is, treat "Actor" as a role relative to either Customer or Reseller.

The reason I say, "I think", is because I'm really not clear on why you're
doing certain things here to start with.  See below.


If this is a good way to do it, how do I handle creating and 
accessing the Person and Organization objects? Do I call 
personRack.newItem(newCustomerId) in the script that creates the 
customer? Or do I somehow do it in a SkinScript in defaultRack? And 
how do I get to the Person data? With an attribute provider? Or in 

Here's a red flag: why are you creating a person when you create a
customer?  If a person is something that you only make when you have a
customer, then the actor-participant-transaction pattern isn't really
valid, IMHO.  For Actor-Participant-Transaction to make sense, you have to
have Actors that exist seperate from the Participants.  While it makes
sense to be able to create an Actor at the same time, your model needs to
also include a way to select an *existing* Actor as the Participant,
otherwise you are not gaining anything from the A-P-T pattern and you might
as well just have the Participant.

Here's a pattern for mapping A-P-T interactions onto ZPatterns, however...
If you are doing A-P-T, make sure you use a Specialist for access to the
Actors.  For example, in some applications Ty and I write, "acl_users" is
designated as the Specialist for actors if all actors in the system have to
be able to use the application.  The user interface and implementation for
creating and/or selecting actors to fill a participant role is placed in
the actors' specialist - acl_users in our case, or perhaps a specialist
called "Actors" in yours.  (But I'd recommend you use a domain-specific
name, if possible.)  So you would not be worrying about whether to create a
person or organization or what fields they need or anything else in the
specialist for your "participant" objects.  Indeed, you wouldn't be
worrying about whether a new one was being created, or an old one selected,
if you delegate that aspect of the UI to the actors' Specialist.



Also, if Actors are stored in the Specialists that implement the 
roles they participate as, there is no place to store methods that 
are common to an Actor regardless of role - for example, a method 
that checks if a password is secure enough and called when adding a 
Person object. So I either duplicate these methods in every 
Participant Specialist, or create more Specialists - which seems like 
a waste either way.

Again, this is solved by using a specialist for the role "Actor".


Another problem is how to edit these objects - if I have a form which 
includes fields for a Customer properties and for the properties of 
the Person object linked to that Customer, can I change the Person 
object from the Customer SkinScript? I don't think I can do this:

   WHEN OBJECT CHANGED STORE name, password USING
 
personObject.propertysheets.manage_changeProperties(name=self.name, 
password=self.password)

Right? Because name and password are not properties on the Customer 
DataSkin. So I have to call person.manage_changeProperties(...) in 
the method that changes Customer... it seems to me that I always end 
up doing object connections work in methods and the SkinScript can't 
help with anything :(

You're making this entirely too hard.  The Prime Directive of ZPatterns
design is, "if it looks too complicated in any one place, your design is
probably wrong.  If almost every individual piece looks simple, even though
the whole is 

RE: [Zope-dev] Create Virtual DataSkin

2000-11-27 Thread Phillip J. Eby

At 02:34 PM 11/27/00 -0800, Ben Schochet wrote:
Seems that way Steve.

I have tried to do this in an external method with
self.get_transaction.commit(1) before doing the changeProperties, but that
didn't seem to work. 

You want get_transaction().commit(1), if you're doing it from Python.
DataSkins also have a commitSubtransaction() method that can be used to do
this.


Is there another way to do this? the CHANGE trigger works fine on its own.

How are others creating new items with properties from an HTML FORM?
Should I be doing this another way?

I can't wait to figure out ZPatterns, I think it is the best way to create
Zope applications! It seems to allow you to have the best of Zope objects
along with your data secure and accessible from a RDBMS. (At least that is
the value I see, there are probably others...)


You can't have an ADDED and CHANGED both fire in the same subtransaction.
ADDED, CHANGED, and DELETED are mutually exclusive.  So your ADDED trigger
has to perform the same operations to save data as your change trigger
would.  One easy way to do this is to do:

WHEN OBJECT ADDED ...stuff to do for adding only
WHEN OBJECT ADDED,CHANGED ...stuff to do when changing or adding

Since the triggers are fired in order, and both triggers fire on add, that
should be pretty easy to set up.

Note that in this case, you won't need to commit a subtransaction.
Subtransaction commits are really pretty rarely needed.  About the only
time you should *normally* need a subtransaction commit is that if you have
triggers you want to take effect before you move on, like triggers that
update an index you're about to search.  The normal assumption in Zope
however is that you generally keep your read and write transactions
seperate; i.e. a POST usually results in a redirect to the updated object,
or something of that sort.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Create Virtual DataSkin

2000-11-27 Thread Phillip J. Eby

At 08:34 PM 11/27/00 -0500, [EMAIL PROTECTED] wrote:
Thanks Phillip. Is there a way to pass my REQUEST info to the ADD 
Trigger? 

I am under the impression that only "self" and some other ZPattern 
specific properties are available to the trigger.

You also have access to everything in the acquisition hierarchy of the
trigger or SkinScript method itself, which of course includes REQUEST.  So
either REQUEST (which would look it up in the trigger's acquisition
hierarchy) or self.REQUEST (which would look it up in the DataSkin's
acquisition hierarchy) should work fine.

Now that I've told you *how* to get at it, however, I should warn against
making too much use of the request to get information that
could've/should've been passed to the DataSkin by application or domain
code.  It makes sense to use the request if you want to log things about
the request that caused the change, but it's probably not a good idea to be
looking at form fields and such, since that would introduce an undesirable
coupling between your application structure and your triggers.  Ideally,
triggers should only look to the DataSkin for anything other than methods
or constants they need to carry out their job.  In practice of course, if
you want to do something like log the AUTHENTICATED_USER and whether they
were logged in via SSL, then of course the REQUEST is the right way to do it.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns and ZCLasses

2000-11-22 Thread Phillip J. Eby

At 10:29 AM 11/22/00 +0100, Joachim Schmitz wrote:

I created a FwCS and in it a customizer, but in my list of to customize
object types are only meta_types listed, which have the Base class
"_ZClass_for_DataSkin",. Is this a requirement, and if yes, is there a way
to add this to existing ZClasses ?


It is a requirement.  The only way to add it (or any other base class) to
existing ZClasses is to use the "setbasesholdontoyourbutts" hack, which I
have never done, but a search of the mailing list or Zope site might reveal
the technique.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: Methods of specialits

2000-11-22 Thread Phillip J. Eby

At 12:41 PM 11/22/00 +0200, Roch'e Compaan wrote:
I have a specialist Contacts and for Contacts I have a method
getAllContactsForCustomer.  Whenever I want to call this method I have to
pass on the whole namespace and the object itself to get it to work eg:
getAllContactsForCustomer(this(), _, _.None).  Why is this the case?  And
what does _.None actually mean?


If your method is a DTML method or document, it does not automatically
supply a "self", so currently you must call such methods in a specialist
like this:

Specialist.someDTMLthing(Specialist,_,...)

Where "..." represents any other arguments you wish to pass the method.
(They must be passed as keyword arguments.)

This is a DTML issue, not a ZPatterns one.  Hopefully, in later versions of
Zope, if method binding is standardized across DTML, Python, etc. method
objects, then you will be able to avoid this issue by setting binding
settings on the method object itself.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




RE: [Zope-dev] ZPatterns Project Help!

2000-11-22 Thread Phillip J. Eby

At 10:21 AM 11/22/00 -0500, [EMAIL PROTECTED] wrote:
Thanks for answering Steve.

Unfortunitly I am working with version 0.3 of ZPatterns so I have 
to use GAP. 

When I try to translate your Skinscript into GAP like this 
"attrsexprs:account_object=(RESULT is _.None) and NOT_FOUND or 
RESULT" and I try to access the object's id with dtml-var 
"account_object.id" I get a "NameError" on account_object. 
Alternativly if I do dtml-var account_object I get a "KeyError". 

(BTW. for testing I used "accounts.getItem('1434')" which is a 
valid object. If I do "account_object=RESULT.id" it works fine.)


Perhaps this is a security issue?  When you set account_object=RESULT.id,
then the account_object attribute is a string, and has no security
protection from access by DTML.  When it is an object, however, your DTML
must have permissions to the object itself.  I am not positive, but I think
ZPatterns 0.3 may have executed GAP expressions as the superuser, so it may
be that your GAP is able to access the object, but not the DTML which is
using the DataSkin.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns and ZCLasses

2000-11-21 Thread Phillip J. Eby

At 11:08 AM 11/21/00 +0100, Joachim Schmitz wrote:
I have an existing ZClass/Data Structure like this

RecruitingPlatform
  Company
Recruiting
  Candidates 

  Student
Profiles
  Address
  Highschool
  IT
  Jobprefs
  ...

I want to store the data in the ZClass instances, must each ZClass have the
Base class _ZClass_for_DataSkin and do I need a Rack for each class ?

If you are storing dataskins in a regular folder hierarchy (or other
persistent hierarchy), you don't need racks.  You just need a Folder
w/Customization support in the objects' acquisition hierarchy.  Of course,
if you don't need DataSkin-ish behavior (i.e. triggers and attribute
providers), you don't need the FwCS either.  DataSkins stored outside of
Racks will "pretend" to be ordinary persistent Zope objects if they can't
find an appropriate Customizer.  That is, they act like regular Zope
objects, only it takes them more work because they're pretending.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Folders w/Customizer Support

2000-11-16 Thread Phillip J. Eby

At 02:46 PM 11/16/00 +, Chris Withers wrote:

To put it another way, could you have a FwCS that provided soem
properties and let another FwCS further up the acquisition tree supply
the rest?

Nope.  But there's nothing stopping you from writing a new version of the
"link to parent providers" plug-in that would get providers from a
higher-up FwCS...  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] __replaceable__ or whatever it is ;-)

2000-11-15 Thread Phillip J. Eby

At 11:14 AM 11/15/00 +, Chris Withers wrote:

Thanks... I guess the behavior that was associated with
ObjectManager.NOT_REPLACEABLE is obtained by just not havign a
__replaceable__ attribute?
..or does ObjectManager.NOT_REPLACEABLE exist, just in an undocumented
fashion ;-)

  Also, when is it going to land in a erleased Zoep version? 2.3 I
  guess...
 
 That's the plan.

Bad question, I know, but any idea when that'll be?


FYI, if you want to play with this before then, the current release of the
PlugIns package has support for the proposed behavior in the
PlugInContainer class, using a code snippet cribbed from Zope CVS.  So you
should be able to make PIC subclasses with overrideable methods.  I put in
that support because I wanted Specialists and such to be able to use
overrideable methods.  I haven't gotten around to actually putting any in,
though.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: Remapping object from on to another specialist

2000-11-13 Thread Phillip J. Eby

At 05:51 PM 11/13/00 +0200, Roch'e Compaan wrote:

Should I still set up a rack and set it's storage to the Customer ZClass and
add a skinscript method to copy attributes from the Customer specialist?

   or

Should I simply write a method for Requester, getRequester, which asks the
Customers specialist for a Customer.

Do the former if you need to implement different behavior.  Do the latter
if Customer already provides the needed interface for a requester.  Be
careful, however, that you do not mix the interface of Customer and
Requester, but have clearly defined them seperately (even if both
interfaces may share a method, or one interface is derived from the other.)


Another question:

If I pass an attribute that is not registered with any attributeproviders in
a manage_changeProperties call to the object's propertysheet, will that
attribute automatically be added on top of the object?  Should one
explicitly call manage_addProperty?

Yes, it would be necessary for you to add the property, since Zope security
ordinarily frowns on setting arbitrary object attributes.  :)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Membership and latest LoginManager

2000-11-13 Thread Phillip J. Eby

At 01:37 PM 11/13/00 -0500, Dan L. Pierson wrote:
I've been trying to get Membership 0.7.6 working with
LoginManager-0-8-8b1 (and it's associated ZPatterns) under Zope 2.2.2
on RedHat 6.2.  After probing around it seems that there is a problem
storing member passwords.  The  following trace from print statements
inserted in PersistentUserSource illustrates the problem:


Dan, can you check what class you're using for users, what kind of
propertysheet SystemProperties is on that class (DataSkin or CIPS), and
whether it actually has a "password" property?  Thanks.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Specialists, Racks, and Objects, oh my!

2000-11-13 Thread Phillip J. Eby

At 04:14 PM 11/13/00 -0700, Bill Anderson wrote:

I want a specialist to have two (or more hypotheticaly) racks, and each
rack is to contain one type of object. I then want to be able to add
objects. 

I have the two racks set up, but I am unclear as to how to specify that
I want to add an item of a certain type, or to a certain rack.

Ideas appreciated ...


You can either give your specialist methods to create objects of each type,
which call the respective Racks' newItem() methods, or give your specialist
a single method that determines based on input parameters which class would
be better suited.  The choice depends on the requirements of your problem
domain.

In either case, the specialist is also the natural place to put the UI
("add forms") for creating the objects.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




RE: [Zope-dev] ZPatterns: Non-ZODB storage and Racks

2000-11-09 Thread Phillip J. Eby

At 09:18 AM 11/9/00 +0200, Roch'e Compaan wrote:

I set "loaded by accessing attribute" to the attribute "id".

You should only do that if you want an "infinite rack".  That is, one which
contains all possible objects.  Using "id" means that if the Rack tries to
see if an object exists, it will *always* exist, whether it really exists
or not.  (Because the "id" attribute will always exist.)  Given your
example SkinScript below, you should probably be using "name" as the
attribute to load off of.  Then, the rack will only return an object if it
exists in the SQL database.  (Btw, you should probably be using WITH QUERY
in your SkinScript.)


Storing items
in the RDBMS works fine.  But when I try to retrieve them with
getPersistentItemIDs() nothing is returned?

That's because getPersistentItemIDs() only returns the id's of objects
which are stored in the ZODB.  That method exists only so you have some way
of iterating over objects when you're using the "stored persistently"
storage mode.  It can also be used to find the id's of objects which have
some of their attributes or propertysheets stored persistently.  It is
*not* a "get me everything in the rack" method.


  I have a skinsript method
getCustomer:

WITH getCustomerSQL(CUSTOMER_ID=self.id) COMPUTE id=CUSTOMER_ID, name=NAME

and getCustomerSQL is a SQL method.

If your objects are stored in an SQL database, then to get a list of
objects you need to use an SQL method.

Here is the "recommended approach" for iterating over objects in ZPatterns:

1. Define domain-specific retrieval methods in your specialist.  For
example, "getPastDueToDoItems()" and "getAllToDoItems()".

2. Create methods in your rack(s) which actually implement the retrieval;
these may be named the same, or depending on your application, they may be
smaller chunks of code which you aggregate or pass parameters to, in order
to implement the higher-level functioning.  If a given rack uses ZODB
storage, its implementation methods may use getPersistentItemIDs(), but
they should otherwise be using SQL methods, catalog searches, or other
means of retrieving a list of objects.


3. Have the domain-specific methods call the methods in the racks to
implement the desired behavior, and have *all* other code call the methods
in the Specialist.

The key here is to remember that:

1. A Specialist is a singleton object (i.e. only one instance per app) that
is responsible for dealing with objects of a particular interface.
Specifically, it is responsible for:

 a) Creating objects which supply that interface, according to given criteria

 b) Retrieving objects which supply that interface, given an identifier

 c) Manipulating groups of objects which supply that interface, through a
domain-specific API (e.g. getPastDueItems(), purgeCompletedItems(), etc.)

 d) Providing an application-level UI for all of the above, as/when needed
by the application

 e) Providing UI "snippet" methods to create selectors (e.g. form fields,
dropdowns, etc.) for other objects to use in their UI's, so that they can
relate to or otherwise interact with objects the Specialist is responsible
for.

(Notice, by the way, that this list effectively puts everything that an
application integrator might want to customize all in one place...)

2. Racks are essentially *private objects* belonging to the Specialist to
help it carry out its responsibilities.  Each rack is responsible for
retrieving objects of a *particular class and storage location* which
implement the interface the Specialist serves.  Multiple racks are used
when there is more than one class that implements the interface in the
application.

3. Because Racks belong to the Specialist, it's okay for the Specialist to
"know" things about its racks as a whole (e.g. which ones provide what
concrete classes, what search order to use, how to combine the results of
queries from them, etc.), but it should still delegate the actual
*implementation* of behaviors to them wherever possible. 


If you follow this approach, you will end up with an application whose
functioning is cleanly divided, and any developer familiar with ZPatterns
will know where to call things, and where to go to change implementations.
Further, if that developer needs to change from an SQL database to using
the ZODB, or vice versa, or change from one database schema to another,
they will be able to do so without changing code outside the racks, or at
most, the specialist, and all other application code, including your
classes and ZClasses, will be unaffected by the changes.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: Non-ZODB storage and Racks

2000-11-09 Thread Phillip J. Eby

At 10:45 AM 11/9/00 +0100, Rik Hoekstra wrote:
[rh]I've been following this thread. This may be a bit of a newbie question,
but it's been bugging me for a while. I see how I can store propertysheets
in Racks using ZClasses and Skinscripts, but the propertysheet term suggests
that there should always be an object that the properties are attached to.

Depends on what you mean by "attached".  One of the most annoying things
about Zope propertysheets is that there are two kinds.  ZPatterns
implements one of the kinds (WebDAV sheets), but not the one that most
people have encountered (the kind used in ZClasses).  Although WebDAV
sheets are associated with a particular object, they are objects in
themselves.  ZClass instance sheets are "virtual" and store all their data
in the associated object.

To do ZClass-style sheets in ZPatterns, all you need to do is implement the
attributes; the sheets can take care of themselves.  To do WebDAV-style
sheets in ZPatterns, you need a SheetProvider or you need to simulate
propertysheets using an attribute provider to make an attribute that is
actually another object, and which supports appropriate methods.


Is that an actual ZODB object or is it the Specialist object that can
'create' virtual objects on the fly?

Racks create "virtual" objects when set to "load by accessing attribute ___".


[rh] If I read this right, this suggests that an object stored in a SQL
database and 'masquerades' as a Zope object? Or does an object always have
to exist in the ZODB (with it's own id that corresponds to the id in the RDB
or knows how to retrieve it).
In other words, does the ZPatterns framework need an 'anchor' in the ZODB to
connect it's properties to, or can you create pure virtual objects, that
retrieve all of their properties from a specialist, including the ID.

When set to store objects persistently, "real" Zope objects are made and
stored in the rack.  When set to load via an attribute, the rack creates a
dummy Zope object with its "id" attribute set appropriately, then tries to
access the specified attribute.  If the attribute exists (i.e., an
attribute provider succeeds in loading the data from the external data
source), then the object is considered to "exist" and can be returned.
This would be a "pure virtual object" in your question.


If the last is the case, could someone give an example how to implement it.
A very simple one would suffice I suppose (hope).

Roche's situation is an example, at least if he used the "name" attribute
as the load attribute, rather than the "id" attribute.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns: Non-ZODB storage and Racks

2000-11-08 Thread Phillip J. Eby

At 06:10 PM 11/8/00 +0200, Roch'e Compaan wrote:
In Rack.py I noticed the following:

a = self.loadAttrib
if not a:
slot = self._writeableSlot(key)
slot[SelfKey] = item.aq_base# strip acquisition wrapping
item._setSlot(slot) # Not needed for non-ZODB
storage

If item._setSlot set is not needed for non-ZODB storage should I subclass
rack and override createItem?


I'm not sure I understand your question.  If you don't have something
special you want to do by subclassing Rack, then the answer would be "no".  :)

The comment is perhaps misleading.  What it means is that the _setSlot call
isn't needed if your Rack implements a non-ZODB storage mechanism.  The
reason *why* it isn't needed, is that the DataSkin will ask for a slot on
demand, so that a ZODB record is only created if something needs to be
stored persistently.  However, in the case where you have not set a "load"
attribute (i.e., you are storing actual objects in the ZODB), then one
might as well tell the object its slot, because the slot is where the
object itself is going to be stored.  Technically, the _setSlot call isn't
necessary even then, because the DataSkin could still ask for it on demand.
 However, since the code at this point has gone to the trouble of getting
the slot object, it might as well pass it to the DataSkin immediately.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




[Zope-dev] Re: Problems with LoginManager 0.8.8b1

2000-11-08 Thread Phillip J. Eby

Jeff,

The behavior is exactly the same with a "plain" Zope User Folder.  It also
has nothing to do with acquisition, at least not in the way you think.

The problem is that a user who is defined in a subfolder is *not* granted
roles to any folder above them.  This means that they have no access to
"standard_html_header", unless it is set to be viewable by Anonymous.  Hope
that answers your question.


At 11:50 AM 11/7/00 -0500, Jeff Hoffman wrote:
Phillip and Ty,

I posted this to the Zope list two to three days ago. No one has
responded, so I am writing you directly in the hopes that one of you 
may have some insight on my problem.

If I can do anything to help you narrow it down, such as tarring up
my Zope install and sending it to you (with my ZODB and products),
let me know.

Thanks,

--Jeff

---
Jeff K. Hoffman   704.849.0731 x108
Chief Technology Officer  mailto:[EMAIL PROTECTED]
Going Virtual, L.L.C. http://www.goingv.com/

-- Forwarded message --
Date: Sun, 5 Nov 2000 16:02:14 -0500 (EST)
From: Jeff Hoffman [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Subject: [Zope] Problems with LoginManager 0.8.8b1

Hello,

I am having an odd problem with LoginManager 0.8.8b1 and am writing the
list in the hopes that someone can either help me out, or confirm that
I've encountered a bug.

I am running Zope 2.2.2 with Python 1.5.2 on a Linux box. I installed
LoginManager as described, and compiled DynPersist and so forth for
ZPatterns. All seems to be working well.

I created a temporary folder called 'sandbox', inside of which I
instantiated a LoginManager. In its UserSource (a Generic User Source), I
created four Python Methods (with Python Methods v0.1.7):

  ---
  userAuthenticate
  paramsself, REQUEST, username, password/params

  if username == 'XXX' and password == 'XXX':
return 1
  else:
return 0
  ---
  userExists
  paramsself, REQUEST, username/params

  if username == 'XXX':
return 1
  else:
return 0
  ---
  userDomains
  paramsself, REQUEST, username/params

  return []
  ---
  userRoles
  paramsself, REQUEST, username/params

  if username == 'XXX':
return ['Manager', 'Member']
  else:
return ['Member']

Once done, I pointed my browser to http://myhost/sandbox/index_html. This
method is a standard DTML Method, inluding standard_html_header and footer
and putting some text in the middle.

I get the following error:

Traceback (innermost last):
  File /usr/local/zope/lib/python/ZPublisher/Publish.py, line 222, in
publish_module
  File /usr/local/zope/lib/python/ZPublisher/Publish.py, line 187, in
publish
  File /usr/local/zope/lib/python/Zope/__init__.py, line 221, in
zpublisher_exception_hook
(Object: Traversable)
  File /usr/local/zope/lib/python/ZPublisher/Publish.py, line 171, in
publish
  File /usr/local/zope/lib/python/ZPublisher/mapply.py, line 160, in
mapply
(Object: index_html)
  File /usr/local/zope/lib/python/ZPublisher/Publish.py, line 112, in
call_object
(Object: index_html)
  File /usr/local/zope/lib/python/OFS/DTMLMethod.py, line 172, in __call__
(Object: index_html)
  File /usr/local/zope/lib/python/DocumentTemplate/DT_String.py, line 528,
in __call__
(Object: index_html)
KeyError: standard_html_header

Zope can't find standard_html_header. I am guessing the acquisition path
is getting hosed somewhere along the way. If I simply delete acl_users
from sandbox (my LoginManager), index_html works fine. Moreover, it is not
just standard_html_header that I can't acquire. I created a DTML Method
called foo, and could not acquire it, either.

Any ideas?

--Jeff

---
Jeff K. Hoffman   704.849.0731 x108
Chief Technology Officer  mailto:[EMAIL PROTECTED]
Going Virtual, L.L.C. http://www.goingv.com/


___
Zope maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope
**   No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope-dev )





___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ZPatterns and Properties that are objects

2000-11-07 Thread Phillip J. Eby

At 01:01 PM 11/7/00 +0200, Roch'e Compaan wrote:

I created a couple of ZClasses based on Dataskin.

In the way I grok ZOPE, properties that are objects can not go onto property
sheets.  So if I have a Customer ZClass that has a property Address (a
property that is an object) then I would create the address object as a
"method" of the Customer that makes references like Customer.Address.Street
possible.

The way Ty and I usually handle "object" properties is to give an object
setter methods (e.g. "setAddress()") that simply set the property (e.g.
self.Address = addr).  The only downside is that you have to do this in a
Python base class or an External method.  Later, we expect to replace this
approach with PropertyHandlers, and we already have a primitive form of
PropertyHandler we have used with some success, but it's too crude at this
point for a product release.


To achieve this without ZPatterns I would base my ZClass on a objectmanager
so that I can create an instance of an Address object within Customer.  So
how does one do this with ZPatterns.  In one posting I picked up that one
does not have much joy with ZPatterns and the ObjectManger base class?

I have created ObjectManager and Folder dataskins before and had them work,
but at the time I was testing with Zope 2.1.6, and it was an older version
of ZPatterns.  I haven't done much lately with them.  If people are
experiencing problems, perhaps someone could send me a bug report?


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] DataSkins containing DataSkins

2000-11-07 Thread Phillip J. Eby

At 05:39 PM 11/6/00 -0800, John Eikenberry wrote:

The base DataSkin will be in a Rack. Would there be any issues in making
the embedded DataSkins (contained on the base DataSkins) use this Rack as
well?  Seems like it might result in the confusion about which DataSkin a
PlugIn on the Rack worked with.

Yes, it would, if you persistently stored the DataSkins in the other
DataSkins.  If you use an Attribute Provider, however, that loads them from
a different Specialist+Rack, you'd be fine.


Would it be better to use Customizers in some way... either have the base
Dataskin or perhaps the Specialist also inherit from the Customizer?

Ugh.  Well, you might be able to make the DataSkin a Folder w/Customization
Support...  but I don't know if it would work.  I've never tried mixing a
DataSkin with the classes that support DataSkins.  I think there might be
some horrible method naming conflicts.


Phillip, I think you've considered this (didn't you once mention converting
PropertySheets to DataSkins). What issues do you think I should be aware of
in planning for this.

Doing DataSkin propertysheets would be done by having the propertysheets
come from a different Specialist.

Thing is, if you want to store DataSkins arbitrarily nested within one
another, you can do it in the regular Zope management structure, without
using a Specialist/Rack combo.  On the other hand, if you have a structured
nesting, (e.g. object type A contains some number of object type B), then
you should be using attribute providers/SkinScript to define how those
sub-objects get stored.

To use ZPatterns for its intended purpose, it is critical that you step
back and NOT think in terms of how you'd implement a solution in Zope
without ZPatterns.  In fact, it is important that you not think of
implementation *at all*, because it will distract you from the real
question, which is how to segment the responsibilities of your application.
 Once those responsibilities are segmented, implementation is simply a
matter of writing the necessary methods and SkinScript.

In this case, segmenting according to the RIPP model means that objects are
never truly "contained" in other objects.  An object just gives you ways to
get at related objects.  And if there is a relationship between objects,
that means that the object on the "other end" of the relationship plays
some role in your system, and where there's a role there almost always
needs to be a Specialist.

Now, it may seem that this is needlessly constraining, because it is more
restrictive than Zope.  After all, Zope lets you put anything in anything
-- just like Basic lets you go to any line in the program.  :)  ZPatterns,
however, exists to make interconnectable frameworks possible.  You can
still do the kinds of things Zope can, but you must explicitly think
through your application's role model, and seperate the responsibilities
accordingly.  The payoff of this more rigorous design approach is that your
application can be backed by *anything* that can support the data,
including combinations of different kinds of data stores.  And, your
application will be a potentially re-usable framework.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Questions about implementing object models with ZPatterns

2000-11-07 Thread Phillip J. Eby

At 05:19 PM 11/1/00 +1100, Itai Tavor wrote:

Ok... I think I get the "Specialist per role, not per class" part. 
But I still can't make the jump from a class diagram to a 
ZClass/Specialist setup.

A class diagram contains all the roles - they're the lines between the
classes.  :)

Look at it this way...  if an object has a particular association role that
it needs filled, and there is more than one kind of object that can fill
that role, then presumably those objects must all implement a certain
interface, right?  You need to create a Specialist for that interface.

In other words, there is usually one Specialist per collaboration interface
-- which is NOT a one-to-one mapping with classes, since some classes may
implement multiple interfaces, and some classes may all implement the same
interface.


I can solve some of it by subclassing ZClasses. So, if I need 
Customers and Resellers, I'll make a Specialist for each, and a 
Customer and Reseller ZClasses, both subclassed from Person which 
stores common properties for a person. This part is ok. 

What *role* do Customer and Reseller objects play in your system?  It
sounds to me like perhaps they play the role of "thing that places orders"
or "thing that orders are shipped to".  Depending on your application's
functions, you could need as many as FOUR specialists:

Customers
Resellers
BillableEntities
ShippingDestinations

Where the latter two specialists would contain a pair of Racks that mapped
back to the Customers and Resellers specialists, respectively.


But it gets 
more complex than that. Take this example: Every OrderLineItem object 
can have one or more Payment objects associated with it. There are 3 
possible payment types - Check, Charge and BankDeposit, so I make a 
ZClass for each one, all subclassed from a general Payment ZClass. I 
create one Payments Specialist with 3 Racks. Where do I store methods 
that are specific to one payment type? In the Rack? I can't store 
them in the Specialist - it would be a mess, and I can't store them 
in the ZClass, because the ZClass doesn't know about the rest of the 
application. 

Huh?  What do you mean by "methods that are specific to one payment type"
in this context?  What do payments do that requires knowledge of the rest
of the application?  If it's a problem-domain method, it belongs in the
ZClass.


Actually, writing this down makes me realize that it 
could work... would Payments.getItem(some_payment_id).someMethod() 
call someMethod in the Rack if one exists, and the one in the 
Specialist if not?

No.  DataSkins acquire only from the Specialist, not the Rack.  However,
you can use ClassExtenders in the Rack to provide methods to an object.
But you *can't* override methods that already exist on the ZClass.  This
should not ordinarily be an issue since you should only be doing problem
domain methods on your ZClasses anyway, and there should be no need to
override them.


Another problem I'm having is how to store id's for different objects 
in the the same field. In the Payments example above this is not a 
problem, because all payments are supplied by the Payments 
specialist. But what about another example - Customers and Resellers 
are two totally different roles, so they each get a Specialist. the 
Payment object has from_id and to_id fields, and each of those can 
hold the id of a customer or reseller, or some special code to 
indicate the store. I could add from_type and to_type fields, or I 
could prefix the id with a code letter, but neither seem like a good 
solution. Is there a recommended approach for solving this problem?

See above, where I mention BillableEntities and ShippingDestinations.
Having only one specialist per role means that you never have to worry
about ambiguous identities.

Please note, however, that at this stage of design you shouldn't be looking
at how the references are going to be stored.  At the abstract design
stage, you would just have "Payor" and "Payee" attributes that are the
actual related objects.  When you write your SkinScript later, you can set
up how the linkages work, using ID fields, or SQL columns, or whatever.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




  1   2   3   >