/// <inherit />
        protected override void AddSearchCondition
        (
            MFSearchBuilder mfSearchBuilder,
            int propertyDef,
            DateTime?value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            DataFunctionCall dataFunctionCall          = null,
            PropertyDefOrObjectTypes indirectionLevels = null
        )
        {
            // Sanity.
            if (null == mfSearchBuilder)
            {
                throw new ArgumentNullException(nameof(mfSearchBuilder));
            }

            // Call the property overload.
            mfSearchBuilder.Date
            (
                propertyDef,
                // Value is not nullable in the real world, but needed here for the test to work.
                value ?? new DateTime(2020, 01, 01),
                conditionType,
                parentChildBehavior,
                indirectionLevels
            );
        }
Пример #2
0
        public void SearchConditionIsCorrect
        (
            int objectId,
            MFConditionType conditionType
        )
        {
            // Create the search builder.
            var mfSearchBuilder = this.GetSearchBuilder();

            // Add the search condition.
            mfSearchBuilder.ObjectId(objectId, conditionType);

            // If there's anything other than one condition then fail.
            if (mfSearchBuilder.Conditions.Count != 1)
            {
                Assert.Inconclusive("Only one search condition should exist");
            }

            // Retrieve the just-added condition.
            var condition = mfSearchBuilder.Conditions[mfSearchBuilder.Conditions.Count];

            // Ensure the condition type is correct.
            Assert.AreEqual(conditionType, condition.ConditionType);

            // Ensure the expression type is correct.
            Assert.AreEqual(MFExpressionType.MFExpressionTypeStatusValue, condition.Expression.Type);

            // Ensure the status value is correct.
            Assert.AreEqual(MFStatusType.MFStatusTypeObjectID, condition.Expression.DataStatusValueType);

            // Ensure that the typed value is correct.
            Assert.AreEqual(MFDataType.MFDatatypeInteger, condition.TypedValue.DataType);
            Assert.AreEqual(objectId, condition.TypedValue.Value as int?);
        }
        /// <inherit />
        protected override void AddSearchCondition
        (
            MFSearchBuilder mfSearchBuilder,
            int propertyDef,
            string value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            DataFunctionCall dataFunctionCall          = null,
            PropertyDefOrObjectTypes indirectionLevels = null
        )
        {
            // Sanity.
            if (null == mfSearchBuilder)
            {
                throw new ArgumentNullException(nameof(mfSearchBuilder));
            }

            // Call the property overload.
            mfSearchBuilder.YearAndMonth
            (
                propertyDef,
                2020,
                1,
                conditionType,
                parentChildBehavior,
                indirectionLevels
            );
        }
Пример #4
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for a <see cref="MFDataType.MFDatatypeDate"/>
        /// or <see cref="MFDataType.MFDatatypeTimestamp"/> property definition.
        /// This method searches solely by the year component in the property value , equivalent to using
        /// a <see cref="DataFunctionCall" /> set to <see cref="DataFunctionCall.SetDataYear"/>.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The ID of the property to search by.</param>
        /// <param name="year">The four-digit year to search by.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well (defaults to <see cref="MFParentChildBehavior.MFParentChildBehaviorNone"/>).</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder Year
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            int year,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            PropertyDefOrObjectTypes indirectionLevels = null
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 > propertyDef)
            {
                throw new ArgumentOutOfRangeException(nameof(propertyDef), "Property Ids must be greater than -1; ensure that your property alias was resolved.");
            }
            if (year < 1000 || year > 9999)
            {
                throw new ArgumentOutOfRangeException(nameof(year), "The year must be four digits.");
            }

            // What is the type of this property?
            var dataType = searchBuilder.Vault.PropertyDefOperations.GetPropertyDef(propertyDef).DataType;

            // What is the data type of the property?
            DataFunctionCall dataFunctionCall;

            switch (dataType)
            {
            case MFDataType.MFDatatypeTimestamp:
            case MFDataType.MFDatatypeDate:

                // Timestamps and dates should be converted to integer using a data function call.
                dataFunctionCall = new DataFunctionCall();
                dataFunctionCall.SetDataYear();

                break;

            default:
                throw new ArgumentException($"Property {propertyDef} is not a date or timestamp property.", nameof(propertyDef));
            }

            // Use the property method.
            return(searchBuilder.Property
                   (
                       propertyDef,
                       year,
                       conditionType,
                       parentChildBehavior,
                       indirectionLevels,
                       dataFunctionCall
                   ));
        }
Пример #5
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for a <see cref="MFDataType.MFDatatypeDate"/>
        /// or <see cref="MFDataType.MFDatatypeTimestamp"/> property definition.
        /// This method searches solely by the month component in the property value , equivalent to using
        /// a <see cref="DataFunctionCall" /> set to <see cref="DataFunctionCall.SetDataMonth" />.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The ID of the property to search by.</param>
        /// <param name="month">The 1-based number of the month to search by (1 = January, 12 = December).</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well (defaults to <see cref="MFParentChildBehavior.MFParentChildBehaviorNone"/>).</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder Month
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            int month,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            PropertyDefOrObjectTypes indirectionLevels = null
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 > propertyDef)
            {
                throw new ArgumentOutOfRangeException(nameof(propertyDef), "Property Ids must be greater than -1; ensure that your property alias was resolved.");
            }
            if (month < 1 || month > 12)
            {
                throw new ArgumentOutOfRangeException(nameof(month), "The month number must be between 1 and 12 inclusive.");
            }

            // What is the type of this property?
            var dataType = searchBuilder.Vault.PropertyDefOperations.GetPropertyDef(propertyDef).DataType;

            // What is the data type of the property?
            DataFunctionCall dataFunctionCall;

            switch (dataType)
            {
            case MFDataType.MFDatatypeTimestamp:
            case MFDataType.MFDatatypeDate:

                // Timestamps and dates should be converted to text using a data function call.
                dataFunctionCall = new DataFunctionCall();
                dataFunctionCall.SetDataMonth();

                break;

            default:
                throw new ArgumentException($"Property {propertyDef} is not a date or timestamp property.", nameof(propertyDef));
            }

            // Use the property method.
            return(searchBuilder.Property
                   (
                       propertyDef,
                       month.ToString("00"),
                       conditionType,
                       parentChildBehavior,
                       indirectionLevels,
                       dataFunctionCall
                   ));
        }
Пример #6
0
        /// <summary>
        /// 对象状态搜索
        /// </summary>
        /// <param name="cType"></param>
        /// <param name="sType"></param>
        /// <param name="dType"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static SearchCondition Status(MFConditionType cType,
                                             MFStatusType sType, MFDataType dType, object value)
        {
            var sc = new SearchCondition();

            sc.ConditionType = cType;
            sc.Expression.DataStatusValueType = sType;
            MFPropertyUtils.SetValue(sc.TypedValue, dType, value);
            return(sc);
        }
Пример #7
0
        /// <summary>
        /// 对象属性搜索
        /// </summary>
        /// <param name="cType"></param>
        /// <param name="propDef"></param>
        /// <param name="dType"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static SearchCondition Property(MFConditionType cType,
                                               int propDef, MFDataType dType, object value)
        {
            var sc = new SearchCondition();

            sc.ConditionType = cType;
            sc.Expression.DataPropertyValuePropertyDef = propDef;
            MFPropertyUtils.SetValue(sc.TypedValue, dType, value);
            return(sc);
        }
Пример #8
0
        public void UnhandledConditionTypeThrows
        (
            int objectId,
            MFConditionType conditionType
        )
        {
            // Create the search builder.
            var mfSearchBuilder = this.GetSearchBuilder();

            // Add the search condition.
            mfSearchBuilder.ObjectId(objectId, conditionType);
        }
Пример #9
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection to find items by <see cref="ObjID.ID"/>.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="objectId">The object ID to search for.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder ObjectId
        (
            this MFSearchBuilder searchBuilder,
            int objectId,
            MFConditionType conditionType = MFConditionType.MFConditionTypeEqual
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 >= objectId)
            {
                throw new ArgumentOutOfRangeException(nameof(objectId), "Object Id must be greater than 0.");
            }

            // We can only handle certain condition types; throw for others.
            if (conditionType != MFConditionType.MFConditionTypeEqual &&
                conditionType != MFConditionType.MFConditionTypeNotEqual &&
                conditionType != MFConditionType.MFConditionTypeLessThan &&
                conditionType != MFConditionType.MFConditionTypeLessThanOrEqual &&
                conditionType != MFConditionType.MFConditionTypeGreaterThan &&
                conditionType != MFConditionType.MFConditionTypeGreaterThanOrEqual)
            {
                throw new ArgumentException
                      (
                          $"The condition type {conditionType} is not supported for object Ids.",
                          nameof(conditionType)
                      );
            }

            // Create the search condition.
            var searchCondition = new SearchCondition
            {
                ConditionType = conditionType
            };

            // Set up the expression.
            searchCondition.Expression.SetStatusValueExpression
            (
                MFStatusType.MFStatusTypeObjectID
            );

            // Set the object id.
            searchCondition.TypedValue.SetValue(MFDataType.MFDatatypeInteger, objectId);

            // Add the search condition to the collection.
            searchBuilder.Conditions.Add(-1, searchCondition);

            // Return the search builder for chaining.
            return(searchBuilder);
        }
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for whether the specified user has the specified permission on an object.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="userId">The ID of the user in question.</param>
        /// <param name="permission">The permission that the user should have on the object.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder UserHasPermissionTo
        (
            this MFSearchBuilder searchBuilder,
            int userId,
            MFPermissionsExpressionType permission,
            MFConditionType conditionType = MFConditionType.MFConditionTypeEqual
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }

            // We can only handle certain condition types; throw for others.
            if (conditionType != MFConditionType.MFConditionTypeEqual &&
                conditionType != MFConditionType.MFConditionTypeNotEqual)
            {
                throw new ArgumentException
                      (
                          $"The condition type {conditionType} is not supported for permission-based search conditions.",
                          nameof(conditionType)
                      );
            }

            // Create the search condition.
            var searchCondition = new SearchCondition
            {
                ConditionType = conditionType
            };

            // Set up the permission expression.
            searchCondition.Expression.SetPermissionExpression
            (
                permission
            );

            // Set the condition value to the lookup.
            var lookup = new MFilesAPI.Lookup()
            {
                ObjectType = (int)MFBuiltInValueList.MFBuiltInValueListUsers,
                Item       = userId
            };

            searchCondition.TypedValue.SetValue(MFDataType.MFDatatypeLookup, lookup);

            // Add the search condition to the collection.
            searchBuilder.Conditions.Add(-1, searchCondition);

            // Return the search builder for chaining.
            return(searchBuilder);
        }
Пример #11
0
        public void UserHasPermissionToInvalidConditionTypeThrows(MFConditionType conditionType)
        {
            // Create the search builder.
            var mfSearchBuilder = this.GetSearchBuilder();

            // Add the search condition.
            mfSearchBuilder.UserHasPermissionTo
            (
                123,
                MFPermissionsExpressionType.MFVisibleTo,
                conditionType
            );
        }
 /// <summary>
 /// Adds a <see cref="SearchCondition"/> to the collection for whether the specified user can see an object.
 /// </summary>
 /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
 /// <param name="userId">The ID of the user that should be able to see the object.</param>
 /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
 /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
 public static MFSearchBuilder VisibleTo
 (
     this MFSearchBuilder searchBuilder,
     int userId,
     MFConditionType conditionType = MFConditionType.MFConditionTypeEqual
 )
 {
     // Use UserHasPermissionTo method.
     return(searchBuilder.UserHasPermissionTo
            (
                userId,
                MFPermissionsExpressionType.MFVisibleTo,
                conditionType
            ));
 }
Пример #13
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for a <see cref="MFDataType.MFDatatypeInteger"/>,
        /// <see cref="MFDataType.MFDatatypeInteger64"/> or <see cref="MFDataType.MFDatatypeFloating"/> property definition.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The ID of the property to search by.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well (defaults to <see cref="MFParentChildBehavior.MFParentChildBehaviorNone"/>).</param>
        /// <param name="dataFunctionCall">An expression for modifying how the results of matches are evaluated (defaults to null).</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder Property
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            long?value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            PropertyDefOrObjectTypes indirectionLevels = null,
            DataFunctionCall dataFunctionCall          = null
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 > propertyDef)
            {
                throw new ArgumentOutOfRangeException(nameof(propertyDef), "Property Ids must be greater than -1; ensure that your property alias was resolved.");
            }

            // What is the type of this property?
            var dataType = searchBuilder.Vault.PropertyDefOperations.GetPropertyDef(propertyDef).DataType;

            // If it is not valid then throw.
            if (dataType != MFDataType.MFDatatypeInteger &&
                dataType != MFDataType.MFDatatypeInteger64 &&
                dataType != MFDataType.MFDatatypeFloating &&
                dataType != MFDataType.MFDatatypeLookup &&
                dataType != MFDataType.MFDatatypeMultiSelectLookup)
            {
                throw new ArgumentException($"Property {propertyDef} is not an integer, long, real, lookup or multi-select lookup property.", nameof(propertyDef));
            }

            // Add the search condition.
            return(searchBuilder.AddPropertyValueSearchCondition
                   (
                       propertyDef,
                       dataType,
                       value,
                       conditionType,
                       parentChildBehavior,
                       indirectionLevels,
                       dataFunctionCall
                   ));
        }
 public void SearchConditionIsCorrect
 (
     int propertyDef,
     DateTime?input,
     MFConditionType conditionType,
     MFParentChildBehavior parentChildBehavior,
     PropertyDefOrObjectTypes indirectionLevels
 )
 {
     base.AssertSearchConditionIsCorrect
     (
         propertyDef,
         MFDataType.MFDatatypeDate,
         input,
         conditionType,
         parentChildBehavior,
         indirectionLevels
     );
 }
Пример #15
0
 public void SearchConditionIsCorrect_WithIndirectionLevels
 (
     int propertyDef,
     long?input,
     MFConditionType conditionType,
     MFParentChildBehavior parentChildBehavior,
     PropertyDefOrObjectTypes indirectionLevels
 )
 {
     base.AssertSearchConditionIsCorrect
     (
         propertyDef,
         MFDataType.MFDatatypeInteger64,
         input,
         conditionType,
         parentChildBehavior,
         indirectionLevels
     );
 }
Пример #16
0
        /// <inherit />
        protected override void AddSearchCondition
        (
            MFSearchBuilder mfSearchBuilder,
            int propertyDef,
            int[] value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            DataFunctionCall dataFunctionCall          = null,
            PropertyDefOrObjectTypes indirectionLevels = null
        )
        {
            // Sanity.
            if (null == mfSearchBuilder)
            {
                throw new ArgumentNullException(nameof(mfSearchBuilder));
            }

            // Use our extension method.
            mfSearchBuilder.PropertyOneOf(propertyDef, value, parentChildBehavior, indirectionLevels);
        }
Пример #17
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection to restrict files by their size.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="size">The file size to restrict by (in bytes).</param>
        /// <param name="conditionType">What type of search to execute.</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder FileSize
        (
            this MFSearchBuilder searchBuilder,
            long size,
            MFConditionType conditionType
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (size < 0)
            {
                throw new ArgumentOutOfRangeException($"The size parameter must be zero or larger.", nameof(size));
            }

            // Create the search condition.
            var searchCondition = new SearchCondition
            {
                ConditionType = conditionType
            };

            // Set up the file value expression.
            searchCondition.Expression.SetFileValueExpression
            (
                MFFileValueType.MFFileValueTypeFileSize
            );

            // Search by the size
            searchCondition.TypedValue.SetValue(MFDataType.MFDatatypeInteger64, size);

            // Add the search condition to the collection.
            searchBuilder.Conditions.Add(-1, searchCondition);

            // Return the search builder for chaining.
            return(searchBuilder);
        }
Пример #18
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for a <see cref="MFDataType.MFDatatypeInteger"/>,
        /// <see cref="MFDataType.MFDatatypeInteger64"/> or <see cref="MFDataType.MFDatatypeFloating"/> property definition.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The ID of the property to search by.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well (defaults to <see cref="MFParentChildBehavior.MFParentChildBehaviorNone"/>).</param>
        /// <param name="dataFunctionCall">An expression for modifying how the results of matches are evaluated (defaults to null).</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder Property
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            int?value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            PropertyDefOrObjectTypes indirectionLevels = null,
            DataFunctionCall dataFunctionCall          = null
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 > propertyDef)
            {
                throw new ArgumentOutOfRangeException(nameof(propertyDef), "Property Ids must be greater than -1; ensure that your property alias was resolved.");
            }

            // What is the type of this property?
            var dataType = searchBuilder.Vault.PropertyDefOperations.GetPropertyDef(propertyDef).DataType;

            // Do we need to change the data type for the data function call?
            if (dataFunctionCall != null)
            {
                switch (dataFunctionCall.DataFunction)
                {
                case MFDataFunction.MFDataFunctionDaysFrom:
                case MFDataFunction.MFDataFunctionDaysTo:
                case MFDataFunction.MFDataFunctionYear:
                {
                    // If it's a timestamp then convert to integer.
                    if (dataType == MFDataType.MFDatatypeDate ||
                        dataType == MFDataType.MFDatatypeTimestamp)
                    {
                        dataType = MFDataType.MFDatatypeInteger;
                    }

                    // Ensure value has a value.
                    if (null == value)
                    {
                        throw new ArgumentException($"value cannot be null.", nameof(value));
                    }

                    // If it's a year then it should be four-digits.
                    if (dataFunctionCall.DataFunction == MFDataFunction.MFDataFunctionYear &&
                        (value < 1000 || value > 9999))
                    {
                        throw new ArgumentException($"The year must be four digits.", nameof(value));
                    }

                    break;
                }
                }
            }

            // If it is not the right data type then throw.
            if (dataType != MFDataType.MFDatatypeInteger &&
                dataType != MFDataType.MFDatatypeInteger64 &&
                dataType != MFDataType.MFDatatypeFloating &&
                dataType != MFDataType.MFDatatypeLookup &&
                dataType != MFDataType.MFDatatypeMultiSelectLookup)
            {
                throw new ArgumentException($"Property {propertyDef} is not an integer, long, real, lookup or multi-select lookup property.", nameof(propertyDef));
            }

            // Add the search condition.
            return(searchBuilder.AddPropertyValueSearchCondition
                   (
                       propertyDef,
                       dataType,
                       value,
                       conditionType,
                       parentChildBehavior,
                       indirectionLevels,
                       dataFunctionCall
                   ));
        }
 public void Set(Expression Expression, MFConditionType ConditionType, TypedValue TypedValue)
 {
     throw new NotImplementedException();
 }
 public SearchParameters AddProperty <T>(object value, MFConditionType cType = MFConditionType.MFConditionTypeEqual)
     where T : IMFPropertyDefinition
 {
     Conditions.AddPropertyCondition <T>(value, cType);
     return(this);
 }
        public static SearchConditions AddPropertyCondition <T>(this SearchConditions search, object value, MFConditionType cType = MFConditionType.MFConditionTypeEqual)
            where T : IMFPropertyDefinition
        {
            int        pd_id     = (int)typeof(T).GetField("id").GetRawConstantValue();
            MFDataType data_type = (MFDataType)typeof(T).GetField("data_type").GetRawConstantValue();

            if (value is IObjVerEx)
            {
                search.AddPropertyCondition(pd_id, cType, data_type, (value as IObjVerEx).objVerEx.ToLookup());
            }
            else if (value is IList)
            {
                Lookups lookups = new Lookups();
                foreach (IObjVerEx objVerEx in (value as IList))
                {
                    if (objVerEx == null)
                    {
                        break;
                    }
                    lookups.Add(-1, objVerEx.objVerEx.ToLookup());
                }
                search.AddPropertyCondition(pd_id, cType, data_type, lookups);
            }
            else
            {
                search.AddPropertyCondition(pd_id, cType, data_type, value);
            }
            return(search);
        }
Пример #22
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for a <see cref="MFDataType.MFDatatypeDate"/>
        /// or <see cref="MFDataType.MFDatatypeTimestamp"/> property definition.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The ID of the property to search by.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well (defaults to <see cref="MFParentChildBehavior.MFParentChildBehaviorNone"/>).</param>
        /// <param name="dataFunctionCall">An expression for modifying how the results of matches are evaluated (defaults to null).</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder Property
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            DateTime?value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            PropertyDefOrObjectTypes indirectionLevels = null,
            DataFunctionCall dataFunctionCall          = null
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 > propertyDef)
            {
                throw new ArgumentOutOfRangeException(nameof(propertyDef), "Property Ids must be greater than -1; ensure that your property alias was resolved.");
            }

            // What is the type of this property?
            var dataType = searchBuilder.Vault.PropertyDefOperations.GetPropertyDef(propertyDef).DataType;

            // Do we need to change the data type for the data function call?
            if (dataFunctionCall != null)
            {
                switch (dataFunctionCall.DataFunction)
                {
                case MFDataFunction.MFDataFunctionDate:
                    // If it's a timestamp then convert to date.
                    if (dataType == MFDataType.MFDatatypeTimestamp)
                    {
                        dataType = MFDataType.MFDatatypeDate;
                    }
                    break;
                }
            }

            // If it is not valid then throw.
            if (dataType != MFDataType.MFDatatypeDate &&
                dataType != MFDataType.MFDatatypeTimestamp)
            {
                throw new ArgumentException($"Property {propertyDef} is not a date or timestamp property.", nameof(propertyDef));
            }

            //// If it's a date and the value has a time component then strip it.
            if (dataType == MFDataType.MFDatatypeDate)
            {
                value = value?.Date;
            }

            // Add the search condition.
            return(searchBuilder.AddPropertyValueSearchCondition
                   (
                       propertyDef,
                       dataType,
                       value,
                       conditionType,
                       parentChildBehavior,
                       indirectionLevels,
                       dataFunctionCall
                   ));
        }
Пример #23
0
        /// <summary>
        /// Adds a property value search condition to the collection.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The property to search by.</param>
        /// <param name="dataType">The data type of the property definition (not checked).</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="conditionType">What type of search to execute.</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well.</param>
        /// <param name="dataFunctionCall">An expression for modifying how the results of matches are evaluated.</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <returns></returns>
        private static MFSearchBuilder AddPropertyValueSearchCondition
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            MFDataType dataType,
            object value,
            MFConditionType conditionType,
            MFParentChildBehavior parentChildBehavior,
            PropertyDefOrObjectTypes indirectionLevels,
            DataFunctionCall dataFunctionCall
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }

            // Create the search condition.
            var searchCondition = new SearchCondition
            {
                ConditionType = conditionType
            };

            // Set up the property value expression.
            searchCondition.Expression.SetPropertyValueExpression
            (
                propertyDef,
                parentChildBehavior,
                dataFunctionCall
            );

            // If we have any indirection levels then use them.
            if (null != indirectionLevels)
            {
                // If any indirection level points at a value list then it will except.
                // Show a nicer error message here.
                foreach (PropertyDefOrObjectType indirectionLevel in indirectionLevels)
                {
                    var objectTypeId = indirectionLevel.ID;
                    if (indirectionLevel.PropertyDef)
                    {
                        // If it's a property def then find the object type.
                        PropertyDef indirectionLevelPropertyDef;
                        try
                        {
                            indirectionLevelPropertyDef = searchBuilder
                                                          .Vault
                                                          .PropertyDefOperations
                                                          .GetPropertyDef(indirectionLevel.ID);
                        }
                        catch
                        {
                            indirectionLevelPropertyDef = null;
                        }

                        // Does it exist?
                        if (null == indirectionLevelPropertyDef)
                        {
                            throw new ArgumentException($"An indirection level references a property definition with ID {indirectionLevel.ID}, but this property definition could not be found.", nameof(indirectionLevel));
                        }

                        // Is it a list-based one?
                        if (false == indirectionLevelPropertyDef.BasedOnValueList)
                        {
                            throw new ArgumentException($"The indirection level for property {indirectionLevel.ID} does not reference a lookup-style property definition.", nameof(indirectionLevel));
                        }

                        // Record the object type id.
                        objectTypeId = indirectionLevelPropertyDef.ValueList;
                    }

                    // Is it an object type (fine) or a value list (not fine)?
                    {
                        ObjType indirectionLevelObjectType;
                        try
                        {
                            indirectionLevelObjectType = searchBuilder
                                                         .Vault
                                                         .ValueListOperations
                                                         .GetValueList(objectTypeId);
                        }
                        catch
                        {
                            indirectionLevelObjectType = null;
                        }

                        // Does it exist?
                        if (null == indirectionLevelObjectType)
                        {
                            throw new ArgumentException($"An indirection level references a value list with ID {objectTypeId}, but this value list could not be found.", nameof(indirectionLevel));
                        }

                        // If it's not a real object type then throw.
                        if (false == indirectionLevelObjectType.RealObjectType)
                        {
                            throw new ArgumentException($"An indirection level references an value list with ID {objectTypeId}, but this list does not refer to an object type (cannot be used with value lists).", nameof(indirectionLevel));
                        }
                    }
                }

                // Set the indirection levels.
                searchCondition.Expression.IndirectionLevels
                    = indirectionLevels;
            }

            // Was the value null?
            if (null == value)
            {
                searchCondition.TypedValue.SetValueToNULL(dataType);
            }
            else
            {
                searchCondition.TypedValue.SetValue(dataType, value);
            }

            // Add the search condition to the collection.
            searchBuilder.Conditions.Add(-1, searchCondition);

            // Return the search builder for chaining.
            return(searchBuilder);
        }
Пример #24
0
        /// <summary>
        /// Adds a <see cref="SearchCondition"/> to the collection for a <see cref="MFDataType.MFDatatypeText"/>
        /// or <see cref="MFDataType.MFDatatypeMultiLineText"/> property definition.
        /// </summary>
        /// <param name="searchBuilder">The <see cref="MFSearchBuilder"/> to add the condition to.</param>
        /// <param name="propertyDef">The ID of the property to search by.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="conditionType">What type of search to execute (defaults to <see cref="MFConditionType.MFConditionTypeEqual"/>).</param>
        /// <param name="parentChildBehavior">Whether to accept matches to parent/child values as well (defaults to <see cref="MFParentChildBehavior.MFParentChildBehaviorNone"/>).</param>
        /// <param name="dataFunctionCall">An expression for modifying how the results of matches are evaluated (defaults to null).</param>
        /// <param name="indirectionLevels">The indirection levels (from the search object) to access the property to match.</param>
        /// <returns>The <paramref name="searchBuilder"/> provided, for chaining.</returns>
        public static MFSearchBuilder Property
        (
            this MFSearchBuilder searchBuilder,
            int propertyDef,
            string value,
            MFConditionType conditionType              = MFConditionType.MFConditionTypeEqual,
            MFParentChildBehavior parentChildBehavior  = MFParentChildBehavior.MFParentChildBehaviorNone,
            PropertyDefOrObjectTypes indirectionLevels = null,
            DataFunctionCall dataFunctionCall          = null
        )
        {
            // Sanity.
            if (null == searchBuilder)
            {
                throw new ArgumentNullException(nameof(searchBuilder));
            }
            if (0 > propertyDef)
            {
                throw new ArgumentOutOfRangeException(nameof(propertyDef), "Property Ids must be greater than -1; ensure that your property alias was resolved.");
            }

            // What is the type of this property?
            var dataType = searchBuilder.Vault.PropertyDefOperations.GetPropertyDef(propertyDef).DataType;

            // Do we need to change the data type for the data function call?
            if (dataFunctionCall != null)
            {
                switch (dataFunctionCall.DataFunction)
                {
                case MFDataFunction.MFDataFunctionMonth:
                {
                    // If it's a timestamp or date then convert to text.
                    if (dataType == MFDataType.MFDatatypeTimestamp ||
                        dataType == MFDataType.MFDatatypeDate)
                    {
                        dataType = MFDataType.MFDatatypeText;
                    }

                    // Validate the value.
                    if (value?.Length != 2)
                    {
                        throw new ArgumentException
                              (
                                  $"The value {value} should contain a two-digit month number (e.g. '03').",
                                  nameof(value)
                              );
                    }

                    // Is it an integer?
                    if (false == Int32.TryParse(value, out int month))
                    {
                        throw new ArgumentException
                              (
                                  $"The value {value} should contain a two-digit month number (e.g. '03').",
                                  nameof(value)
                              );
                    }

                    // Validate the month.
                    if (month <= 0 || month > 12)
                    {
                        throw new ArgumentException
                              (
                                  $"The month value {month} should be between 1 and 12.",
                                  nameof(value)
                              );
                    }
                }
                break;

                case MFDataFunction.MFDataFunctionYearAndMonth:
                {
                    // If it's a timestamp or date then convert to text.
                    if (dataType == MFDataType.MFDatatypeTimestamp ||
                        dataType == MFDataType.MFDatatypeDate)
                    {
                        dataType = MFDataType.MFDatatypeText;
                    }

                    // Also, validate the value.
                    var splitValue = (value ?? "").Split("-".ToCharArray());
                    if (splitValue.Length != 2 ||
                        splitValue[0].Length != 4 ||
                        splitValue[1].Length != 2)
                    {
                        throw new ArgumentException
                              (
                                  $"The value {value} is not of the expected format (YYYY-MM).",
                                  nameof(value)
                              );
                    }

                    // Is it a valid set of integers?
                    {
                        if (false == Int32.TryParse(splitValue[0], out _) ||
                            false == Int32.TryParse(splitValue[1], out int month))
                        {
                            throw new ArgumentException
                                  (
                                      $"The value {value} is not of the expected format (YYYY-MM).",
                                      nameof(value)
                                  );
                        }

                        // Validate the month.
                        if (month <= 0 || month > 12)
                        {
                            throw new ArgumentException
                                  (
                                      $"The month value {month} should be between 1 and 12.",
                                      nameof(value)
                                  );
                        }
                    }
                }
                break;
                }
            }

            // If it is not okay then throw.
            if (dataType != MFDataType.MFDatatypeText &&
                dataType != MFDataType.MFDatatypeMultiLineText)
            {
                throw new ArgumentException($"Property {propertyDef} is not a text property.", nameof(propertyDef));
            }

            // Add the search condition.
            return(searchBuilder.AddPropertyValueSearchCondition
                   (
                       propertyDef,
                       dataType,
                       value,
                       conditionType,
                       parentChildBehavior,
                       indirectionLevels,
                       dataFunctionCall
                   ));
        }