[Zope-CVS] CVS: Products/AdaptableStorage/serial - AspectEvent.py:1.1 FieldSchema.py:1.1 MapperEvent.py:1.1 DeserializationEvent.py:1.4 ObjectGateway.py:1.6 ObjectMapper.py:1.3 ObjectSerializer.py:1.4 SerializationEvent.py:1.5 public.py:1.3 EventBase.py:NONE RecordSchema.py:NONE

Shane Hathaway shane@zope.com
Mon, 9 Dec 2002 13:25:59 -0500


Update of /cvs-repository/Products/AdaptableStorage/serial
In directory cvs.zope.org:/tmp/cvs-serv24698/serial

Modified Files:
	DeserializationEvent.py ObjectGateway.py ObjectMapper.py 
	ObjectSerializer.py SerializationEvent.py public.py 
Added Files:
	AspectEvent.py FieldSchema.py MapperEvent.py 
Removed Files:
	EventBase.py RecordSchema.py 
Log Message:
More sanitization and documentation:

- Renamed RecordSchema to FieldSchema and made the simpler schema classes
  usable.  This removed the need to always work with record sets when all
  that is needed is a single value.

- Finally successfully abstracted away keychain generation.  Now gateways
  and serializers don't have to duplicate logic.

- Renamed IEventBase to IMapperEvent, created a derivative IAspectEvent, and
  moved some of the methods of IMapperEvent to IAspectEvent.
  ISerializationEvent and IDeserializationEvent now derive from IAspectEvent.

- Changed IGateways to expect IMapperEvents instead of a (mapper, keychain)
  pair.



=== Added File Products/AdaptableStorage/serial/AspectEvent.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Aspect-related event base.

$Id: AspectEvent.py,v 1.1 2002/12/09 18:25:27 shane Exp $
"""

from interfaces.public import IAspectEvent
from MapperEvent import MapperEvent


class AspectEvent (MapperEvent):

    __implements__ = IAspectEvent

    _aspect_name = ''

    def __init__(self, keyed_ob_sys, object_mapper, keychain, object):
        MapperEvent.__init__(self, object_mapper, keychain)
        self._keyed_ob_sys = keyed_ob_sys
        self._object = object

    def getKeyedObjectSystem(self):
        """Returns the IKeyedObjectSystem that generated this event.

        It is needed for loading and identifying other objects.
        """
        return self._keyed_ob_sys

    def setAspectName(self, name):
        """Sets the name of the aspect being (de)serialized."""
        self._aspect_name = name

    def getAspectName(self):
        """Returns the name of the aspect being (de)serialized."""
        return self._aspect_name

    def getObject(self):
        """Returns the object being serialized."""
        return self._object



=== Added File Products/AdaptableStorage/serial/FieldSchema.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Row-oriented schema definitions

$Id: FieldSchema.py,v 1.1 2002/12/09 18:25:27 shane Exp $
"""

from interfaces.public import ISchema

# ok_types just constrains the possible types until we figure out
# what we really want to do here.
ok_types = ('unicode', 'string', 'int', 'float', 'bool', 'object',
            'classification', 'keychain')


class FieldSchema:
    """Defines the schema of one field."""
    __implements__ = ISchema

    def __init__(self, name, type='string', unique=0):
        assert type in ok_types, type
        self.name = name
        self.type = type
        self.unique = not not unique

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            if (other.name == self.name) and (other.type == self.type) and (
                other.unique == self.unique):
                return 1  # Same
        return 0  # Different


class RowSchema:
    """Defines an ordered set of fields for exactly one row.
    """
    __implements__ = ISchema

    def __init__(self, fields=()):
        self.fields = []
        self.field_names = {}
        for c in fields:
            self._add(c)

    def _add(self, c):
        if self.field_names.has_key(c.name):
            raise KeyError, 'Duplicate field name: %s' % c.name
        self.field_names[c.name] = 1
        self.fields.append(c)

    def addField(self, name, type='string', unique=0):
        self._add(FieldSchema(name, type, unique))

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            if (self.fields == other.fields):
                return 1  # Same
        return 0  # Different


class RowSequenceSchema (RowSchema):
    """Defines a schema for a sequence of rows, including row count limits.
    """
    __implements__ = ISchema

    def __init__(self, fields=(), min_rows=0, max_rows=0):
        # max_rows == 0 means unlimited.
        assert (max_rows == 0 or max_rows >= min_rows)
        RowSchema.__init__(self, fields)
        self.min_rows = min_rows
        self.max_rows = max_rows

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            if (self.fields == other.fields) and (
                self.min_rows == other.min_rows) and (
                self.max_rows == other.max_rows):
                return 1  # Same
        return 0  # Different



=== Added File Products/AdaptableStorage/serial/MapperEvent.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Mapper event base.

$Id: MapperEvent.py,v 1.1 2002/12/09 18:25:27 shane Exp $
"""

from interfaces.public import IMapperEvent

class MapperEvent:

    __implements__ = IMapperEvent

    _aspect_name = ''

    def __init__(self, object_mapper, keychain):
        self._object_mapper = object_mapper
        self._keychain = keychain

    def getObjectMapper(self):
        """Returns the object mapper for the object being (de)serialized."""
        return self._object_mapper

    def getKeychain(self):
        """Returns the keychain of the object being (de)serialized."""
        return self._keychain

    def makeKeychain(self, name, stored):
        kcg = self.getObjectMapper().getKeychainGenerator()
        return kcg.makeKeychain(self, name, stored)



=== Products/AdaptableStorage/serial/DeserializationEvent.py 1.3 => 1.4 ===
--- Products/AdaptableStorage/serial/DeserializationEvent.py:1.3	Sat Dec  7 00:59:13 2002
+++ Products/AdaptableStorage/serial/DeserializationEvent.py	Mon Dec  9 13:25:27 2002
@@ -19,15 +19,16 @@
 
 from interfaces.public import IFullDeserializationEvent
 
-from EventBase import EventBase
+from AspectEvent import AspectEvent
 
 
-class DeserializationEvent (EventBase):
+class DeserializationEvent (AspectEvent):
 
     __implements__ = IFullDeserializationEvent
 
-    def __init__(self, object_mapper, keychain, object, keyed_ob_sys):
-        EventBase.__init__(self, object_mapper, keychain, object, keyed_ob_sys)
+    def __init__(self, keyed_ob_sys, object_mapper, keychain, object):
+        AspectEvent.__init__(
+            self, keyed_ob_sys, object_mapper, keychain, object)
         self._loaded_refs = {}  # { (aspect_name, name) -> object }
 
     # IDeserializationEvent interface methods:


=== Products/AdaptableStorage/serial/ObjectGateway.py 1.5 => 1.6 ===
--- Products/AdaptableStorage/serial/ObjectGateway.py:1.5	Mon Dec  9 10:57:23 2002
+++ Products/AdaptableStorage/serial/ObjectGateway.py	Mon Dec  9 13:25:27 2002
@@ -43,7 +43,7 @@
                 res[name] = s
         return res
 
-    def load(self, object_mapper, keychain):
+    def load(self, event):
         """Loads data.
 
         Returns a pair containing the data and an object
@@ -54,7 +54,7 @@
         full_state = {}
         serials = {}
         for name, gw in self._gws.items():
-            state, serial = gw.load(object_mapper, keychain)
+            state, serial = gw.load(event)
             if state is not None:
                 full_state[name] = state
                 if serial is not None:
@@ -63,7 +63,7 @@
         serials.sort()
         return full_state, tuple(serials)
 
-    def store(self, object_mapper, keychain, full_state):
+    def store(self, event, full_state):
         """Stores data.
 
         Returns a new serial.
@@ -72,7 +72,7 @@
         for name, gw in self._gws.items():
             state = full_state.get(name)
             # print 'gateway storing', keychain, name, state
-            serial = gw.store(object_mapper, keychain, state)
+            serial = gw.store(event, state)
             if serial is not None:
                 serials[name] = serial
         serials = serials.items()


=== Products/AdaptableStorage/serial/ObjectMapper.py 1.2 => 1.3 ===
--- Products/AdaptableStorage/serial/ObjectMapper.py:1.2	Fri Dec  6 17:06:50 2002
+++ Products/AdaptableStorage/serial/ObjectMapper.py	Mon Dec  9 13:25:27 2002
@@ -24,7 +24,7 @@
     __implements__ = IObjectMapper
 
     def __init__(self, parent, serializer, gateway,
-                 classifier=None, volatile=None):
+                 classifier=None, kgen=None, volatile=None):
         assert serializer.getSchema() == gateway.getSchema(), (
             serializer.getSchema(), gateway.getSchema())
         self._sub_mappers = {}
@@ -32,6 +32,7 @@
         self._serializer = serializer
         self._gateway = gateway
         self._classifier = classifier
+        self._kgen = kgen
         self._volatile = volatile
 
     def addSubMapper(self, name, m):
@@ -51,6 +52,13 @@
             return self._classifier
         if self._parent is not None:
             return self._parent.getClassifier()
+        return None
+
+    def getKeychainGenerator(self):
+        if self._kgen is not None:
+            return self._kgen
+        if self._parent is not None:
+            return self._parent.getKeychainGenerator()
         return None
 
     def isVolatile(self):


=== Products/AdaptableStorage/serial/ObjectSerializer.py 1.3 => 1.4 ===
--- Products/AdaptableStorage/serial/ObjectSerializer.py:1.3	Mon Dec  9 10:57:23 2002
+++ Products/AdaptableStorage/serial/ObjectSerializer.py	Mon Dec  9 13:25:27 2002
@@ -47,9 +47,9 @@
         c = object.__class__
         return (c.__module__ == self._module and c.__name__ == self._name)
 
-    def serialize(self, object_mapper, keychain, object, keyed_ob_sys):
-        event = SerializationEvent(object_mapper, keychain,
-                                   object, keyed_ob_sys)
+    def serialize(self, keyed_ob_sys, object_mapper, keychain, object):
+        event = SerializationEvent(
+            keyed_ob_sys, object_mapper, keychain, object)
         full_state = {}
         for name, aspect in self._aspects:
             event.setAspectName(name)
@@ -58,10 +58,10 @@
                 full_state[name] = state
         return full_state, event.getExternalRefs()
 
-    def deserialize(self, object_mapper, keychain, object, keyed_ob_sys,
+    def deserialize(self, keyed_ob_sys, object_mapper, keychain, object,
                     full_state):
         event = DeserializationEvent(
-            object_mapper, keychain, object, keyed_ob_sys)
+            keyed_ob_sys, object_mapper, keychain, object)
         for name, aspect in self._aspects:
             state = full_state.get(name)
             event.setAspectName(name)


=== Products/AdaptableStorage/serial/SerializationEvent.py 1.4 => 1.5 ===
--- Products/AdaptableStorage/serial/SerializationEvent.py:1.4	Mon Dec  9 10:57:23 2002
+++ Products/AdaptableStorage/serial/SerializationEvent.py	Mon Dec  9 13:25:27 2002
@@ -20,15 +20,16 @@
 
 from interfaces.public import IFullSerializationEvent
 
-from EventBase import EventBase
+from AspectEvent import AspectEvent
 
 
-class SerializationEvent (EventBase):
+class SerializationEvent (AspectEvent):
 
     __implements__ = IFullSerializationEvent
 
-    def __init__(self, object_mapper, keychain, object, keyed_ob_sys):
-        EventBase.__init__(self, object_mapper, keychain, object, keyed_ob_sys)
+    def __init__(self, keyed_ob_sys, object_mapper, keychain, object):
+        AspectEvent.__init__(
+            self, keyed_ob_sys, object_mapper, keychain, object)
         self._attrs = {}
 
         # _refs is the list of externally referenced objects.


=== Products/AdaptableStorage/serial/public.py 1.2 => 1.3 ===
--- Products/AdaptableStorage/serial/public.py:1.2	Mon Dec  9 10:57:23 2002
+++ Products/AdaptableStorage/serial/public.py	Mon Dec  9 13:25:27 2002
@@ -20,10 +20,10 @@
 from exceptions import *
 
 from DeserializationEvent import DeserializationEvent
-from EventBase import EventBase
+from MapperEvent import MapperEvent
 from ObjectGateway import ObjectGateway
 from ObjectMapper import ObjectMapper
 from ObjectSerializer import ObjectSerializer
-from RecordSchema import RecordSchema
+from FieldSchema import FieldSchema, RowSchema, RowSequenceSchema
 from SerializationEvent import SerializationEvent
 

=== Removed File Products/AdaptableStorage/serial/EventBase.py ===

=== Removed File Products/AdaptableStorage/serial/RecordSchema.py ===