Ejemplo n.º 1
0
        /// <summary>
        ///   Build a meta representation of an object
        ///   <pre>warning: When an object has two fields with the same name
        ///        (a private field with the same name in a parent class, the deeper field (of the parent) is ignored!)</pre>
        /// </summary>
        /// <returns> The ObjectInfo </returns>
        private AbstractObjectInfo GetObjectInfoInternal(AbstractObjectInfo nnoi, object o, ClassInfo classInfo,
                                                         bool recursive,
                                                         IDictionary <object, NonNativeObjectInfo> alreadyReadObjects,
                                                         IIntrospectionCallback callback)
        {
            if (o == null)
            {
                return(NullNativeObjectInfo.GetInstance());
            }

            var clazz = o.GetType();
            var type  = OdbType.GetFromClass(clazz);

            if (type.IsNative())
            {
                return(GetNativeObjectInfoInternal(type, o, recursive, alreadyReadObjects, callback));
            }

            // sometimes the type.getName() may not match the ci.getClassName()
            // It happens when the attribute is an interface or superclass of the
            // real attribute class
            // In this case, ci must be updated to the real class info
            if (classInfo != null && !classInfo.FullClassName.Equals(OdbClassNameResolver.GetFullName(clazz)))
            {
                classInfo = GetClassInfo(clazz);
                nnoi      = null;
            }
            var mainAoi      = (NonNativeObjectInfo)nnoi;
            var isRootObject = false;

            if (alreadyReadObjects == null)
            {
                alreadyReadObjects = new OdbHashMap <object, NonNativeObjectInfo>();
                isRootObject       = true;
            }

            NonNativeObjectInfo cachedNnoi;

            alreadyReadObjects.TryGetValue(o, out cachedNnoi);

            if (cachedNnoi != null)
            {
                return(new ObjectReference(cachedNnoi));
            }

            if (callback != null)
            {
                callback.ObjectFound(o);
            }

            if (mainAoi == null)
            {
                mainAoi = BuildNnoi(o, classInfo);
            }

            alreadyReadObjects[o] = mainAoi;

            var fields = ClassIntrospector.GetAllFieldsFrom(clazz);

            foreach (var field in fields)
            {
                try
                {
                    var value       = field.GetValue(o);
                    var attributeId = classInfo.GetAttributeId(field.Name);
                    if (attributeId == -1)
                    {
                        throw new OdbRuntimeException(
                                  NDatabaseError.ObjectIntrospectorNoFieldWithName.AddParameter(classInfo.FullClassName).
                                  AddParameter(field.Name));
                    }

                    var valueType = OdbType.GetFromClass(value == null
                                                             ? field.FieldType
                                                             : value.GetType());
                    // for native fields
                    AbstractObjectInfo abstractObjectInfo;

                    if (valueType.IsNative())
                    {
                        abstractObjectInfo = GetNativeObjectInfoInternal(valueType, value, recursive, alreadyReadObjects,
                                                                         callback);
                        mainAoi.SetAttributeValue(attributeId, abstractObjectInfo);
                    }
                    else
                    {
                        // Non Native Objects
                        if (value == null)
                        {
                            var classInfo1 = GetClassInfo(field.GetType());

                            abstractObjectInfo = new NonNativeNullObjectInfo(classInfo1);
                            mainAoi.SetAttributeValue(attributeId, abstractObjectInfo);
                        }
                        else
                        {
                            var classInfo2 = GetClassInfo(value.GetType());
                            if (recursive)
                            {
                                abstractObjectInfo = GetObjectInfoInternal(null, value, classInfo2, true,
                                                                           alreadyReadObjects, callback);
                                mainAoi.SetAttributeValue(attributeId, abstractObjectInfo);
                            }
                            else
                            {
                                // When it is not recursive, simply add the object
                                // values.add(value);
                                throw new OdbRuntimeException(
                                          NDatabaseError.InternalError.AddParameter(
                                              "Should not enter here - ObjectIntrospector - 'simply add the object'"));
                            }
                        }
                    }
                }
                catch (ArgumentException e)
                {
                    throw new OdbRuntimeException(
                              NDatabaseError.InternalError.AddParameter("in getObjectInfoInternal"), e);
                }
                catch (MemberAccessException e)
                {
                    throw new OdbRuntimeException(NDatabaseError.InternalError.AddParameter("getObjectInfoInternal"), e);
                }
            }

            if (isRootObject)
            {
                alreadyReadObjects.Clear();
            }

            return(mainAoi);
        }
Ejemplo n.º 2
0
        private OID WriteNonNativeObjectInfo(OID existingOid, NonNativeObjectInfo objectInfo, long position,
                                             bool writeDataInTransaction, bool isNewObject)
        {
            var lsession  = _session;
            var cache     = lsession.GetCache();
            var hasObject = objectInfo.GetObject() != null;

            // Checks if object is null,for null objects,there is nothing to do
            if (objectInfo.IsNull())
            {
                return(StorageEngineConstant.NullObjectId);
            }

            var metaModel = lsession.GetMetaModel();

            // first checks if the class of this object already exist in the
            // metamodel
            if (!metaModel.ExistClass(objectInfo.GetClassInfo().UnderlyingType))
            {
                _objectWriter.AddClass(objectInfo.GetClassInfo(), true);
            }

            // if position is -1, gets the position where to write the object
            if (position == -1)
            {
                // Write at the end of the file
                position = _objectWriter.FileSystemProcessor.FileSystemInterface.GetAvailablePosition();
                // Updates the meta object position
                objectInfo.SetPosition(position);
            }

            // Gets the object id
            var oid = existingOid;

            if (oid == null)
            {
                // If, to get the next id, a new id block must be created, then
                // there is an extra work
                // to update the current object position
                if (_objectWriter.GetIdManager().MustShift())
                {
                    oid = _objectWriter.GetIdManager().GetNextObjectId(position);
                    // The id manager wrote in the file so the position for the
                    // object must be re-computed
                    position = _objectWriter.FileSystemProcessor.FileSystemInterface.GetAvailablePosition();
                    // The oid must be associated to this new position - id
                    // operations are always out of transaction
                    // in this case, the update is done out of the transaction as a
                    // rollback won t need to
                    // undo this. We are just creating the id
                    // => third parameter(write in transaction) = false
                    _objectWriter.GetIdManager().UpdateObjectPositionForOid(oid, position, false);
                }
                else
                {
                    oid = _objectWriter.GetIdManager().GetNextObjectId(position);
                }
            }
            else
            {
                // If an oid was passed, it is because object already exist and
                // is being updated. So we
                // must update the object position
                // Here the update of the position of the id must be done in
                // transaction as the object
                // position of the id is being updated, and a rollback should undo
                // this
                // => third parameter(write in transaction) = true
                _objectWriter.GetIdManager().UpdateObjectPositionForOid(oid, position, true);
                // Keep the relation of id and position in the cache until the
                // commit
                cache.SavePositionOfObjectWithOid(oid, position);
            }

            // Sets the oid of the object in the inserting cache
            cache.UpdateIdOfInsertingObject(objectInfo.GetObject(), oid);

            // Only add the oid to unconnected zone if it is a new object
            if (isNewObject)
            {
                cache.AddOIDToUnconnectedZone(oid);
            }

            objectInfo.SetOid(oid);

            if (objectInfo.GetClassInfo() == null || objectInfo.GetClassInfo().ClassInfoId == null)
            {
                if (objectInfo.GetClassInfo() != null)
                {
                    var clinfo =
                        _storageEngine.GetSession().GetMetaModel().GetClassInfo(
                            objectInfo.GetClassInfo().FullClassName, true);
                    objectInfo.SetClassInfo(clinfo);
                }
                else
                {
                    throw new OdbRuntimeException(NDatabaseError.UndefinedClassInfo.AddParameter(objectInfo.ToString()));
                }
            }

            // updates the meta model - If class already exist, it returns the
            // metamodel class, which contains
            // a bit more informations
            var classInfo = _objectWriter.AddClass(objectInfo.GetClassInfo(), true);

            objectInfo.SetClassInfo(classInfo);
            //
            if (isNewObject)
            {
                _objectWriter.ManageNewObjectPointers(objectInfo, classInfo);
            }


            _objectWriter.FileSystemProcessor.FileSystemInterface.SetWritePosition(position, writeDataInTransaction);
            objectInfo.SetPosition(position);
            var nbAttributes = objectInfo.GetClassInfo().Attributes.Count;
            // compute the size of the array of byte needed till the attibute
            // positions
            // BlockSize + Block Type + OID  + ClassOid + PrevOid + NextOid + CreatDate + UpdateDate + objectVersion + NbAttributes + RefCoutner + IsRoot
            // Int       + Byte        + Long + Long     + Long    + Long    + Long      + Long       + int          + int          + long       + byte
            // 6 Longs + 3Ints + Byte
            var tsize = 7 * OdbType.SizeOfLong + 3 * OdbType.SizeOfInt + 2 * OdbType.SizeOfByte;
            var bytes = new byte[tsize];

            // Block size
            IntToByteArray(0, bytes, 0);
            // Block type
            bytes[4] = BlockTypes.BlockTypeNonNativeObject;

            // The object id
            EncodeOid(oid, bytes, 5);

            // Class info id
            LongToByteArray(classInfo.ClassInfoId.ObjectId, bytes, 13);

            // previous instance
            EncodeOid(objectInfo.GetPreviousObjectOID(), bytes, 21);

            // next instance
            EncodeOid(objectInfo.GetNextObjectOID(), bytes, 29);

            // creation date, for update operation must be the original one
            LongToByteArray(objectInfo.GetHeader().GetCreationDate(), bytes, 37);

            LongToByteArray(OdbTime.GetCurrentTimeInTicks(), bytes, 45);

            IntToByteArray(objectInfo.GetHeader().GetObjectVersion(), bytes, 53);

            LongToByteArray(objectInfo.GetHeader().RefCounter, bytes, 57);

            BooleanToByteArray(objectInfo.GetHeader().IsRoot, bytes, 65);

            // now write the number of attributes and the position of all
            // attributes, we do not know them yet, so write 00 but at the end of the write operation
            // These positions will be updated The positions that is going to be written are 'int' representing
            // the offset position of the attribute first write the number of attributes
            IntToByteArray(nbAttributes, bytes, 66);

            // Then write the array of bytes
            _objectWriter.FileSystemProcessor.FileSystemInterface.WriteBytes(bytes, writeDataInTransaction);
            // Store the position
            var attributePositionStart = _objectWriter.FileSystemProcessor.FileSystemInterface.GetPosition();
            var attributeSize          = OdbType.SizeOfInt + OdbType.SizeOfLong;
            var abytes = new byte[nbAttributes * (attributeSize)];

            // here, just write an empty (0) array, as real values will be set at
            // the end
            _objectWriter.FileSystemProcessor.FileSystemInterface.WriteBytes(abytes, writeDataInTransaction);
            var attributesIdentification = new long[nbAttributes];
            var attributeIds             = new int[nbAttributes];
            // Puts the object info in the cache
            // storageEngine.getSession().getCache().addObject(position,
            // aoi.getObject(), objectInfo.getHeader());

            var maxWritePosition = _objectWriter.FileSystemProcessor.FileSystemInterface.GetPosition();

            // Loop on all attributes
            for (var i = 0; i < nbAttributes; i++)
            {
                // Gets the attribute meta description
                var classAttributeInfo = classInfo.GetAttributeInfo(i);
                // Gets the id of the attribute
                attributeIds[i] = classAttributeInfo.GetId();
                // Gets the attribute data
                var aoi2 = objectInfo.GetAttributeValueFromId(classAttributeInfo.GetId());
                if (aoi2 == null)
                {
                    // This only happens in 1 case : when a class has a field with
                    // the same name of one of is superclass. In this, the deeper
                    // attribute is null
                    if (classAttributeInfo.IsNative())
                    {
                        aoi2 = new NullNativeObjectInfo(classAttributeInfo.GetAttributeType().Id);
                    }
                    else
                    {
                        aoi2 = new NonNativeNullObjectInfo(classAttributeInfo.GetClassInfo());
                    }
                }
                if (aoi2.IsNative())
                {
                    var nativeAttributePosition = _objectWriter.InternalStoreObject((NativeObjectInfo)aoi2);
                    // For native objects , odb stores their position
                    attributesIdentification[i] = nativeAttributePosition;
                }
                else
                {
                    OID nonNativeAttributeOid;
                    if (aoi2.IsObjectReference())
                    {
                        var or = (ObjectReference)aoi2;
                        nonNativeAttributeOid = or.GetOid();
                    }
                    else
                    {
                        nonNativeAttributeOid = _objectWriter.StoreObject(null, (NonNativeObjectInfo)aoi2);
                    }
                    // For non native objects , odb stores its oid as a negative
                    // number!!u
                    if (nonNativeAttributeOid != null)
                    {
                        attributesIdentification[i] = -nonNativeAttributeOid.ObjectId;
                    }
                    else
                    {
                        attributesIdentification[i] = StorageEngineConstant.NullObjectIdId;
                    }
                }
                var p = _objectWriter.FileSystemProcessor.FileSystemInterface.GetPosition();
                if (p > maxWritePosition)
                {
                    maxWritePosition = p;
                }
            }
            // Updates attributes identification in the object info header
            objectInfo.GetHeader().SetAttributesIdentification(attributesIdentification);
            objectInfo.GetHeader().SetAttributesIds(attributeIds);
            var positionAfterWrite = maxWritePosition;

            // Now writes back the attribute positions
            _objectWriter.FileSystemProcessor.FileSystemInterface.SetWritePosition(attributePositionStart, writeDataInTransaction);
            abytes = new byte[attributesIdentification.Length * (attributeSize)];
            for (var i = 0; i < attributesIdentification.Length; i++)
            {
                IntToByteArray(attributeIds[i], abytes, i * attributeSize);
                LongToByteArray(attributesIdentification[i], abytes,
                                i * (attributeSize) + OdbType.SizeOfInt);
                // fsi.writeInt(attributeIds[i], writeDataInTransaction, "attr id");
                // fsi.writeLong(attributesIdentification[i],
                // writeDataInTransaction, "att real pos",
                // WriteAction.DATA_WRITE_ACTION);
                // if (classInfo.getAttributeInfo(i).isNonNative() &&
                // attributesIdentification[i] > 0) {
                if (objectInfo.GetAttributeValueFromId(attributeIds[i]).IsNonNativeObject() &&
                    attributesIdentification[i] > 0)
                {
                    throw new OdbRuntimeException(
                              NDatabaseError.NonNativeAttributeStoredByPositionInsteadOfOid.AddParameter(
                                  classInfo.GetAttributeInfo(i).GetName()).AddParameter(classInfo.FullClassName).
                              AddParameter(attributesIdentification[i]));
                }
            }
            _objectWriter.FileSystemProcessor.FileSystemInterface.WriteBytes(abytes, writeDataInTransaction);
            _objectWriter.FileSystemProcessor.FileSystemInterface.SetWritePosition(positionAfterWrite, writeDataInTransaction);
            var blockSize = (int)(positionAfterWrite - position);

            WriteBlockSizeAt(position, blockSize, writeDataInTransaction, objectInfo);

            // Only insert in index for new objects
            if (isNewObject)
            {
                // insert object id in indexes, if exist
                _objectWriter.ManageIndexesForInsert(oid, objectInfo);
                var value = hasObject
                                ? objectInfo.GetObject()
                                : objectInfo;

                _triggerManager.ManageInsertTriggerAfter(objectInfo.GetClassInfo().UnderlyingType, value, oid);
            }

            return(oid);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///   Build a meta representation of an object 
        ///   <pre>warning: When an object has two fields with the same name 
        ///        (a private field with the same name in a parent class, the deeper field (of the parent) is ignored!)</pre>
        /// </summary>
        /// <returns> The ObjectInfo </returns>
        private AbstractObjectInfo GetObjectInfoInternal(AbstractObjectInfo nnoi, object o, ClassInfo classInfo,
                                                         bool recursive,
                                                         IDictionary<object, NonNativeObjectInfo> alreadyReadObjects,
                                                         IIntrospectionCallback callback)
        {
            if (o == null)
                return NullNativeObjectInfo.GetInstance();

            var clazz = o.GetType();
            var type = OdbType.GetFromClass(clazz);
            if (type.IsNative())
                return GetNativeObjectInfoInternal(type, o, recursive, alreadyReadObjects, callback);

            // sometimes the type.getName() may not match the ci.getClassName()
            // It happens when the attribute is an interface or superclass of the
            // real attribute class
            // In this case, ci must be updated to the real class info
            if (classInfo != null && !classInfo.FullClassName.Equals(OdbClassNameResolver.GetFullName(clazz)))
            {
                classInfo = GetClassInfo(clazz);
                nnoi = null;
            }
            var mainAoi = (NonNativeObjectInfo) nnoi;
            var isRootObject = false;

            if (alreadyReadObjects == null)
            {
                alreadyReadObjects = new OdbHashMap<object, NonNativeObjectInfo>();
                isRootObject = true;
            }

            NonNativeObjectInfo cachedNnoi;
            alreadyReadObjects.TryGetValue(o, out cachedNnoi);

            if (cachedNnoi != null)
                return new ObjectReference(cachedNnoi);

            if (callback != null)
                callback.ObjectFound(o);

            if (mainAoi == null)
                mainAoi = BuildNnoi(o, classInfo);

            alreadyReadObjects[o] = mainAoi;
            
            var fields = ClassIntrospector.GetAllFieldsFrom(clazz);
            
            foreach (var field in fields)
            {
                try
                {
                    var value = field.GetValue(o);
                    var attributeId = classInfo.GetAttributeId(field.Name);
                    if (attributeId == -1)
                    {
                        throw new OdbRuntimeException(
                            NDatabaseError.ObjectIntrospectorNoFieldWithName.AddParameter(classInfo.FullClassName).
                                AddParameter(field.Name));
                    }

                    var valueType = OdbType.GetFromClass(value == null
                                                             ? field.FieldType
                                                             : value.GetType());
                    // for native fields
                    AbstractObjectInfo abstractObjectInfo;

                    if (valueType.IsNative())
                    {
                        abstractObjectInfo = GetNativeObjectInfoInternal(valueType, value, recursive, alreadyReadObjects,
                                                                         callback);
                        mainAoi.SetAttributeValue(attributeId, abstractObjectInfo);
                    }
                    else
                    {
                        // Non Native Objects
                        if (value == null)
                        {
                            var classInfo1 = GetClassInfo(field.GetType());

                            abstractObjectInfo = new NonNativeNullObjectInfo(classInfo1);
                            mainAoi.SetAttributeValue(attributeId, abstractObjectInfo);
                        }
                        else
                        {
                            var classInfo2 = GetClassInfo(value.GetType());
                            if (recursive)
                            {
                                abstractObjectInfo = GetObjectInfoInternal(null, value, classInfo2, true,
                                                                           alreadyReadObjects, callback);
                                mainAoi.SetAttributeValue(attributeId, abstractObjectInfo);
                            }
                            else
                            {
                                // When it is not recursive, simply add the object
                                // values.add(value);
                                throw new OdbRuntimeException(
                                    NDatabaseError.InternalError.AddParameter(
                                        "Should not enter here - ObjectIntrospector - 'simply add the object'"));
                            }
                        }
                    }
                }
                catch (ArgumentException e)
                {
                    throw new OdbRuntimeException(
                        NDatabaseError.InternalError.AddParameter("in getObjectInfoInternal"), e);
                }
                catch (MemberAccessException e)
                {
                    throw new OdbRuntimeException(NDatabaseError.InternalError.AddParameter("getObjectInfoInternal"), e);
                }
            }

            if (isRootObject)
                alreadyReadObjects.Clear();

            return mainAoi;
        }