Ejemplo n.º 1
0
        /// <summary>
        ///   Query execution full scan <pre>startIndex &amp; endIndex
        ///                               A B C D E F G H I J K L
        ///                               [1,3] : nb &gt;=1 &amp;&amp; nb&lt;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&gt; upperBound([1,3]) =&gt; 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>());
        }