[TransWarp] First attempt to use the storage package in PEAK

Roch'e Compaan roche at upfrontsystems.co.za
Tue Dec 24 21:46:37 EST 2002


Thanks Philip

Best wishes to you and the rest of the people on the list. PEAK is my
toy under the tree this Christmas and it's giving me endless pleasure
although I suspect that the family will tear me away from it soon :-)

> class Contact(model.Element):
> 
>      class Name(model.Field):
>          referencedType = String
> 
>      class Surname(model.Field):
>          referencedType = String
> 
>      #etc...
> 
> But it isn't actually necessary for you to do all that; if you don't care 
> about any of the special capabilities provided by 'peak.model' bases and 
> metaclassses, you can just subclass Persistence.Persistent and be done with 
> it.

I suspect that I will want what 'peak.model' provides in the long run
although I haven't spent enough time with it to appreciate what it can
do for me now. One requirement I have for my domain classes is that
properties on them are easily discoverable which should help a lot when
writing validators to validate user input etc. It seems that subclassing
attributes from model.Field can help with this.

> 
> Also, 'peak.model' has a significant refactoring pending, and it's not well 
> documented.  For the time being, you may not want to bother with it.  But 
> if you want examples of its use, look at:
> 
> peak.metamodels.MOF131,
> peak.metamodels.uml.MetaModel, and
> peak.metamodels.uml.Model
> 
> More or less in that order, with the caveat that MOF131 is untested and 
> might contain errors, or that it might have code that depends on 
> refactorings in 'peak.model' that haven't actually been done yet.  :)

For now I am happy with what peak.storage and peak.naming has given me
but I am very curious to see how PEAK can convert a UML model to code and
vica verca.

> >class ContactDM(storage.EntityDM):
> >
> >    defaultClass = Contact
> >
> >    attrs = ['Name', 'Surname', 'HomePhone', 'WorkPhone', 'Email']
> >
> >    DBConn = binding.bindTo(storage.ISQLConnection)
> 
> Replace the line above with:
> 
>      DBConn = binding.bindTo("mysql://roche:mypasswd@localhost/Contacts")
> 
> This suffices to instantiate a MySQLConnection.  You also don't need to 
> import MySQLConnection.  This is one of the things that the naming system 
> is for.  :)

Now I can appreciate what peak.naming is for. This is great!

> 
> 
> >    def defaultState(self, ob):
> >        state = {}
> >        for attr in self.attrs:
> >            state[attr] = ''
> >        return state
> >
> >    def load(self, oid, ob):
> >        print "load"
> >        result = self.DBConn('SELECT * FROM Contact WHERE oid=%s'%oid)
> >        state = {}
> >        for r in result:
> >            for attr in self.attrs:
> >                value = getattr(r, attr)
> >                state[attr] = value
> >        return state
> 
> Another way to specify the above is:
> 
> def load(self, oid, ob):
>     return dict(
>         (~self.DBConn('SELECT * FROM Contact WHERE oid=%s' % oid)).items()
>     )
> 
> Two things are happening here...  first the '~' means you want exactly one 
> row from the result.

Yes I wanted to know what that '~' is for.  Is this some form of
operator overloading?  Where in the source does this happen?

> ># Retrieve and modify existing instance with oid=1
> >storage.begin(ContactDM)
> >ni = myDM.preloadState(1)
> 
> storage.begin(mYDM)
> ni = myDM[1]
> 
> The "preloadState()" method is not for this purpose.  Use __getitem__ to 
> retrieve objects.  'preloadState()' is for collaboration with query 
> DMs.  

I read your post on the design back in June and then realised I should
use __getitem__.

Thanks for your comments and help and have a great Christmas.

-- 
Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za



More information about the PEAK mailing list