コード例 #1
0
 public static Parameter Parse(WhereInfo whereInfo)
 {
     return(new Parameter()
     {
         Param = "@" + whereInfo.Column,
         Value = whereInfo.Value
     });
 }
コード例 #2
0
        private WhereInfo GetFilledRandomWhereInfo(string OmitPropName)
        {
            WhereInfo whereInfo = new WhereInfo();

            if (OmitPropName != "PropertyName")
            {
                whereInfo.PropertyName = GetRandomString("", 5);
            }
            if (OmitPropName != "PropertyType")
            {
                whereInfo.PropertyType = (PropertyTypeEnum)GetRandomEnumType(typeof(PropertyTypeEnum));
            }
            if (OmitPropName != "WhereOperator")
            {
                whereInfo.WhereOperator = (WhereOperatorEnum)GetRandomEnumType(typeof(WhereOperatorEnum));
            }
            if (OmitPropName != "Value")
            {
                whereInfo.Value = GetRandomString("", 5);
            }
            if (OmitPropName != "ValueInt")
            {
                whereInfo.ValueInt = GetRandomInt(-1, -1);
            }
            if (OmitPropName != "ValueDouble")
            {
                whereInfo.ValueDouble = GetRandomDouble(-1.0D, -1.0D);
            }
            if (OmitPropName != "ValueBool")
            {
                whereInfo.ValueBool = true;
            }
            if (OmitPropName != "ValueDateTime")
            {
                whereInfo.ValueDateTime = new DateTime(2005, 3, 6);
            }
            if (OmitPropName != "ValueEnumText")
            {
                whereInfo.ValueEnumText = GetRandomString("", 5);
            }
            //CSSPError: property [EnumType] and type [WhereInfo] is  not implemented

            return(whereInfo);
        }
コード例 #3
0
        private void UpdateWhereInfo()
        {
            UnionSubQuery unionSubQuery = Builder.ActiveUnionSubQuery;
            StringBuilder stringBuilder = new StringBuilder();

            SQLSubQuerySelectExpression unionSubQueryAst = unionSubQuery.ResultQueryAST;

            try
            {
                if (unionSubQueryAst.Where != null)
                {
                    WhereInfo.DumpWhereInfo(stringBuilder, unionSubQueryAst.Where);
                }
            }
            finally
            {
                unionSubQueryAst.Dispose();
            }

            tbWhere.Text = stringBuilder.ToString();
        }
コード例 #4
0
 public WhereInfoTest()
 {
     whereInfo = new WhereInfo();
 }
コード例 #5
0
        public ContentQueryBuilder SetWhereClause(String clause)
        {
            if (this.subscriptionGuid == null)
                throw new ApplicationException("The subscription guid must be set prior to calling this method");

            if (!String.IsNullOrEmpty(clause))
            {
                CmsContentTypeDao dao = new CmsContentTypeDao();

                //Get the fields and their types for the content type
                CmsContentType type = dao.FindBySiteAndName(this.subscriptionGuid, this.contentType);
                IList<CmsContentTypeField> fields = dao.FindFieldsByContentTypeGuid(type.Guid);

                //Perform error checking and make sure that there's not more than one paren pair
                int leftParens = clause.Count(f => f == '(');
                int rightParens = clause.Count(f => f == ')');

                if (leftParens > 1)
                    throw new ArgumentException("The where clause '" + clause + "' is not currently supported. Only a single set of parens may be present");
                if (leftParens != rightParens)
                    throw new ArgumentException("The where clause '" + clause + "' is not valid. Parentheses mitmatch. Expected " + leftParens + " but found " + rightParens);

                //Make sure there are not any conditional statements
                if (ConditionalMatch.IsMatch(clause))
                    throw new ArgumentException("The where clause '" + clause + "' is not valid: GooeyCms does not currently support conditional where clauses");

                //Parse the actual string
                clause = clause.Replace("'", "");
                clause = clause.Replace("(", "");
                clause = clause.Replace(")", "");

                Match match = StatementMatch.Match(clause);
                if (!match.Success)
                    throw new ArgumentException("The where clause '" + clause + "' is not in a valid format. Format should be: field-name [<,>,=] value. Greater-than and Less-than are only supported on datetime field types.");

                String fieldname = match.Groups["fieldname"].Value;
                String condition = match.Groups["condition"].Value;
                String value = match.Groups["value"].Value;

                //Make sure that this fieldname is valid for the content type
                CmsContentTypeField field = null;
                try
                {
                    field = fields.Single(f => f.SystemName.Equals(fieldname));
                }
                catch (InvalidOperationException e)
                {
                    StringBuilder builder = new StringBuilder();
                    foreach (CmsContentTypeField temp in fields)
                    {
                        builder.Append(temp.SystemName + "|");
                    }
                    throw new ArgumentException("The where clause '" + clause + "' is not valid: The content type '" + type.Name + "' does not contain the field '" + fieldname + "'. Available fields:" + builder.ToString());
                }

                WhereInfo whereInfo = new WhereInfo();
                whereInfo.Value1 = value;
                whereInfo.Field = field;
                whereInfo.ParseConditional(condition);

                this.whereClauses.Add(whereInfo);
            }
            return this;
        }
コード例 #6
0
        static void FKScanChildren(Parse parse, SrcList src, Table table, Index index, FKey fkey, int[] cols, int regDataId, int incr)
        {
            Context ctx    = parse.Ctx; // Database handle
            Vdbe    v      = parse.GetVdbe();
            Expr    where_ = null;      // WHERE clause to scan with

            Debug.Assert(index == null || index.Table == table);
            int fkIfZero = 0; // Address of OP_FkIfZero

            if (incr < 0)
            {
                fkIfZero = v.AddOp2(OP.FkIfZero, fkey.IsDeferred, 0);
            }

            // Create an Expr object representing an SQL expression like:
            //
            //   <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
            //
            // The collation sequence used for the comparison should be that of the parent key columns. The affinity of the parent key column should
            // be applied to each child key value before the comparison takes place.
            for (int i = 0; i < fkey.Cols.length; i++)
            {
                int  col;                                      // Index of column in child table
                Expr left = Expr.Expr(ctx, TK.REGISTER, null); // Value from parent table row
                if (left != null)
                {
                    // Set the collation sequence and affinity of the LHS of each TK_EQ expression to the parent key column defaults.
                    if (index != null)
                    {
                        col = index.Columns[i];
                        Column colObj = table.Cols[col];
                        if (table.PKey == col)
                        {
                            col = -1;
                        }
                        left.TableId = regDataId + col + 1;
                        left.Aff     = colObj.Affinity;
                        string collName = colObj.Coll;
                        if (collName == null)
                        {
                            collName = ctx.DefaultColl.Name;
                        }
                        left = Expr.AddCollateString(parse, left, collName);
                    }
                    else
                    {
                        left.TableId = regDataId;
                        left.Aff     = AFF.INTEGER;
                    }
                }
                col = (cols != null ? cols[i] : fkey.Cols[0].From);
                Debug.Assert(col >= 0);
                string colName = fkey.From.Cols[col].Name;                 // Name of column in child table
                Expr   right   = Expr.Expr(ctx, TK.ID, colName);           // Column ref to child table
                Expr   eq      = Expr.PExpr(parse, TK.EQ, left, right, 0); // Expression (pLeft = pRight)
                where_ = Expr.And(ctx, where_, eq);
            }

            // If the child table is the same as the parent table, and this scan is taking place as part of a DELETE operation (operation D.2), omit the
            // row being deleted from the scan by adding ($rowid != rowid) to the WHERE clause, where $rowid is the rowid of the row being deleted.
            if (table == fkey.From && incr > 0)
            {
                Expr left  = Expr.Expr(ctx, TK.REGISTER, null); // Value from parent table row
                Expr right = Expr.Expr(ctx, TK.COLUMN, null);   // Column ref to child table
                if (left != null && right != null)
                {
                    left.TableId   = regDataId;
                    left.Aff       = AFF.INTEGER;
                    right.TableId  = src.Ids[0].Cursor;
                    right.ColumnId = -1;
                }
                Expr eq = Expr.PExpr(parse, TK.NE, left, right, 0); // Expression (pLeft = pRight)
                where_ = Expr.And(ctx, where_, eq);
            }

            // Resolve the references in the WHERE clause.
            NameContext nameContext;                 // Context used to resolve WHERE clause

            nameContext         = new NameContext(); // memset( &sNameContext, 0, sizeof( NameContext ) );
            nameContext.SrcList = src;
            nameContext.Parse   = parse;
            ResolveExprNames(nameContext, ref where_);

            // Create VDBE to loop through the entries in src that match the WHERE clause. If the constraint is not deferred, throw an exception for
            // each row found. Otherwise, for deferred constraints, increment the deferred constraint counter by incr for each row selected.
            ExprList  dummy     = null;
            WhereInfo whereInfo = Where.Begin(parse, src, where_, ref dummy, 0); // Context used by sqlite3WhereXXX()

            if (incr > 0 && !fkey.IsDeferred)
            {
                E.Parse_Toplevel(parse).MayAbort = true;
            }
            v.AddOp2(OP.FkCounter, fkey.IsDeferred, incr);
            if (whereInfo != null)
            {
                Where.End(whereInfo);
            }

            // Clean up the WHERE clause constructed above.
            Expr.Delete(ctx, ref where_);
            if (fkIfZero != 0)
            {
                v.JumpHere(fkIfZero);
            }
        }
コード例 #7
0
ファイル: WhereQuery.cs プロジェクト: PyForMcj/Elasticsearch
        /// <summary>
        /// searchRequest 生成
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public static Func <SearchDescriptor <Student>, ISearchRequest> CreateSearchRequest(WhereInfo where)
        {
            //querys
            var mustQuerys = new List <Func <QueryContainerDescriptor <Student>, QueryContainer> >();

            if (where.venId > 0)
            {
                mustQuerys.Add(t => t.Term(f => f.Id, where.venId));
            }

            //filters
            var mustFilters = new List <Func <QueryContainerDescriptor <Student>, QueryContainer> >();

            if (!string.IsNullOrEmpty(where.venName))
            {
                mustFilters.Add(t => t.MatchPhrase(f => f.Field(fd => fd.Description).Query(where.venName)));
            }
            Func <SearchDescriptor <Student>, ISearchRequest> searchRequest = r =>
                                                                              r.Query(q =>
                                                                                      q.Bool(b =>
                                                                                             b.Must(mustQuerys)

                                                                                             .Filter(f =>
                                                                                                     f.Bool(fb =>
                                                                                                            fb.Must(mustFilters))
                                                                                                     )
                                                                                             )
                                                                                      );

            return(searchRequest);
        }
コード例 #8
0
        private IEnumerable <ValidationResult> Validate(ValidationContext validationContext, ActionDBTypeEnum actionDBType)
        {
            string    retStr    = "";
            Enums     enums     = new Enums(LanguageRequest);
            WhereInfo whereInfo = validationContext.ObjectInstance as WhereInfo;

            whereInfo.HasErrors = false;

            if (string.IsNullOrWhiteSpace(whereInfo.PropertyName))
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._IsRequired, "PropertyName"), new[] { "PropertyName" }));
            }

            if (!string.IsNullOrWhiteSpace(whereInfo.PropertyName) && whereInfo.PropertyName.Length > 100)
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._MaxLengthIs_, "PropertyName", "100"), new[] { "PropertyName" }));
            }

            retStr = enums.EnumTypeOK(typeof(PropertyTypeEnum), (int?)whereInfo.PropertyType);
            if (!string.IsNullOrWhiteSpace(retStr))
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._IsRequired, "PropertyType"), new[] { "PropertyType" }));
            }

            retStr = enums.EnumTypeOK(typeof(WhereOperatorEnum), (int?)whereInfo.WhereOperator);
            if (!string.IsNullOrWhiteSpace(retStr))
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._IsRequired, "WhereOperator"), new[] { "WhereOperator" }));
            }

            if (string.IsNullOrWhiteSpace(whereInfo.Value))
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._IsRequired, "Value"), new[] { "Value" }));
            }

            if (!string.IsNullOrWhiteSpace(whereInfo.Value) && whereInfo.Value.Length > 100)
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._MaxLengthIs_, "Value", "100"), new[] { "Value" }));
            }

            if (whereInfo.ValueInt < -1 || whereInfo.ValueInt > -1)
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ValueShouldBeBetween_And_, "ValueInt", "-1", "-1"), new[] { "ValueInt" }));
            }

            if (whereInfo.ValueDouble < -1 || whereInfo.ValueDouble > -1)
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ValueShouldBeBetween_And_, "ValueDouble", "-1", "-1"), new[] { "ValueDouble" }));
            }

            if (whereInfo.ValueDateTime.Year == 1)
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._IsRequired, "ValueDateTime"), new[] { "ValueDateTime" }));
            }
            else
            {
                if (whereInfo.ValueDateTime.Year < 1900)
                {
                    whereInfo.HasErrors = true;
                    yield return(new ValidationResult(string.Format(CSSPServicesRes._YearShouldBeBiggerThan_, "ValueDateTime", "1900"), new[] { "ValueDateTime" }));
                }
            }

            if (string.IsNullOrWhiteSpace(whereInfo.ValueEnumText))
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._IsRequired, "ValueEnumText"), new[] { "ValueEnumText" }));
            }

            if (!string.IsNullOrWhiteSpace(whereInfo.ValueEnumText) && whereInfo.ValueEnumText.Length > 100)
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._MaxLengthIs_, "ValueEnumText", "100"), new[] { "ValueEnumText" }));
            }

            //CSSPError: Type not implemented [EnumType] of type [Type]

            //CSSPError: Type not implemented [EnumType] of type [Type]
            retStr = "";      // added to stop compiling CSSPError
            if (retStr != "") // will never be true
            {
                whereInfo.HasErrors = true;
                yield return(new ValidationResult("AAA", new[] { "AAA" }));
            }
        }
コード例 #9
0
        public static object GetEnumCasting(WhereInfo whereInfo)
        {
            switch (whereInfo.EnumType.Name)
            {
            case "IEnums":
                return((IEnums)whereInfo.ValueInt);

            case "ActionDBTypeEnum":
                return((ActionDBTypeEnum)whereInfo.ValueInt);

            case "AddContactTypeEnum":
                return((AddContactTypeEnum)whereInfo.ValueInt);

            case "EntityQueryTypeEnum":
                return((EntityQueryTypeEnum)whereInfo.ValueInt);

            case "PolSourceObsInfoTypeEnum":
                return((PolSourceObsInfoTypeEnum)whereInfo.ValueInt);

            case "AddressTypeEnum":
                return((AddressTypeEnum)whereInfo.ValueInt);

            case "AerationTypeEnum":
                return((AerationTypeEnum)whereInfo.ValueInt);

            case "AlarmSystemTypeEnum":
                return((AlarmSystemTypeEnum)whereInfo.ValueInt);

            case "AnalysisCalculationTypeEnum":
                return((AnalysisCalculationTypeEnum)whereInfo.ValueInt);

            case "AnalysisReportExportCommandEnum":
                return((AnalysisReportExportCommandEnum)whereInfo.ValueInt);

            case "AnalyzeMethodEnum":
                return((AnalyzeMethodEnum)whereInfo.ValueInt);

            case "AppTaskCommandEnum":
                return((AppTaskCommandEnum)whereInfo.ValueInt);

            case "AppTaskStatusEnum":
                return((AppTaskStatusEnum)whereInfo.ValueInt);

            case "BeaufortScaleEnum":
                return((BeaufortScaleEnum)whereInfo.ValueInt);

            case "BoxModelResultTypeEnum":
                return((BoxModelResultTypeEnum)whereInfo.ValueInt);

            case "CanOverflowTypeEnum":
                return((CanOverflowTypeEnum)whereInfo.ValueInt);

            case "ClassificationTypeEnum":
                return((ClassificationTypeEnum)whereInfo.ValueInt);

            case "CollectionSystemTypeEnum":
                return((CollectionSystemTypeEnum)whereInfo.ValueInt);

            case "ContactTitleEnum":
                return((ContactTitleEnum)whereInfo.ValueInt);

            case "CSSPWQInputSheetTypeEnum":
                return((CSSPWQInputSheetTypeEnum)whereInfo.ValueInt);

            case "CSSPWQInputTypeEnum":
                return((CSSPWQInputTypeEnum)whereInfo.ValueInt);

            case "DailyOrHourlyDataEnum":
                return((DailyOrHourlyDataEnum)whereInfo.ValueInt);

            case "DisinfectionTypeEnum":
                return((DisinfectionTypeEnum)whereInfo.ValueInt);

            case "DrogueTypeEnum":
                return((DrogueTypeEnum)whereInfo.ValueInt);

            case "EmailTypeEnum":
                return((EmailTypeEnum)whereInfo.ValueInt);

            case "ExcelExportShowDataTypeEnum":
                return((ExcelExportShowDataTypeEnum)whereInfo.ValueInt);

            case "FacilityTypeEnum":
                return((FacilityTypeEnum)whereInfo.ValueInt);

            case "FilePurposeEnum":
                return((FilePurposeEnum)whereInfo.ValueInt);

            case "FileStatusEnum":
                return((FileStatusEnum)whereInfo.ValueInt);

            case "FileTypeEnum":
                return((FileTypeEnum)whereInfo.ValueInt);

            case "InfrastructureTypeEnum":
                return((InfrastructureTypeEnum)whereInfo.ValueInt);

            case "KMZActionEnum":
                return((KMZActionEnum)whereInfo.ValueInt);

            case "LaboratoryEnum":
                return((LaboratoryEnum)whereInfo.ValueInt);

            case "LabSheetStatusEnum":
                return((LabSheetStatusEnum)whereInfo.ValueInt);

            case "LabSheetTypeEnum":
                return((LabSheetTypeEnum)whereInfo.ValueInt);

            case "LanguageEnum":
                return((LanguageEnum)whereInfo.ValueInt);

            case "LogCommandEnum":
                return((LogCommandEnum)whereInfo.ValueInt);

            case "MapInfoDrawTypeEnum":
                return((MapInfoDrawTypeEnum)whereInfo.ValueInt);

            case "MikeBoundaryConditionLevelOrVelocityEnum":
                return((MikeBoundaryConditionLevelOrVelocityEnum)whereInfo.ValueInt);

            case "MikeScenarioSpecialResultKMLTypeEnum":
                return((MikeScenarioSpecialResultKMLTypeEnum)whereInfo.ValueInt);

            case "MWQMSiteLatestClassificationEnum":
                return((MWQMSiteLatestClassificationEnum)whereInfo.ValueInt);

            case "PolSourceInactiveReasonEnum":
                return((PolSourceInactiveReasonEnum)whereInfo.ValueInt);

            case "PolSourceIssueRiskEnum":
                return((PolSourceIssueRiskEnum)whereInfo.ValueInt);

            case "PositionEnum":
                return((PositionEnum)whereInfo.ValueInt);

            case "PreliminaryTreatmentTypeEnum":
                return((PreliminaryTreatmentTypeEnum)whereInfo.ValueInt);

            case "PrimaryTreatmentTypeEnum":
                return((PrimaryTreatmentTypeEnum)whereInfo.ValueInt);

            case "PropertyTypeEnum":
                return((PropertyTypeEnum)whereInfo.ValueInt);

            case "ReportConditionEnum":
                return((ReportConditionEnum)whereInfo.ValueInt);

            case "ReportFieldTypeEnum":
                return((ReportFieldTypeEnum)whereInfo.ValueInt);

            case "ReportFileTypeEnum":
                return((ReportFileTypeEnum)whereInfo.ValueInt);

            case "ReportFormatingDateEnum":
                return((ReportFormatingDateEnum)whereInfo.ValueInt);

            case "ReportFormatingNumberEnum":
                return((ReportFormatingNumberEnum)whereInfo.ValueInt);

            case "ReportGenerateObjectsKeywordEnum":
                return((ReportGenerateObjectsKeywordEnum)whereInfo.ValueInt);

            case "ReportSortingEnum":
                return((ReportSortingEnum)whereInfo.ValueInt);

            case "ReportTreeNodeSubTypeEnum":
                return((ReportTreeNodeSubTypeEnum)whereInfo.ValueInt);

            case "ReportTreeNodeTypeEnum":
                return((ReportTreeNodeTypeEnum)whereInfo.ValueInt);

            case "SameDayNextDayEnum":
                return((SameDayNextDayEnum)whereInfo.ValueInt);

            case "SampleMatrixEnum":
                return((SampleMatrixEnum)whereInfo.ValueInt);

            case "SampleStatusEnum":
                return((SampleStatusEnum)whereInfo.ValueInt);

            case "SampleTypeEnum":
                return((SampleTypeEnum)whereInfo.ValueInt);

            case "SamplingPlanTypeEnum":
                return((SamplingPlanTypeEnum)whereInfo.ValueInt);

            case "ScenarioStatusEnum":
                return((ScenarioStatusEnum)whereInfo.ValueInt);

            case "SearchTagEnum":
                return((SearchTagEnum)whereInfo.ValueInt);

            case "SecondaryTreatmentTypeEnum":
                return((SecondaryTreatmentTypeEnum)whereInfo.ValueInt);

            case "SiteTypeEnum":
                return((SiteTypeEnum)whereInfo.ValueInt);

            case "SpecialTableTypeEnum":
                return((SpecialTableTypeEnum)whereInfo.ValueInt);

            case "StorageDataTypeEnum":
                return((StorageDataTypeEnum)whereInfo.ValueInt);

            case "StreetTypeEnum":
                return((StreetTypeEnum)whereInfo.ValueInt);

            case "TelTypeEnum":
                return((TelTypeEnum)whereInfo.ValueInt);

            case "TertiaryTreatmentTypeEnum":
                return((TertiaryTreatmentTypeEnum)whereInfo.ValueInt);

            case "TideDataTypeEnum":
                return((TideDataTypeEnum)whereInfo.ValueInt);

            case "TideTextEnum":
                return((TideTextEnum)whereInfo.ValueInt);

            case "TranslationStatusEnum":
                return((TranslationStatusEnum)whereInfo.ValueInt);

            case "TreatmentTypeEnum":
                return((TreatmentTypeEnum)whereInfo.ValueInt);

            case "TVAuthEnum":
                return((TVAuthEnum)whereInfo.ValueInt);

            case "TVTypeEnum":
                return((TVTypeEnum)whereInfo.ValueInt);

            case "ValveTypeEnum":
                return((ValveTypeEnum)whereInfo.ValueInt);

            case "WebTideDataSetEnum":
                return((WebTideDataSetEnum)whereInfo.ValueInt);

            case "PolSourceObsInfoEnum":
                return((PolSourceObsInfoEnum)whereInfo.ValueInt);

            default:
                return(null);
            }
        }
コード例 #10
0
        public static void sqlite3Update(Parse parse, SrcList tabList, ExprList changes, Expr where_, OE onError)
        {
            int i, j;                                 // Loop counters

            AuthContext sContext = new AuthContext(); // The authorization context
            Context     ctx      = parse.Ctx;         // The database structure

            if (parse.Errs != 0 || ctx.MallocFailed)
            {
                goto update_cleanup;
            }
            Debug.Assert(tabList.Srcs == 1);

            // Locate the table which we want to update.
            Table table = sqlite3SrcListLookup(parse, tabList); // The table to be updated

            if (table == null)
            {
                goto update_cleanup;
            }
            int db = sqlite3SchemaToIndex(ctx, table.Schema); // Database containing the table being updated

            // Figure out if we have any triggers and if the table being updated is a view.
#if !OMIT_TRIGGER
            int     tmask   = 0;                                                                 // Mask of TRIGGER_BEFORE|TRIGGER_AFTER
            Trigger trigger = sqlite3TriggersExist(parse, table, TK.UPDATE, changes, out tmask); // List of triggers on pTab, if required
#if OMIT_VIEW
            const bool isView = false;
#else
            bool isView = (table.Select != null); // True when updating a view (INSTEAD OF trigger)
#endif
            Debug.Assert(trigger != null || tmask == 0);
#else
            const Trigger trigger = null;
            const int     tmask   = 0;
            const bool    isView  = false;
#endif

            if (sqlite3ViewGetColumnNames(parse, table) != 0 || sqlite3IsReadOnly(parse, table, tmask))
            {
                goto update_cleanup;
            }

            int[] xrefs = new int[table.Cols.length]; // xrefs[i] is the index in pChanges->a[] of the an expression for the i-th column of the table. xrefs[i]==-1 if the i-th column is not changed.
            if (xrefs == null)
            {
                goto update_cleanup;
            }
            for (i = 0; i < table.Cols.length; i++)
            {
                xrefs[i] = -1;
            }

            // Allocate a cursors for the main database table and for all indices. The index cursors might not be used, but if they are used they
            // need to occur right after the database cursor.  So go ahead and allocate enough space, just in case.
            int curId; // VDBE Cursor number of pTab
            tabList.Ids[0].Cursor = curId = parse.Tabs++;
            Index idx; // For looping over indices
            for (idx = table.Index; idx != null; idx = idx.Next)
            {
                parse.Tabs++;
            }

            // Initialize the name-context
            NameContext sNC = new NameContext(); // The name-context to resolve expressions in
            sNC.Parse   = parse;
            sNC.SrcList = tabList;

            // Resolve the column names in all the expressions of the of the UPDATE statement.  Also find the column index
            // for each column to be updated in the pChanges array.  For each column to be updated, make sure we have authorization to change that column.
            bool chngRowid = false; // True if the record number is being changed
            Expr rowidExpr = null;  // Expression defining the new record number
            for (i = 0; i < changes.Exprs; i++)
            {
                if (sqlite3ResolveExprNames(sNC, ref changes.Ids[i].Expr) != 0)
                {
                    goto update_cleanup;
                }
                for (j = 0; j < table.Cols.length; j++)
                {
                    if (string.Equals(table.Cols[j].Name, changes.Ids[i].Name, StringComparison.OrdinalIgnoreCase))
                    {
                        if (j == table.PKey)
                        {
                            chngRowid = true;
                            rowidExpr = changes.Ids[i].Expr;
                        }
                        xrefs[j] = i;
                        break;
                    }
                }
                if (j >= table.Cols.length)
                {
                    if (Expr::IsRowid(changes.Ids[i].Name))
                    {
                        chngRowid = true;
                        rowidExpr = changes.Ids[i].Expr;
                    }
                    else
                    {
                        parse.ErrorMsg("no such column: %s", changes.Ids[i].Name);
                        parse.CheckSchema = 1;
                        goto update_cleanup;
                    }
                }
#if !OMIT_AUTHORIZATION
                {
                    ARC rc = Auth.Check(parse, AUTH.UPDATE, table.Name, table.Cols[j].Name, ctx.DBs[db].Name);
                    if (rc == ARC.DENY)
                    {
                        goto update_cleanup;
                    }
                    else if (rc == ARC.IGNORE)
                    {
                        xrefs[j] = -1;
                    }
                }
#endif
            }

            bool hasFK = sqlite3FkRequired(parse, table, xrefs, chngRowid ? 1 : 0); // True if foreign key processing is required

            // Allocate memory for the array aRegIdx[].  There is one entry in the array for each index associated with table being updated.  Fill in
            // the value with a register number for indices that are to be used and with zero for unused indices.
            int idxLength;                   // Number of indices that need updating
            for (idxLength = 0, idx = table.Index; idx != null; idx = idx.Next, idxLength++)
            {
                ;
            }
            int[] regIdxs = null; // One register assigned to each index to be updated
            if (idxLength > 0)
            {
                regIdxs = new int[idxLength];
                if (regIdxs == null)
                {
                    goto update_cleanup;
                }
            }
            for (j = 0, idx = table.Index; idx != null; idx = idx.Next, j++)
            {
                int regId;
                if (hasFK || chngRowid)
                {
                    regId = ++parse.Mems;
                }
                else
                {
                    regId = 0;
                    for (i = 0; i < idx.Columns.length; i++)
                    {
                        if (xrefs[idx.Columns[i]] >= 0)
                        {
                            regId = ++parse.Mems;
                            break;
                        }
                    }
                }
                regIdxs[j] = regId;
            }

            // Begin generating code.
            Vdbe v = parse.GetVdbe(); // The virtual database engine
            if (v == null)
            {
                goto update_cleanup;
            }
            if (parse.Nested == 0)
            {
                v.CountChanges();
            }
            parse.BeginWriteOperation(1, db);

#if !OMIT_VIRTUALTABLE
            // Virtual tables must be handled separately
            if (IsVirtual(table))
            {
                UpdateVirtualTable(parse, tabList, table, changes, rowidExpr, xrefs, where_, onError);
                where_  = null;
                tabList = null;
                goto update_cleanup;
            }
#endif

            // Register Allocations
            int regRowCount = 0;         // A count of rows changed
            int regOldRowid;             // The old rowid
            int regNewRowid;             // The new rowid
            int regNew;
            int regOld    = 0;
            int regRowSet = 0;           // Rowset of rows to be updated

            // Allocate required registers.
            regOldRowid = regNewRowid = ++parse.Mems;
            if (trigger != null || hasFK)
            {
                regOld      = parse.Mems + 1;
                parse.Mems += table.Cols.length;
            }
            if (chngRowid || trigger != null || hasFK)
            {
                regNewRowid = ++parse.Mems;
            }
            regNew      = parse.Mems + 1;
            parse.Mems += table.Cols.length;

            // Start the view context.
            if (isView)
            {
                Auth.ContextPush(parse, sContext, table.Name);
            }

            // If we are trying to update a view, realize that view into a ephemeral table.
#if !OMIT_VIEW && !OMIT_TRIGGER
            if (isView)
            {
                sqlite3MaterializeView(parse, table, where_, curId);
            }
#endif

            // Resolve the column names in all the expressions in the WHERE clause.
            if (sqlite3ResolveExprNames(sNC, ref where_) != 0)
            {
                goto update_cleanup;
            }

            // Begin the database scan
            v.AddOp2(OP.Null, 0, regOldRowid);
            ExprList  dummy = null;
            WhereInfo winfo = Where.Begin(parse, tabList, where_, ref dummy, WHERE.ONEPASS_DESIRED); // Information about the WHERE clause
            if (winfo == null)
            {
                goto update_cleanup;
            }
            bool okOnePass = winfo.OkOnePass; // True for one-pass algorithm without the FIFO

            // Remember the rowid of every item to be updated.
            v.AddOp2(OP.Rowid, curId, regOldRowid);
            if (!okOnePass)
            {
                v.AddOp2(OP.RowSetAdd, regRowSet, regOldRowid);
            }

            // End the database scan loop.
            Where.End(winfo);

            // Initialize the count of updated rows
            if ((ctx.Flags & Context.FLAG.CountRows) != 0 && parse.TriggerTab == null)
            {
                regRowCount = ++parse.Mems;
                v.AddOp2(OP.Integer, 0, regRowCount);
            }

            bool openAll = false; // True if all indices need to be opened
            if (!isView)
            {
                // Open every index that needs updating.  Note that if any index could potentially invoke a REPLACE conflict resolution
                // action, then we need to open all indices because we might need to be deleting some records.
                if (!okOnePass)
                {
                    sqlite3OpenTable(parse, curId, db, table, OP.OpenWrite);
                }
                if (onError == OE.Replace)
                {
                    openAll = true;
                }
                else
                {
                    openAll = false;
                    for (idx = table.Index; idx != null; idx = idx.Next)
                    {
                        if (idx.OnError == OE.Replace)
                        {
                            openAll = true;
                            break;
                        }
                    }
                }
                for (i = 0, idx = table.Index; idx != null; idx = idx.Next, i++)
                {
                    if (openAll || regIdxs[i] > 0)
                    {
                        KeyInfo key = sqlite3IndexKeyinfo(parse, idx);
                        v.AddOp4(OP.OpenWrite, curId + i + 1, idx.Id, db, key, Vdbe.P4T.KEYINFO_HANDOFF);
                        Debug.Assert(parse.Tabs > curId + i + 1);
                    }
                }
            }

            // Top of the update loop
            int addr = 0; // VDBE instruction address of the start of the loop
            if (okOnePass)
            {
                int a1 = v.AddOp1(OP.NotNull, regOldRowid);
                addr = v.AddOp0(OP.Goto);
                v.JumpHere(a1);
            }
            else
            {
                addr = v.AddOp3(OP.RowSetRead, regRowSet, 0, regOldRowid);
            }

            // Make cursor iCur point to the record that is being updated. If this record does not exist for some reason (deleted by a trigger,
            // for example, then jump to the next iteration of the RowSet loop.
            v.AddOp3(OP.NotExists, curId, addr, regOldRowid);

            // If the record number will change, set register regNewRowid to contain the new value. If the record number is not being modified,
            // then regNewRowid is the same register as regOldRowid, which is already populated.
            Debug.Assert(chngRowid || trigger != null || hasFK || regOldRowid == regNewRowid);
            if (chngRowid)
            {
                Expr.Code(parse, rowidExpr, regNewRowid);
                v.AddOp1(OP.MustBeInt, regNewRowid);
            }

            // If there are triggers on this table, populate an array of registers with the required old.* column data.
            if (hasFK || trigger != null)
            {
                uint oldmask = (hasFK ? sqlite3FkOldmask(parse, table) : 0);
                oldmask |= sqlite3TriggerColmask(parse, trigger, changes, 0, TRIGGER_BEFORE | TRIGGER_AFTER, table, onError);
                for (i = 0; i < table.Cols.length; i++)
                {
                    if (xrefs[i] < 0 || oldmask == 0xffffffff || (i < 32 && 0 != (oldmask & (1 << i))))
                    {
                        Expr.CodeGetColumnOfTable(v, table, curId, i, regOld + i);
                    }
                    else
                    {
                        v.AddOp2(OP.Null, 0, regOld + i);
                    }
                }
                if (!chngRowid)
                {
                    v.AddOp2(OP.Copy, regOldRowid, regNewRowid);
                }
            }

            // Populate the array of registers beginning at regNew with the new row data. This array is used to check constaints, create the new
            // table and index records, and as the values for any new.* references made by triggers.
            //
            // If there are one or more BEFORE triggers, then do not populate the registers associated with columns that are (a) not modified by
            // this UPDATE statement and (b) not accessed by new.* references. The values for registers not modified by the UPDATE must be reloaded from
            // the database after the BEFORE triggers are fired anyway (as the trigger may have modified them). So not loading those that are not going to
            // be used eliminates some redundant opcodes.
            int newmask = (int)sqlite3TriggerColmask(parse, trigger, changes, 1, TRIGGER_BEFORE, table, onError); // Mask of NEW.* columns accessed by BEFORE triggers
            for (i = 0; i < table.Cols.length; i++)
            {
                if (i == table.PKey)
                {
                    //v.AddOp2(OP.Null, 0, regNew + i);
                }
                else
                {
                    j = xrefs[i];
                    if (j >= 0)
                    {
                        Expr.Code(parse, changes.Ids[j].Expr, regNew + i);
                    }
                    else if ((tmask & TRIGGER_BEFORE) == 0 || i > 31 || (newmask & (1 << i)) != 0)
                    {
                        // This branch loads the value of a column that will not be changed into a register. This is done if there are no BEFORE triggers, or
                        // if there are one or more BEFORE triggers that use this value via a new.* reference in a trigger program.
                        C.ASSERTCOVERAGE(i == 31);
                        C.ASSERTCOVERAGE(i == 32);
                        v.AddOp3(OP.Column, curId, i, regNew + i);
                        v.ColumnDefault(table, i, regNew + i);
                    }
                }
            }

            // Fire any BEFORE UPDATE triggers. This happens before constraints are verified. One could argue that this is wrong.
            if ((tmask & TRIGGER_BEFORE) != 0)
            {
                v.AddOp2(OP.Affinity, regNew, table.Cols.length);
                sqlite3TableAffinityStr(v, table);
                sqlite3CodeRowTrigger(parse, trigger, TK.UPDATE, changes, TRIGGER_BEFORE, table, regOldRowid, onError, addr);

                // The row-trigger may have deleted the row being updated. In this case, jump to the next row. No updates or AFTER triggers are
                // required. This behavior - what happens when the row being updated is deleted or renamed by a BEFORE trigger - is left undefined in the documentation.
                v.AddOp3(OP.NotExists, curId, addr, regOldRowid);

                // If it did not delete it, the row-trigger may still have modified some of the columns of the row being updated. Load the values for
                // all columns not modified by the update statement into their registers in case this has happened.
                for (i = 0; i < table.Cols.length; i++)
                {
                    if (xrefs[i] < 0 && i != table.PKey)
                    {
                        v.AddOp3(OP.Column, curId, i, regNew + i);
                        v.ColumnDefault(table, i, regNew + i);
                    }
                }
            }

            if (!isView)
            {
                // Do constraint checks.
                int dummy2;
                sqlite3GenerateConstraintChecks(parse, table, curId, regNewRowid, regIdxs, (chngRowid ? regOldRowid : 0), true, onError, addr, out dummy2);

                // Do FK constraint checks.
                if (hasFK)
                {
                    sqlite3FkCheck(parse, table, regOldRowid, 0);
                }

                // Delete the index entries associated with the current record.
                int j1 = v.AddOp3(OP.NotExists, curId, 0, regOldRowid); // Address of jump instruction
                sqlite3GenerateRowIndexDelete(parse, table, curId, regIdxs);

                // If changing the record number, delete the old record.
                if (hasFK || chngRowid)
                {
                    v.AddOp2(OP.Delete, curId, 0);
                }
                v.JumpHere(j1);

                if (hasFK)
                {
                    sqlite3FkCheck(parse, table, 0, regNewRowid);
                }

                // Insert the new index entries and the new record.
                sqlite3CompleteInsertion(parse, table, curId, regNewRowid, regIdxs, true, false, false);

                // Do any ON CASCADE, SET NULL or SET DEFAULT operations required to handle rows (possibly in other tables) that refer via a foreign key
                // to the row just updated.
                if (hasFK)
                {
                    sqlite3FkActions(parse, table, changes, regOldRowid);
                }
            }

            // Increment the row counter
            if ((ctx.Flags & Context.FLAG.CountRows) != 0 && parse.TriggerTab == null)
            {
                v.AddOp2(OP.AddImm, regRowCount, 1);
            }

            sqlite3CodeRowTrigger(parse, trigger, TK.UPDATE, changes, TRIGGER_AFTER, table, regOldRowid, onError, addr);

            // Repeat the above with the next record to be updated, until all record selected by the WHERE clause have been updated.
            v.AddOp2(OP.Goto, 0, addr);
            v.JumpHere(addr);

            // Close all tables
            Debug.Assert(regIdxs != null);
            for (i = 0, idx = table.Index; idx != null; idx = idx.Next, i++)
            {
                if (openAll || regIdxs[i] > 0)
                {
                    v.AddOp2(OP.Close, curId + i + 1, 0);
                }
            }
            v.AddOp2(OP.Close, curId, 0);

            // Update the sqlite_sequence table by storing the content of the maximum rowid counter values recorded while inserting into
            // autoincrement tables.
            if (parse.Nested == 0 && parse.TriggerTab == null)
            {
                sqlite3AutoincrementEnd(parse);
            }

            // Return the number of rows that were changed. If this routine is generating code because of a call to sqlite3NestedParse(), do not
            // invoke the callback function.
            if ((ctx.Flags & Context.FLAG.CountRows) != 0 && parse.TriggerTab == null && parse.Nested == 0)
            {
                v.AddOp2(OP.ResultRow, regRowCount, 1);
                v.SetNumCols(1);
                v.SetColName(0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
            }

update_cleanup:
#if !OMIT_AUTHORIZATION
            Auth.ContextPop(sContext);
#endif
            C._tagfree(ctx, ref regIdxs);
            C._tagfree(ctx, ref xrefs);
            SrcList.Delete(ctx, ref tabList);
            ExprList.Delete(ctx, ref changes);
            Expr.Delete(ctx, ref where_);
            return;
        }
コード例 #11
0
ファイル: Delete.cs プロジェクト: BclEx/GpuStructs
        public static void DeleteFrom(Parse parse, SrcList tabList, Expr where_)
        {
            AuthContext sContext = new AuthContext(); // Authorization context
            Context ctx = parse.Ctx; // Main database structure
            if (parse.Errs != 0 || ctx.MallocFailed)
                goto delete_from_cleanup;
            Debug.Assert(tabList.Srcs == 1);

            // Locate the table which we want to delete.  This table has to be put in an SrcList structure because some of the subroutines we
            // will be calling are designed to work with multiple tables and expect an SrcList* parameter instead of just a Table* parameter.
            Table table = SrcList.Lookup(parse, tabList); // The table from which records will be deleted
            if (table == null) goto delete_from_cleanup;

            // Figure out if we have any triggers and if the table being deleted from is a view
#if !OMIT_TRIGGER
            int dummy;
            Trigger trigger = Triggers.Exist(parse, table, TK.DELETE, null, out dummy); // List of table triggers, if required
#if OMIT_VIEW
            const bool isView = false;
#else
            bool isView = (table.Select != null); // True if attempting to delete from a view
#endif
#else
            const Trigger trigger = null;
            bool isView = false;
#endif

            // If pTab is really a view, make sure it has been initialized.
            if (sqlite3ViewGetColumnNames(parse, table) != null || IsReadOnly(parse, table, (trigger != null)))
                goto delete_from_cleanup;
            int db = sqlite3SchemaToIndex(ctx, table.Schema); // Database number
            Debug.Assert(db < ctx.DBs.length);
            string dbName = ctx.DBs[db].Name; // Name of database holding pTab
            ARC rcauth = Auth.Check(parse, AUTH.DELETE, table.Name, 0, dbName); // Value returned by authorization callback
            Debug.Assert(rcauth == ARC.OK || rcauth == ARC.DENY || rcauth == ARC.IGNORE);
            if (rcauth == ARC.DENY)
                goto delete_from_cleanup;
            Debug.Assert(!isView || trigger != null);

            // Assign cursor number to the table and all its indices.
            Debug.Assert(tabList.Srcs == 1);
            int curId = tabList.Ids[0].Cursor = parse.Tabs++; // VDBE VdbeCursor number for pTab
            Index idx; // For looping over indices of the table
            for (idx = table.Index; idx != null; idx = idx.Next)
                parse.Tabs++;

            // Start the view context
            if (isView)
                Auth.ContextPush(parse, sContext, table.Name);

            // Begin generating code.
            Vdbe v = parse.GetVdbe(); // The virtual database engine 
            if (v == null)
                goto delete_from_cleanup;
            if (parse.Nested == 0) v.CountChanges();
            parse.BeginWriteOperation(1, db);

            // If we are trying to delete from a view, realize that view into a ephemeral table.
#if !OMIT_VIEW && !OMIT_TRIGGER
            if (isView)
                MaterializeView(parse, table, where_, curId);
#endif
            // Resolve the column names in the WHERE clause.
            NameContext sNC = new NameContext(); // Name context to resolve expressions in
            sNC.Parse = parse;
            sNC.SrcList = tabList;
            if (sqlite3ResolveExprNames(sNC, ref where_) != 0)
                goto delete_from_cleanup;

            // Initialize the counter of the number of rows deleted, if we are counting rows.
            int memCnt = -1; // Memory cell used for change counting
            if ((ctx.Flags & Context.FLAG.CountRows) != 0)
            {
                memCnt = ++parse.Mems;
                v.AddOp2(OP.Integer, 0, memCnt);
            }

#if !OMIT_TRUNCATE_OPTIMIZATION
            // Special case: A DELETE without a WHERE clause deletes everything. It is easier just to erase the whole table. Prior to version 3.6.5,
            // this optimization caused the row change count (the value returned by API function sqlite3_count_changes) to be set incorrectly.
            if (rcauth == ARC.OK && where_ == null && trigger == null && !IsVirtual(table) && !FKey.FkRequired(parse, table, null, 0))
            {
                Debug.Assert(!isView);
                v.AddOp4(OP.Clear, table.Id, db, memCnt, table.Name, Vdbe.P4T.STATIC);
                for (idx = table.Index; idx != null; idx = idx.Next)
                {
                    Debug.Assert(idx.Schema == table.Schema);
                    v.AddOp2(OP.Clear, idx.Id, db);
                }
            }
            else
#endif
            // The usual case: There is a WHERE clause so we have to scan through the table and pick which records to delete.
            {
                int rowSet = ++parse.Mems; // Register for rowset of rows to delete
                int rowid = ++parse.Mems; // Used for storing rowid values.

                // Collect rowids of every row to be deleted.
                v.AddOp2(OP.Null, 0, rowSet);
                ExprList dummy = null;
                WhereInfo winfo = Where.Begin(parse, tabList, where_, ref dummy, WHERE_DUPLICATES_OK, 0); // Information about the WHERE clause
                if (winfo == null) goto delete_from_cleanup;
                int regRowid = Expr.CodeGetColumn(parse, table, -1, curId, rowid); // Actual register containing rowids
                v.AddOp2(OP.RowSetAdd, rowSet, regRowid);
                if ((ctx.Flags & Context.FLAG.CountRows) != 0)
                    v.AddOp2(OP.AddImm, memCnt, 1);
                Where.End(winfo);

                // Delete every item whose key was written to the list during the database scan.  We have to delete items after the scan is complete
                // because deleting an item can change the scan order.
                int end = v.MakeLabel();

                // Unless this is a view, open cursors for the table we are deleting from and all its indices. If this is a view, then the
                // only effect this statement has is to fire the INSTEAD OF triggers.
                if (!isView)
                    sqlite3OpenTableAndIndices(parse, table, curId, OP.OpenWrite);
                int addr = v.AddOp3(OP.RowSetRead, rowSet, end, rowid);

                // Delete the row
#if !OMIT_VIRTUALTABLE
                if (IsVirtual(table))
                {
                    VTable vtable = VTable.GetVTable(ctx, table);
                    VTable.MakeWritable(parse, table);
                    v.AddOp4(OP.VUpdate, 0, 1, rowid, vtable, Vdbe.P4T.VTAB);
                    v.ChangeP5(OE.Abort);
                    sqlite3MayAbort(parse);
                }
                else
#endif
                {
                    int count = (parse.Nested == 0; // True to count changes
                    GenerateRowDelete(parse, table, curId, rowid, count, trigger, OE.Default);
                }

                // End of the delete loop
                v.AddOp2(OP.Goto, 0, addr);
                v.ResolveLabel(end);

                // Close the cursors open on the table and its indexes.
                if (!isView && !IsVirtual(table))
                {
                    for (int i = 1, idx = table.Index; idx != null; i++, idx = idx.Next)
                        v.AddOp2(OP.Close, curId + i, idx.Id);
                    v.AddOp1(OP.Close, curId);
                }
            }

            // Update the sqlite_sequence table by storing the content of the maximum rowid counter values recorded while inserting into
		    // autoincrement tables.
            if (parse.Nested == 0 && parse.TriggerTab == null)
                sqlite3AutoincrementEnd(parse);

            // Return the number of rows that were deleted. If this routine is generating code because of a call to sqlite3NestedParse(), do not
		    // invoke the callback function.
            if ((ctx.Flags & Context.FLAG.CountRows) != 0 && parse.Nested == 0 && parse.TriggerTab == null)
            {
                v.AddOp2(OP.ResultRow, memCnt, 1);
                v.SetNumCols(1);
                v.SetColName(0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
            }

        delete_from_cleanup:
            Auth.ContextPop(sContext);
            SrcList.Delete(ctx, ref tabList);
            Expr.Delete(ctx, ref where_);
            return;
        }
コード例 #12
0
        public IEnumerable <ValidationResult> ValidateQuery(ValidationContext validationContext)
        {
            Enums enums = new Enums(LanguageRequest);
            Query query = validationContext.ObjectInstance as Query;

            query.HasErrors = false;

            if (query.ModelType == null)
            {
                query.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ShouldNotBeNullOrEmpty, "ModelType"), new[] { "ModelType" }));
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(query.Extra))
                {
                    if (!(query.ModelType.Name.Length > 6 && !query.ModelType.Name.Substring(query.ModelType.Name.Length - 6).StartsWith("Extra")))
                    {
                        string   AllowableExtra  = "";
                        bool     QueryExtraExist = false;
                        FileInfo fiDLL           = new FileInfo($@"{ AppDomain.CurrentDomain.BaseDirectory }\CSSPModels.dll");

                        if (!fiDLL.Exists)
                        {
                            fiDLL = new FileInfo($@"{ AppDomain.CurrentDomain.BaseDirectory }\bin\CSSPModels.dll");
                            if (!fiDLL.Exists)
                            {
                                query.HasErrors = true;
                                yield return(new ValidationResult(string.Format(CSSPServicesRes.CouldNotFindFile_, $@"{ AppDomain.CurrentDomain.BaseDirectory }\CSSPModels.dll or { AppDomain.CurrentDomain.BaseDirectory }\bin\CSSPModels.dll"), new[] { "Where" }));
                            }
                        }

                        var         importAssembly = Assembly.LoadFile(fiDLL.FullName);
                        List <Type> TypeList       = importAssembly.GetTypes().ToList();

                        foreach (string s in new List <string>()
                        {
                            "A", "B", "C", "D", "E"
                        })
                        {
                            bool exist = false;
                            foreach (Type type in TypeList)
                            {
                                //string ExtraName = $"{ query.ModelType.Name }Extra{ s }";
                                if (query.ModelType.Name == type.Name)
                                {
                                    exist = true;
                                    break;
                                }
                            }

                            if (exist)
                            {
                                if (query.Extra == s)
                                {
                                    QueryExtraExist = true;
                                }
                                AllowableExtra = AllowableExtra + s + ", ";
                            }
                        }

                        if (!QueryExtraExist)
                        {
                            AllowableExtra  = AllowableExtra.Trim();
                            AllowableExtra  = AllowableExtra.Substring(0, AllowableExtra.Length - 1);
                            query.HasErrors = true;
                            yield return(new ValidationResult(string.Format(CSSPServicesRes.Extra_OfModel_IsInvalidAllowableValuesAre_, query.Extra, query.ModelType.Name, $"[{ AllowableExtra }]"), new[] { "extra" }));
                        }
                    }
                }
            }

            if (!(query.Lang == "fr" || query.Lang == "en"))
            {
                query.HasErrors = true;
                yield return(new ValidationResult(CSSPServicesRes.AllowableLanguagesAreFRAndEN, new[] { "Lang" }));
            }

            if (query.Skip < 0)
            {
                query.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ShouldBeAbove_, "Skip", "-1"), new[] { "Skip" }));
            }

            if (query.Skip > 1000000)
            {
                query.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ShouldBeBelow_, "Skip", "1000000"), new[] { "Skip" }));
            }

            if (query.Take < 1)
            {
                query.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ShouldBeAbove_, "Take", "0"), new[] { "Take" }));
            }

            if (query.Take > 1000000)
            {
                query.HasErrors = true;
                yield return(new ValidationResult(string.Format(CSSPServicesRes._ShouldBeBelow_, "Take", "1000000"), new[] { "Take" }));
            }

            query.AscList = new List <string>();
            if (!string.IsNullOrWhiteSpace(query.Asc))
            {
                query.AscList = query.Asc.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(c => c.Trim()).ToList();

                foreach (string PropertyName in query.AscList)
                {
                    if (!query.ModelType.GetProperties().Where(c => c.Name == PropertyName).Any())
                    {
                        query.HasErrors = true;
                        yield return(new ValidationResult(string.Format(CSSPServicesRes._DoesNotExistForModelType_, PropertyName, query.ModelType.Name), new[] { "Order" }));
                    }
                }
            }

            query.DescList = new List <string>();
            if (!string.IsNullOrWhiteSpace(query.Desc))
            {
                query.DescList = query.Desc.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(c => c.Trim()).ToList();

                foreach (string PropertyName in query.DescList)
                {
                    if (!query.ModelType.GetProperties().Where(c => c.Name == PropertyName).Any())
                    {
                        query.HasErrors = true;
                        yield return(new ValidationResult(string.Format(CSSPServicesRes._DoesNotExistForModelType_, PropertyName, query.ModelType.Name), new[] { "Order" }));
                    }
                }
            }

            query.WhereInfoList = new List <WhereInfo>();

            if (!string.IsNullOrWhiteSpace(query.Where))
            {
                List <string> WhereList = query.Where.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(c => c.Trim()).ToList();

                foreach (string w in WhereList)
                {
                    // Example of where == "TVItemID,GT,5|TVItemID,LT,20"
                    List <string> ValList = w.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(c => c.Trim()).ToList();
                    if (ValList.Count != 3)
                    {
                        query.HasErrors = true;
                        yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedToHaveValidStringFormatEx_, "Where", "TVItemID,GT,5|TVItemID,LT,20"), new[] { "Where" }));
                    }
                    else
                    {
                        WhereInfo whereInfo = new WhereInfo();

                        PropertyInfo propertyInfo = query.ModelType.GetProperties().Where(c => c.Name == ValList[0]).FirstOrDefault();
                        if (propertyInfo == null)
                        {
                            query.HasErrors = true;
                            yield return(new ValidationResult(string.Format(CSSPServicesRes._DoesNotExistForModelType_, ValList[0], query.ModelType.Name), new[] { "Where" }));
                        }
                        else
                        {
                            whereInfo.PropertyName = ValList[0];
                            whereInfo.Value        = ValList[2];

                            string PropTypeName = propertyInfo.PropertyType.FullName;
                            if (PropTypeName.Contains("Nullable"))
                            {
                                PropTypeName = PropTypeName.Substring(PropTypeName.IndexOf("[[") + 2);
                                PropTypeName = PropTypeName.Substring(0, PropTypeName.IndexOf(","));
                            }

                            switch (PropTypeName)
                            {
                            case "System.Boolean":
                            {
                                whereInfo.PropertyType = PropertyTypeEnum.Boolean;
                                bool TempBool;
                                if (bool.TryParse(whereInfo.Value, out TempBool))
                                {
                                    whereInfo.ValueBool = TempBool;
                                }
                                else
                                {
                                    query.HasErrors = true;
                                    yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeTrueOrFalseFor_OfModel_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name), new[] { "Where" }));
                                }
                            }
                            break;

                            case "System.DateTime":
                            {
                                whereInfo.PropertyType = PropertyTypeEnum.DateTime;
                                DateTime TempDateTime;
                                if (DateTime.TryParse(whereInfo.Value, out TempDateTime))
                                {
                                    whereInfo.ValueDateTime = TempDateTime;
                                }
                                else
                                {
                                    query.HasErrors = true;
                                    yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeADateFor_OfModel_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name), new[] { "Where" }));
                                }
                            }
                            break;

                            case "System.Double":
                            {
                                whereInfo.PropertyType = PropertyTypeEnum.Double;
                                double TempDouble;
                                if (Double.TryParse(whereInfo.Value, out TempDouble))
                                {
                                    whereInfo.ValueDouble = TempDouble;
                                }
                                else
                                {
                                    query.HasErrors = true;
                                    yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeANumberFor_OfModel_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name), new[] { "Where" }));
                                }
                            }
                            break;

                            case "System.Int16":
                            case "System.Int32":
                            case "System.Int64":
                            {
                                whereInfo.PropertyType = PropertyTypeEnum.Int;
                                int TempInt;
                                if (int.TryParse(whereInfo.Value, out TempInt))
                                {
                                    whereInfo.ValueInt = TempInt;
                                }
                                else
                                {
                                    query.HasErrors = true;
                                    yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeANumberFor_OfModel_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name), new[] { "Where" }));
                                }
                            }
                            break;

                            case "System.String":
                            {
                                whereInfo.PropertyType = PropertyTypeEnum.String;
                                // no need to do anything here as the string value has already been saved under the whereInfo.Value
                            }
                            break;

                            default:
                            {
                                if (propertyInfo.PropertyType.FullName.Contains("CSSPEnums."))
                                {
                                    whereInfo.PropertyType = PropertyTypeEnum.Enum;
                                    if (ValList[1] == "EQ")
                                    {
                                        string EnumTypeName = propertyInfo.PropertyType.FullName.Substring(propertyInfo.PropertyType.FullName.IndexOf("CSSPEnums.") + "CSSPEnums.".Length);
                                        if (EnumTypeName.Contains(","))
                                        {
                                            EnumTypeName = EnumTypeName.Substring(0, EnumTypeName.IndexOf(","));
                                        }
                                        FileInfo fiDLL = new FileInfo($@"{ AppDomain.CurrentDomain.BaseDirectory }\CSSPEnums.dll");

                                        if (!fiDLL.Exists)
                                        {
                                            fiDLL = new FileInfo($@"{ AppDomain.CurrentDomain.BaseDirectory }\bin\CSSPEnums.dll");
                                            if (!fiDLL.Exists)
                                            {
                                                query.HasErrors = true;
                                                yield return(new ValidationResult(string.Format(CSSPServicesRes.CouldNotFindFile_, $@"{ AppDomain.CurrentDomain.BaseDirectory }\CSSPEnums.dll or { AppDomain.CurrentDomain.BaseDirectory }\bin\CSSPEnums.dll"), new[] { "Where" }));
                                            }
                                        }

                                        var         importAssembly = Assembly.LoadFile(fiDLL.FullName);
                                        List <Type> TypeList       = importAssembly.GetTypes().ToList();

                                        foreach (Type type in TypeList)
                                        {
                                            if (type.Name == EnumTypeName)
                                            {
                                                whereInfo.EnumType = type;
                                                if (Char.IsNumber(whereInfo.Value[0]))
                                                {
                                                    if (int.TryParse(whereInfo.Value, out int TempInt))
                                                    {
                                                        whereInfo.ValueInt = TempInt;
                                                    }
                                                    else
                                                    {
                                                        query.HasErrors = true;
                                                        yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeANumberFor_OfModel_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name), new[] { "Where" }));
                                                    }

                                                    if (!(from c in Enum.GetValues(type) as int[] where c == whereInfo.ValueInt select c).Any())
                                                    {
                                                        List <int>    EnumValueList     = (from c in Enum.GetValues(type) as int[] select c).ToList();
                                                        List <string> EnumValueTextList = (from c in Enum.GetNames(type) as string[] select c).ToList();
                                                        StringBuilder sb = new StringBuilder();
                                                        for (int i = 0, count = EnumValueList.Count; i < count; i++)
                                                        {
                                                            sb.Append($"{ EnumValueList[i] } = { EnumValueTextList[i] }, ");
                                                        }
                                                        query.HasErrors = true;
                                                        yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeAValidEnumNumberFor_OfModel_AllowableValuesAre_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name, $"[{ sb.ToString() }]"), new[] { "Where" }));
                                                    }
                                                    else
                                                    {
                                                        int[]    AllEnumIntList  = Enum.GetValues(type) as int[];
                                                        string[] AllEnumTextList = Enum.GetNames(type) as string[];

                                                        for (int i = 0, count = AllEnumIntList.Count(); i < count; i++)
                                                        {
                                                            if (AllEnumIntList[i] == whereInfo.ValueInt)
                                                            {
                                                                whereInfo.ValueInt      = AllEnumIntList[i];
                                                                whereInfo.ValueEnumText = AllEnumTextList[i];
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    if (!(from c in Enum.GetNames(type) where c == whereInfo.Value select c).Any())
                                                    {
                                                        List <int>    EnumValueList     = (from c in Enum.GetValues(type) as int[] select c).ToList();
                                                        List <string> EnumValueTextList = (from c in Enum.GetNames(type) as string[] select c).ToList();
                                                        StringBuilder sb = new StringBuilder();
                                                        for (int i = 0, count = EnumValueList.Count; i < count; i++)
                                                        {
                                                            sb.Append($"{ EnumValueList[i] } = { EnumValueTextList[i] }, ");
                                                        }
                                                        query.HasErrors = true;
                                                        yield return(new ValidationResult(string.Format(CSSPServicesRes._NeedsToBeAValidEnumTextFor_OfModel_AllowableValuesAre_, whereInfo.Value, whereInfo.PropertyName, query.ModelType.Name, $"[{ sb.ToString() }]"), new[] { "Where" }));
                                                    }
                                                    else
                                                    {
                                                        int[]    AllEnumIntList  = Enum.GetValues(type) as int[];
                                                        string[] AllEnumTextList = Enum.GetNames(type) as string[];

                                                        for (int i = 0, count = AllEnumIntList.Count(); i < count; i++)
                                                        {
                                                            if (AllEnumTextList[i] == whereInfo.Value)
                                                            {
                                                                whereInfo.ValueInt      = AllEnumIntList[i];
                                                                whereInfo.ValueEnumText = AllEnumTextList[i];
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        query.HasErrors = true;
                                        yield return(new ValidationResult(string.Format(CSSPServicesRes.WhereOperator_For_OfModel_IsNotValidOnlyEQIsAllowed, ValList[1], whereInfo.PropertyName, query.ModelType.Name), new[] { "Where" }));
                                    }
                                }
                                else
                                {
                                    query.HasErrors = true;
                                    yield return(new ValidationResult(string.Format(CSSPServicesRes._NotImplementedYet, PropTypeName), new[] { "Where" }));
                                }
                            }
                            break;
                            }

                            switch (ValList[1])
                            {
                            case "EQ":
                            {
                                whereInfo.WhereOperator = WhereOperatorEnum.Equal;
                            }
                            break;

                            case "LT":
                            {
                                whereInfo.WhereOperator = WhereOperatorEnum.LessThan;
                            }
                            break;

                            case "GT":
                            {
                                whereInfo.WhereOperator = WhereOperatorEnum.GreaterThan;
                            }
                            break;

                            case "C":
                            {
                                whereInfo.WhereOperator = WhereOperatorEnum.Contains;
                            }
                            break;

                            case "SW":
                            {
                                whereInfo.WhereOperator = WhereOperatorEnum.StartsWith;
                            }
                            break;

                            case "EW":
                            {
                                whereInfo.WhereOperator = WhereOperatorEnum.EndsWith;
                            }
                            break;

                            default:
                            {
                                query.HasErrors = true;
                                yield return(new ValidationResult(string.Format(CSSPServicesRes.WhereOperator_NotValidAllowableValuesAre_, ValList[1], "[EQ = EQUAL, LT = LESS THAN, GT = GREATER THAN, C = CONTAINS, SW = STARTS WITH, EW = ENDS WITH]"), new[] { "Where" }));
                            }
                            break;
                            }

                            query.WhereInfoList.Add(whereInfo);
                        }
                    }
                }
            }
        }