Exemplo n.º 1
0
class Parent(Serializable):
    db_table = test_parent_tab
    db_mapping = {'_id':'id',
                  'data':'data',
                  'child1':Relation(Child1, 'child1_rel', lazy=False,
                                    cascading_delete=True),
                  'child2':Relation(Child2, 'child2_rel', lazy=True,
                                    cascading_delete=False)
                  }

    def __init__(self, data=None, child1=None, child2=None):
        self.data = data
        self.child1 = child1
        self.child2 = child2

    def setChild1(self, value):
        self._child1 = value

    def getChild1(self):
        return self._child1

    child1 = db_property(getChild1, setChild1, attr='_child1')

    def setChild2(self, value):
        self._child2 = value

    def getChild2(self):
        return self._child2

    child2 = db_property(getChild2, setChild2, attr='_child2')
Exemplo n.º 2
0
class Child2(Serializable):
    db_table = test_child2_tab
    db_mapping = {'_id':'id',
                  'data':'data',
                  'grandchild':Relation(GrandChild, 'grandchild_rel',
                                        lazy=False,
                                        cascading_delete=False),
                  'lego':Relation(LegoBrick, 'owner2_rel',
                                  lazy=False,
                                  relation_type='to-many',
                                  cascading_delete=True)
                  }

    def __init__(self, data=None, grandchild=None, lego=None):
        self.data = data
        self.grandchild = grandchild
        self.lego = lego

    def setData(self, value):
        self._data = value

    def getData(self):
        return self._data

    data = db_property(getData, setData, attr='_data')
Exemplo n.º 3
0
class KeyIndexElement(Serializable):
    """
    Base class for all indexes.
    """
    db_mapping = {
        '_id': 'id',
        'index': Relation(XmlIndex, 'index_id'),
        'key': 'keyval',
        'group_pos': 'group_pos',
        'document': Relation(XmlDocument, 'document_id')
    }

    def __init__(self, index=None, key=None, document=None, group_pos=None):
        self.index = index
        if key:
            self.key = self._filter_key(key)
        else:
            self.key = None
        self.document = document
        self.group_pos = group_pos

    def _filter_key(self, data):
        """
        Overwrite to do a type specific key handling.
        """
        return data

    def _prepare_key(self, data):
        return str(data)

    def getIndex(self):
        return self._index

    def setIndex(self, data):
        self._index = data

    index = db_property(getIndex, setIndex, "Index", attr='_index')

    def getDocument(self):
        return self._document

    def setDocument(self, data):
        self._document = data

    document = db_property(getDocument,
                           setDocument,
                           "XmlDocument",
                           attr='_document')

    def getKey(self):
        return self._key

    def setKey(self, data):
        self._key = data

    key = property(getKey, setKey, "Index key")
Exemplo n.º 4
0
class GrandChild(Serializable):
    db_table = test_grandchild_tab
    db_mapping = {'_id':'id',
                  'data':'data',
                  'lego':Relation(LegoBrick, 'owner_rel', lazy=False,
                                  relation_type='to-many',
                                  cascading_delete=True)
                  }

    def __init__(self, data=None, lego=None):
        self.data = data
        self.lego = lego
Exemplo n.º 5
0
class XmlDocument(Serializable):
    """
    Auto-parsing XML resource.

    Given xml data gets validated and parsed on resource creation.
    """

    implements(IXmlDocument)

    db_table = document_tab
    db_mapping = {
        '_id': 'id',
        'revision': 'revision',
        'data': LazyAttribute('data'),
        'meta': Relation(DocumentMeta, 'id', cascading_delete=True, lazy=False)
    }

    def __init__(self, data=None, revision=None, uid=None):  #@UnusedVariable
        self._xml_doc = None
        self.meta = DocumentMeta(uid=uid)
        self.data = data
        # self.datetime = None
        Serializable.__init__(self)

    def setData(self, data):
        """set data, convert to unicode and remove XML declaration"""
        if not data or data == "":
            self._data = None
            return
        if not isinstance(data, unicode):
            raise TypeError("Data has to be unicode!")
        # encode "utf-8" to determine hash and size
        raw_data = data.encode("utf-8")
        self._data = data
        self.meta._size = len(raw_data) + XML_DECLARATION_LENGTH
        self.meta._hash = hash(raw_data)

    def getData(self):
        """Returns data as unicode object."""
        data = self._data
        assert not data or isinstance(data, unicode)
        return data

    data = db_property(getData,
                       setData,
                       'Raw xml data as a string',
                       attr='_data')

    def getXml_doc(self):
        if not self._xml_doc:
            self._xml_doc = self._validateXml_data(self.data)
        return self._xml_doc

    def setXml_doc(self, xml_doc):
        if not IXmlDoc.providedBy(xml_doc):
            raise TypeError("%s is not an IXmlDoc" % str(xml_doc))
        self._xml_doc = xml_doc

    xml_doc = property(getXml_doc, setXml_doc, 'Parsed xml document (IXmlDoc)')

    def getMeta(self):
        return self._meta

    def setMeta(self, meta):
        if meta and not IDocumentMeta.providedBy(meta):
            raise TypeError("%s is not an IDocumentMeta" % str(meta))
        self._meta = meta

    meta = db_property(getMeta, setMeta, "Document metadata", attr='_meta')

    def getRevision(self):
        return self._revision

    def setRevision(self, revision):
        self._revision = revision

    revision = property(getRevision, setRevision, "Document revision")

    def _validateXml_data(self, value):
        return self._parseXml_data(value)

    def _parseXml_data(self, xml_data):
        # encode before handing it to parser:
        # xml_data = xml_data.encode("utf-8")
        return XmlTreeDoc(xml_data=xml_data, blocking=True)
Exemplo n.º 6
0
class Resource(Serializable):

    implements(IResource)

    db_table = resource_tab
    db_mapping = {
        '_id':
        'id',  # external id
        'resourcetype':
        Relation(ResourceTypeWrapper, 'resourcetype_id', lazy=False),
        'name':
        'name',
        'document':
        Relation(XmlDocument,
                 'resource_id',
                 lazy=False,
                 relation_type='to-many',
                 cascading_delete=True),
    }

    def __init__(self,
                 resourcetype=ResourceTypeWrapper(),
                 id=None,
                 document=None,
                 name=None):
        self.document = document
        self._id = id
        self.resourcetype = resourcetype
        self.name = name

    def __str__(self):
        return "/%s/%s/%s" % (self.package.package_id,
                              self.resourcetype.resourcetype_id, str(
                                  self.name))

    def getId(self):
        return self._getId()

    def setId(self, id):
        return self._setId(id)

    id = property(getId, setId, "Unique resource id (integer)")

    def getResourceType(self):
        return self._resourcetype

    def setResourceType(self, data):
        self._resourcetype = data

    resourcetype = db_property(getResourceType,
                               setResourceType,
                               "Resource type",
                               attr='_resourcetype')

    def getPackage(self):
        return self.resourcetype.package

    def setPackage(self, data):
        pass

    package = property(getPackage, setPackage, "Package")

    def getDocument(self):
        # return document as a list only if multiple revisions are present
        if len(self._document) == 1:
            return self._document[0]
        else:
            return self._document

    def setDocument(self, data):
        if not isinstance(data, list):
            data = [data]
        self._document = data

    document = db_property(getDocument,
                           setDocument,
                           "xml document",
                           attr='_document')

    def getName(self):
        if not self._name:
            return self.id
        return self._name

    def setName(self, data):
        try:
            data = validate_id(data)
        except ValueError:
            msg = "Invalid resource name: %s"
            raise InvalidParameterError(msg % str(data))
        self._name = data

    name = property(getName, setName, "Alphanumeric name (optional)")
Exemplo n.º 7
0
class XmlIndex(Serializable):
    """
    A XML index.

    @param resourcetype: ResourcetypeWrapper instance
    @param xpath: path to node in XML tree to be indexed, or any arbitrary
    xpath expression, that returns a value of correct type
    @param type: TEXT_INDEX | NUMERIC_INDEX | DATETIME_INDEX | BOOLEAN_INDEX |
                 DATE_INDEX | FLOAT_INDEX | INTEGER_INDEX | TIMESTAMP_INDEX
    @param options: additional options for an index

    Note:
    DATETIME_INDEX: options may be a format string (see time.strftime()
    documentation), but note that strftime / strptime does not support
    microseconds! Without a format string we assume a ISO 8601 string.
    """

    implements(IXmlIndex)

    db_table = defaults.index_def_tab
    db_mapping = {
        'resourcetype': Relation(ResourceTypeWrapper,
                                 'resourcetype_id',
                                 lazy=True),
        'xpath': 'xpath',
        'group_path': 'group_path',
        'type': 'type',
        'options': 'options',
        'label': 'label',
        '_id': 'id'
    }

    def __init__(self,
                 resourcetype=None,
                 xpath=None,
                 type=TEXT_INDEX,
                 options=None,
                 group_path=None,
                 label=None):
        self.resourcetype = resourcetype
        self.xpath = xpath
        self.type = type
        self.options = options
        self.group_path = group_path
        self.relative_xpath = None
        self.label = label

    def __str__(self):
        return '/' + self.resourcetype.package.package_id + '/' + \
                self.resourcetype.resourcetype_id + self.xpath

    def getPackage_id(self):
        return self.resourcetype.package.package_id

    package_id = property(getPackage_id)

    def getResourcetype_id(self):
        return self.resourcetype.resourcetype_id

    resourcetype_id = property(getResourcetype_id)

    def getResourceType(self):
        return self._resourcetype

    def setResourceType(self, data):
        self._resourcetype = data

    resourcetype = db_property(getResourceType,
                               setResourceType,
                               "Resource type",
                               attr='_resourcetype')

    def getXPath(self):
        return self._xpath

    def setXPath(self, xpath):
        self._xpath = xpath

    xpath = property(getXPath, setXPath, "XPath expression")

    def getType(self):
        return self._type

    def setType(self, type):
        self._type = type

    type = property(getType, setType, "Data type")

    def getOptions(self):
        return self._options

    def setOptions(self, options):
        self._options = options

    options = property(getOptions, setOptions, "Options")

    def getRelative_xpath(self):
        if self.group_path and not self._relative_xpath:
            self._relative_xpath = self.xpath[len(self.group_path) + 1:]
        return self._relative_xpath

    def setRelative_xpath(self, data):
        self._relative_xpath = data

    relative_xpath = property(getRelative_xpath, setRelative_xpath,
                              "relative xpath")

    def _getElementCls(self):
        """
        Return the correct index element class, according to index type.
        """
        if self.type == PROCESSOR_INDEX:
            return type_classes[self._getProcessorIndex().type]
        return type_classes[self.type]

    def _getProcessorIndex(self):
        if hasattr(self, '_processor_idx'):
            return self._processor_idx
        # import the IProcessorIndex implementer class for this index
        pos = self.options.rfind(u".")
        class_name = self.options[pos + 1:]
        mod_name = self.options[:pos]
        mod = sys.modules[mod_name]
        cls = getattr(mod, class_name)
        # self._processor_idx = cls(env)
        self._processor_idx = cls
        return cls

    def _eval(self, xml_doc):
        if not IXmlDocument.providedBy(xml_doc):
            raise TypeError("%s is not an IXmlDocument." % str(xml_doc))
        parsed_doc = xml_doc.getXml_doc()
        try:
            if self.group_path:
                nodes = parsed_doc.evalXPath(self.group_path)
                return [
                    node.evalXPath(self.relative_xpath) or [None]
                    for node in nodes
                ]
            return [parsed_doc.evalXPath(self.xpath) or [None]]
        except Exception, e:
            log.err(e)
            return list()
Exemplo n.º 8
0
class ResourceTypeWrapper(Serializable):
    """Wrapped around resource types for storage in database."""

    db_table = resourcetypes_tab
    db_mapping = {'resourcetype_id':'name',
                  'package':Relation(PackageWrapper, 'package_id',
                                     lazy=False),
                  'version':'version',
                  'version_control':'version_control',
                  '_id':'id'
                  }

    def __init__(self, resourcetype_id=None, package=PackageWrapper(),
                 version='', version_control=False):
        self.resourcetype_id = resourcetype_id
        self.package = package
        self.version = version
        self.version_control = version_control

    def __str__(self):
        return str(self.package.package_id) + '/' + \
               str(self.resourcetype_id) + '/' + self.version

    def setResourcetype_id(self, id):
        self._resourcetype_id = validate_id(id)

    def getResourcetype_id(self):
        return self._resourcetype_id

    resourcetype_id = property(getResourcetype_id, setResourcetype_id,
                               "unique package id (string)")

    def getPackage(self):
        return self._package

    def setPackage(self, package):
        self._package = package

    package = db_property(getPackage, setPackage, "Package",
                           attr='_package')

    def setVersion(self, version):
        version = version or ''
        if not isinstance(version, basestring):
            raise TypeError("Version must be a string.")
        self._version = version

    def getVersion(self):
        return self._version

    version = property(getVersion, setVersion, 'version of package')

    def setVersion_control(self, value):
        if not isinstance(value, bool):
            raise TypeError("Version_control must be boolean.")
        self._version_control = value

    def getVersion_control(self):
        return self._version_control

    version_control = property(getVersion_control, setVersion_control,
                            'Boolean indicating if version control is enabled')
Exemplo n.º 9
0
class DocBase(Serializable):
    db_mapping = {'resourcetype':Relation(ResourceTypeWrapper,
                                          'resourcetype_id'),
                  'package':Relation(PackageWrapper,
                                     'package_id'),
                  'type':'type',
                  'document_id':'document_id'
                  }

    def __init__(self, package=PackageWrapper(),
                 resourcetype=ResourceTypeWrapper(),
                 type=None, document_id=None):
        super(Serializable, self).__init__()
        self.package = package
        self.resourcetype = resourcetype
        self.type = type
        self.document_id = document_id

    def __str__(self):
        return to_uri(self.package.package_id,
                      self.resourcetype.resourcetype_id) + '/' + self.type

    def getResourceType(self):
        return self._resourcetype

    def setResourceType(self, data):
        self._resourcetype = data

    resourcetype = db_property(getResourceType, setResourceType,
                               "Resource type", attr='_resourcetype')

    def getPackage(self):
        return self._package

    def setPackage(self, data):
        self._package = data

    package = db_property(getPackage, setPackage, "Package", attr='_package')

    def getDocument_id(self):
        return self._document_id

    def setDocument_id(self, data):
        self._document_id = data

    document_id = property(getDocument_id, setDocument_id,
                           "Unique document identifier (integer)")

    def getType(self):
        return self._type

    def setType(self, data):
        self._type = validate_id(data)

    type = property(getType, setType, "Type")

    def getResource(self):
        # lazy resource retrieval: to avoid getting all resources in the registry
        # on every query, resources are retrieved only if really needed (and 
        # accessed via schema.resource
        if hasattr(self, '_resource'):
            return self._resource
        if not hasattr(self, '_catalog'):
            return None
        r = self._catalog.xmldb.getResource(document_id=self.document_id)
        self._resource = r
        return r

    resource = property(getResource, doc="XmlResource (read only)")