/// <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>()); }