def type(self, value): if 'types' in self._references: for t in self._references['types']: if t.recognizes(value): return t else: return TypeHandler.typeHandler(self.itsView, value) return None
def _type(self, record, flags, item, value, verify, withSchema, attrType): if attrType is None: if verify: attrType = TypeHandler.typeHandler(item.itsView, value) typeId = attrType.itsUUID else: typeId = None elif attrType.isAlias(): if verify: aliasType = attrType.type(value) if aliasType is None: raise TypeError, "%s does not alias type of value '%s' of type %s" % ( attrType.itsPath, value, type(value), ) attrType = aliasType typeId = attrType.itsUUID else: typeId = None else: if verify and not attrType.recognizes(value): raise TypeError, "value '%s' of type %s is not recognized by type %s" % ( value, type(value), attrType.itsPath, ) if withSchema: typeId = attrType.itsUUID else: typeId = None if flags & DBItemWriter.SINGLE and attrType is not None and attrType.getFlags() & CAttribute.SIMPLE: flags |= DBItemWriter.SIMPLE record += (Record.BYTE, flags) elif typeId is None: record += (Record.BYTE, flags) else: flags |= DBItemWriter.TYPED record += (Record.BYTE, flags, Record.UUID, typeId) return attrType
def _type(self, record, flags, item, value, verify, withSchema, attrType): if attrType is None: if verify: attrType = TypeHandler.typeHandler(item.itsView, value) typeId = attrType.itsUUID else: typeId = None elif attrType.isAlias(): if verify: aliasType = attrType.type(value) if aliasType is None: raise TypeError, "%s does not alias type of value '%s' of type %s" % ( attrType.itsPath, value, type(value)) attrType = aliasType typeId = attrType.itsUUID else: typeId = None else: if verify and not attrType.recognizes(value): raise TypeError, "value '%s' of type %s is not recognized by type %s" % ( value, type(value), attrType.itsPath) if withSchema: typeId = attrType.itsUUID else: typeId = None if (flags & DBItemWriter.SINGLE and attrType is not None and attrType.getFlags() & CAttribute.SIMPLE): flags |= DBItemWriter.SIMPLE record += (Record.BYTE, flags) elif typeId is None: record += (Record.BYTE, flags) else: flags |= DBItemWriter.TYPED record += (Record.BYTE, flags, Record.UUID, typeId) return attrType
class DBItemWriter(ItemWriter): def __init__(self, store, view): super(DBItemWriter, self).__init__() self.store = store self.valueBuffer = [] self.dataBuffer = [] self.toindex = view.isBackgroundIndexed() def writeItem(self, item, version): self.values = [] self.uParent = DBItemWriter.NOITEM if not ((item._status & (CItem.NEW | CItem.MERGED)) != 0 or item._version == 0): self.oldValues = self.store._items.getItemValues( item.itsVersion, item.itsUUID) if self.oldValues is None: raise AssertionError, ("Record not found for %s, version %s" % (item._repr_(), item._version)) else: self.oldValues = None if item._isKDirty() and not item.isNew(): prevKind = item._pastKind or DBItemWriter.NOITEM else: prevKind = None size = super(DBItemWriter, self).writeItem(item, version) size += self.store._items.saveItem(item.itsUUID, version, self.uKind, prevKind, item._status & CItem.SAVEMASK, self.uParent, self.name, self.moduleName, self.className, self.values, item._values._getDirties(), item._references._getDirties()) return size def writeValue(self, record, item, version, value, withSchema, attrType): flags = DBItemWriter.SINGLE | DBItemWriter.VALUE attrType = self._type(record, flags, item, value, True, withSchema, attrType) return attrType.writeValue(self, record, item, version, value, withSchema) def writeList(self, record, item, version, value, withSchema, attrType): flags = DBItemWriter.LIST | DBItemWriter.VALUE attrType = self._type(record, flags, item, value, False, withSchema, attrType) record += (Record.INT, len(value)) size = 0 for v in value: size += self.writeValue(record, item, version, v, withSchema, attrType) return size def writeSet(self, record, item, version, value, withSchema, attrType): flags = DBItemWriter.SET | DBItemWriter.VALUE attrType = self._type(record, flags, item, value, False, withSchema, attrType) record += (Record.INT, len(value)) size = 0 for v in value: size += self.writeValue(record, item, version, v, withSchema, attrType) return size def writeDict(self, record, item, version, value, withSchema, attrType): flags = DBItemWriter.DICT | DBItemWriter.VALUE attrType = self._type(record, flags, item, value, False, withSchema, attrType) record += (Record.INT, len(value)) size = 0 for k, v in value._iteritems(): size += self.writeValue(record, item, version, k, False, None) size += self.writeValue(record, item, version, v, withSchema, attrType) return size def writeIndexes(self, record, item, version, value): if value._indexes: record += (Record.BYTE, len(value._indexes)) return value._saveIndexes(self, record, version) else: record += (Record.BYTE, 0) return 0 def _kind(self, kind): if kind is None: self.uKind = DBItemWriter.NOITEM else: self.uKind = kind.itsUUID return 0 def _parent(self, parent, isContainer): if parent is None: self.uParent = DBItemWriter.NOITEM else: self.uParent = parent.itsUUID return 0 def _name(self, name): self.name = name return 0 def _className(self, moduleName, className): self.moduleName = moduleName self.className = className return 0 def _children(self, item, version, all): if item._children is not None: return item._children._saveValues(version) return 0 def _acls(self, item, version, all): size = 0 if item._status & CItem.ADIRTY: store = self.store uuid = item.itsUUID for name, acl in item._acls.iteritems(): size += store.saveACL(version, uuid, name, acl) return size def _values(self, item, version, withSchema, all): return item._values._writeValues(self, version, withSchema, all) def _references(self, item, version, withSchema, all): return item._references._writeValues(self, version, withSchema, all) def _value(self, item, name, value, version, flags, withSchema, attribute): self.lobs = [] self.indexes = [] view = item.itsView uValue = UUID() self.values.append((name, uValue)) if isinstance(value, Indexable): indexed = value.isIndexed() indexable = True else: indexed = None indexable = False if attribute is None: attrCard = 'single' attrType = None if indexed is None: indexed = False else: c = attribute.c attrCard = c.cardinality attrType = attribute.type if indexed is None: indexed = c.indexed if indexed and self.toindex: flags |= CValues.TOINDEX item._status |= CItem.TOINDEX indexed = False record = Record(Record.UUID, attribute.itsUUID, Record.BYTE, flags) valueRecord = Record() if withSchema: valueRecord += (Record.SYMBOL, name) try: if attrCard == 'single': self.writeValue(valueRecord, item, version, value, withSchema, attrType) elif attrCard == 'list': self.writeList(valueRecord, item, version, value, withSchema, attrType) elif attrCard == 'set': self.writeSet(valueRecord, item, version, value, withSchema, attrType) elif attrCard == 'dict': self.writeDict(valueRecord, item, version, value, withSchema, attrType) except DBLockDeadlockError: raise except Exception, e: raise SaveValueError, (item, name, e) if indexed: if indexable: value.indexValue(view, item.itsUUID, attribute.itsUUID, uValue, version) elif attrCard == 'single': if attrType is None: valueType = TypeHandler.typeHandler(view, value) elif attrType.isAlias(): valueType = attrType.type(value) else: valueType = attrType self.indexValue(view, valueType.makeUnicode(value), item.itsUUID, attribute.itsUUID, uValue, version) else: raise NotImplementedError, (attrCard, "full text indexing") record += (Record.RECORD, valueRecord) lobRecord = Record() for uuid in self.lobs: lobRecord += (Record.UUID, uuid) record += (Record.RECORD, lobRecord) indexRecord = Record() for uuid in self.indexes: indexRecord += (Record.UUID, uuid) record += (Record.RECORD, indexRecord) return self.store._values.c.saveValue(item.itsUUID, uValue, record)