Example #1
0
	def fetchObjRef(self, objRef):
		"""
		Given an unarchived object reference, this method returns the
		actual object for it (or None if the reference is NULL or
		dangling). While this method assumes that obj refs are stored
		as 64-bit numbers containing the class id and object serial
		number, subclasses are certainly able to override that
		assumption by overriding this method.
		"""
		assert isinstance(objRef, types.LongType), 'type=%r, objRef=%r' % (type(objRef), objRef)
		if objRef == 0:
			return None
		else:
			klassId, serialNum = objRefSplit(objRef)
			if klassId == 0 or serialNum == 0:
				# invalid! we don't use 0 serial numbers
				return self.objRefZeroSerialNum(objRef)

			klass = self.klassForId(klassId)

			# Check if we already have this in memory first
			key = ObjectKey()
			key.initFromClassNameAndSerialNum(klass.name(), serialNum)
			obj = self._objects.get(key, None)
			if obj:
				return obj

			clauses = 'where %s=%d' % (klass.sqlSerialColumnName(), serialNum)
			objs = self.fetchObjectsOfClass(klass, clauses, isDeep=False)
			if len(objs) == 1:
				return objs[0]
			elif len(objs) > 1:
				raise ValueError, 'Multiple objects.' # @@ 2000-11-22 ce: expand the msg with more information
			else:
				return self.objRefDangles(objRef)
Example #2
0
    def _insertObject(self, obj, unknownSerialNums):
        # New objects not in the persistent store have serial numbers less than 1
        if obj.serialNum() > 0:
            try:
                rep = repr(obj)
            except Exception:
                rep = '(repr exception)'
            assert obj.serialNum() < 1, 'obj=%s' % rep

        # try to get the next ID (if database supports this)
        idNum = self.retrieveNextInsertId(obj.klass())

        # SQL insert
        sql = obj.sqlInsertStmt(unknownSerialNums, idNum)
        conn, cur = self.executeSQL(sql)
        try:
            # Get new id/serial num
            if idNum is None:
                idNum = self.retrieveLastInsertId(conn, cur)

            # Update object
            obj.setSerialNum(idNum)
            obj.setKey(ObjectKey().initFromObject(obj))
            obj.setChanged(False)

            # Update our object pool
            self._objects[obj.key()] = obj
        finally:
            self.doneWithConnection(conn)
Example #3
0
    def fetchObjectsOfClass(self,
                            aClass,
                            clauses='',
                            isDeep=1,
                            refreshAttrs=1,
                            serialNum=None):
        """
		Fetches a list of objects of a specific class. The list may be empty if no objects are found.
		aClass can be a Klass object (from the MiddleKit object model), the name of the class (e.g., a string) or a Python class.
		The clauses argument can be any SQL clauses such as 'where x<5 order by x'. Obviously, these could be specific to your SQL database, thereby making your code non-portable. Use your best judgement.
		serialNum can be a specific serial number if you are looking for a specific object.  If serialNum is provided, it overrides the clauses.
		You should label all arguments other than aClass:
			objs = store.fetchObjectsOfClass('Foo', clauses='where x<5')
		The reason for labeling is that this method is likely to undergo improvements in the future which could include additional arguments. No guarantees are made about the order of the arguments except that aClass will always be the first.
		Raises an exception if aClass parameter is invalid.
		"""
        klass = self._klassForClass(aClass)

        # Fetch objects of subclasses first, because the code below will be modifying clauses and serialNum
        deepObjs = []
        if isDeep:
            for subklass in klass.subklasses():
                deepObjs.extend(
                    self.fetchObjectsOfClass(subklass, clauses, isDeep,
                                             refreshAttrs, serialNum))

        # Now get objects of this exact class
        objs = []
        if not klass.isAbstract():
            fetchSQLStart = klass.fetchSQLStart()
            className = klass.name()
            if serialNum is not None:
                clauses = 'where %s=%d' % (klass.sqlIdName(), serialNum)
            if self._markDeletes:
                clauses = self.addDeletedToClauses(clauses)
            conn, cur = self.executeSQL(fetchSQLStart + clauses + ';')
            for row in cur.fetchall():
                serialNum = row[0]
                key = ObjectKey().initFromClassNameAndSerialNum(
                    className, serialNum)
                obj = self._objects.get(key, None)
                if obj is None:
                    pyClass = klass.pyClass()
                    obj = pyClass()
                    assert isinstance(
                        obj, MiddleObject
                    ), 'Not a MiddleObject. obj = %r, type = %r, MiddleObject = %r' % (
                        obj, type(obj), MiddleObject)
                    obj.readStoreData(self, row)
                    obj.setKey(key)
                    self._objects[key] = obj
                else:
                    # Existing object
                    if refreshAttrs:
                        obj.readStoreData(self, row)
                objs.append(obj)
        objs.extend(deepObjs)
        return objs
Example #4
0
 def objectForClassAndSerial(self, klass, serialNum, default=NoDefault):
     if isinstance(klass, BaseKlass):
         klass = klass.name()
     elif isinstance(klass, (type, ClassType)):
         klass = klass.__name__
     else:
         assert isinstance(klass, str)
     key = ObjectKey().initFromClassNameAndSerialNum(klass, serialNum)
     return self.objectForKey(key, default)
Example #5
0
	def objRefInMem(self, objRef):
		""" Return the object corresponding to the given objref if and only
		if it has been loaded into memory.  If the object has never been
		fetched from the database, None is returned. """
		assert isinstance(objRef, types.LongType), 'type=%r, objRef=%r' % (type(objRef), objRef)
		if objRef == 0:
			return 0
		else:
			klassId, serialNum = objRefSplit(objRef)
			if klassId == 0 or serialNum == 0:
				# invalid! we don't use 0 serial numbers
				return self.objRefZeroSerialNum(objRef)

			klass = self.klassForId(klassId)

			# return whether we have this object in memory
			key = ObjectKey()
			key.initFromClassNameAndSerialNum(klass.name(), serialNum)
			return self._objects.get(key, None)
Example #6
0
    def objRefInMem(self, objRef):
        """Return referenced object in memory.

        Returns the object corresponding to the given objref if and only if it
        has been loaded into memory. If the object has never been fetched from
        the database, None is returned.
        """
        assert isinstance(objRef, long), 'type=%r, objRef=%r' % (type(objRef), objRef)
        if objRef == 0:
            return 0
        else:
            klassId, serialNum = objRefSplit(objRef)
            if klassId == 0 or serialNum == 0:
                # invalid! we don't use 0 serial numbers
                return self.objRefZeroSerialNum(objRef)

            klass = self.klassForId(klassId)

            # return whether we have this object in memory
            key = ObjectKey()
            key.initFromClassNameAndSerialNum(klass.name(), serialNum)
            return self._objects.get(key)
Example #7
0
    def fetchObjRef(self, objRef):
        """Fetch referenced object.

        Given an unarchived object reference, this method returns the actual
        object for it (or None if the reference is NULL or dangling). While
        this method assumes that obj refs are stored as 64-bit numbers containing
        the class id and object serial number, subclasses are certainly able to
        override that assumption by overriding this method.
        """
        assert isinstance(objRef,
                          long), 'type=%r, objRef=%r' % (type(objRef), objRef)
        if objRef == 0:
            return None
        else:
            klassId, serialNum = objRefSplit(objRef)
            if klassId == 0 or serialNum == 0:
                # invalid! we don't use 0 serial numbers
                return self.objRefZeroSerialNum(objRef)

            klass = self.klassForId(klassId)

            # Check if we already have this in memory first
            key = ObjectKey()
            key.initFromClassNameAndSerialNum(klass.name(), serialNum)
            obj = self._objects.get(key)
            if obj:
                return obj

            clauses = 'where %s=%d' % (klass.sqlSerialColumnName(), serialNum)
            objs = self.fetchObjectsOfClass(klass, clauses, isDeep=False)
            if len(objs) == 1:
                return objs[0]
            elif len(objs) > 1:
                # @@ 2000-11-22 ce: expand the msg with more information
                raise ValueError('Multiple objects.')
            else:
                return self.objRefDangles(objRef)
Example #8
0
    def _insertObject(self, object, unknownSerialNums):
        # New objects not in the persistent store have serial numbers less than 1
        if object.serialNum() > 0:
            try:
                rep = repr(object)
            except:
                rep = '(repr exception)'
            assert object.serialNum() < 1, 'object=%s' % rep

        # SQL insert
        sql = object.sqlInsertStmt(unknownSerialNums)
        conn, cur = self.executeSQL(sql)

        # Get new id/serial num
        idNum = self.retrieveLastInsertId(conn, cur)

        # Update object
        object.setSerialNum(idNum)
        object.setKey(ObjectKey().initFromObject(object))
        object.setChanged(0)

        # Update our object pool
        self._objects[object.key()] = object