コード例 #1
0
ファイル: DBTypeManager.cs プロジェクト: TheByte/sones
        /// <summary>
        /// This method adds a bunch of new GraphTypeDefinitions (comes from a CREATE TYPE(S) statement) to the TypeManager.
        /// If a certain PType can't be added (because of some inheritance or 
        /// attribute errors), this method tries to add it in a second 
        /// step.
        /// </summary>
        /// <param name="TypeList">List of GraphType definitions that should 
        /// be added to the TypeManager</param>
        /// <returns>List of GraphError</returns>
        public Exceptional<QueryResult> AddBulkTypes(List<GraphDBTypeDefinition> TypeList, DBContext currentContext)
        {
            #region Input Exceptions

            if (TypeList == null)
            {
                return new Exceptional<QueryResult>(new QueryResult());
            }

            if (TypeList.Count.Equals(0))
            {
                return new Exceptional<QueryResult>(new QueryResult());
            }

            #endregion

            #region Data

            var errors = new List<GraphDBError>();
            List<GraphDBType> addedTypes = new List<GraphDBType>();
            List<AttributeUUID> uniqueAttrIDs = new List<AttributeUUID>();
            QueryResult result = new QueryResult();

            #endregion

            try
            {

                #region Create the types without attributes

                foreach (GraphDBTypeDefinition aTypeDef in TypeList)
                {

                    #region Input validation

                    if (String.IsNullOrEmpty(aTypeDef.Name))
                        return new Exceptional<QueryResult>(new Error_ArgumentNullOrEmpty("myTypeName"));

                    if (String.IsNullOrEmpty(aTypeDef.ParentType))
                        return new Exceptional<QueryResult>(new Error_ArgumentNullOrEmpty("myParentType"));

                    if (aTypeDef.Attributes == null)
                        return new Exceptional<QueryResult>(new Error_ArgumentNullOrEmpty("myAttributes"));

                    #endregion

                    GraphDBType thisType = GetTypeByName(aTypeDef.Name);

                    #region Check if the name of the type is already used

                    if (thisType != null)
                    {
                        return new Exceptional<QueryResult>(new Error_TypeAlreadyExist(aTypeDef.Name));
                    }

                    #endregion

                    GraphDBType parentType = GetTypeByName(aTypeDef.ParentType);
                    Dictionary<AttributeUUID, TypeAttribute> attributes = new Dictionary<AttributeUUID, TypeAttribute>();

                    #region objectDirectoryShards

                    var objectDirectoryShards = UInt16.Parse(currentContext.GraphAppSettings.Get<ObjectsDirectoryShardsSetting>());

                    #endregion

                    #region Add type

                    TypeUUID parentUUID = (parentType == null) ? null : parentType.UUID;

                    #region hack

                    GraphDBType _NewGraphType = new GraphDBType(null, new ObjectLocation(_DatabaseRootPath), aTypeDef.Name, parentUUID, attributes, true, aTypeDef.IsAbstract, aTypeDef.Comment, objectDirectoryShards);

                    #endregion

                    addedTypes.Add(_NewGraphType);

                    _UserDefinedTypes.Add(_NewGraphType.UUID, _NewGraphType);
                    _TypesNameLookUpTable.Add(_NewGraphType.Name, _NewGraphType);

                    #endregion

                }

                #endregion

                var backwardEdgesToBeAddedAfterwards = new Dictionary<GraphDBType, List<BackwardEdgeDefinition>>();

                #region Validate the previously added types and add the attributes and backwardEdges

                foreach (var aTypeDef in TypeList)
                {
                    GraphDBType aType = addedTypes.Where(item => item.Name == aTypeDef.Name).FirstOrDefault();

                    #region Check and set parent

                    GraphDBType parentType;

                    #region Verify base type existence

                    if (aType.ParentTypeUUID == null)
                    {
                        parentType = addedTypes.Where(item => item.Name == aTypeDef.ParentType).FirstOrDefault();
                        if (parentType == null)
                        {
                            RemoveRecentlyAddedTypes(addedTypes);
                            return new Exceptional<QueryResult>(new Error_ParentTypeDoesNotExist(aTypeDef.ParentType, aTypeDef.Name));
                        }
                        aType.SetParentTypeUUID(parentType.UUID);
                    }
                    else
                    {
                        parentType = aType.GetParentType(this);
                    }

                    #endregion

                    #region Verify that the type inherit DBReference

                    var parentTypeExcept = HasParentType(parentType.UUID, DBReference.UUID);

                    if (parentTypeExcept.Failed())
                    {
                        return new Exceptional<QueryResult>(parentTypeExcept);
                    }

                    if (!parentTypeExcept.Value)
                    {
                        RemoveRecentlyAddedTypes(addedTypes);
                        return new Exceptional<QueryResult>(new Error_InvalidBaseType(parentType.Name));
                    }

                    #endregion

                    #endregion

                    //add TypeAttributeLookuptable to current type
                    aType.AttributeLookupTable.AddRange(parentType.AttributeLookupTable);

                    #region check and set type of attributes

                    UInt16 attributeCounter = 0;

                    foreach (var attributeDef in aTypeDef.Attributes)
                    {
                        var attribute = attributeDef.Key.CreateTypeAttribute(currentContext, addedTypes, attributeCounter);
                        if (attribute.Failed())
                        {
                            return new Exceptional<QueryResult>(attribute);
                        }

                        if (attribute.Value.Name == aType.Name)
                        {
                            RemoveRecentlyAddedTypes(addedTypes);
                            return new Exceptional<QueryResult>(new Error_InvalidAttributeName("The attribute " + attribute.Value.Name + " can not be added, because it has the same name as its related type."));
                        }

                        GraphDBType attrType = GetTypeByName(attributeDef.Value);
                        if (attrType == null)
                        {
                            attrType = addedTypes.Where(item => item.Name == attributeDef.Value).FirstOrDefault();
                            if (attrType == null)
                            {
                                RemoveRecentlyAddedTypes(addedTypes);
                                return new Exceptional<QueryResult>(new Error_TypeDoesNotExist(attributeDef.Value));
                            }
                        }

                        attributeCounter++;

                        TypeAttribute newAttr = attribute.Value;

                        newAttr.DBTypeUUID = attrType.UUID;
                        newAttr.RelatedGraphDBTypeUUID = aType.UUID;

                        #region we had not defined a special EdgeType - for single reference attributes we need to set the EdgeTypeSingle NOW!

                        if (newAttr.KindOfType == KindsOfType.SingleReference && attrType.IsUserDefined && newAttr.EdgeType == null)
                            newAttr.EdgeType = new EdgeTypeSingleReference(null, newAttr.DBTypeUUID);

                        #endregion

                        #region Validate EdgeType in terms of List & Single

                        if (newAttr.KindOfType == KindsOfType.SingleReference && attrType.IsUserDefined && !(newAttr.EdgeType is ASingleReferenceEdgeType))
                        {
                            RemoveRecentlyAddedTypes(addedTypes);
                            return new Exceptional<QueryResult>(new Error_InvalidEdgeType(newAttr.EdgeType.GetType(), typeof(ASingleReferenceEdgeType)));
                        }
                        else if (newAttr.KindOfType == KindsOfType.SetOfReferences || newAttr.KindOfType == KindsOfType.SetOfNoneReferences)
                        {
                            if (attrType.IsUserDefined && !(newAttr.EdgeType is ASetOfReferencesEdgeType))
                            {
                                RemoveRecentlyAddedTypes(addedTypes);
                                return new Exceptional<QueryResult>(new Error_InvalidEdgeType(newAttr.EdgeType.GetType(), typeof(ASetOfReferencesEdgeType)));
                            }
                            else if (!attrType.IsUserDefined && !(newAttr.EdgeType is ASetOfBaseEdgeType))
                            {
                                RemoveRecentlyAddedTypes(addedTypes);
                                return new Exceptional<QueryResult>(new Error_InvalidEdgeType(newAttr.EdgeType.GetType(), typeof(AListOfBaseEdgeType)));
                            }
                        }

                        #endregion

                        aType.AddAttribute(newAttr, this, true);
                    }

                    #endregion

                    #region Set BackwardEdges

                    if (!aTypeDef.BackwardEdgeNodes.IsNullOrEmpty())
                    {
                        backwardEdgesToBeAddedAfterwards.Add(aType, aTypeDef.BackwardEdgeNodes);
                    }

                    #endregion
                }

                #endregion

                #region Add the BackwardEdges

                foreach (var beDefinition in backwardEdgesToBeAddedAfterwards)
                {
                    var aType = beDefinition.Key;
                    UInt16 beAttrCounter = 0;
                    foreach (var be in beDefinition.Value)
                    {

                        var bedgeAttribute = CreateBackwardEdgeAttribute(be, aType, beAttrCounter);

                        if (!bedgeAttribute.Success())
                        {
                            RemoveRecentlyAddedTypes(addedTypes);
                            return new Exceptional<QueryResult>(bedgeAttribute);
                        }

                        aType.AddAttribute(bedgeAttribute.Value, this, true);

                        beAttrCounter++;
                    }
                }

                #endregion

                #region Validate Attribute dependencies

                var _Vertices = new List<Vertex>();

                foreach (var _GraphDBType in addedTypes)
                {
                    foreach (var _GraphDBType2 in GetAllParentTypes(_GraphDBType, false, true))
                    {

                        var _MandatoryAttributes = _GraphDBType2.GetMandatoryAttributesUUIDs(this);
                        var _UniqueAttributes    = _GraphDBType2.GetAllUniqueAttributes(false, this);

                        foreach (var _TypeAttribute in _GraphDBType.Attributes.Values)
                        {

                            if (_GraphDBType2.GetTypeAttributeByName(_TypeAttribute.Name) != null)
                            {
                                // Todo: Use notification here
                                RemoveRecentlyAddedTypes(addedTypes);
                                return new Exceptional<QueryResult>(new Error_AttributeExistsInSupertype(_TypeAttribute.Name, _GraphDBType.Name));
                            }

                            #region unique and mandatory attributes

                            if (_TypeAttribute.TypeCharacteristics.IsUnique && !_UniqueAttributes.Contains(_TypeAttribute.UUID))
                            {
                                //if the attrbute has been marked unique and it is not contained in uniques of super types
                                if (!uniqueAttrIDs.Contains(_TypeAttribute.UUID))
                                {
                                    uniqueAttrIDs.Add(_TypeAttribute.UUID);
                                }
                            }

                            if (_TypeAttribute.TypeCharacteristics.IsMandatory && !_MandatoryAttributes.Contains(_TypeAttribute.UUID))
                            {
                                _GraphDBType.AddMandatoryAttribute(_TypeAttribute.UUID, this);
                            }

                            #endregion

                        }
                    }

                    //Add the unique attribute ids for the current type
                    var AddUniqueAttrExcept = _GraphDBType.AddUniqueAttributes(uniqueAttrIDs, currentContext);

                    if(AddUniqueAttrExcept.Failed())
                        return new Exceptional<QueryResult>(AddUniqueAttrExcept);

                    uniqueAttrIDs.Clear();
                }

                #endregion

                #region Create indices

                foreach (GraphDBType aType in addedTypes)
                {
                    #region Create userdefined Indices

                    var aTypeDef = TypeList.Where(item => item.Name == aType.Name).FirstOrDefault();

                    if (!aTypeDef.Indices.IsNullOrEmpty())
                    {
                        foreach (var index in aTypeDef.Indices)
                        {

                            if (!index.IndexAttributeDefinitions.All(node => !node.IndexAttribute.Validate(currentContext, false, aType).Failed()))
                            {
                                RemoveRecentlyAddedTypes(addedTypes);
                                return new Exceptional<QueryResult>(new Error_AttributeIsNotDefined(aType.Name, aType.Name));
                            }

                            var idxName = index.IndexName;
                            if (String.IsNullOrEmpty(index.IndexName))
                            {
                                idxName = index.IndexAttributeDefinitions.Aggregate(new StringBuilder(DBConstants.IndexKeyPrefix), (stringB, elem) => { stringB.Append(String.Concat(DBConstants.IndexKeySeperator, elem.IndexAttribute.LastAttribute.Name)); return stringB; }).ToString();
                            }

                            List<AttributeUUID> indexAttrs = new List<AttributeUUID>(index.IndexAttributeDefinitions.Select(node => node.IndexAttribute.LastAttribute.UUID));

                            foreach (var item in GetAllSubtypes(aType))
                            {
                                var CreateIdxExcept = item.CreateAttributeIndex(currentContext, idxName, indexAttrs, index.Edition, index.IndexType);

                                if (!CreateIdxExcept.Success())
                                    return new Exceptional<QueryResult>(CreateIdxExcept);
                            }
                        }
                    }

                    #endregion

                    //UUID index
                    var createIndexExcept = aType.CreateUUIDIndex(_DBContext, GetUUIDTypeAttribute().UUID);

                    if (!createIndexExcept.Success())
                    {
                        return new Exceptional<QueryResult>(createIndexExcept);
                    }

                    List<AttributeUUID> UniqueIDs = aType.GetAllUniqueAttributes(true, this);

                    if (UniqueIDs.Count() > 0)
                    {
                        var idxName = _DBContext.DBIndexManager.GetUniqueIndexName(UniqueIDs, aType); // UniqueIDs.Aggregate<AttributeUUID, String>("Idx", (result, item) => result = result + "_" + aType.GetTypeAttributeByUUID(item).Name);
                        var createIdxExcept = aType.CreateUniqueAttributeIndex(currentContext, idxName, UniqueIDs, DBConstants.UNIQUEATTRIBUTESINDEX);

                        if (!createIdxExcept.Success())
                            return new Exceptional<QueryResult>(createIdxExcept);
                    }
                }

                #endregion

                #region flush to fs

                foreach (var item in addedTypes)
                {
                    var createException = CreateTypeOnFS(item);

                    if (!createException.Success())
                        return new Exceptional<QueryResult>(createException);

                    #region get system attributes from type

                    var readOut = GetVertexForType(item);

                    if (!readOut.Success())
                        return new Exceptional<QueryResult>(readOut.IErrors.First());

                    _Vertices.Add(readOut.Value);

                    #endregion
                }

                result.Vertices = _Vertices;

                #endregion

            }
            catch (GraphDBException ee)
            {
                RemoveRecentlyAddedTypes(addedTypes);

                var _Exceptional = new Exceptional<QueryResult>();
                foreach (var _ex in ee.GraphDBErrors)
                    _Exceptional.PushIError(_ex);

                return _Exceptional;

            }
            catch (GraphDBWarningException ee)
            {
                RemoveRecentlyAddedTypes(addedTypes);
                return new Exceptional<QueryResult>(ee.GraphDBWarning);
            }
            catch (Exception e)
            //finally
            {
                //if (!succeeded)
                //{
                addedTypes.ForEach(item =>
                {
                    _UserDefinedTypes.Remove(item.UUID);
                    _TypesNameLookUpTable.Remove(item.Name);
                });
                //}

                return new Exceptional<QueryResult>(new Error_UnknownDBError(e));

            }

            return new Exceptional<QueryResult>(result);
        }
コード例 #2
0
ファイル: DBTypeManager.cs プロジェクト: TheByte/sones
        private Exceptional<ResultType> AddAttributeToDBObject(GraphDBType myTypeOfDBObject, ObjectUUID myUUID, AttributeUUID myAttributeUUID, IObject myAttributeValue)
        {
            //myGraphType is needed due to correctness concerning the attribute name

            #region Input exceptions

            if ((myTypeOfDBObject == null) || (myUUID == null) || (myAttributeUUID == null) || (myAttributeValue == null))
            {
                throw new ArgumentNullException();
            }

            #endregion

            #region Check GraphType for new Attribute

            TypeAttribute typeAttribute = myTypeOfDBObject.GetTypeAttributeByUUID(myAttributeUUID);

            if (typeAttribute == null)
            {
                //Todo: add notification here (the user has to be informed about the detailed circumstances)

                GraphDBError aError = new Error_AttributeIsNotDefined(myTypeOfDBObject.Name, myAttributeUUID.ToString());

                return new Exceptional<ResultType>(aError);
            }

            #endregion

            #region Data

            var objectLocation = new ObjectLocation(myTypeOfDBObject.ObjectLocation, DBConstants.DBObjectsLocation, myUUID.ToString());
            Exceptional<DBObjectStream> aNewDBObject;
            Exceptional<ResultType> result = new Exceptional<ResultType>();

            #endregion

            #region add attribute

            aNewDBObject = _DBContext.DBObjectManager.LoadDBObject(myTypeOfDBObject, myUUID);

            if (aNewDBObject.Failed())
            {
                result.PushIError(new Error_LoadObject(aNewDBObject.Value.ObjectLocation));
                return result;
            }

            result = aNewDBObject.Value.AddAttribute(typeAttribute.UUID, myAttributeValue);

            if (result.Failed())
                return result;

            try
            {
                _DBContext.DBObjectManager.FlushDBObject(aNewDBObject.Value);
            }
            catch (Exception ex)
            {
                result.PushIError(new Error_FlushObject(aNewDBObject.Value.ObjectLocation, ex));
                aNewDBObject.Value.RemoveAttribute(typeAttribute.UUID);
            }

            #endregion

            return result;
        }
コード例 #3
0
ファイル: DBIndexManager.cs プロジェクト: TheByte/sones
        public Exceptional<ResultType> RebuildIndex(String myIndexName, String myIndexEdition, GraphDBType myDBTypeStream, IndexSetStrategy myIndexSetStrategy)
        {
            var objectLocation = new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation);
            IEnumerable<String> allDBOLocations = null;

            try
            {
                allDBOLocations = _DBContext.DBObjectManager.GetAllStreamsRecursive(objectLocation, DBConstants.DBOBJECTSTREAM);
            }
            catch (Exception e)
            {
                return new Exceptional<ResultType>(new Error_RebuildIndexFailed(myIndexName, myIndexEdition, e.Message));

            }

            try
            {

                var index = myDBTypeStream.GetAttributeIndex(myIndexName, myIndexEdition);

                index.ClearAndRemoveFromDisc(this);

                    foreach (var loc in allDBOLocations)
                    {
                        var dbo = _DBContext.DBObjectManager.LoadDBObject(new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation, _DBContext.DBObjectManager.GetDBObjectStreamShard(myDBTypeStream, new ObjectUUID(loc)), loc));

                        if (dbo.Failed())
                        {
                            return new Exceptional<ResultType>(dbo);
                        }

                        if (!dbo.Value.ObjectLocation.Contains(loc))
                        {
                            //NLOG: temporarily commented
                            ////_Logger.Error("Could not found the correct DBObject for Location " + loc + " the ObjectUUID is now " + dbo.Value.ObjectUUID.ToString());
                        }
                        else
                        {
                            if (dbo.Value.HasAtLeastOneAttribute(index.IndexKeyDefinition.IndexKeyAttributeUUIDs, myDBTypeStream, null))
                            {
                                var insertResult = index.Insert(dbo.Value, myIndexSetStrategy, myDBTypeStream, _DBContext);
                                if (!insertResult.Success())
                                {
                                    return new Exceptional<ResultType>(insertResult);
                                }
                            }
                        }

                }
            }
            catch (GraphDBException pe)
            {
                var _Exceptional = new Exceptional<ResultType>();
                foreach (var _ex in pe.GraphDBErrors)
                    _Exceptional.PushIError(_ex);
                return _Exceptional;
            }
            catch (GraphFSException_IndexKeyAlreadyExist)
            {
                //NLOG: temporarily commented
                ////_Logger.ErrorException("GraphFSException_IndexKeyAlreadyExist", ikae);
                return new Exceptional<ResultType>(new Error_UniqueConstrainViolation(myDBTypeStream.Name, myIndexName));
            }
            catch
            {
                return new Exceptional<ResultType>(new Error_IndexDoesNotExist(myIndexName, myIndexEdition));
            }

            return new Exceptional<ResultType>(ResultType.Successful);
        }
コード例 #4
0
ファイル: DBIndexManager.cs プロジェクト: ipbi/sones
        public Exceptional<ResultType> RebuildIndex(String myIndexName, String myIndexEdition, GraphDBType myDBTypeStream, IndexSetStrategy myIndexSetStrategy)
        {
            var objectLocation = new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation);
            var allDBOLocations = _IGraphFSSession.GetFilteredDirectoryListing(objectLocation, null, null, null, new List<String>(new String[] { DBConstants.DBOBJECTSTREAM }), null, null, null, null, null, null);

            if (allDBOLocations.Failed() && allDBOLocations.IErrors.First().GetType() != typeof(GraphFSError_ObjectLocatorNotFound))
                return new Exceptional<ResultType>(allDBOLocations);

            try
            {

                var index = myDBTypeStream.GetAttributeIndex(myIndexName, myIndexEdition);

                index.ClearAndRemoveFromDisc(this);

                if (allDBOLocations.Value != null)
                {
                    foreach (var loc in allDBOLocations.Value)
                    {
                        var dbo = _DBContext.DBObjectManager.LoadDBObject(new ObjectLocation(myDBTypeStream.ObjectLocation, DBConstants.DBObjectsLocation, loc));

                        if (dbo.Failed())
                        {
                            return new Exceptional<ResultType>(dbo);
                        }

                        if (!dbo.Value.ObjectLocation.Contains(loc))
                        {
                            //NLOG: temporarily commented
                            ////_Logger.Error("Could not found the correct DBObject for Location " + loc + " the ObjectUUID is now " + dbo.Value.ObjectUUID.ToString());
                        }
                        else
                        {
                            if (dbo.Value.HasAtLeastOneAttribute(index.IndexKeyDefinition.IndexKeyAttributeUUIDs, myDBTypeStream, null))
                            {
                                var insertResult = index.Insert(dbo.Value, myIndexSetStrategy, myDBTypeStream, _DBContext);
                                if (!insertResult.Success())
                                {
                                    return new Exceptional<ResultType>(insertResult);
                                }
                            }
                        }
                    }
                }
            }
            catch (GraphDBException pe)
            {
                var _Exceptional = new Exceptional<ResultType>();
                foreach (var _ex in pe.GraphDBErrors)
                    _Exceptional.PushIError(_ex);
                return _Exceptional;
            }
            catch (GraphFSException_IndexKeyAlreadyExist)
            {
                //NLOG: temporarily commented
                ////_Logger.ErrorException("GraphFSException_IndexKeyAlreadyExist", ikae);
                return new Exceptional<ResultType>(new Error_UniqueConstrainViolation(myDBTypeStream.Name, myIndexName));
            }
            catch
            {
                return new Exceptional<ResultType>(new Error_IndexDoesNotExist(myIndexName, myIndexEdition));
            }

            return new Exceptional<ResultType>(ResultType.Successful);
        }
コード例 #5
0
        /// <summary>
        /// Executes the removal of certain myAttributes.
        /// <seealso cref=" AAlterTypeCommand"/>
        /// </summary>
        public override Exceptional Execute(DBContext myDBContext, GraphDBType myGraphDBType)
        {
            Exceptional result = new Exceptional();

            foreach (String aAttributeName in _ListOfAttributes)
            {
                var attr = myGraphDBType.GetTypeAttributeByName(aAttributeName);

                if (attr != null)
                {
                    var idxs = new List<Indices.AAttributeIndex>(myGraphDBType.GetAttributeIndices(myDBContext, attr.UUID));

                    foreach (var item in idxs)
                    {
                        var remIdxResult = myGraphDBType.RemoveIndex(item.IndexName, item.IndexEdition, myDBContext);

                        if (remIdxResult.Failed())
                        {
                            result.PushIExceptional(remIdxResult);
                        }
                    }
                }
                else
                {
                    result.PushIError(new Error_AttributeIsNotDefined(aAttributeName));
                    return result;
                }

                //Hack: remove myAttributes in DBObjects
                var aTempResult = myDBContext.DBTypeManager.RemoveAttributeFromType(myGraphDBType.Name, aAttributeName, myDBContext.DBTypeManager);

                if (aTempResult.Failed())
                {
                    result.PushIExceptional(aTempResult);
                    return result;
                }
            }

            return result;
        }
コード例 #6
0
ファイル: PathFunc.cs プロジェクト: TheByte/sones
        public override Exceptional<FuncParameter> ExecFunc(DBContext dbContext, params FuncParameter[] myParams)
        {
            // The edge we starting of (e.g. Friends)
            var typeAttribute = CallingAttribute;

            // The destination DBObjects, they are of the type "typeAttribute.RelatedDBType"
            var destDBOs = (myParams[0].Value as DBEdge).GetDBObjects();

            byte maxDepth = Convert.ToByte((myParams[1].Value as DBInt64).GetValue());

            byte maxPathLength = Convert.ToByte((myParams[2].Value as DBInt64).GetValue());

            //check if values incorrect
            if (maxDepth < 1 && maxPathLength < 2)
            {
                Exceptional<FuncParameter> errorResult = new Exceptional<FuncParameter>();
                IError error = new Error_InvalidFunctionParameter("maxDepth", ">= 1", maxDepth);
                errorResult.PushIError(error);
                error = new Error_InvalidFunctionParameter("maxPathLength", ">= 2", maxPathLength);
                errorResult.PushIError(error);

                return errorResult;
            }
            else if (maxDepth < 1)
            {
                return new Exceptional<FuncParameter>(new Error_InvalidFunctionParameter("maxDepth", ">= 1", maxDepth));
            }
            else if (maxPathLength < 2)
            {
                return new Exceptional<FuncParameter>(new Error_InvalidFunctionParameter("maxPathLength", ">= 2", maxPathLength));
            }

            bool onlyShortestPath = (myParams[3].Value as DBBoolean).GetValue();

            bool allPaths = (myParams[4].Value as DBBoolean).GetValue();

            if (!onlyShortestPath && !allPaths)
            {
                allPaths = true;
            }

            #region Call graph function

            if (destDBOs.Count() != 1)
                throw new GraphDBException(new Error_NotImplemented(new StackTrace(true)));

            var dbObject = destDBOs.First();
            if (dbObject.Failed())
            {
                throw new GraphDBException(dbObject.IErrors);
            }

            HashSet<List<ObjectUUID>> paths;

            if (onlyShortestPath && allPaths) //use bi-directional search for "all shortest paths"
            {
                //normal BFS
                //paths = new BreadthFirstSearch().Find(typeAttribute, typeManager, cache, mySourceDBObject, dbObject, onlyShortestPath, allPaths, maxDepth, maxPathLength);

                //bidirectional BFS
                paths = new BidirectionalBFS().Find(typeAttribute, dbContext, CallingDBObjectStream as DBObjectStream, CallingObject as IReferenceEdge, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength);
            }
            else //use uni-directional search for "shortest path and all paths up to given depth"
            {
                //normal BFS
                //paths = new BreadthFirstSearch().Find(typeAttribute, dbContext.DBTypeManager, dbContext.DBObjectCache, CallingDBObjectStream as DBObjectStream, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength);

                //bidirectional BFS
                paths = new BidirectionalBFS().Find(typeAttribute, dbContext, CallingDBObjectStream as DBObjectStream, CallingObject as IReferenceEdge, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength);
            }

            //This variable will be returned
            Exceptional<FuncParameter> pResult = new Exceptional<FuncParameter>();

            if (paths != null)
            {
                pResult.Value = new FuncParameter(new EdgeTypePath(paths, typeAttribute, typeAttribute.GetDBType(dbContext.DBTypeManager)), typeAttribute);
            }
            else
            {
                return new Exceptional<FuncParameter>(new FuncParameter(new EdgeTypePath(new HashSet<List<ObjectUUID>>(), typeAttribute, typeAttribute.GetDBType(dbContext.DBTypeManager)), typeAttribute));
            }

            #endregion

            return pResult;
        }