예제 #1
0
        private ArrayObjectInfo IntrospectArray(object array,
                                                IDictionary <object, NonNativeObjectInfo> alreadyReadObjects,
                                                OdbType odbType, IIntrospectionCallback callback)
        {
            var length      = ((Array)array).GetLength(0);
            var elementType = array.GetType().GetElementType();
            var type        = OdbType.GetFromClass(elementType);

            if (type.IsAtomicNative())
            {
                return(IntropectAtomicNativeArray(array, type));
            }

            var arrayCopy = new object[length];

            for (var i = 0; i < length; i++)
            {
                var o = ((Array)array).GetValue(i);
                if (o != null)
                {
                    var classInfo          = GetClassInfo(o.GetType());
                    var abstractObjectInfo = GetObjectInfo(o, classInfo, true, alreadyReadObjects, callback);
                    arrayCopy[i] = abstractObjectInfo;
                }
                else
                {
                    arrayCopy[i] = NullNativeObjectInfo.GetInstance();
                }
            }

            return(new ArrayObjectInfo(arrayCopy, odbType, type.Id));
        }
예제 #2
0
        /// <summary>
        ///   Builds a class info from a class and an existing class info
        ///   The existing class info is used to make sure that fields with the same name will have the same id
        /// </summary>
        /// <param name="fullClassName"> The name of the class to get info </param>
        /// <param name="existingClassInfo"> </param>
        /// <returns> A ClassInfo - a meta representation of the class </returns>
        private static ClassInfo GetClassInfo(String fullClassName, ClassInfo existingClassInfo)
        {
            var type      = TypeResolutionUtils.ResolveType(fullClassName);
            var classInfo = new ClassInfo(type);

            var fields     = GetAllFieldsFrom(type);
            var attributes = new OdbList <ClassAttributeInfo>(fields.Count);

            var maxAttributeId = existingClassInfo.MaxAttributeId;

            foreach (var fieldInfo in fields)
            {
                // Gets the attribute id from the existing class info
                var attributeId = existingClassInfo.GetAttributeId(fieldInfo.Name);
                if (attributeId == -1)
                {
                    maxAttributeId++;
                    // The attribute with field.getName() does not exist in existing class info
                    //  create a new id
                    attributeId = maxAttributeId;
                }
                var fieldClassInfo = !OdbType.GetFromClass(fieldInfo.FieldType).IsNative()
                                         ? new ClassInfo(fieldInfo.FieldType)
                                         : null;

                attributes.Add(new ClassAttributeInfo(attributeId, fieldInfo.Name, fieldInfo.FieldType,
                                                      OdbClassNameResolver.GetFullName(fieldInfo.FieldType), fieldClassInfo));
            }

            classInfo.Attributes     = attributes;
            classInfo.MaxAttributeId = maxAttributeId;

            return(classInfo);
        }
예제 #3
0
        /// <param name="type"> The class to introspect </param>
        /// <param name="recursive"> If true, goes does the hierarchy to try to analyze all classes </param>
        /// <param name="classInfoList"> map with class name that are being introspected, to avoid recursive calls </param>
        private static ClassInfoList InternalIntrospect(Type type, bool recursive, ClassInfoList classInfoList)
        {
            if (classInfoList != null)
            {
                var existingClassInfo = classInfoList.GetClassInfoBy(type);

                if (existingClassInfo != null)
                {
                    return(classInfoList);
                }
            }

            var classInfo = new ClassInfo(type);

            if (classInfoList == null)
            {
                classInfoList = new ClassInfoList(classInfo);
            }
            else
            {
                classInfoList.AddClassInfo(classInfo);
            }

            var fields     = GetAllFieldsFrom(type);
            var attributes = new OdbList <ClassAttributeInfo>(fields.Count);

            for (var i = 0; i < fields.Count; i++)
            {
                var field = fields[i];

                ClassInfo classInfoByName;

                if (OdbType.GetFromClass(field.FieldType).IsNative())
                {
                    classInfoByName = null;
                }
                else
                {
                    if (recursive)
                    {
                        classInfoList   = InternalIntrospect(field.FieldType, true, classInfoList);
                        classInfoByName = classInfoList.GetClassInfoBy(field.FieldType);
                    }
                    else
                    {
                        classInfoByName = new ClassInfo(field.FieldType);
                    }
                }

                attributes.Add(new ClassAttributeInfo((i + 1), field.Name, field.FieldType,
                                                      OdbClassNameResolver.GetFullName(field.FieldType), classInfoByName));
            }

            classInfo.Attributes     = attributes;
            classInfo.MaxAttributeId = fields.Count;

            return(classInfoList);
        }
예제 #4
0
        /// <summary>
        ///   Store an object with the specific id
        /// </summary>
        /// <param name="oid"> </param>
        /// <param name="plainObject"> </param>
        private OID InternalStore <T>(OID oid, T plainObject) where T : class
        {
            if (GetSession().IsRollbacked())
            {
                throw new OdbRuntimeException(
                          NDatabaseError.OdbHasBeenRollbacked.AddParameter(GetBaseIdentification().ToString()));
            }

            if (plainObject == null)
            {
                throw new OdbRuntimeException(NDatabaseError.OdbCanNotStoreNullObject);
            }

            var type = typeof(T);

            if (OdbType.IsNative(type))
            {
                throw new OdbRuntimeException(
                          NDatabaseError.OdbCanNotStoreNativeObjectDirectly.AddParameter(type.FullName).AddParameter(
                              OdbType.GetFromClass(type).Name).AddParameter(type.FullName));
            }

            // first detects if we must perform an insert or an update
            // If object is in the cache, we must perform an update, else an insert
            var cache = GetSession().GetCache();

            var cacheOid = cache.IdOfInsertingObject(plainObject);

            if (cacheOid != null)
            {
                return(cacheOid);
            }

            // throw new ODBRuntimeException("Inserting meta representation of
            // an object without the object itself is not yet supported");
            var mustUpdate = cache.Contains(plainObject);

            // The introspection callback is used to execute some specific task (like calling trigger, for example) while introspecting the object
            var callback = _introspectionCallbackForInsert;

            if (mustUpdate)
            {
                callback = _introspectionCallbackForUpdate;
            }

            // Transform the object into an ObjectInfo
            var nnoi =
                (NonNativeObjectInfo)
                _objectIntrospector.GetMetaRepresentation(plainObject, true, null, callback);

            // During the introspection process, if object is to be updated, then the oid has been set
            mustUpdate = nnoi.GetOid() != null;

            return(mustUpdate
                       ? _objectWriter.UpdateNonNativeObjectInfo(nnoi, false)
                       : _objectWriter.InsertNonNativeObject(oid, nnoi, true));
        }
예제 #5
0
        public void It_should_extend_class_info_with_new_attribute_info()
        {
            Assert.That(_classInfo.Attributes.Count, Is.EqualTo(3));

            var attributeInfo = _classInfo.GetAttributeInfoFromName(_fieldName);

            Assert.That(attributeInfo, Is.Not.Null);
            Assert.That(attributeInfo.GetName(), Is.EqualTo(_fieldName));
            Assert.That(attributeInfo.GetAttributeType(), Is.EqualTo(OdbType.GetFromClass(_fieldType)));
        }
예제 #6
0
        public virtual void Test3()
        {
            var array1 = new[] { 1, 2 };

            AssertEquals(OdbType.Array, OdbType.GetFromClass(array1.GetType()));
            AssertEquals(OdbType.Integer, OdbType.GetFromClass(array1.GetType()).SubType);
            var array2 = new[] { "1", "2" };

            AssertEquals(OdbType.Array, OdbType.GetFromClass(array2.GetType()));
            AssertEquals(OdbType.String, OdbType.GetFromClass(array2.GetType()).SubType);
        }
예제 #7
0
 public void Check_type_conversion()
 {
     AssertEquals(OdbType.Integer, OdbType.GetFromClass(typeof(int)));
     AssertEquals(OdbType.Boolean, OdbType.GetFromClass(typeof(bool)));
     AssertEquals(OdbType.Byte, OdbType.GetFromClass(typeof(byte)));
     AssertEquals(OdbType.Character, OdbType.GetFromClass(typeof(char)));
     AssertEquals(OdbType.Double, OdbType.GetFromClass(typeof(double)));
     AssertEquals(OdbType.Float, OdbType.GetFromClass(typeof(float)));
     AssertEquals(OdbType.Long, OdbType.GetFromClass(typeof(long)));
     AssertEquals(OdbType.Short, OdbType.GetFromClass(typeof(short)));
     AssertEquals(OdbType.String, OdbType.GetFromClass(typeof(string)));
     AssertEquals(OdbType.Decimal, OdbType.GetFromClass(typeof(Decimal)));
 }
예제 #8
0
        public ClassInfo GetClassInfo(Type type)
        {
            var odbType = OdbType.GetFromClass(type);

            if (odbType.IsNative() && !odbType.IsEnum())
            {
                return(null);
            }

            var metaModel = _session.GetMetaModel();

            if (metaModel.ExistClass(type))
            {
                return(metaModel.GetClassInfo(type, true));
            }

            var classInfoList = ClassIntrospector.Introspect(type, true);

            _session.GetObjectWriter().AddClasses(classInfoList);

            return(classInfoList.GetMainClassInfo());
        }
예제 #9
0
        private static ArrayObjectInfo IntropectAtomicNativeArray(object array, OdbType type)
        {
            var length    = ((Array)array).GetLength(0);
            var arrayCopy = new object[length];

            for (var i = 0; i < length; i++)
            {
                var o = ((Array)array).GetValue(i);
                if (o != null)
                {
                    // If object is not null, try to get the exact type
                    var typeId = OdbType.GetFromClass(o.GetType()).Id;
                    var atomicNativeObjectInfo = new AtomicNativeObjectInfo(o, typeId);
                    arrayCopy[i] = atomicNativeObjectInfo;
                }
                else
                {
                    // Else take the declared type
                    arrayCopy[i] = new NullNativeObjectInfo(type.Id);
                }
            }

            return(new ArrayObjectInfo(arrayCopy, OdbType.Array, type.Id));
        }
예제 #10
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);
        }