Exemple #1
0
        /// <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>());
        }
Exemple #2
0
        /// <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>());
        }
        /// <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 &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>());
        }