Beispiel #1
0
 public virtual NeoDatis.Odb.Objects <T> Execute <T>(bool inMemory, int startIndex,
                                                     int endIndex, bool returnObjects, NeoDatis.Odb.Core.Query.Execution.IMatchingObjectAction
                                                     queryResultAction)
 {
     if (storageEngine.IsClosed())
     {
         throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.OdbIsClosed
                                                    .AddParameter(storageEngine.GetBaseIdentification().GetIdentification()));
     }
     if (session.IsRollbacked())
     {
         throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.OdbHasBeenRollbacked
                                                    );
     }
     // When used as MultiClass Executor, classInfo is already set
     if (classInfo == null)
     {
         // Class to execute query on
         string fullClassName = NeoDatis.Odb.Core.Query.QueryManager.GetFullClassName(query
                                                                                      );
         // If the query class does not exist in meta model, return an empty
         // collection
         if (!session.GetMetaModel().ExistClass(fullClassName))
         {
             queryResultAction.Start();
             queryResultAction.End();
             query.SetExecutionPlan(new NeoDatis.Odb.Core.Query.Execution.EmptyExecutionPlan()
                                    );
             return(queryResultAction.GetObjects <T>());
         }
         classInfo = session.GetMetaModel().GetClassInfo(fullClassName, true);
     }
     // Get the query execution plan
     NeoDatis.Odb.Core.Query.Execution.IQueryExecutionPlan plan = GetExecutionPlan();
     plan.Start();
     try
     {
         if (plan.UseIndex() && NeoDatis.Odb.OdbConfiguration.UseIndex())
         {
             return(ExecuteUsingIndex <T>(plan.GetIndex(), inMemory, startIndex, endIndex, returnObjects
                                          , queryResultAction));
         }
         // When query must be applied to a single object
         if (query.IsForSingleOid())
         {
             return(ExecuteForOneOid <T>(inMemory, returnObjects, queryResultAction));
         }
         return(ExecuteFullScan <T>(inMemory, startIndex, endIndex, returnObjects, queryResultAction
                                    ));
     }
     finally
     {
         plan.End();
     }
 }
        /// <summary>The main query execution method</summary>
        /// <param name="query"></param>
        /// <param name="inMemory"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="returnObjects"></param>
        /// <returns></returns>
        /// <exception cref="System.Exception">System.Exception</exception>
        public virtual NeoDatis.Odb.Objects <T> Execute <T>(bool inMemory, int startIndex,
                                                            int endIndex, bool returnObjects, NeoDatis.Odb.Core.Query.Execution.IMatchingObjectAction
                                                            queryResultAction)
        {
            if (executor.GetStorageEngine().IsClosed())
            {
                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.OdbIsClosed
                                                           .AddParameter(executor.GetStorageEngine().GetBaseIdentification().GetIdentification
                                                                             ()));
            }
            if (executor.GetStorageEngine().GetSession(true).IsRollbacked())
            {
                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.OdbHasBeenRollbacked
                                                           );
            }
            // Get the main class
            string fullClassName = NeoDatis.Odb.Core.Query.QueryManager.GetFullClassName(executor
                                                                                         .GetQuery());

            // this is done once.
            queryResultAction.Start();
            NeoDatis.Tool.Wrappers.List.IOdbList <NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo
                                                  > allClassInfos = executor.GetStorageEngine().GetSession(true).GetMetaModel().GetPersistentSubclassesOf
                                                                        (fullClassName);
            int nbClasses = allClassInfos.Count;

            NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null;
            for (int i = 0; i < nbClasses; i++)
            {
                ci = allClassInfos[i];
                // Sets the class info to the current
                executor.SetClassInfo(ci);
                // Then execute query
                executor.Execute <T>(inMemory, startIndex, endIndex, returnObjects, queryResultAction
                                     );
            }
            queryResultAction.End();
            return(queryResultAction.GetObjects <T>());
        }
Beispiel #3
0
        /// <summary>Execute query using index</summary>
        /// <param name="inMemory"></param>
        /// <param name="returnObjects"></param>
        /// <returns></returns>
        /// <exception cref="System.Exception">System.Exception</exception>
        private NeoDatis.Odb.Objects <T> ExecuteForOneOid <T>(bool inMemory, bool returnObjects
                                                              , NeoDatis.Odb.Core.Query.Execution.IMatchingObjectAction queryResultAction)
        {
            if (NeoDatis.Odb.OdbConfiguration.IsDebugEnabled(LogId))
            {
                NeoDatis.Tool.DLogger.Debug("loading Object with oid " + query.GetOidOfObjectToQuery
                                                () + " - class " + classInfo.GetFullClassName());
            }
            if (ExecuteStartAndEndOfQueryAction())
            {
                queryResultAction.Start();
            }
            PrepareQuery();
            NeoDatis.Odb.OID oid = query.GetOidOfObjectToQuery();
            // FIXME Why calling this method
            long position      = objectReader.GetObjectPositionFromItsOid(oid, true, true);
            bool objectMatches = MatchObjectWithOid(oid, returnObjects, inMemory);

            queryResultAction.ObjectMatch(oid, GetCurrentObjectMetaRepresentation(), orderByKey
                                          );
            queryResultAction.End();
            return(queryResultAction.GetObjects <T>());
        }
Beispiel #4
0
        /// <summary>Execute query using index</summary>
        /// <param name="index"></param>
        /// <param name="inMemory"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="returnObjects"></param>
        /// <returns></returns>
        /// <exception cref="System.Exception">System.Exception</exception>
        private NeoDatis.Odb.Objects <T> ExecuteUsingIndex <T>(NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfoIndex
                                                               index, bool inMemory, int startIndex, int endIndex, bool returnObjects, NeoDatis.Odb.Core.Query.Execution.IMatchingObjectAction
                                                               queryResultAction)
        {
            // Index that have not been used yet do not have persister!
            if (index.GetBTree().GetPersister() == null)
            {
                index.GetBTree().SetPersister(new NeoDatis.Odb.Impl.Core.Btree.LazyODBBTreePersister
                                                  (storageEngine));
            }
            bool objectMatches = false;
            long nbObjects     = classInfo.GetNumberOfObjects();
            long btreeSize     = index.GetBTree().GetSize();

            // the two values should be equal
            if (nbObjects != btreeSize)
            {
                NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = storageEngine.GetSession(true
                                                                                             ).GetMetaModel().GetClassInfoFromId(index.GetClassInfoId());
                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.IndexIsCorrupted
                                                           .AddParameter(index.GetName()).AddParameter(ci.GetFullClassName()).AddParameter(
                                                               nbObjects).AddParameter(btreeSize));
            }
            if (NeoDatis.Odb.OdbConfiguration.IsDebugEnabled(LogId))
            {
                NeoDatis.Tool.DLogger.Debug("loading " + nbObjects + " instance(s) of " + classInfo
                                            .GetFullClassName());
            }
            if (ExecuteStartAndEndOfQueryAction())
            {
                queryResultAction.Start();
            }
            PrepareQuery();
            if (query != null)
            {
                queryHasOrderBy = query.HasOrderBy();
            }
            NeoDatis.Btree.IBTree tree = index.GetBTree();
            bool isUnique = index.IsUnique();

            // Iterator iterator = new BTreeIterator(tree,
            // OrderByConstants.ORDER_BY_ASC);
            System.IComparable       key  = ComputeIndexKey(classInfo, index);
            System.Collections.IList list = null;
            // If index is unique, get the object
            if (isUnique)
            {
                NeoDatis.Btree.IBTreeSingleValuePerKey treeSingle = (NeoDatis.Btree.IBTreeSingleValuePerKey
                                                                     )tree;
                object o = treeSingle.Search(key);
                if (o != null)
                {
                    list = new System.Collections.ArrayList();
                    list.Add(o);
                }
            }
            else
            {
                NeoDatis.Btree.IBTreeMultipleValuesPerKey treeMultiple = (NeoDatis.Btree.IBTreeMultipleValuesPerKey
                                                                          )tree;
                list = treeMultiple.Search(key);
            }
            if (list != null)
            {
                System.Collections.IEnumerator iterator = list.GetEnumerator();
                while (iterator.MoveNext())
                {
                    NeoDatis.Odb.OID oid = (NeoDatis.Odb.OID)iterator.Current;
                    // FIXME Why calling this method
                    long position = objectReader.GetObjectPositionFromItsOid(oid, true, true);
                    orderByKey    = null;
                    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>());
        }
Beispiel #5
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>
        /// <returns></returns>
        /// <exception cref="System.Exception">System.Exception</exception>
        private NeoDatis.Odb.Objects <T> ExecuteFullScan <T>(bool inMemory, int startIndex,
                                                             int endIndex, bool returnObjects, NeoDatis.Odb.Core.Query.Execution.IMatchingObjectAction
                                                             queryResultAction)
        {
            bool objectInRange = false;
            bool objectMatches = false;

            if (storageEngine.IsClosed())
            {
                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.OdbIsClosed
                                                           .AddParameter(storageEngine.GetBaseIdentification().GetIdentification()));
            }
            long nbObjects = classInfo.GetNumberOfObjects();

            if (NeoDatis.Odb.OdbConfiguration.IsDebugEnabled(LogId))
            {
                NeoDatis.Tool.DLogger.Debug("loading " + nbObjects + " instance(s) of " + classInfo
                                            .GetFullClassName());
            }
            if (ExecuteStartAndEndOfQueryAction())
            {
                queryResultAction.Start();
            }
            NeoDatis.Odb.OID currentOID = null;
            NeoDatis.Odb.OID prevOID    = null;
            // TODO check if all instances are in the cache! and then load from the
            // cache
            nextOID = classInfo.GetCommitedZoneInfo().first;
            if (nbObjects > 0 && nextOID == null)
            {
                // This means that some changes have not been commited!
                // Take next position from uncommited zone
                nextOID = classInfo.GetUncommittedZoneInfo().first;
            }
            PrepareQuery();
            if (query != null)
            {
                queryHasOrderBy = query.HasOrderBy();
            }
            bool monitorMemory = NeoDatis.Odb.OdbConfiguration.IsMonitoringMemory();
            // used when startIndex and endIndex are not negative
            int nbObjectsInResult = 0;

            for (int i = 0; i < nbObjects; i++)
            {
                //Console.WriteLine(i);
                if (monitorMemory && i % 10000 == 0)
                {
                    NeoDatis.Odb.Impl.Tool.MemoryMonitor.DisplayCurrentMemory(string.Empty + (i + 1),
                                                                              true);
                }
                // Reset the order by key
                orderByKey    = null;
                objectMatches = false;
                prevOID       = currentOID;
                currentOID    = nextOID;
                // This is an error
                if (currentOID == null)
                {
                    if (NeoDatis.Odb.OdbConfiguration.ThrowExceptionWhenInconsistencyFound())
                    {
                        throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.NullNextObjectOid
                                                                   .AddParameter(classInfo.GetFullClassName()).AddParameter(i).AddParameter(nbObjects
                                                                                                                                            ).AddParameter(prevOID));
                    }
                    break;
                }
                // If there is an endIndex condition
                if (endIndex != -1 && nbObjectsInResult >= endIndex)
                {
                    break;
                }
                // If there is a startIndex condition
                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
                {
                    objectMatches = MatchObjectWithOid(currentOID, returnObjects, inMemory);
                    if (objectMatches)
                    {
                        nbObjectsInResult++;
                        if (objectInRange)
                        {
                            if (queryHasOrderBy)
                            {
                                orderByKey = BuildOrderByKey(GetCurrentObjectMetaRepresentation());
                            }
                            queryResultAction.ObjectMatch(currentOID, GetCurrentObjectMetaRepresentation(), orderByKey
                                                          );
                            if (callback != null)
                            {
                                callback.ReadingObject(i, -1);
                            }
                        }
                    }
                }
            }
            if (ExecuteStartAndEndOfQueryAction())
            {
                queryResultAction.End();
            }
            return(queryResultAction.GetObjects <T>());
        }