/// <summary> /// Execute query using index /// </summary> /// <param name="inMemory"> </param> /// <param name="returnObjects"> </param> /// <param name="queryResultAction"> </param> private IInternalObjectSet <T> ExecuteForOneOid <T>(bool inMemory, bool returnObjects, IMatchingObjectAction queryResultAction) { Log4NetHelper.Instance.LogDebugMessage(string.Format("GenericQueryExecutor: loading Object with oid {0} - class {1}", Query.GetOidOfObjectToQuery(), ClassInfo.FullClassName)); if (ExecuteStartAndEndOfQueryAction()) { queryResultAction.Start(); } PrepareQuery(); var oid = Query.GetOidOfObjectToQuery(); MatchObjectWithOid(oid, returnObjects, inMemory); queryResultAction.ObjectMatch(oid, GetCurrentObjectMetaRepresentation(), _orderByKey); queryResultAction.End(); return(queryResultAction.GetObjects <T>()); }
/// <summary> /// The main query execution method /// </summary> /// <param name="inMemory"> </param> /// <param name="startIndex"> </param> /// <param name="endIndex"> </param> /// <param name="returnObjects"> </param> /// <param name="queryResultAction"> </param> public IInternalObjectSet <T> Execute <T>(bool inMemory, int startIndex, int endIndex, bool returnObjects, IMatchingObjectAction queryResultAction) { if (_executor.GetStorageEngine().IsClosed()) { throw new OdbRuntimeException( NDatabaseError.OdbIsClosed.AddParameter( _executor.GetStorageEngine().GetBaseIdentification().Id)); } if (_executor.GetStorageEngine().GetSession().IsRollbacked()) { throw new OdbRuntimeException(NDatabaseError.OdbHasBeenRollbacked); } // Get the main class var underlyingType = _executor.GetQuery().UnderlyingType; // this is done once. queryResultAction.Start(); var allClassInfos = _executor.GetStorageEngine().GetSession().GetMetaModel().GetPersistentSubclassesOf(underlyingType); var nbClasses = allClassInfos.Count; for (var i = 0; i < nbClasses; i++) { var classInfo = allClassInfos[i]; // Sets the class info to the current _executor.SetClassInfo(classInfo); // Then execute query _executor.Execute <T>(inMemory, startIndex, endIndex, returnObjects, queryResultAction); } queryResultAction.End(); return(queryResultAction.GetObjects <T>()); }
public virtual IInternalObjectSet <T> Execute <T>(bool inMemory, int startIndex, int endIndex, bool returnObjects, IMatchingObjectAction queryResultAction) { if (StorageEngine.IsClosed()) { throw new OdbRuntimeException( NDatabaseError.OdbIsClosed.AddParameter(StorageEngine.GetBaseIdentification().Id)); } if (Session.IsRollbacked()) { throw new OdbRuntimeException(NDatabaseError.OdbHasBeenRollbacked); } // Get the query execution plan var executionPlan = GetExecutionPlan(); executionPlan.Start(); try { if (executionPlan.UseIndex()) { return(ExecuteUsingIndex <T>(executionPlan.GetIndex(), inMemory, returnObjects, queryResultAction)); } // When query must be applied to a single object return(Query.IsForSingleOid() ? ExecuteForOneOid <T>(inMemory, returnObjects, queryResultAction) : ExecuteFullScan <T>(inMemory, startIndex, endIndex, returnObjects, queryResultAction)); } finally { executionPlan.End(); } }
/// <summary> /// Execute query using index /// </summary> /// <param name="index"> </param> /// <param name="inMemory"> </param> /// <param name="returnObjects"> </param> /// <param name="queryResultAction"> </param> private IInternalObjectSet <T> ExecuteUsingIndex <T>(ClassInfoIndex index, bool inMemory, bool returnObjects, IMatchingObjectAction queryResultAction) { // Index that have not been used yet do not have persister! if (index.BTree.GetPersister() == null) { index.BTree.SetPersister(new LazyOdbBtreePersister(StorageEngine)); } var nbObjects = ClassInfo.NumberOfObjects; var btreeSize = index.BTree.GetSize(); // the two values should be equal if (nbObjects != btreeSize) { var classInfo = StorageEngine.GetSession().GetMetaModel().GetClassInfoFromId(index.ClassInfoId); throw new OdbRuntimeException( NDatabaseError.IndexIsCorrupted.AddParameter(index.Name).AddParameter(classInfo.FullClassName). AddParameter(nbObjects).AddParameter(btreeSize)); } if (OdbConfiguration.IsLoggingEnabled()) { DLogger.Debug(string.Format("GenericQueryExecutor: loading {0} instance(s) of {1}", nbObjects, ClassInfo.FullClassName)); } if (ExecuteStartAndEndOfQueryAction()) { queryResultAction.Start(); } PrepareQuery(); if (Query != null) { _queryHasOrderBy = Query.HasOrderBy(); } var tree = index.BTree; var isUnique = index.IsUnique; // Iterator iterator = new BTreeIterator(tree, // OrderByConstants.ORDER_BY_ASC); var key = ComputeIndexKey(index); IList list = null; // If index is unique, get the object if (isUnique) { var treeSingle = (IBTreeSingleValuePerKey)tree; var value = treeSingle.Search(key); if (value != null) { list = new List <object> { value } } ; } else { var treeMultiple = (IBTreeMultipleValuesPerKey)tree; list = treeMultiple.Search(key); } if (list != null) { foreach (OID oid in list) { // FIXME Why calling this method ObjectReader.GetObjectPositionFromItsOid(oid, true, true); _orderByKey = null; var objectMatches = MatchObjectWithOid(oid, returnObjects, inMemory); if (objectMatches) { queryResultAction.ObjectMatch(oid, GetCurrentObjectMetaRepresentation(), _orderByKey); } } queryResultAction.End(); return(queryResultAction.GetObjects <T>()); } if (ExecuteStartAndEndOfQueryAction()) { queryResultAction.End(); } return(queryResultAction.GetObjects <T>()); }
/// <summary> /// Query execution full scan <pre>startIndex & endIndex /// A B C D E F G H I J K L /// [1,3] : nb >=1 && nb<3 /// 1) /// analyze A /// nb = 0 /// nb E [1,3] ? no /// r=[] /// 2) /// analyze B /// nb = 1 /// nb E [1,3] ? yes /// r=[B] /// 3) analyze C /// nb = 2 /// nb E [1,3] ? yes /// r=[B,C] /// 4) analyze C /// nb = 3 /// nb E [1,3] ? no and 3> upperBound([1,3]) => exit</pre> /// </summary> /// <param name="inMemory"> </param> /// <param name="startIndex"> </param> /// <param name="endIndex"> </param> /// <param name="returnObjects"> </param> /// <param name="queryResultAction"> </param> private IInternalObjectSet <T> ExecuteFullScan <T>(bool inMemory, int startIndex, int endIndex, bool returnObjects, IMatchingObjectAction queryResultAction) { if (StorageEngine.IsClosed()) { throw new OdbRuntimeException( NDatabaseError.OdbIsClosed.AddParameter(StorageEngine.GetBaseIdentification().Id)); } var nbObjects = ClassInfo.NumberOfObjects; if (OdbConfiguration.IsLoggingEnabled()) { DLogger.Debug(string.Format("GenericQueryExecutor: loading {0} instance(s) of {1}", nbObjects, ClassInfo.FullClassName)); } if (ExecuteStartAndEndOfQueryAction()) { queryResultAction.Start(); } OID currentOID = null; // TODO check if all instances are in the cache! and then load from the cache NextOID = ClassInfo.CommitedZoneInfo.First; if (nbObjects > 0 && NextOID == null) { // This means that some changes have not been commited! // Take next position from uncommited zone NextOID = ClassInfo.UncommittedZoneInfo.First; } PrepareQuery(); if (Query != null) { _queryHasOrderBy = Query.HasOrderBy(); } // used when startIndex and endIndex are not negative var nbObjectsInResult = 0; for (var i = 0; i < nbObjects; i++) { // Reset the order by key _orderByKey = null; var prevOID = currentOID; currentOID = NextOID; // This is an error if (currentOID == null) { throw new OdbRuntimeException( NDatabaseError.NullNextObjectOid.AddParameter(ClassInfo.FullClassName).AddParameter(i). AddParameter(nbObjects).AddParameter(prevOID)); } // If there is an endIndex condition if (endIndex != -1 && nbObjectsInResult >= endIndex) { break; } // If there is a startIndex condition bool objectInRange; if (startIndex != -1 && nbObjectsInResult < startIndex) { objectInRange = false; } else { objectInRange = true; } // There is no query if (!inMemory && Query == null) { nbObjectsInResult++; // keep object position if we must if (objectInRange) { _orderByKey = BuildOrderByKey(CurrentNnoi); // TODO Where is the key for order by queryResultAction.ObjectMatch(NextOID, _orderByKey); } NextOID = ObjectReader.GetNextObjectOID(currentOID); } else { var objectMatches = MatchObjectWithOid(currentOID, returnObjects, inMemory); if (objectMatches) { nbObjectsInResult++; if (objectInRange) { if (_queryHasOrderBy) { _orderByKey = BuildOrderByKey(GetCurrentObjectMetaRepresentation()); } queryResultAction.ObjectMatch(currentOID, GetCurrentObjectMetaRepresentation(), _orderByKey); } } } } if (ExecuteStartAndEndOfQueryAction()) { queryResultAction.End(); } return(queryResultAction.GetObjects <T>()); }
public IObjectSet <T> GetObjectInfos <T>(IQuery query, bool inMemory, int startIndex, int endIndex, bool returnObjects, IMatchingObjectAction queryResultAction) { return(null); }
public IObjectSet <TResult> GetObjectInfos <TResult, TObject>(IQuery query, bool inMemory, int startIndex, int endIndex, bool returnObjects, IMatchingObjectAction queryResultAction) where TObject : class { throw new NotImplementedException(); }