Пример #1
0
        static void selectQueryHandler(ref QueryBuilder newQuery, string sqlStr)
        {
            string[] tokenList = new string[] { "select", "from", "inner join",  "where", "group by", "order by", "limit" };
            string tmp = "";
            for(int i=0;i<=tokenList.Length-1;i++) {
                tmp = tokenList[i];
                sqlStr = sqlStr.Replace(tmp, "[" + tmp + "]");
                tokenList[i]="["+tmp+"]";
            }
            System.Collections.ArrayList tokenised = new System.Collections.ArrayList();
            newQuery.setType(ABSTRACTQUERYTYPES.SelectQuery);
            newQuery.QueryLimit.lStart = -1;
            newQuery.QueryLimit.lLimit = -1;

            // build the token list
            tokenised = SQLConsole.Data.utils.tokenizeList(sqlStr, tokenList);

            foreach (tokenItem tokenitem in tokenised)
            {
                string tokenString = tokenitem.tokenValue;
                string comString = tokenitem.tokenName;

                string paramString = tokenString.Substring(tokenString.IndexOf(tokenitem.tokenName) + tokenitem.tokenName.Length + 1).Trim();

                if(paramString.Length > 10)
                if (paramString.Trim().ToLower().Substring(0, "distinct".Length) == "distinct")
                {
                    newQuery.distinct = true;
                    paramString = paramString.Trim().Substring("distinct ".Length);
                }

                //string comString = tokenString.Substring(0, tokenString.IndexOf(" ")).Trim();
                //string paramString = tokenString.Substring(tokenString.IndexOf(" ") + 1).Trim();
                string tableAlias = ""; string tablename = "";
                string[] fieldList;
                switch (comString)
                {
                    case "select":
                        string[] fieldnames = paramString.Split(',');
                        string realname = "";
                        string agg;
                        ABSTRACTAGGREGATE aggMode = ABSTRACTAGGREGATE.None;
                        foreach (string field in fieldnames)
                        {
                            realname = field.Trim();
                            if (field.IndexOf(")") > 0)
                            {
                                realname = field.Substring(field.IndexOf("(") + 1, field.IndexOf(")") - field.IndexOf("(") - 1);
                                realname = realname.Trim();
                                agg = field.Substring(0, field.IndexOf("(") - 1);
                                switch (agg)
                                {
                                    case "count":
                                        aggMode = ABSTRACTAGGREGATE.Count;
                                        break;
                                    case "max":
                                        aggMode = ABSTRACTAGGREGATE.Max;
                                        break;
                                    case "min":
                                        aggMode = ABSTRACTAGGREGATE.Min;
                                        break;
                                }
                            }
                            if (realname.IndexOf(".") > 0)
                                newQuery.addField(new AField(realname.Substring(realname.IndexOf(".") + 1), null, realname.Substring(0, realname.IndexOf("."))));
                            else
                            {
                                if (realname == "*")
                                {
                                    // deal with this seperately.
                                    newQuery.addField(new AField(realname, null));
                                }
                                else
                                {
                                    // Work out what source this field belongs to...
                                    string pureName = realname.Substring(realname.IndexOf(".") + 1);

                                    string[] sources = {};
                                    for (int i = 0; i < tokenised.Count; i++)
                                    {
                                        if (((tokenItem)tokenised[i]).tokenName == "from")
                                        {
                                            string sourcesList = ((tokenItem)tokenised[i]).tokenValue;
                                            sourcesList = sourcesList.Substring(sourcesList.IndexOf(((tokenItem)tokenised[i]).tokenName) + ((tokenItem)tokenised[i]).tokenName.Length + 1);
                                            sourcesList.Trim();
                                            string[] sources2 = sourcesList.Split(',');
                                            sources = (string[])utils.ConcatenateArrays(sources, sources2);
                                        }
                                        else if (((tokenItem)tokenised[i]).tokenName == "inner join") {
                                            string sourcesList = ((tokenItem)tokenised[i]).tokenValue;
                                            sourcesList = sourcesList.Substring(sourcesList.IndexOf(((tokenItem)tokenised[i]).tokenName) + ((tokenItem)tokenised[i]).tokenName.Length + 1);
                                            sourcesList = sourcesList.Substring(0, sourcesList.IndexOf(" on "));
                                            sourcesList.Trim();
                                            string[] sources2 = { sourcesList };
                                            sources = (string[])utils.ConcatenateArrays(sources, sources2);
                                        }
                                        else if (((tokenItem)tokenised[i]).tokenName == "outer join") {
                                            string sourcesList = ((tokenItem)tokenised[i]).tokenValue;
                                            sourcesList = sourcesList.Substring(sourcesList.IndexOf(((tokenItem)tokenised[i]).tokenName) + ((tokenItem)tokenised[i]).tokenName.Length + 1);
                                            sourcesList = sourcesList.Substring(0, sourcesList.IndexOf(" on "));
                                            sourcesList.Trim();
                                            string[] sources2 = { sourcesList };
                                            sources = (string[])utils.ConcatenateArrays(sources, sources2);
                                        }
                                        else if (((tokenItem)tokenised[i]).tokenName == "join") {
                                            string sourcesList = ((tokenItem)tokenised[i]).tokenValue;
                                            sourcesList = sourcesList.Substring(sourcesList.IndexOf(((tokenItem)tokenised[i]).tokenName) + ((tokenItem)tokenised[i]).tokenName.Length + 1);

                                            if(sourcesList.IndexOf(" on ") > 0)
                                                sourcesList = sourcesList.Substring(0, sourcesList.IndexOf(" on "));

                                            sourcesList.Trim();
                                            string[] sources2 = { sourcesList };
                                            sources = (string[])utils.ConcatenateArrays(sources, sources2);
                                        }
                                    }
                                    AField newField = null;
                                    foreach (string source in sources)
                                    {
                                        ATable src = null;

                                        if (source.IndexOf(" ") > 0)
                                            src = newQuery.getDatabaseObject().getTableObject(source.Substring(0, source.IndexOf(" ")));
                                        else
                                            src = newQuery.getDatabaseObject().getTableObject(source);
                                        if (src == null)
                                            throw (new Exception("Bad table name exception"));
                                        if (src.getFieldByName(pureName) != null)
                                        {
                                            if (newField != null) throw (new Exception("Ambiguous field name: " + realname + ". Field could belong to more than one source table."));

                                            newField = src.getFieldByName(pureName);
                                            if (source.IndexOf(" ") > 0)
                                            {
                                                newField.owner = source.Substring(source.IndexOf(" ")+1);
                                            }
                                        }

                                    }

                                    if (newField == null)
                                        throw (new Exception("Unable to determine source for field: " + realname));
                                    newQuery.addField(newField);

                                    //newQuery.addField(new AField(realname, null, (ATable)((QueryBuilder.SOURCEBINDING)newQuery.getSourceList()[0]).sourceObject));
                                    //newQuery.addField(new AField(realname,null,""));
                                }

                            }
                            if (realname.IndexOf(".") > 0)
                                newQuery.getField(realname.Substring(realname.IndexOf(".") + 1), realname.Substring(0, realname.IndexOf("."))).function = aggMode;
                            else
                                newQuery.getField(realname).function = aggMode;
                        }

                        break;
                    case "distinct":
                        newQuery.distinct = true;
                        break;
                    case "from":

                        if (paramString.IndexOf(' ') != -1) {
                            tableAlias = paramString.Substring(paramString.IndexOf(' ') + 1);
                            tablename = paramString.Substring(0, paramString.IndexOf(' '));
                        }
                        else
                            tablename = paramString.Trim();
                        newQuery.addSource(new ATable(tablename, tableAlias));
                        break;
                    case "inner join":
                        System.Collections.ArrayList joinList = new System.Collections.ArrayList();
                        paramString = "inner join " + paramString;
                        if (paramString.ToLower().IndexOf("inner join", "inner join".Length + 1) >= 2)
                        {
                        while (paramString.Length >= 0)
                        {
                            string tmp2 = paramString;
                            if (paramString.ToLower().IndexOf("inner join", "inner join".Length + 1) >= 2)
                                tmp2 = paramString.ToLower().Substring(0, paramString.ToLower().IndexOf("inner join", "inner join".Length + 2)).Trim();
                            else
                            {
                                joinList.Add(tmp2);
                                break;
                            }
                            joinList.Add(tmp2);
                            paramString = paramString.ToLower().Substring(paramString.ToLower().IndexOf("inner join", "inner join".Length + 2)).Trim();

                        }
                        }
                        else
                        {
                            joinList.Add(paramString);
                        }

                        foreach (string tmpstr in joinList)
                        {
                            paramString = tmpstr.Substring("inner join".Length+1);
                            // inner join anothertable on sjlieglij=sliejgil
                            string lTmp = paramString.Substring(0, paramString.IndexOf(" on "));
                            if (lTmp.IndexOf(' ') != -1)
                            {
                                tableAlias = lTmp.Substring(lTmp.IndexOf(' ')).Trim();
                                tablename = lTmp.Substring(0, lTmp.IndexOf(' ')).Trim();
                            }
                            else
                                tablename = lTmp.Trim();

                            lTmp = paramString.Substring(paramString.IndexOf(" on") + " on".Length + 1);
                            string srcTable = ""; string dstTable = "";
                            string srcField = ""; string dstField = "";

                            srcTable = lTmp.Substring(0, lTmp.IndexOf('='));
                            dstTable = lTmp.Substring(lTmp.IndexOf('=') + 1);
                            if (srcTable.IndexOf('.') > 0)
                            {
                                // Assume specifed table.
                                srcField = srcTable.Substring(srcTable.IndexOf(".") + 1);
                                srcTable = srcTable.Substring(0, srcTable.IndexOf("."));
                            }
                            if (dstTable.IndexOf('.') > 0)
                            {
                                // Assume specifed table.
                                dstField = dstTable.Substring(dstTable.IndexOf(".") + 1);
                                dstTable = dstTable.Substring(0, dstTable.IndexOf("."));
                            }

                            newQuery.addSource(new ATable(tablename, tableAlias), ABSTRACTSOURCEBINDTYPES.INNERJOIN, ((QueryBuilder.SOURCEBINDING)newQuery.getSourceList()[newQuery.getSourceList().Count - 1]).sourceObject, srcField, dstField);
                        }
                        //newQuery.addSource(new ATable(tablename, tableAlias), ABSTRACTSOURCEBINDTYPES.INNERJOIN, null, lTmp.Substring(0, lTmp.IndexOf('=')), lTmp.Substring(lTmp.IndexOf('=')+1));
                        break;

                    case "join":
                        joinList = new System.Collections.ArrayList();
                        paramString = "join " + paramString;
                        if (paramString.ToLower().IndexOf("join", "join".Length + 1) >= 2)
                        {
                            while (paramString.Length >= 0)
                            {
                                string tmp2 = paramString;
                                if (paramString.ToLower().IndexOf("join", "join".Length + 1) >= 2)
                                    tmp2 = paramString.ToLower().Substring(0, paramString.ToLower().IndexOf("join", "join".Length + 2)).Trim();
                                else
                                {
                                    joinList.Add(tmp2);
                                    break;
                                }
                                joinList.Add(tmp2);
                                paramString = paramString.ToLower().Substring(paramString.ToLower().IndexOf("join", "join".Length + 2)).Trim();

                            }
                        }
                        else
                        {
                            joinList.Add(paramString);
                        }

                        foreach (string tmpstr in joinList)
                        {
                            paramString = tmpstr.Substring("join".Length + 1);
                            // inner join anothertable on sjlieglij=sliejgil
                            string lTmp = paramString.Substring(0, paramString.IndexOf(" on "));
                            if (lTmp.IndexOf(' ') != -1)
                            {
                                tableAlias = lTmp.Substring(lTmp.IndexOf(' ')).Trim();
                                tablename = lTmp.Substring(0, lTmp.IndexOf(' ')).Trim();
                            }
                            else
                                tablename = lTmp.Trim();

                            lTmp = paramString.Substring(paramString.IndexOf(" on") + " on".Length + 1);
                            string srcTable = ""; string dstTable = "";
                            string srcField = ""; string dstField = "";

                            srcTable = lTmp.Substring(0, lTmp.IndexOf('='));
                            dstTable = lTmp.Substring(lTmp.IndexOf('=') + 1);
                            if (srcTable.IndexOf('.') > 0)
                            {
                                // Assume specifed table.
                                srcField = srcTable.Substring(srcTable.IndexOf(".") + 1);
                                srcTable = srcTable.Substring(0, srcTable.IndexOf("."));
                            }
                            if (dstTable.IndexOf('.') > 0)
                            {
                                // Assume specifed table.
                                dstField = dstTable.Substring(dstTable.IndexOf(".") + 1);
                                dstTable = dstTable.Substring(0, dstTable.IndexOf("."));
                            }

                            newQuery.addSource(new ATable(tablename, tableAlias), ABSTRACTSOURCEBINDTYPES.INNERJOIN, ((QueryBuilder.SOURCEBINDING)newQuery.getSourceList()[newQuery.getSourceList().Count - 1]).sourceObject, srcField, dstField);
                        }
                        //newQuery.addSource(new ATable(tablename, tableAlias), ABSTRACTSOURCEBINDTYPES.INNERJOIN, null, lTmp.Substring(0, lTmp.IndexOf('=')), lTmp.Substring(lTmp.IndexOf('=')+1));
                        break;

                    case "where":
                        // where b.id = sjilegj, b.Name = fjff
                        // where b.id = silegjlsg and
                        newQuery.conditionalString = paramString;
                        break;
                    case "group by":
                        fieldList = paramString.Split(',');
                        foreach(string ff in fieldList) {
                            newQuery.getField(ff).GroupBy = true;
                        }
                        break;
                    case "order by":
                        fieldList = paramString.Split(',');

                        foreach (string ff in fieldList)
                        {
                            /* patch...
                            bugfix: orderby where the field is not in the select field list
                            * ie: select * from [table] order by field
                            */
                            string fname = null;
                            string fOrderType = null;
                            if (ff.IndexOf(' ') > 0)
                            {
                                ff.Trim();
                                fname = ff.Substring(0, ff.IndexOf(' '));
                                fOrderType = ff.Substring(ff.IndexOf(' ') + 1);
                            }
                            else
                                fname = ff;

                            if (newQuery.getField(fname) == null)
                            {
                                if (fname.IndexOf(".") > 0)
                                {
                                    string tblName = ((ATable)newQuery.getSourceTableByAlias(fname.Substring(0, fname.IndexOf(".")))).name;
                                    AField fld = newQuery.getDatabaseObject().getTableObject(tblName).getFieldByName((fname.Substring(fname.IndexOf(".") + 1)));
                                    fld.owner = fname.Substring(0, fname.IndexOf("."));
                                    newQuery.addField(fld);
                                }
                                else
                                newQuery.addField(newQuery.getDatabaseObject().GetTableCache().getCachedTable(((ATable)((QueryBuilder.SOURCEBINDING)newQuery.getSourceList()[0]).sourceObject).name).getFieldByName(fname));
                            }
                            if(fOrderType != null) {
                                if (fOrderType.ToLower() == "asc")
                                    newQuery.getField(fname).OrderBy = ABSTRACTORDERTYPE.Ascending;
                                else
                                    newQuery.getField(fname).OrderBy = ABSTRACTORDERTYPE.Descending;
                            }
                            else { //default to order by asc
                                if (fname.IndexOf(".")>0)
                                {
                                    fname = fname.Substring(fname.IndexOf(".")+1);
                                }
                                if (fname == newQuery.getField(fname).name)
                                {
                                    newQuery.getField(fname).OrderBy = ABSTRACTORDERTYPE.Ascending;
                                }
                            }
                        }
                        break;
                    case "limit":
                        newQuery.QueryLimit.lStart = 0;
                        if (paramString.IndexOf(',') > 0)
                        {
                            // format limit 0,5
                            // format limit offset, count
                            newQuery.QueryLimit.lStart = Convert.ToInt32(paramString.Substring(0, paramString.IndexOf(',')));
                            newQuery.QueryLimit.lLimit = Convert.ToInt32(paramString.Substring(paramString.IndexOf(',') + 1));
                        }
                        else
                            newQuery.QueryLimit.lLimit = Convert.ToInt32(paramString);
                        break;
                }
            }
        }