Ejemplo n.º 1
0
        /// <summary>
        /// Finds the number of items that are returned by this search.
        /// Wraps https://www.m-files.com/api/documentation/#MFilesAPI~VaultObjectSearchOperations~GetObjectCountInSearch.html.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="searchFlags">Any search flags to use.</param>
        /// <returns>The count.</returns>
        public static int FindCount
        (
            this MFSearchBuilder searchBuilder,
            MFSearchFlags searchFlags = MFSearchFlags.MFSearchFlagNone
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (null == searchBuilder.Vault)
            {
                throw new ArgumentException("The search builder's vault reference is null.", nameof(searchBuilder));
            }
            if (null == searchBuilder.Vault.ObjectSearchOperations)
            {
                throw new ArgumentException("The vault's ObjectSearchOperations reference is null.", nameof(searchBuilder));
            }
            if (null == searchBuilder.Conditions)
            {
                throw new ArgumentException("The search builder's conditions are null.", nameof(searchBuilder));
            }

            // Use the GetObjectCountInSearch API method.
            return(searchBuilder
                   .Vault
                   .ObjectSearchOperations
                   .GetObjectCountInSearch
                   (
                       searchBuilder.Conditions,
                       searchFlags
                   ));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns whether there are objects in the vault that have a higher internal Id than
        /// the current segment.
        /// </summary>
        /// <param name="vaultObjectSearchOperations">The search operations object to query with.</param>
        /// <param name="searchConditions">The search conditions to execute.</param>
        /// <param name="searchFlags">Any search flags to execute (note that the order will not be respected).</param>
        /// <param name="segment">The zero-based index of the segment to return data for.</param>
        /// <param name="itemsPerSegment">The number of items to include in each segment. See <see cref="DefaultNumberOfItemsInSegment"/>.</param>
        /// <returns>true if there is at least one, false if there are none.</returns>
        private static bool HasMoreResults(this IVaultObjectSearchOperations vaultObjectSearchOperations,
                                           SearchConditions searchConditions,
                                           int segment,
                                           MFSearchFlags searchFlags = MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                                           int itemsPerSegment       = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment)
        {
            // Sanity.
            if (null == vaultObjectSearchOperations)
            {
                throw new ArgumentNullException(nameof(vaultObjectSearchOperations));
            }
            if (null == searchConditions)
            {
                throw new ArgumentNullException(nameof(searchConditions));
            }
            if (segment <= 0)
            {
                segment = 0;
            }
            if (itemsPerSegment <= 0)
            {
                itemsPerSegment = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment;
            }

            // There are more results if there are any objects that meet the search criteria, with
            // an Id greater than the current segment range.

            // Clone the search conditions (so we can add object id condition).
            var internalSearchConditions = searchConditions.Clone();

            // Add search condition:
            //   Id at least (segment * itemsPerSegment)
            internalSearchConditions.AddMinimumObjectIdSearchCondition(segment * itemsPerSegment);

            // If we get zero items then there are no more results.
            var results = vaultObjectSearchOperations.SearchForObjectsByConditionsEx(
                internalSearchConditions,          // Our search conditions.
                searchFlags,
                SortResults: false,                // Don't bother attempting to sort them.
                MaxResultCount: 1,                 // We only need to know if there is at least one, nothing more.
                SearchTimeoutInSeconds: 0);

            // Did we only get one?
            return(0 != results.Count);
        }
Ejemplo n.º 3
0
        public ObjectSearchResults SearchForObjectsByConditionsEx(SearchConditions searchConditions, MFSearchFlags searchFlags, bool sortResults, int maxResultCount = 500, int searchTimeoutInSeconds = 60)
        {
            vault.MetricGatherer.MethodCalled();

            if (searchFlags.HasFlag(MFSearchFlags.MFSearchFlagLookInAllVersions))
            {
                throw new NotImplementedException();
            }
            if (searchFlags.HasFlag(MFSearchFlags.MFSearchFlagReturnLatestVisibleVersion))
            {
                throw new NotImplementedException();
            }

            List <TestObjectVersionAndProperties> results = new List <TestObjectVersionAndProperties>(vault.ovaps);

            foreach (SearchCondition searchCondition in searchConditions)
            {
                List <TestObjectVersionAndProperties> remainingResults = new List <TestObjectVersionAndProperties>(results);
                foreach (TestObjectVersionAndProperties testOvap in remainingResults)
                {
                    // Latest version only
                    List <TestObjectVersionAndProperties> thisObj =
                        vault.ovaps.Where(obj => obj.ObjVer.ID == testOvap.ObjVer.ID && obj.ObjVer.Type == testOvap.ObjVer.Type)
                        .ToList();
                    int maxVersion = thisObj.Max(obj => obj.ObjVer.Version);
                    if (testOvap.ObjVer.Version != maxVersion)
                    {
                        results.Remove(testOvap);
                        continue;
                    }

                    switch (searchCondition.Expression.Type)
                    {
                    case MFExpressionType.MFExpressionTypePropertyValue:
                    {
                        int propId = searchCondition.Expression.DataPropertyValuePropertyDef;

                        if (testOvap.Properties.IndexOf(propId) != -1)
                        {
                            PropertyValue pv = testOvap.Properties.SearchForProperty(propId);
                            switch (searchCondition.TypedValue.DataType)
                            {
                            case MFDataType.MFDatatypeLookup:
                                if (pv.TypedValue.DataType == MFDataType.MFDatatypeMultiSelectLookup)
                                {
                                    Lookups lks    = pv.TypedValue.GetValueAsLookups();
                                    bool    exists = false;
                                    foreach (Lookup lookup in lks)
                                    {
                                        if (lookup.Item == searchCondition.TypedValue.GetLookupID())
                                        {
                                            exists = true;
                                        }
                                    }
                                    if (!exists)
                                    {
                                        results.Remove(testOvap);
                                    }
                                }
                                else if (pv.TypedValue.DataType == MFDataType.MFDatatypeLookup)
                                {
                                    if (searchCondition.TypedValue.GetLookupID()
                                        != testOvap.Properties.SearchForProperty(propId).Value.GetLookupID())
                                    {
                                        if (searchCondition.ConditionType == MFConditionType.MFConditionTypeEqual)
                                        {
                                            results.Remove(testOvap);
                                        }
                                        else
                                        {
                                            throw new Exception("ConditionType not yet supported in Search Conditions :: DataType lookup");
                                        }
                                    }
                                }
                                else
                                {
                                    throw new Exception("Parameter incorrect");
                                }
                                break;

                            default:
                                throw new Exception("Datatype not yet supported in Search Conditions");
                            }
                            //if(searchCondition.TypedValue.Value == testOvap.Properties.SearchForProperty( propId ).Value.Value)
                            //{
                            //	osr.Add( testOvap );
                            //}
                        }
                        else
                        {
                            results.Remove(testOvap);
                        }
                    }
                    break;

                    case MFExpressionType.MFExpressionTypeStatusValue:
                        switch (searchCondition.ConditionType)
                        {
                        case MFConditionType.MFConditionTypeEqual:
                            switch (searchCondition.Expression.DataStatusValueType)
                            {
                            case MFStatusType.MFStatusTypeDeleted:
                                if (testOvap.VersionData.Deleted)
                                {
                                    results.Remove(testOvap);
                                }
                                break;

                            case MFStatusType.MFStatusTypeObjectTypeID:
                                if (testOvap.ObjVer.Type != searchCondition.TypedValue.GetLookupID())
                                {
                                    results.Remove(testOvap);
                                }
                                break;

                            default:
                                throw new Exception("MFStatusType not yet supported in Search Conditions for MFExpressionTypeStatusValue::MFConditionTypeEqual");
                            }
                            break;

                        default:
                            throw new Exception("ConditionType not yet supported in Search Conditions for MFExpressionTypeStatusValue");
                        }
                        break;

                    default:
                        throw new Exception("Expression Type not yet supported in SearchForObjects::" + searchCondition.Expression.Type);
                    }      // End Switch ExpressionType
                }          // End iteration of objects
            }              // End iteration of Search Conditions

            //if(SearchFlags != MFSearchFlags.MFSearchFlagNone)
            //    throw new NotImplementedException();

            //List<ObjectVersionAndProperties> objects = vault.ovaps.Where()

            TestObjectSearchResults osr = new TestObjectSearchResults();

            foreach (TestObjectVersionAndProperties testOvap in results)
            {
                osr.Add(testOvap);
            }

            return(osr);
        }
Ejemplo n.º 4
0
        public ObjectSearchResults SearchForObjectsByConditions(SearchConditions searchConditions, MFSearchFlags searchFlags, bool sortResults)
        {
            vault.MetricGatherer.MethodCalled();

            throw new NotImplementedException();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Searches for objects matching the search conditions, in segments by M-Files Object Id.
        /// Returns an enumerable of each segment's search results.
        /// Using this approach (e.g. searching for IDs 1-1000, then 1001-2000, etc.) bypasses the return count limitations.
        /// </summary>
        /// <param name="vaultObjectSearchOperations">The search operations object to query with.</param>
        /// <param name="searchConditions">The search conditions to execute.</param>
        /// <param name="searchFlags">Any search flags to execute (note that the order will not be respected).</param>
        /// <param name="startSegment">The (zero-based) index of the segment to start at.</param>
        /// <param name="itemsPerSegment">The number of items to include in each segment. See <see cref="DefaultNumberOfItemsInSegment"/>.</param>
        /// <param name="maximumSegmentIndex"></param>
        /// <returns></returns>
        /// <remarks>Be aware that calling this method will return all matching items, which may cause significant load on the M-Files server.</remarks>
        public static IEnumerable <IObjectSearchResults> SearchForObjectsByConditionsSegmented(this IVaultObjectSearchOperations vaultObjectSearchOperations,
                                                                                               SearchConditions searchConditions,
                                                                                               MFSearchFlags searchFlags = MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                                                                                               int startSegment          = 0,
                                                                                               int itemsPerSegment       = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment,
                                                                                               int maximumSegmentIndex   = IVaultObjectSearchOperationsExtensionMethods.MaximumSegmentIndex)
        {
            // Sanity.
            if (null == searchConditions)
            {
                throw new ArgumentNullException(nameof(searchConditions));
            }
            if (null == vaultObjectSearchOperations)
            {
                throw new ArgumentNullException(nameof(vaultObjectSearchOperations));
            }
            if (startSegment < 0)
            {
                startSegment = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment;
            }
            if (maximumSegmentIndex < 0)
            {
                maximumSegmentIndex = IVaultObjectSearchOperationsExtensionMethods.MaximumSegmentIndex;
            }

            // No point having relevancy ranking as we're throwing it away.
            // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
            searchFlags = searchFlags | MFSearchFlags.MFSearchFlagDisableRelevancyRanking;

            // A segment has a start index and a number of items in it.
            // Segment 0 = object Ids 0 through 999.
            // Segment 1 = object Ids 1000 through 1999.
            // ....

            // Start at segment zero.
            int segment = startSegment;

            // Let's have a sanity counter, just in case.
            int sanity = maximumSegmentIndex;

            // While there are objects with a higher ID than the segment we're in, continue searching.
            while ((sanity > 0) && vaultObjectSearchOperations.HasMoreResults(searchConditions, segment, searchFlags, itemsPerSegment))
            {
                // Clone the search conditions (so we can add current-segment condition).
                var internalSearchConditions = searchConditions.Clone();

                // Add search condition:
                //   Id within the range: (segment - itemsPerSegment) to ((segment + 1) * itemsPerSegment)
                internalSearchConditions.AddObjectIdSegmentSearchCondition(segment, itemsPerSegment);

                // Return the results.
                yield return(vaultObjectSearchOperations
                             .SearchForObjectsByConditionsEx(internalSearchConditions, searchFlags, SortResults: false, MaxResultCount: 0,
                                                             SearchTimeoutInSeconds: 0));

                // Move to the next segment.
                segment++;

                // Reduce the sanity value (if we hit zero we will exit).
                sanity--;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Searches for objects matching the search conditions, in segments by M-Files Object Id.
        /// Returns an enumerable of object versions, flattening out the segment data.
        /// Using this approach (e.g. searching for IDs 1-1000, then 1001-2000, etc.) bypasses the return count limitations.
        /// </summary>
        /// <param name="vaultObjectSearchOperations">The search operations object to query with.</param>
        /// <param name="searchConditions">The search conditions to execute.</param>
        /// <param name="searchFlags">Any search flags to execute (note that the order will not be respected).</param>
        /// <param name="startSegment">The (zero-based) index of the segment to start at.</param>
        /// <param name="itemsPerSegment">The number of items to include in each segment. See <see cref="DefaultNumberOfItemsInSegment"/>.</param>
        /// <param name="maximumSegmentIndex"></param>
        /// <returns></returns>
        /// <remarks>Be aware that calling this method will return all matching items, which may cause significant load on the M-Files server.</remarks>
        public static IEnumerable <ObjectVersion> SearchForObjectsByConditionsSegmented_Flat(this IVaultObjectSearchOperations vaultObjectSearchOperations,
                                                                                             SearchConditions searchConditions,
                                                                                             MFSearchFlags searchFlags = MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                                                                                             int startSegment          = 0,
                                                                                             int itemsPerSegment       = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment,
                                                                                             int maximumSegmentIndex   = IVaultObjectSearchOperationsExtensionMethods.MaximumSegmentIndex)
        {
            // Sanity.
            if (null == searchConditions)
            {
                throw new ArgumentNullException(nameof(searchConditions));
            }
            if (null == vaultObjectSearchOperations)
            {
                throw new ArgumentNullException(nameof(vaultObjectSearchOperations));
            }
            if (startSegment < 0)
            {
                startSegment = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment;
            }
            if (maximumSegmentIndex < 0)
            {
                maximumSegmentIndex = IVaultObjectSearchOperationsExtensionMethods.MaximumSegmentIndex;
            }

            // Iterate over each segment to return results.
            foreach (
                var segment in
                vaultObjectSearchOperations.SearchForObjectsByConditionsSegmented(searchConditions, searchFlags, startSegment,
                                                                                  itemsPerSegment, maximumSegmentIndex))
            {
                // Iterate over each result.
                foreach (var result in segment.ObjectVersions.Cast <ObjectVersion>())
                {
                    yield return(result);
                }
            }
        }