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)); }
private System.Collections.Generic.IDictionary <AbstractObjectInfo, AbstractObjectInfo> IntrospectGenericMap( System.Collections.Generic.IDictionary <object, object> map, bool introspect, IDictionary <object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { System.Collections.Generic.IDictionary <AbstractObjectInfo, AbstractObjectInfo> mapCopy = new OdbHashMap <AbstractObjectInfo, AbstractObjectInfo>(); System.Collections.Generic.ICollection <object> keySet = map.Keys; System.Collections.IEnumerator keys = keySet.GetEnumerator(); NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ciKey = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ciValue = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoiForKey = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoiForValue = null; while (keys.MoveNext()) { object key = keys.Current; object value = map[key]; if (key != null) { ciKey = GetClassInfo(OdbClassUtil.GetFullName(key.GetType())); if (value != null) { ciValue = GetClassInfo(OdbClassUtil.GetFullName(value.GetType())); } aoiForKey = GetObjectInfo(key, ciKey, introspect, alreadyReadObjects, callback); aoiForValue = GetObjectInfo(value, ciValue, introspect, alreadyReadObjects, callback); mapCopy.Add(aoiForKey, aoiForValue); } } return(mapCopy); }
/// <summary> /// The database file name /// </summary> public StorageEngine(IDbIdentification parameters) { _reflectionService = DependencyContainer.Resolve <IReflectionService>(); try { var metaModelCompabilityChecker = DependencyContainer.Resolve <IMetaModelCompabilityChecker>(); DbIdentification = parameters; IsDbClosed = false; var isNewDatabase = DbIdentification.IsNew(); _session = DependencyContainer.Resolve <ISession>(this); // Object Writer must be created before object Reader _objectWriter = DependencyContainer.Resolve <IObjectWriter>(this); ObjectReader = DependencyContainer.Resolve <IObjectReader>(this); // Associate current session to the fsi -> all transaction writes // will be applied to this FileSystemInterface _session.SetFileSystemInterfaceToApplyTransaction(_objectWriter.FileSystemProcessor.FileSystemInterface); _objectIntrospectionDataProvider = new SessionDataProvider(_session); if (isNewDatabase) { _objectWriter.CreateEmptyDatabaseHeader(OdbTime.GetCurrentTimeInTicks()); } else { GetObjectReader().ReadDatabaseHeader(); } _objectWriter.AfterInit(); _objectIntrospector = new ObjectIntrospector(GetClassInfoProvider()); _triggerManager = GetLocalTriggerManager(); // This forces the initialization of the meta model var metaModel = GetMetaModel(); var shouldUpdate = metaModelCompabilityChecker.Check(ClassIntrospector.Instrospect(metaModel.GetAllClasses()), GetMetaModel()); if (shouldUpdate) { UpdateMetaModel(); } _objectWriter.SetTriggerManager(_triggerManager); _introspectionCallbackForInsert = new InstrumentationCallbackForStore(_triggerManager, false); _introspectionCallbackForUpdate = new InstrumentationCallbackForStore(_triggerManager, true); } catch { if (parameters is FileIdentification) { Monitor.Exit(string.Intern(Path.GetFullPath(parameters.FileName))); } throw; } }
private AbstractObjectInfo GetNativeObjectInfoInternal(OdbType type, object o, bool recursive, IDictionary <object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) { aoi = new NullNativeObjectInfo(type.Id); } else { aoi = new AtomicNativeObjectInfo(o, type.Id); } } else if (type.IsArray()) { if (o == null) { aoi = new ArrayObjectInfo(null); } else { // Gets the type of the elements of the array var realArrayClassName = OdbClassNameResolver.GetFullName(o.GetType().GetElementType()); var arrayObjectInfo = recursive ? IntrospectArray(o, alreadyReadObjects, type, callback) : new ArrayObjectInfo((object[])o); arrayObjectInfo.SetRealArrayComponentClassName(realArrayClassName); aoi = arrayObjectInfo; } } else if (type.IsEnum()) { var enumObject = (Enum)o; // Here we must check if the enum is already in the meta model. Enum must be stored in the meta // model to optimize its storing as we need to keep track of the enum class // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long // instead of the full enum class name string var classInfo = GetClassInfo(enumObject.GetType()); var enumValue = enumObject.ToString(); aoi = new EnumNativeObjectInfo(classInfo, enumValue); } return(aoi); }
public AbstractObjectInfo GetMetaRepresentation(object plainObject, bool recursive, IDictionary<object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { if (plainObject == null) return GetObjectInfo(null, null, recursive, alreadyReadObjects, callback); // The object must be transformed into meta representation var type = plainObject.GetType(); var classInfo = _classInfoProvider.GetClassInfo(type); return GetObjectInfo(plainObject, classInfo, recursive, alreadyReadObjects, callback); }
public AbstractObjectInfo GetMetaRepresentation(object plainObject, bool recursive, IDictionary <object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { if (plainObject == null) { return(GetObjectInfo(null, null, recursive, alreadyReadObjects, callback)); } // The object must be transformed into meta representation var type = plainObject.GetType(); var classInfo = _classInfoProvider.GetClassInfo(type); return(GetObjectInfo(plainObject, classInfo, recursive, alreadyReadObjects, callback)); }
private AbstractObjectInfo GetNativeObjectInfoInternal(OdbType type, object o, bool recursive, IDictionary<object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) aoi = new NullNativeObjectInfo(type.Id); else aoi = new AtomicNativeObjectInfo(o, type.Id); } else if (type.IsArray()) { if (o == null) aoi = new ArrayObjectInfo(null); else { // Gets the type of the elements of the array var realArrayClassName = OdbClassNameResolver.GetFullName(o.GetType().GetElementType()); var arrayObjectInfo = recursive ? IntrospectArray(o, alreadyReadObjects, type, callback) : new ArrayObjectInfo((object[]) o); arrayObjectInfo.SetRealArrayComponentClassName(realArrayClassName); aoi = arrayObjectInfo; } } else if (type.IsEnum()) { var enumObject = (Enum) o; // Here we must check if the enum is already in the meta model. Enum must be stored in the meta // model to optimize its storing as we need to keep track of the enum class // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long // instead of the full enum class name string var classInfo = GetClassInfo(enumObject.GetType()); var enumValue = enumObject.ToString(); aoi = new EnumNativeObjectInfo(classInfo, enumValue); } return aoi; }
/// <summary> /// retrieve object data /// </summary> /// <returns> The object info </returns> private AbstractObjectInfo GetObjectInfo(object o, ClassInfo ci, bool recursive, IDictionary <object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { return(GetObjectInfoInternal(null, o, ci, recursive, alreadyReadObjects, callback)); }
/// <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); }
/// <summary> /// retrieve object data /// </summary> /// <returns> The object info </returns> private AbstractObjectInfo GetObjectInfo(object o, ClassInfo ci, bool recursive, IDictionary<object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { return GetObjectInfoInternal(null, o, ci, recursive, alreadyReadObjects, callback); }
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); }
/// <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; }
private System.Collections.Generic.IDictionary<AbstractObjectInfo, AbstractObjectInfo> IntrospectGenericMap( System.Collections.Generic.IDictionary<object,object> map, bool introspect, IDictionary<object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { System.Collections.Generic.IDictionary<AbstractObjectInfo, AbstractObjectInfo> mapCopy = new OdbHashMap<AbstractObjectInfo, AbstractObjectInfo>(); System.Collections.Generic.ICollection<object> keySet = map.Keys; System.Collections.IEnumerator keys = keySet.GetEnumerator(); NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ciKey = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ciValue = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoiForKey = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoiForValue = null; while (keys.MoveNext()) { object key = keys.Current; object value = map[key]; if (key != null) { ciKey = GetClassInfo(OdbClassUtil.GetFullName(key.GetType())); if (value != null) { ciValue = GetClassInfo(OdbClassUtil.GetFullName(value.GetType())); } aoiForKey = GetObjectInfo(key, ciKey, introspect, alreadyReadObjects, callback); aoiForValue = GetObjectInfo(value, ciValue, introspect, alreadyReadObjects, callback); mapCopy.Add(aoiForKey, aoiForValue); } } return mapCopy; }
/// <summary>Store an object with the specific id</summary> /// <param name="oid"></param> /// <param name="@object"></param> /// <returns></returns> /// <></> protected virtual NeoDatis.Odb.OID InternalStore(OID oid, object o) { if (GetSession(true).IsRollbacked()) { throw new ODBRuntimeException(NeoDatisError.OdbHasBeenRollbacked.AddParameter(GetBaseIdentification().ToString())); } if (o == null) { throw new ODBRuntimeException(NeoDatisError.OdbCanNotStoreNullObject); } Type clazz = o.GetType(); if (ODBType.IsNative(clazz)) { throw new ODBRuntimeException(NeoDatisError.OdbCanNotStoreNativeObjectDirectly .AddParameter(clazz.FullName).AddParameter(ODBType.GetFromClass(clazz).GetName()).AddParameter(clazz.FullName)); } // The object must be transformed into meta representation ClassInfo ci = null; string className = OdbClassUtil.GetFullName(clazz); // first checks if the class of this object already exist in the // metamodel if (GetMetaModel().ExistClass(className)) { ci = GetMetaModel().GetClassInfo(className, true); } else { ClassInfoList ciList = classIntrospector.Introspect(o.GetType(), true); // All new classes found objectWriter.AddClasses(ciList); ci = ciList.GetMainClassInfo(); } // 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 bool mustUpdate = false; ICache cache = GetSession(true).GetCache(); if (o != null) { OID cacheOid = cache.IdOfInsertingObject(o); if (cacheOid != null) { return(cacheOid); } // throw new ODBRuntimeException("Inserting meta representation of // an object without the object itself is not yet supported"); mustUpdate = cache.ExistObject(o); } // The introspection callback is used to execute some specific task (like calling trigger, for example) while introspecting the object IIntrospectionCallback callback = introspectionCallbackForInsert; if (mustUpdate) { callback = introspectionCallbackForUpdate; } // Transform the object into an ObjectInfo NonNativeObjectInfo nnoi = (NonNativeObjectInfo)objectIntrospector.GetMetaRepresentation(o, ci, true, null, callback); // During the introspection process, if object is to be updated, then the oid has been set mustUpdate = nnoi.GetOid() != null; if (mustUpdate) { return(objectWriter.UpdateNonNativeObjectInfo(nnoi, false)); } return(objectWriter.InsertNonNativeObject(oid, nnoi, true)); }