/// <summary>
        /// Prepares CommandText for use with the Prepare method
        /// </summary>
        /// <returns>Command text stripped of all paramter names</returns>
        /// <remarks>
        /// Takes the output of TokenizeSql and creates a single string of SQL
        /// that only contains '?' markers for each parameter.  It also creates
        /// the parameterMap array list that includes all the paramter names in the
        /// order they appeared in the SQL
        /// </remarks>
        private List <string> PrepareCommandText(out string stripped_sql)
        {
            var newSQL       = new StringBuilder();
            var parameterMap = new List <string>();

            var startPos  = 0;
            var sql       = ResolvedCommandText;
            var tokenizer = new MySqlTokenizer(sql);
            var parameter = tokenizer.NextParameter();

            while (parameter != null)
            {
                if (parameter.IndexOf(StoredProcedure.ParameterPrefix) == -1)
                {
                    newSQL.Append(sql.Substring(startPos, tokenizer.StartIndex - startPos));
                    newSQL.Append("?");
                    parameterMap.Add(parameter);
                    startPos = tokenizer.StopIndex;
                }
                parameter = tokenizer.NextParameter();
            }
            newSQL.Append(sql.Substring(startPos));
            stripped_sql = newSQL.ToString();
            return(parameterMap);
        }
Example #2
0
        private static void ParseConstraint(MySqlSchemaCollection fkTable, MySqlSchemaRow table,
                                            MySqlTokenizer tokenizer, bool includeColumns)
        {
            string         name = tokenizer.NextToken();
            MySqlSchemaRow row  = fkTable.AddRow();

            // make sure this constraint is a FK
            string token = tokenizer.NextToken();

            if (token != "foreign" || tokenizer.Quoted)
            {
                return;
            }
            tokenizer.NextToken(); // read off the 'KEY' symbol
            tokenizer.NextToken(); // read off the '(' symbol

            row["CONSTRAINT_CATALOG"]       = table["TABLE_CATALOG"];
            row["CONSTRAINT_SCHEMA"]        = table["TABLE_SCHEMA"];
            row["TABLE_CATALOG"]            = table["TABLE_CATALOG"];
            row["TABLE_SCHEMA"]             = table["TABLE_SCHEMA"];
            row["TABLE_NAME"]               = table["TABLE_NAME"];
            row["REFERENCED_TABLE_CATALOG"] = null;
            row["CONSTRAINT_NAME"]          = name.Trim(new char[] { '\'', '`' });

            List <string> srcColumns = includeColumns ? ParseColumns(tokenizer) : null;

            // now look for the references section
            while (token != "references" || tokenizer.Quoted)
            {
                token = tokenizer.NextToken();
            }
            string target1 = tokenizer.NextToken();
            string target2 = tokenizer.NextToken();

            if (target2.StartsWith(".", StringComparison.Ordinal))
            {
                row["REFERENCED_TABLE_SCHEMA"] = target1;
                row["REFERENCED_TABLE_NAME"]   = target2.Substring(1).Trim(new char[] { '\'', '`' });
                tokenizer.NextToken(); // read off the '('
            }
            else
            {
                row["REFERENCED_TABLE_SCHEMA"] = table["TABLE_SCHEMA"];
                row["REFERENCED_TABLE_NAME"]   = target1.Substring(1).Trim(new char[] { '\'', '`' });;
            }

            // if we are supposed to include columns, read the target columns
            List <string> targetColumns = includeColumns ? ParseColumns(tokenizer) : null;

            if (includeColumns)
            {
                ProcessColumns(fkTable, row, srcColumns, targetColumns);
            }
            else
            {
                fkTable.Rows.Add(row);
            }
        }
Example #3
0
 internal string GetCommandTextForBatching()
 {
     if (this.batchableCommandText == null)
     {
         if (string.Compare(this.CommandText.Substring(0, 6), "INSERT", StringComparison.OrdinalIgnoreCase) == 0)
         {
             MySqlCommand   mySqlCommand   = new MySqlCommand("SELECT @@sql_mode", this.Connection);
             string         text           = StringUtility.ToUpperInvariant(mySqlCommand.ExecuteScalar().ToString());
             MySqlTokenizer mySqlTokenizer = new MySqlTokenizer(this.CommandText);
             mySqlTokenizer.AnsiQuotes       = (text.IndexOf("ANSI_QUOTES") != -1);
             mySqlTokenizer.BackslashEscapes = (text.IndexOf("NO_BACKSLASH_ESCAPES") == -1);
             for (string text2 = StringUtility.ToLowerInvariant(mySqlTokenizer.NextToken()); text2 != null; text2 = mySqlTokenizer.NextToken())
             {
                 if (StringUtility.ToUpperInvariant(text2) == "VALUES" && !mySqlTokenizer.Quoted)
                 {
                     text2 = mySqlTokenizer.NextToken();
                     int num = 1;
                     while (text2 != null)
                     {
                         this.batchableCommandText += text2;
                         text2 = mySqlTokenizer.NextToken();
                         if (text2 == "(")
                         {
                             num++;
                         }
                         else
                         {
                             if (text2 == ")")
                             {
                                 num--;
                             }
                         }
                         if (num == 0)
                         {
                             break;
                         }
                     }
                     if (text2 != null)
                     {
                         this.batchableCommandText += text2;
                     }
                     text2 = mySqlTokenizer.NextToken();
                     if (text2 != null && (text2 == "," || StringUtility.ToUpperInvariant(text2) == "ON"))
                     {
                         this.batchableCommandText = null;
                         break;
                     }
                 }
             }
         }
         else
         {
             this.batchableCommandText = this.CommandText;
         }
     }
     return(this.batchableCommandText);
 }
Example #4
0
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters, MySqlPacket packet)
        {
            bool sqlServerMode = command.Connection.Settings.SqlServerMode;

            if (packet == null)
            {
                packet = new MySqlPacket(Driver.Encoding)
                {
                    Version = Driver.Version
                };
                packet.WriteByte(0);
            }

            MySqlTokenizer tokenizer = new MySqlTokenizer(sql)
            {
                ReturnComments = true,
                SqlServerMode  = sqlServerMode
            };

            int    pos            = 0;
            string token          = tokenizer.NextToken();
            int    parameterCount = 0;

            while (token != null)
            {
                // serialize everything that came before the token (i.e. whitespace)
                packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos));
                pos = tokenizer.StopIndex;

                if (MySqlTokenizer.IsParameter(token))
                {
                    if ((!parameters.containsUnnamedParameters && token.Length == 1 && parameterCount > 0) || parameters.containsUnnamedParameters && token.Length > 1)
                    {
                        throw new MySqlException(Resources.MixedParameterNamingNotAllowed);
                    }

                    parameters.containsUnnamedParameters = token.Length == 1;
                    if (SerializeParameter(parameters, packet, token, parameterCount))
                    {
                        token = null;
                    }
                    parameterCount++;
                }

                if (token != null)
                {
                    if (sqlServerMode && tokenizer.Quoted && token.StartsWith("[", StringComparison.Ordinal))
                    {
                        token = String.Format("`{0}`", token.Substring(1, token.Length - 2));
                    }
                    packet.WriteStringNoNull(token);
                }
                token = tokenizer.NextToken();
            }
            _buffers.Add(packet);
        }
Example #5
0
        private static List <string> GetPossibleValues(MySqlSchemaRow row)
        {
            string[] array = new string[]
            {
                "ENUM",
                "SET"
            };
            string text = row["DTD_IDENTIFIER"].ToString().Trim();
            int    num  = 0;

            while (num < 2 && !text.StartsWith(array[num], StringComparison.OrdinalIgnoreCase))
            {
                num++;
            }
            if (num == 2)
            {
                return(null);
            }
            text = text.Substring(array[num].Length).Trim();
            text = text.Trim(new char[]
            {
                '(',
                ')'
            }).Trim();
            List <string>  list           = new List <string>();
            MySqlTokenizer mySqlTokenizer = new MySqlTokenizer(text);
            string         text2          = mySqlTokenizer.NextToken();
            int            num2           = mySqlTokenizer.StartIndex;

            while (true)
            {
                if (text2 == null || text2 == ",")
                {
                    int num3 = text.Length - 1;
                    if (text2 == ",")
                    {
                        num3 = mySqlTokenizer.StartIndex;
                    }
                    string item = text.Substring(num2, num3 - num2).Trim(new char[]
                    {
                        '\'',
                        '"'
                    }).Trim();
                    list.Add(item);
                    num2 = mySqlTokenizer.StopIndex;
                }
                if (text2 == null)
                {
                    break;
                }
                text2 = mySqlTokenizer.NextToken();
            }
            return(list);
        }
Example #6
0
        private void AdjustDelimiterEnd(MySqlTokenizer tokenizer)
        {
            int  pos = tokenizer.StopIndex;
            char c   = query[pos];

            while (!Char.IsWhiteSpace(c) && pos < (query.Length - 1))
            {
                c = query[++pos];
            }
            tokenizer.StopIndex = pos;
            tokenizer.Position  = pos;
        }
Example #7
0
        private static List <string> ParseColumns(MySqlTokenizer tokenizer)
        {
            List <string> list = new List <string>();

            for (string str = tokenizer.NextToken(); str != ")"; str = tokenizer.NextToken())
            {
                if (str != ",")
                {
                    list.Add(str);
                }
            }
            return(list);
        }
Example #8
0
 private void AdjustDelimiterEnd(MySqlTokenizer tokenizer)
 {
     if (tokenizer.StopIndex < this.query.Length)
     {
         int  num = tokenizer.StopIndex;
         char c   = this.query[num];
         while (!char.IsWhiteSpace(c) && num < this.query.Length - 1)
         {
             c = this.query[++num];
         }
         tokenizer.StopIndex = num;
         tokenizer.Position  = num;
     }
 }
        private string GetProcedureParameterLine(DataRow isRow)
        {
            string sql = "SHOW CREATE {0} `{1}`.`{2}`";

            sql = String.Format(sql, isRow["ROUTINE_TYPE"], isRow["ROUTINE_SCHEMA"],
                                isRow["ROUTINE_NAME"]);
            MySqlCommand cmd = new MySqlCommand(sql, connection);

            using (MySqlDataReader reader = cmd.ExecuteReader())
            {
                reader.Read();

                // if we are not the owner of this proc or have permissions
                // then we will get null for the body
                if (reader.IsDBNull(2))
                {
                    return(null);
                }

                string sql_mode = reader.GetString(1);

                string         body      = reader.GetString(2);
                MySqlTokenizer tokenizer = new MySqlTokenizer(body);
                tokenizer.AnsiQuotes       = sql_mode.IndexOf("ANSI_QUOTES") != -1;
                tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;

                string token = tokenizer.NextToken();
                while (token != "(")
                {
                    token = tokenizer.NextToken();
                }
                int start = tokenizer.StartIndex + 1;
                token = tokenizer.NextToken();
                while (token != ")" || tokenizer.Quoted)
                {
                    token = tokenizer.NextToken();
                    // if we see another ( and we are not quoted then we
                    // are in a size element and we need to look for the closing paren
                    if (token == "(" && !tokenizer.Quoted)
                    {
                        while (token != ")" || tokenizer.Quoted)
                        {
                            token = tokenizer.NextToken();
                        }
                        token = tokenizer.NextToken();
                    }
                }
                return(body.Substring(start, tokenizer.StartIndex - start));
            }
        }
        private static ArrayList ParseColumns(MySqlTokenizer tokenizer)
        {
            ArrayList sc    = new ArrayList();
            string    token = tokenizer.NextToken();

            while (token != ")")
            {
                if (token != ",")
                {
                    sc.Add(token);
                }
                token = tokenizer.NextToken();
            }
            return(sc);
        }
Example #11
0
        private static List <string> ParseColumns(MySqlTokenizer tokenizer)
        {
            List <string> sc    = new List <string>();
            string        token = tokenizer.NextToken();

            while (token != ")")
            {
                if (token != ",")
                {
                    sc.Add(token);
                }
                token = tokenizer.NextToken();
            }
            return(sc);
        }
        private static List <string> GetPossibleValues(DataRow row)
        {
            string[] types         = new string[] { "ENUM", "SET" };
            string   dtdIdentifier = row["DTD_IDENTIFIER"].ToString().Trim();

            int index = 0;

            for (; index < 2; index++)
            {
                if (dtdIdentifier.StartsWith(types[index], StringComparison.InvariantCultureIgnoreCase))
                {
                    break;
                }
            }
            if (index == 2)
            {
                return(null);
            }
            dtdIdentifier = dtdIdentifier.Substring(types[index].Length).Trim();
            dtdIdentifier = dtdIdentifier.Trim('(', ')').Trim();

            List <string>  values    = new List <string>();
            MySqlTokenizer tokenzier = new MySqlTokenizer(dtdIdentifier);
            string         token     = tokenzier.NextToken();
            int            start     = tokenzier.StartIndex;

            while (true)
            {
                if (token == null || token == ",")
                {
                    int end = dtdIdentifier.Length - 1;
                    if (token == ",")
                    {
                        end = tokenzier.StartIndex;
                    }

                    string value = dtdIdentifier.Substring(start, end - start).Trim('\'', '\"').Trim();
                    values.Add(value);
                    start = tokenzier.StopIndex;
                }
                if (token == null)
                {
                    break;
                }
                token = tokenzier.NextToken();
            }
            return(values);
        }
Example #13
0
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters, MySqlPacket packet)
        {
            bool sqlServerMode = this.command.Connection.Settings.SqlServerMode;

            if (packet == null)
            {
                packet         = new MySqlPacket(this.Driver.Encoding);
                packet.Version = this.Driver.Version;
                packet.WriteByte(0);
            }
            MySqlTokenizer mySqlTokenizer = new MySqlTokenizer(sql);

            mySqlTokenizer.ReturnComments = true;
            mySqlTokenizer.SqlServerMode  = sqlServerMode;
            int    num  = 0;
            string text = mySqlTokenizer.NextToken();
            int    num2 = 0;

            while (text != null)
            {
                packet.WriteStringNoNull(sql.Substring(num, mySqlTokenizer.StartIndex - num));
                num = mySqlTokenizer.StopIndex;
                if (MySqlTokenizer.IsParameter(text))
                {
                    if ((!parameters.containsUnnamedParameters && text.Length == 1 && num2 > 0) || (parameters.containsUnnamedParameters && text.Length > 1))
                    {
                        throw new MySqlException(Resources.MixedParameterNamingNotAllowed);
                    }
                    parameters.containsUnnamedParameters = (text.Length == 1);
                    if (this.SerializeParameter(parameters, packet, text, num2))
                    {
                        text = null;
                    }
                    num2++;
                }
                if (text != null)
                {
                    if (sqlServerMode && mySqlTokenizer.Quoted && text.StartsWith("[", StringComparison.Ordinal))
                    {
                        text = string.Format("`{0}`", text.Substring(1, text.Length - 2));
                    }
                    packet.WriteStringNoNull(text);
                }
                text = mySqlTokenizer.NextToken();
            }
            this.buffers.Add(packet);
        }
Example #14
0
        private string GetProcedureParameterLine(MySqlSchemaRow isRow)
        {
            string text = "SHOW CREATE {0} `{1}`.`{2}`";

            text = string.Format(text, isRow["ROUTINE_TYPE"], isRow["ROUTINE_SCHEMA"], isRow["ROUTINE_NAME"]);
            MySqlCommand mySqlCommand = new MySqlCommand(text, this.connection);
            string       result;

            using (MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader())
            {
                mySqlDataReader.Read();
                if (mySqlDataReader.IsDBNull(2))
                {
                    result = null;
                }
                else
                {
                    string         @string        = mySqlDataReader.GetString(1);
                    string         string2        = mySqlDataReader.GetString(2);
                    MySqlTokenizer mySqlTokenizer = new MySqlTokenizer(string2);
                    mySqlTokenizer.AnsiQuotes       = (@string.IndexOf("ANSI_QUOTES") != -1);
                    mySqlTokenizer.BackslashEscapes = (@string.IndexOf("NO_BACKSLASH_ESCAPES") == -1);
                    string a = mySqlTokenizer.NextToken();
                    while (a != "(")
                    {
                        a = mySqlTokenizer.NextToken();
                    }
                    int num = mySqlTokenizer.StartIndex + 1;
                    a = mySqlTokenizer.NextToken();
                    while (a != ")" || mySqlTokenizer.Quoted)
                    {
                        a = mySqlTokenizer.NextToken();
                        if (a == "(" && !mySqlTokenizer.Quoted)
                        {
                            while (a != ")" || mySqlTokenizer.Quoted)
                            {
                                a = mySqlTokenizer.NextToken();
                            }
                            a = mySqlTokenizer.NextToken();
                        }
                    }
                    result = string2.Substring(num, mySqlTokenizer.StartIndex - num);
                }
            }
            return(result);
        }
        /// <summary>
        /// Prepares CommandText for use with the Prepare method
        /// </summary>
        /// <returns>Command text stripped of all paramter names</returns>
        /// <remarks>
        /// Takes the output of TokenizeSql and creates a single string of SQL
        /// that only contains '?' markers for each parameter.  It also creates
        /// the parameterMap array list that includes all the paramter names in the
        /// order they appeared in the SQL
        /// </remarks>
        private List <string> PrepareCommandText(out string stripped_sql)
        {
            StringBuilder newSQL       = new StringBuilder();
            List <string> parameterMap = new List <string>();

            int            startPos  = 0;
            string         sql       = ResolvedCommandText;
            MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
            string         parameter = tokenizer.NextParameter();

            while (parameter != null)
            {
                parameter = tokenizer.NextParameter();
            }
            newSQL.Append(sql.Substring(startPos));
            stripped_sql = newSQL.ToString();
            return(parameterMap);
        }
Example #16
0
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters,
                                            MySqlPacket packet)
        {
            bool sqlServerMode = command.Connection.Settings.SqlServerMode;

            if (packet == null)
            {
                packet         = new MySqlPacket(Driver.Encoding);
                packet.Version = Driver.Version;
                packet.WriteByte(0);
            }

            MySqlTokenizer tokenizer = new MySqlTokenizer(sql);

            tokenizer.ReturnComments = true;
            tokenizer.SqlServerMode  = sqlServerMode;

            int    pos   = 0;
            string token = tokenizer.NextToken();

            while (token != null)
            {
                // serialize everything that came before the token (i.e. whitespace)
                packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos));
                pos = tokenizer.StopIndex;
                if (MySqlTokenizer.IsParameter(token))
                {
                    if (SerializeParameter(parameters, packet, token))
                    {
                        token = null;
                    }
                }
                if (token != null)
                {
                    if (sqlServerMode && tokenizer.Quoted && token.StartsWith("["))
                    {
                        token = String.Format("`{0}`", token.Substring(1, token.Length - 2));
                    }
                    packet.WriteStringNoNull(token);
                }
                token = tokenizer.NextToken();
            }
            buffers.Add(packet);
        }
Example #17
0
        /// <summary>
        /// GetForeignKeysOnTable retrieves the foreign keys on the given table.
        /// Since MySQL supports foreign keys on versions prior to 5.0, we can't  use
        /// information schema.  MySQL also does not include any type of SHOW command
        /// for foreign keys so we have to resort to use SHOW CREATE TABLE and parsing
        /// the output.
        /// </summary>
        /// <param name="fkTable">The table to store the key info in.</param>
        /// <param name="tableToParse">The table to get the foeign key info for.</param>
        /// <param name="filterName">Only get foreign keys that match this name.</param>
        /// <param name="includeColumns">Should column information be included in the table.</param>
        private void GetForeignKeysOnTable(MySqlSchemaCollection fkTable, MySqlSchemaRow tableToParse,
                                           string filterName, bool includeColumns)
        {
            string sqlMode = GetSqlMode();

            if (filterName != null)
            {
                filterName = StringUtility.ToLowerInvariant(filterName);
            }

            string sql = string.Format("SHOW CREATE TABLE `{0}`.`{1}`",
                                       tableToParse["TABLE_SCHEMA"], tableToParse["TABLE_NAME"]);
            string       lowerBody = null, body = null;
            MySqlCommand cmd = new MySqlCommand(sql, connection);

            using (MySqlDataReader reader = cmd.ExecuteReader())
            {
                reader.Read();
                body      = reader.GetString(1);
                lowerBody = StringUtility.ToLowerInvariant(body);
            }

            MySqlTokenizer tokenizer = new MySqlTokenizer(lowerBody);

            tokenizer.AnsiQuotes       = sqlMode.IndexOf("ANSI_QUOTES") != -1;
            tokenizer.BackslashEscapes = sqlMode.IndexOf("NO_BACKSLASH_ESCAPES") != -1;

            while (true)
            {
                string token = tokenizer.NextToken();
                // look for a starting contraint
                while (token != null && (token != "constraint" || tokenizer.Quoted))
                {
                    token = tokenizer.NextToken();
                }
                if (token == null)
                {
                    break;
                }

                ParseConstraint(fkTable, tableToParse, tokenizer, includeColumns);
            }
        }
Example #18
0
        private List <string> PrepareCommandText(out string stripped_sql)
        {
            StringBuilder  stringBuilder       = new StringBuilder();
            List <string>  list                = new List <string>();
            int            num                 = 0;
            string         resolvedCommandText = this.ResolvedCommandText;
            MySqlTokenizer mySqlTokenizer      = new MySqlTokenizer(resolvedCommandText);

            for (string text = mySqlTokenizer.NextParameter(); text != null; text = mySqlTokenizer.NextParameter())
            {
                if (text.IndexOf("_cnet_param_") == -1)
                {
                    stringBuilder.Append(resolvedCommandText.Substring(num, mySqlTokenizer.StartIndex - num));
                    stringBuilder.Append("?");
                    list.Add(text);
                    num = mySqlTokenizer.StopIndex;
                }
            }
            stringBuilder.Append(resolvedCommandText.Substring(num));
            stripped_sql = stringBuilder.ToString();
            return(list);
        }
Example #19
0
        private void GetForeignKeysOnTable(MySqlSchemaCollection fkTable, MySqlSchemaRow tableToParse, string filterName, bool includeColumns)
        {
            string sqlMode = this.GetSqlMode();

            if (filterName != null)
            {
                filterName = StringUtility.ToLowerInvariant(filterName);
            }
            string       cmdText = string.Format("SHOW CREATE TABLE `{0}`.`{1}`", tableToParse["TABLE_SCHEMA"], tableToParse["TABLE_NAME"]);
            string       input   = null;
            MySqlCommand command = new MySqlCommand(cmdText, this.connection);

            using (MySqlDataReader reader = command.ExecuteReader())
            {
                reader.Read();
                input = StringUtility.ToLowerInvariant(reader.GetString(1));
            }
            MySqlTokenizer tokenizer = new MySqlTokenizer(input)
            {
                AnsiQuotes       = sqlMode.IndexOf("ANSI_QUOTES") != -1,
                BackslashEscapes = sqlMode.IndexOf("NO_BACKSLASH_ESCAPES") != -1
            };

            while (true)
            {
                string str5 = tokenizer.NextToken();
                while ((str5 != null) && ((str5 != "constraint") || tokenizer.Quoted))
                {
                    str5 = tokenizer.NextToken();
                }
                if (str5 == null)
                {
                    return;
                }
                ParseConstraint(fkTable, tableToParse, tokenizer, includeColumns);
            }
        }
Example #20
0
        private string ParseDataType(MySqlSchemaRow row, MySqlTokenizer tokenizer)
        {
            StringBuilder stringBuilder = new StringBuilder(StringUtility.ToUpperInvariant(tokenizer.NextToken()));

            row["DATA_TYPE"] = stringBuilder.ToString();
            string text  = row["DATA_TYPE"].ToString();
            string text2 = tokenizer.NextToken();

            if (text2 == "(")
            {
                text2 = tokenizer.ReadParenthesis();
                stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", new object[]
                {
                    text2
                });
                if (text != "ENUM" && text != "SET")
                {
                    ISSchemaProvider.ParseDataTypeSize(row, text2);
                }
                text2 = tokenizer.NextToken();
            }
            else
            {
                stringBuilder.Append(ISSchemaProvider.GetDataTypeDefaults(text, row));
            }
            while (text2 != ")" && text2 != "," && string.Compare(text2, "begin", StringComparison.OrdinalIgnoreCase) != 0 && string.Compare(text2, "return", StringComparison.OrdinalIgnoreCase) != 0)
            {
                if (string.Compare(text2, "CHARACTER", StringComparison.OrdinalIgnoreCase) != 0 && string.Compare(text2, "BINARY", StringComparison.OrdinalIgnoreCase) != 0)
                {
                    if (string.Compare(text2, "SET", StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(text2, "CHARSET", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        row["CHARACTER_SET_NAME"] = tokenizer.NextToken();
                    }
                    else if (string.Compare(text2, "ASCII", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        row["CHARACTER_SET_NAME"] = "latin1";
                    }
                    else if (string.Compare(text2, "UNICODE", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        row["CHARACTER_SET_NAME"] = "ucs2";
                    }
                    else if (string.Compare(text2, "COLLATE", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        row["COLLATION_NAME"] = tokenizer.NextToken();
                    }
                    else
                    {
                        stringBuilder.AppendFormat(CultureInfo.InvariantCulture, " {0}", new object[]
                        {
                            text2
                        });
                    }
                }
                text2 = tokenizer.NextToken();
            }
            if (stringBuilder.Length > 0)
            {
                row["DTD_IDENTIFIER"] = stringBuilder.ToString();
            }
            if (string.IsNullOrEmpty((string)row["COLLATION_NAME"]) && !string.IsNullOrEmpty((string)row["CHARACTER_SET_NAME"]))
            {
                row["COLLATION_NAME"] = CharSetMap.GetDefaultCollation(row["CHARACTER_SET_NAME"].ToString(), this.connection);
            }
            if (row["CHARACTER_MAXIMUM_LENGTH"] != null)
            {
                if (row["CHARACTER_SET_NAME"] == null)
                {
                    row["CHARACTER_SET_NAME"] = "";
                }
                row["CHARACTER_OCTET_LENGTH"] = CharSetMap.GetMaxLength((string)row["CHARACTER_SET_NAME"], this.connection) * (int)row["CHARACTER_MAXIMUM_LENGTH"];
            }
            return(text2);
        }
Example #21
0
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters, 
            MySqlPacket packet)
        {
            bool sqlServerMode = command.Connection.Settings.SqlServerMode;

            if (packet == null)
            {
                packet = new MySqlPacket(Driver.Encoding);
                packet.Version = Driver.Version;
                packet.WriteByte(0);
            }

            MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
            tokenizer.ReturnComments = true;
            tokenizer.SqlServerMode = sqlServerMode;

            int pos = 0;
            string token = tokenizer.NextToken();
            while (token != null)
            {
                // serialize everything that came before the token (i.e. whitespace)
                packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos));
                pos = tokenizer.StopIndex;
                if (MySqlTokenizer.IsParameter(token))
                {
                    if (SerializeParameter(parameters, packet, token))
                        token = null;
                }
                if (token != null)
                {
                    if (sqlServerMode && tokenizer.Quoted && token.StartsWith("["))
                        token = String.Format("`{0}`", token.Substring(1, token.Length - 2));
                    packet.WriteStringNoNull(token);
                }
                token = tokenizer.NextToken();
            }
            buffers.Add(packet);
        }
Example #22
0
    private string GetTargetedTable(string sql)
    {
      MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
      tokenizer.ReturnComments = false;
      tokenizer.AnsiQuotes = sql_mode.ToLowerInvariant().Contains("ansi_quotes");
      tokenizer.BackslashEscapes = !sql_mode.ToLowerInvariant().Contains("no_backslash_escapes");

      string token = null;
      while (token != "ON" || tokenizer.Quoted)
        token = tokenizer.NextToken();

      string tableName = tokenizer.NextToken();
      if (tokenizer.NextToken() == ".")
        tableName = tokenizer.NextToken();
      if (tableName.StartsWith("`", StringComparison.Ordinal))
        return tableName.Trim('`');
      if (tableName.StartsWith("\"", StringComparison.Ordinal) && tokenizer.AnsiQuotes)
        return tableName.Trim('"');
      return tableName;
    }
Example #23
0
        private List <ScriptStatement> BreakIntoStatements(bool ansiQuotes, bool noBackslashEscapes)
        {
            string text = this.Delimiter;
            int    num  = 0;
            List <ScriptStatement> list           = new List <ScriptStatement>();
            List <int>             list2          = this.BreakScriptIntoLines();
            MySqlTokenizer         mySqlTokenizer = new MySqlTokenizer(this.query);

            mySqlTokenizer.AnsiQuotes       = ansiQuotes;
            mySqlTokenizer.BackslashEscapes = !noBackslashEscapes;
            for (string text2 = mySqlTokenizer.NextToken(); text2 != null; text2 = mySqlTokenizer.NextToken())
            {
                if (!mySqlTokenizer.Quoted)
                {
                    if (text2.ToLower(CultureInfo.InvariantCulture) == "delimiter")
                    {
                        mySqlTokenizer.NextToken();
                        this.AdjustDelimiterEnd(mySqlTokenizer);
                        text = this.query.Substring(mySqlTokenizer.StartIndex, mySqlTokenizer.StopIndex - mySqlTokenizer.StartIndex).Trim();
                        num  = mySqlTokenizer.StopIndex;
                    }
                    else
                    {
                        if (text.StartsWith(text2, StringComparison.OrdinalIgnoreCase) && mySqlTokenizer.StartIndex + text.Length <= this.query.Length && this.query.Substring(mySqlTokenizer.StartIndex, text.Length) == text)
                        {
                            text2 = text;
                            mySqlTokenizer.Position  = mySqlTokenizer.StartIndex + text.Length;
                            mySqlTokenizer.StopIndex = mySqlTokenizer.Position;
                        }
                        int num2 = text2.IndexOf(text, StringComparison.OrdinalIgnoreCase);
                        if (num2 != -1)
                        {
                            int num3 = mySqlTokenizer.StopIndex - text2.Length + num2;
                            if (mySqlTokenizer.StopIndex == this.query.Length - 1)
                            {
                                num3++;
                            }
                            string          text3 = this.query.Substring(num, num3 - num);
                            ScriptStatement item  = default(ScriptStatement);
                            item.text     = text3.Trim();
                            item.line     = MySqlScript.FindLineNumber(num, list2);
                            item.position = num - list2[item.line];
                            list.Add(item);
                            num = num3 + text.Length;
                        }
                    }
                }
            }
            if (num < this.query.Length - 1)
            {
                string text4 = this.query.Substring(num).Trim();
                if (!string.IsNullOrEmpty(text4))
                {
                    ScriptStatement item2 = default(ScriptStatement);
                    item2.text     = text4;
                    item2.line     = MySqlScript.FindLineNumber(num, list2);
                    item2.position = num - list2[item2.line];
                    list.Add(item2);
                }
            }
            return(list);
        }
    private void ParseProcedureBody(DataTable parametersTable, string body,
        DataRow row, string nameToRestrict)
    {
      var modes = new ArrayList(new string[3] { "IN", "OUT", "INOUT" });

      var sqlMode = row["SQL_MODE"].ToString();

      var pos = 1;
      var tokenizer = new MySqlTokenizer(body);
      tokenizer.AnsiQuotes = sqlMode.IndexOf("ANSI_QUOTES") != -1;
      tokenizer.BackslashEscapes = sqlMode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
      tokenizer.ReturnComments = false;
      var token = tokenizer.NextToken();

      // this block will scan for the opening paren while also determining
      // if this routine is a function.  If so, then we need to add a
      // parameter row for the return parameter since it is ordinal position
      // 0 and should appear first.
      while (token != "(")
      {
        if (String.Compare(token, "FUNCTION", true) == 0 &&
            nameToRestrict == null)
        {
          parametersTable.Rows.Add(parametersTable.NewRow());
          InitParameterRow(row, parametersTable.Rows[0]);
        }
        token = tokenizer.NextToken();
      }
      token = tokenizer.NextToken();  // now move to the next token past the (

      while (token != ")")
      {
        var parmRow = parametersTable.NewRow();
        InitParameterRow(row, parmRow);
        parmRow["ORDINAL_POSITION"] = pos++;

        // handle mode and name for the parameter
        var mode = token.ToUpper(CultureInfo.InvariantCulture);
        if (!tokenizer.Quoted && modes.Contains(mode))
        {
          parmRow["PARAMETER_MODE"] = mode;
          token = tokenizer.NextToken();
        }
        if (tokenizer.Quoted)
          token = token.Substring(1, token.Length - 2);
        parmRow["PARAMETER_NAME"] = token;

        // now parse data type
        token = ParseDataType(parmRow, tokenizer);
        if (token == ",")
          token = tokenizer.NextToken();

        // now determine if we should include this row after all
        // we need to parse it before this check so we are correctly
        // positioned for the next parameter
        if (nameToRestrict == null ||
            String.Compare(parmRow["PARAMETER_NAME"].ToString(), nameToRestrict, true) == 0)
          parametersTable.Rows.Add(parmRow);
      }

      // now parse out the return parameter if there is one.
      token = tokenizer.NextToken().ToUpper(CultureInfo.InvariantCulture);
      if (String.Compare(token, "RETURNS", true) == 0)
      {
        var parameterRow = parametersTable.Rows[0];
        parameterRow["PARAMETER_NAME"] = "RETURN_VALUE";
        ParseDataType(parameterRow, tokenizer);
      }
    }
    /// <summary>
    ///  Parses out the elements of a procedure parameter data type.
    /// </summary>
    private string ParseDataType(DataRow row, MySqlTokenizer tokenizer)
    {
      var dtd = new StringBuilder(
          tokenizer.NextToken().ToUpper(CultureInfo.InvariantCulture));
      row["DATA_TYPE"] = dtd.ToString();
      var type = row["DATA_TYPE"].ToString();

      var token = tokenizer.NextToken();
      if (token == "(")
      {
        token = tokenizer.ReadParenthesis();
        dtd.AppendFormat(CultureInfo.InvariantCulture, "{0}", token);
        if (type != "ENUM" && type != "SET")
          ParseDataTypeSize(row, token);
        token = tokenizer.NextToken();
      }
      else
        dtd.Append(GetDataTypeDefaults(type, row));

      while (token != ")" &&
             token != "," &&
             String.Compare(token, "begin", true) != 0 &&
             String.Compare(token, "return", true) != 0)
      {
        if (String.Compare(token, "CHARACTER", true) == 0 ||
            String.Compare(token, "BINARY", true) == 0)
        { }  // we don't need to do anything with this
        else if (String.Compare(token, "SET", true) == 0 ||
                 String.Compare(token, "CHARSET", true) == 0)
          row["CHARACTER_SET_NAME"] = tokenizer.NextToken();
        else if (String.Compare(token, "ASCII", true) == 0)
          row["CHARACTER_SET_NAME"] = "latin1";
        else if (String.Compare(token, "UNICODE", true) == 0)
          row["CHARACTER_SET_NAME"] = "ucs2";
        else if (String.Compare(token, "COLLATE", true) == 0)
          row["COLLATION_NAME"] = tokenizer.NextToken();
        else
          dtd.AppendFormat(CultureInfo.InvariantCulture, " {0}", token);
        token = tokenizer.NextToken();
      }

      if (dtd.Length > 0)
        row["DTD_IDENTIFIER"] = dtd.ToString();

      // now default the collation if one wasn't given
      if (row["COLLATION_NAME"].ToString().Length == 0 &&
          row["CHARACTER_SET_NAME"].ToString().Length > 0)
        row["COLLATION_NAME"] = CharSetMap.GetDefaultCollation(
            row["CHARACTER_SET_NAME"].ToString(), connection);

      // now set the octet length
      if (row["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
        row["CHARACTER_OCTET_LENGTH"] =
            CharSetMap.GetMaxLength(row["CHARACTER_SET_NAME"].ToString(), connection) *
            (int)row["CHARACTER_MAXIMUM_LENGTH"];

      return token;
    }
        private List<ScriptStatement> BreakIntoStatements(bool ansiQuotes, bool noBackslashEscapes)
        {
            string currentDelimiter = Delimiter;
              int startPos = 0;
              List<ScriptStatement> statements = new List<ScriptStatement>();
              List<int> lineNumbers = BreakScriptIntoLines();
              MySqlTokenizer tokenizer = new MySqlTokenizer(query);

              tokenizer.AnsiQuotes = ansiQuotes;
              tokenizer.BackslashEscapes = !noBackslashEscapes;

              string token = tokenizer.NextToken();
              while (token != null)
              {
            if (!tokenizer.Quoted)
            {
              if (token.ToLower(CultureInfo.InvariantCulture) == "delimiter")
              {
            tokenizer.NextToken();
            AdjustDelimiterEnd(tokenizer);
            currentDelimiter = query.Substring(tokenizer.StartIndex,
              tokenizer.StopIndex - tokenizer.StartIndex).Trim();
            startPos = tokenizer.StopIndex;
              }
              else
              {
            // this handles the case where our tokenizer reads part of the
            // delimiter
            if (currentDelimiter.StartsWith(token, StringComparison.OrdinalIgnoreCase))
            {
              if ((tokenizer.StartIndex + currentDelimiter.Length) <= query.Length)
              {
                if (query.Substring(tokenizer.StartIndex, currentDelimiter.Length) == currentDelimiter)
                {
                  token = currentDelimiter;
                  tokenizer.Position = tokenizer.StartIndex + currentDelimiter.Length;
                  tokenizer.StopIndex = tokenizer.Position;
                }
              }
            }

            int delimiterPos = token.IndexOf(currentDelimiter, StringComparison.OrdinalIgnoreCase);
            if (delimiterPos != -1)
            {
              int endPos = tokenizer.StopIndex - token.Length + delimiterPos;
              if (tokenizer.StopIndex == query.Length - 1)
                endPos++;
              string currentQuery = query.Substring(startPos, endPos - startPos);
              ScriptStatement statement = new ScriptStatement();
              statement.text = currentQuery.Trim();
              statement.line = FindLineNumber(startPos, lineNumbers);
              statement.position = startPos - lineNumbers[statement.line];
              statements.Add(statement);
              startPos = endPos + currentDelimiter.Length;
            }
              }
            }
            token = tokenizer.NextToken();
              }

              // now clean up the last statement
              if (startPos < query.Length - 1)
              {
            string sqlLeftOver = query.Substring(startPos).Trim();
            if (!String.IsNullOrEmpty(sqlLeftOver))
            {
              ScriptStatement statement = new ScriptStatement();
              statement.text = sqlLeftOver;
              statement.line = FindLineNumber(startPos, lineNumbers);
              statement.position = startPos - lineNumbers[statement.line];
              statements.Add(statement);
            }
              }
              return statements;
        }
Example #27
0
        private void ParseProcedureBody(MySqlSchemaCollection parametersTable, string body, MySqlSchemaRow row, string nameToRestrict)
        {
            List <string> list = new List <string>(new string[]
            {
                "IN",
                "OUT",
                "INOUT"
            });
            string         text           = row["SQL_MODE"].ToString();
            int            num            = 1;
            MySqlTokenizer mySqlTokenizer = new MySqlTokenizer(body);

            mySqlTokenizer.AnsiQuotes       = (text.IndexOf("ANSI_QUOTES") != -1);
            mySqlTokenizer.BackslashEscapes = (text.IndexOf("NO_BACKSLASH_ESCAPES") == -1);
            mySqlTokenizer.ReturnComments   = false;
            string text2 = mySqlTokenizer.NextToken();

            while (text2 != "(")
            {
                if (string.Compare(text2, "FUNCTION", StringComparison.OrdinalIgnoreCase) == 0 && nameToRestrict == null)
                {
                    parametersTable.AddRow();
                    ISSchemaProvider.InitParameterRow(row, parametersTable.Rows[0]);
                }
                text2 = mySqlTokenizer.NextToken();
            }
            text2 = mySqlTokenizer.NextToken();
            while (text2 != ")")
            {
                MySqlSchemaRow mySqlSchemaRow = parametersTable.NewRow();
                ISSchemaProvider.InitParameterRow(row, mySqlSchemaRow);
                mySqlSchemaRow["ORDINAL_POSITION"] = num++;
                string text3 = StringUtility.ToUpperInvariant(text2);
                if (!mySqlTokenizer.Quoted && list.Contains(text3))
                {
                    mySqlSchemaRow["PARAMETER_MODE"] = text3;
                    text2 = mySqlTokenizer.NextToken();
                }
                if (mySqlTokenizer.Quoted)
                {
                    text2 = text2.Substring(1, text2.Length - 2);
                }
                mySqlSchemaRow["PARAMETER_NAME"] = text2;
                text2 = this.ParseDataType(mySqlSchemaRow, mySqlTokenizer);
                if (text2 == ",")
                {
                    text2 = mySqlTokenizer.NextToken();
                }
                if (nameToRestrict == null || string.Compare(mySqlSchemaRow["PARAMETER_NAME"].ToString(), nameToRestrict, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    parametersTable.Rows.Add(mySqlSchemaRow);
                }
            }
            text2 = StringUtility.ToUpperInvariant(mySqlTokenizer.NextToken());
            if (string.Compare(text2, "RETURNS", StringComparison.OrdinalIgnoreCase) == 0)
            {
                MySqlSchemaRow mySqlSchemaRow2 = parametersTable.Rows[0];
                mySqlSchemaRow2["PARAMETER_NAME"] = "RETURN_VALUE";
                this.ParseDataType(mySqlSchemaRow2, mySqlTokenizer);
            }
        }
    private static List<string> GetPossibleValues(DataRow row)
    {
      var types = new string[] { "ENUM", "SET" };
      var dtdIdentifier = row["DTD_IDENTIFIER"].ToString().Trim();

      var index = 0;
      for (; index < 2; index++)
        if (dtdIdentifier.StartsWith(types[index], StringComparison.OrdinalIgnoreCase ))
          break;
      if (index == 2) return null;
      dtdIdentifier = dtdIdentifier.Substring(types[index].Length).Trim();
      dtdIdentifier = dtdIdentifier.Trim('(', ')').Trim();

      var values = new List<string>();
      var tokenzier = new MySqlTokenizer(dtdIdentifier);
      var token = tokenzier.NextToken();
      var start = tokenzier.StartIndex;
      while (true)
      {
        if (token == null || token == ",")
        {
          var end = dtdIdentifier.Length - 1;
          if (token == ",")
            end = tokenzier.StartIndex;

          var value = dtdIdentifier.Substring(start, end - start).Trim('\'', '\"').Trim();
          values.Add(value);
          start = tokenzier.StopIndex;
        }
        if (token == null) break;
        token = tokenzier.NextToken();
      }
      return values;
    }
Example #29
0
        internal string GetCommandTextForBatching()
        {
            if (BatchableCommandText == null)
            {
                // if the command starts with insert and is "simple" enough, then
                // we can use the multi-value form of insert
                if (String.Compare(CommandText.Substring(0, 6), "INSERT", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    MySqlCommand   cmd       = new MySqlCommand("SELECT @@sql_mode", Connection);
                    string         sql_mode  = StringUtility.ToUpperInvariant(cmd.ExecuteScalar().ToString());
                    MySqlTokenizer tokenizer = new MySqlTokenizer(CommandText);
                    tokenizer.AnsiQuotes       = sql_mode.IndexOf("ANSI_QUOTES") != -1;
                    tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
                    string token = StringUtility.ToLowerInvariant(tokenizer.NextToken());
                    while (token != null)
                    {
                        if (StringUtility.ToUpperInvariant(token) == "VALUES" &&
                            !tokenizer.Quoted)
                        {
                            token = tokenizer.NextToken();
                            Debug.Assert(token == "(");

                            // find matching right paren, and ensure that parens
                            // are balanced.
                            int openParenCount = 1;
                            while (token != null)
                            {
                                BatchableCommandText += token;
                                token = tokenizer.NextToken();

                                if (token == "(")
                                {
                                    openParenCount++;
                                }
                                else if (token == ")")
                                {
                                    openParenCount--;
                                }

                                if (openParenCount == 0)
                                {
                                    break;
                                }
                            }

                            if (token != null)
                            {
                                BatchableCommandText += token;
                            }
                            token = tokenizer.NextToken();
                            if (token != null && (token == "," ||
                                                  StringUtility.ToUpperInvariant(token) == "ON"))
                            {
                                BatchableCommandText = null;
                                break;
                            }
                        }
                        token = tokenizer.NextToken();
                    }
                }
                // Otherwise use the command verbatim
                else
                {
                    BatchableCommandText = CommandText;
                }
            }

            return(BatchableCommandText);
        }
Example #30
0
        private static void ParseConstraint(MySqlSchemaCollection fkTable, MySqlSchemaRow table, MySqlTokenizer tokenizer, bool includeColumns)
        {
            string         str  = tokenizer.NextToken();
            MySqlSchemaRow row  = fkTable.AddRow();
            string         str2 = tokenizer.NextToken();

            if ((str2 == "foreign") && !tokenizer.Quoted)
            {
                tokenizer.NextToken();
                tokenizer.NextToken();
                row["CONSTRAINT_CATALOG"]       = table["TABLE_CATALOG"];
                row["CONSTRAINT_SCHEMA"]        = table["TABLE_SCHEMA"];
                row["TABLE_CATALOG"]            = table["TABLE_CATALOG"];
                row["TABLE_SCHEMA"]             = table["TABLE_SCHEMA"];
                row["TABLE_NAME"]               = table["TABLE_NAME"];
                row["REFERENCED_TABLE_CATALOG"] = null;
                row["CONSTRAINT_NAME"]          = str.Trim(new char[] { '\'', '`' });
                List <string> srcColumns = includeColumns ? ParseColumns(tokenizer) : null;
                while ((str2 != "references") || tokenizer.Quoted)
                {
                    str2 = tokenizer.NextToken();
                }
                string str3 = tokenizer.NextToken();
                string str4 = tokenizer.NextToken();
                if (str4.StartsWith(".", StringComparison.Ordinal))
                {
                    row["REFERENCED_TABLE_SCHEMA"] = str3;
                    row["REFERENCED_TABLE_NAME"]   = str4.Substring(1).Trim(new char[] { '\'', '`' });
                    tokenizer.NextToken();
                }
                else
                {
                    row["REFERENCED_TABLE_SCHEMA"] = table["TABLE_SCHEMA"];
                    row["REFERENCED_TABLE_NAME"]   = str3.Substring(1).Trim(new char[] { '\'', '`' });
                }
                List <string> targetColumns = includeColumns ? ParseColumns(tokenizer) : null;
                if (includeColumns)
                {
                    ProcessColumns(fkTable, row, srcColumns, targetColumns);
                }
                else
                {
                    fkTable.Rows.Add(row);
                }
            }
        }
        /// <summary>
        ///  Parses out the elements of a procedure parameter data type.
        /// </summary>
        private string ParseDataType(DataRow row, MySqlTokenizer tokenizer)
        {
            StringBuilder dtd = new StringBuilder(
                tokenizer.NextToken().ToUpper(CultureInfo.InvariantCulture));

            row["DATA_TYPE"] = dtd.ToString();
            string type = row["DATA_TYPE"].ToString();

            string token = tokenizer.NextToken();

            if (token == "(")
            {
                token = tokenizer.ReadParenthesis();
                dtd.AppendFormat(CultureInfo.InvariantCulture, "{0}", token);
                if (type != "ENUM" && type != "SET")
                {
                    ParseDataTypeSize(row, token);
                }
                token = tokenizer.NextToken();
            }
            else
            {
                dtd.Append(GetDataTypeDefaults(type, row));
            }

            while (token != ")" &&
                   token != "," &&
                   String.Compare(token, "begin", true) != 0 &&
                   String.Compare(token, "return", true) != 0)
            {
                if (String.Compare(token, "CHARACTER", true) == 0 ||
                    String.Compare(token, "BINARY", true) == 0)
                {
                } // we don't need to do anything with this
                else if (String.Compare(token, "SET", true) == 0 ||
                         String.Compare(token, "CHARSET", true) == 0)
                {
                    row["CHARACTER_SET_NAME"] = tokenizer.NextToken();
                }
                else if (String.Compare(token, "ASCII", true) == 0)
                {
                    row["CHARACTER_SET_NAME"] = "latin1";
                }
                else if (String.Compare(token, "UNICODE", true) == 0)
                {
                    row["CHARACTER_SET_NAME"] = "ucs2";
                }
                else if (String.Compare(token, "COLLATE", true) == 0)
                {
                    row["COLLATION_NAME"] = tokenizer.NextToken();
                }
                else
                {
                    dtd.AppendFormat(CultureInfo.InvariantCulture, " {0}", token);
                }
                token = tokenizer.NextToken();
            }

            if (dtd.Length > 0)
            {
                row["DTD_IDENTIFIER"] = dtd.ToString();
            }

            // now default the collation if one wasn't given
            if (row["COLLATION_NAME"].ToString().Length == 0 &&
                row["CHARACTER_SET_NAME"].ToString().Length > 0)
            {
                row["COLLATION_NAME"] = CharSetMap.GetDefaultCollation(
                    row["CHARACTER_SET_NAME"].ToString(), connection);
            }

            // now set the octet length
            if (row["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
            {
                row["CHARACTER_OCTET_LENGTH"] =
                    CharSetMap.GetMaxLength(row["CHARACTER_SET_NAME"].ToString(), connection) *
                    (int)row["CHARACTER_MAXIMUM_LENGTH"];
            }

            return(token);
        }
    /// <summary>
    ///  Parses out the elements of a procedure parameter data type.
    /// </summary>
    private string ParseDataType(MySqlSchemaRow row, MySqlTokenizer tokenizer)
    {
      StringBuilder dtd = new StringBuilder(
          StringUtility.ToUpperInvariant(tokenizer.NextToken()));
      row["DATA_TYPE"] = dtd.ToString();
      string type = row["DATA_TYPE"].ToString();

      string token = tokenizer.NextToken();
      if (token == "(")
      {
        token = tokenizer.ReadParenthesis();
        dtd.AppendFormat(CultureInfo.InvariantCulture, "{0}", token);
        if (type != "ENUM" && type != "SET")
          ParseDataTypeSize(row, token);
        token = tokenizer.NextToken();
      }
      else
        dtd.Append(GetDataTypeDefaults(type, row));

      while (token != ")" &&
             token != "," &&
             String.Compare(token, "begin", StringComparison.OrdinalIgnoreCase) != 0 &&
             String.Compare(token, "return", StringComparison.OrdinalIgnoreCase) != 0)
      {
        if (String.Compare(token, "CHARACTER", StringComparison.OrdinalIgnoreCase) == 0 ||
            String.Compare(token, "BINARY", StringComparison.OrdinalIgnoreCase) == 0)
        { }  // we don't need to do anything with this
        else if (String.Compare(token, "SET", StringComparison.OrdinalIgnoreCase) == 0 ||
                 String.Compare(token, "CHARSET", StringComparison.OrdinalIgnoreCase) == 0)
          row["CHARACTER_SET_NAME"] = tokenizer.NextToken();
        else if (String.Compare(token, "ASCII", StringComparison.OrdinalIgnoreCase) == 0)
          row["CHARACTER_SET_NAME"] = "latin1";
        else if (String.Compare(token, "UNICODE", StringComparison.OrdinalIgnoreCase) == 0)
          row["CHARACTER_SET_NAME"] = "ucs2";
        else if (String.Compare(token, "COLLATE", StringComparison.OrdinalIgnoreCase) == 0)
          row["COLLATION_NAME"] = tokenizer.NextToken();
        else
          dtd.AppendFormat(CultureInfo.InvariantCulture, " {0}", token);
        token = tokenizer.NextToken();
      }

      if (dtd.Length > 0)
        row["DTD_IDENTIFIER"] = dtd.ToString();

      // now default the collation if one wasn't given
      if ( string.IsNullOrEmpty( ( string )row["COLLATION_NAME"] ) &&
          !string.IsNullOrEmpty( ( string )row["CHARACTER_SET_NAME"] ))
        row["COLLATION_NAME"] = CharSetMap.GetDefaultCollation(
            row["CHARACTER_SET_NAME"].ToString(), connection);

      // now set the octet length
      if (row["CHARACTER_MAXIMUM_LENGTH"] != null)
      {
        if (row["CHARACTER_SET_NAME"] == null)
          row["CHARACTER_SET_NAME"] = "";
        row["CHARACTER_OCTET_LENGTH"] =
            CharSetMap.GetMaxLength(( string )row["CHARACTER_SET_NAME"], connection) *
            (int)row["CHARACTER_MAXIMUM_LENGTH"];
      }

      return token;
    }
        /// <summary>
        /// Prepares CommandText for use with the Prepare method
        /// </summary>
        /// <returns>Command text stripped of all paramter names</returns>
        /// <remarks>
        /// Takes the output of TokenizeSql and creates a single string of SQL
        /// that only contains '?' markers for each parameter.  It also creates
        /// the parameterMap array list that includes all the paramter names in the
        /// order they appeared in the SQL
        /// </remarks>
        private List<string> PrepareCommandText(out string stripped_sql)
        {
            StringBuilder newSQL = new StringBuilder();
            List<string> parameterMap = new List<string>();

            int startPos = 0;
            string sql = ResolvedCommandText;
            MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
            string parameter = tokenizer.NextParameter();
            while (parameter != null)
            {
                parameter = tokenizer.NextParameter();
            }
            newSQL.Append(sql.Substring(startPos));
            stripped_sql = newSQL.ToString();
            return parameterMap;
        }
Example #34
0
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters, 
            MySqlPacket packet)
        {
            if (packet == null)
            {
                packet = new MySqlPacket(Driver.Encoding);
                packet.Version = Driver.Version;
                packet.WriteByte(0);
            }

            int startPos = 0;
            MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
            tokenizer.ReturnComments = true;
            string parameter = tokenizer.NextParameter();
            while (parameter != null)
            {
                packet.WriteStringNoNull(sql.Substring(startPos, tokenizer.StartIndex - startPos));
                bool serialized = SerializeParameter(parameters, packet, parameter);
                startPos = tokenizer.StopIndex;
                if (!serialized)
                    startPos = tokenizer.StartIndex;
                parameter = tokenizer.NextParameter();
            }
            packet.WriteStringNoNull(sql.Substring(startPos));
            buffers.Add(packet);
        }
    /// <summary>
    /// Prepares CommandText for use with the Prepare method
    /// </summary>
    /// <returns>Command text stripped of all paramter names</returns>
    /// <remarks>
    /// Takes the output of TokenizeSql and creates a single string of SQL
    /// that only contains '?' markers for each parameter.  It also creates
    /// the parameterMap array list that includes all the paramter names in the
    /// order they appeared in the SQL
    /// </remarks>
    private List<string> PrepareCommandText(out string stripped_sql)
    {
      StringBuilder newSQL = new StringBuilder();
      List<string> parameterMap = new List<string>();

      int startPos = 0;
      string sql = ResolvedCommandText;
      MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
      string parameter = tokenizer.NextParameter();
      while (parameter != null)
      {
        if (parameter.IndexOf(StoredProcedure.ParameterPrefix) == -1)
        {
          newSQL.Append(sql.Substring(startPos, tokenizer.StartIndex - startPos));
          newSQL.Append("?");
          parameterMap.Add(parameter);
          startPos = tokenizer.StopIndex;
        }
        parameter = tokenizer.NextParameter();
      }
      newSQL.Append(sql.Substring(startPos));
      stripped_sql = newSQL.ToString();
      return parameterMap;
    }
        private static void ParseConstraint(DataTable fkTable, DataRow table, 
            MySqlTokenizer tokenizer, bool includeColumns)
        {
            string name = tokenizer.NextToken();
            DataRow row = fkTable.NewRow();

            // make sure this constraint is a FK
            string token = tokenizer.NextToken();
            if (token != "foreign" || tokenizer.Quoted)
                return;
            tokenizer.NextToken(); // read off the 'KEY' symbol
            tokenizer.NextToken(); // read off the '(' symbol

            row["CONSTRAINT_CATALOG"] = table["TABLE_CATALOG"];
            row["CONSTRAINT_SCHEMA"] = table["TABLE_SCHEMA"];
            row["TABLE_CATALOG"] = table["TABLE_CATALOG"];
            row["TABLE_SCHEMA"] = table["TABLE_SCHEMA"];
            row["TABLE_NAME"] = table["TABLE_NAME"];
            row["REFERENCED_TABLE_CATALOG"] = null;
            row["CONSTRAINT_NAME"] = name.Trim(new char[] { '\'', '`' });

            ArrayList srcColumns = includeColumns ? ParseColumns(tokenizer) : null;

            // now look for the references section
            while (token != "references" || tokenizer.Quoted)
                token = tokenizer.NextToken();
            string target1 = tokenizer.NextToken();
            string target2 = tokenizer.NextToken();
            if (target2.StartsWith("."))
            {
                row["REFERENCED_TABLE_SCHEMA"] = target1;
                row["REFERENCED_TABLE_NAME"] = target2.Substring(1).Trim(new char[] { '\'', '`' });
                tokenizer.NextToken();  // read off the '('
            }
            else
            {
                row["REFERENCED_TABLE_SCHEMA"] = table["TABLE_SCHEMA"];
                row["REFERENCED_TABLE_NAME"] = target1.Substring(1).Trim(new char[] { '\'', '`' }); ;
            }

            // if we are supposed to include columns, read the target columns
            ArrayList targetColumns = includeColumns ? ParseColumns(tokenizer) : null;

            if (includeColumns)
                ProcessColumns(fkTable, row, srcColumns, targetColumns);
            else
                fkTable.Rows.Add(row);
        }
Example #37
0
        private List <ScriptStatement> BreakIntoStatements(bool ansiQuotes, bool noBackslashEscapes)
        {
            string currentDelimiter            = Delimiter;
            int    startPos                    = 0;
            List <ScriptStatement> statements  = new List <ScriptStatement>();
            List <int>             lineNumbers = BreakScriptIntoLines();
            MySqlTokenizer         tokenizer   = new MySqlTokenizer(query);

            tokenizer.AnsiQuotes       = ansiQuotes;
            tokenizer.BackslashEscapes = !noBackslashEscapes;

            string token = tokenizer.NextToken();

            while (token != null)
            {
                if (!tokenizer.Quoted)
                {
                    if (token.ToLower(CultureInfo.InvariantCulture) == "delimiter")
                    {
                        tokenizer.NextToken();
                        AdjustDelimiterEnd(tokenizer);
                        currentDelimiter = query.Substring(tokenizer.StartIndex,
                                                           tokenizer.StopIndex - tokenizer.StartIndex).Trim();
                        startPos = tokenizer.StopIndex;
                    }
                    else
                    {
                        // this handles the case where our tokenizer reads part of the
                        // delimiter
                        if (currentDelimiter.StartsWith(token, StringComparison.OrdinalIgnoreCase))
                        {
                            if ((tokenizer.StartIndex + currentDelimiter.Length) <= query.Length)
                            {
                                if (query.Substring(tokenizer.StartIndex, currentDelimiter.Length) == currentDelimiter)
                                {
                                    token = currentDelimiter;
                                    tokenizer.Position  = tokenizer.StartIndex + currentDelimiter.Length;
                                    tokenizer.StopIndex = tokenizer.Position;
                                }
                            }
                        }

                        int delimiterPos = token.IndexOf(currentDelimiter, StringComparison.OrdinalIgnoreCase);
                        if (delimiterPos != -1)
                        {
                            int endPos = tokenizer.StopIndex - token.Length + delimiterPos;
                            if (tokenizer.StopIndex == query.Length - 1)
                            {
                                endPos++;
                            }
                            string          currentQuery = query.Substring(startPos, endPos - startPos);
                            ScriptStatement statement    = new ScriptStatement();
                            statement.text     = currentQuery.Trim();
                            statement.line     = FindLineNumber(startPos, lineNumbers);
                            statement.position = startPos - lineNumbers[statement.line];
                            statements.Add(statement);
                            startPos = endPos + currentDelimiter.Length;
                        }
                    }
                }
                token = tokenizer.NextToken();
            }

            // now clean up the last statement
            if (startPos < query.Length - 1)
            {
                string sqlLeftOver = query.Substring(startPos).Trim();
                if (!String.IsNullOrEmpty(sqlLeftOver))
                {
                    ScriptStatement statement = new ScriptStatement();
                    statement.text     = sqlLeftOver;
                    statement.line     = FindLineNumber(startPos, lineNumbers);
                    statement.position = startPos - lineNumbers[statement.line];
                    statements.Add(statement);
                }
            }
            return(statements);
        }
 private static ArrayList ParseColumns(MySqlTokenizer tokenizer)
 {
     ArrayList sc = new ArrayList();
     string token = tokenizer.NextToken();
     while (token != ")")
     {
         if (token != ",")
             sc.Add(token);
         token = tokenizer.NextToken();
     }
     return sc;
 }
        private void AdjustDelimiterEnd(MySqlTokenizer tokenizer)
        {
            if (tokenizer.StopIndex < query.Length)
              {
            int pos = tokenizer.StopIndex;
            char c = query[pos];

            while (!Char.IsWhiteSpace(c) && pos < (query.Length - 1))
            {
              c = query[++pos];
            }
            tokenizer.StopIndex = pos;
            tokenizer.Position = pos;
              }
        }
Example #40
0
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters,
        MySqlPacket packet)
        {
            bool sqlServerMode = command.Connection.Settings.SqlServerMode;

              if (packet == null)
              {
            packet = new MySqlPacket(Driver.Encoding);
            packet.Version = Driver.Version;
            packet.WriteByte(0);
              }

              MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
              tokenizer.ReturnComments = true;
              tokenizer.SqlServerMode = sqlServerMode;

              int pos = 0;
              string token = tokenizer.NextToken();
              int parameterCount = 0;
              while (token != null)
              {
            // serialize everything that came before the token (i.e. whitespace)
            packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos));
            pos = tokenizer.StopIndex;
            if (MySqlTokenizer.IsParameter(token))
            {
              if ((!parameters.containsUnnamedParameters && token.Length == 1 && parameterCount > 0) || parameters.containsUnnamedParameters && token.Length > 1)
            throw new MySqlException("Resources.MixedParameterNamingNotAllowed");

              parameters.containsUnnamedParameters = token.Length == 1;
              if (SerializeParameter(parameters, packet, token, parameterCount))
            token = null;
              parameterCount++;
            }
            if (token != null)
            {
              if (sqlServerMode && tokenizer.Quoted && token.StartsWith("[", StringComparison.Ordinal))
            token = String.Format("`{0}`", token.Substring(1, token.Length - 2));
              packet.WriteStringNoNull(token);
            }
            token = tokenizer.NextToken();
              }
              buffers.Add(packet);
        }
    private string GetProcedureParameterLine(DataRow isRow)
    {
      var sql = "SHOW CREATE {0} `{1}`.`{2}`";
      sql = String.Format(sql, isRow["ROUTINE_TYPE"], isRow["ROUTINE_SCHEMA"],
          isRow["ROUTINE_NAME"]);
      var cmd = new MySqlCommand(sql, connection);
      using (var reader = cmd.ExecuteReader())
      {
        reader.Read();

        // if we are not the owner of this proc or have permissions
        // then we will get null for the body
        if (reader.IsDBNull(2)) return null;

        var sql_mode = reader.GetString(1);

        var body = reader.GetString(2);
        var tokenizer = new MySqlTokenizer(body);
        tokenizer.AnsiQuotes = sql_mode.IndexOf("ANSI_QUOTES") != -1;
        tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;

        var token = tokenizer.NextToken();
        while (token != "(")
          token = tokenizer.NextToken();
        var start = tokenizer.StartIndex + 1;
        token = tokenizer.NextToken();
        while (token != ")" || tokenizer.Quoted)
        {
          token = tokenizer.NextToken();
          // if we see another ( and we are not quoted then we
          // are in a size element and we need to look for the closing paren
          if (token == "(" && !tokenizer.Quoted)
          {
            while (token != ")" || tokenizer.Quoted)
              token = tokenizer.NextToken();
            token = tokenizer.NextToken();
          }
        }
        return body.Substring(start, tokenizer.StartIndex - start);
      }
    }
 private static List<string> ParseColumns(MySqlTokenizer tokenizer)
 {
     List<string> sc = new List<string>();
       string token = tokenizer.NextToken();
       while (token != ")")
       {
     if (token != ",")
       sc.Add(token);
     token = tokenizer.NextToken();
       }
       return sc;
 }
        private void ParseProcedureBody(DataTable parametersTable, string body,
                                        DataRow row, string nameToRestrict)
        {
            ArrayList modes = new ArrayList(new string[3] {
                "IN", "OUT", "INOUT"
            });

            string sqlMode = row["SQL_MODE"].ToString();

            int            pos       = 1;
            MySqlTokenizer tokenizer = new MySqlTokenizer(body);

            tokenizer.AnsiQuotes       = sqlMode.IndexOf("ANSI_QUOTES") != -1;
            tokenizer.BackslashEscapes = sqlMode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
            tokenizer.ReturnComments   = false;
            string token = tokenizer.NextToken();

            // this block will scan for the opening paren while also determining
            // if this routine is a function.  If so, then we need to add a
            // parameter row for the return parameter since it is ordinal position
            // 0 and should appear first.
            while (token != "(")
            {
                if (String.Compare(token, "FUNCTION", true) == 0 &&
                    nameToRestrict == null)
                {
                    parametersTable.Rows.Add(parametersTable.NewRow());
                    InitParameterRow(row, parametersTable.Rows[0]);
                }
                token = tokenizer.NextToken();
            }
            token = tokenizer.NextToken(); // now move to the next token past the (

            while (token != ")")
            {
                DataRow parmRow = parametersTable.NewRow();
                InitParameterRow(row, parmRow);
                parmRow["ORDINAL_POSITION"] = pos++;

                // handle mode and name for the parameter
                string mode = token.ToUpper(CultureInfo.InvariantCulture);
                if (!tokenizer.Quoted && modes.Contains(mode))
                {
                    parmRow["PARAMETER_MODE"] = mode;
                    token = tokenizer.NextToken();
                }
                if (tokenizer.Quoted)
                {
                    token = token.Substring(1, token.Length - 2);
                }
                parmRow["PARAMETER_NAME"] = token;

                // now parse data type
                token = ParseDataType(parmRow, tokenizer);
                if (token == ",")
                {
                    token = tokenizer.NextToken();
                }

                // now determine if we should include this row after all
                // we need to parse it before this check so we are correctly
                // positioned for the next parameter
                if (nameToRestrict == null ||
                    String.Compare(parmRow["PARAMETER_NAME"].ToString(), nameToRestrict, true) == 0)
                {
                    parametersTable.Rows.Add(parmRow);
                }
            }

            // now parse out the return parameter if there is one.
            token = tokenizer.NextToken().ToUpper(CultureInfo.InvariantCulture);
            if (String.Compare(token, "RETURNS", true) == 0)
            {
                DataRow parameterRow = parametersTable.Rows[0];
                parameterRow["PARAMETER_NAME"] = "RETURN_VALUE";
                ParseDataType(parameterRow, tokenizer);
            }
        }
        internal string GetCommandTextForBatching()
        {
            if (batchableCommandText == null)
            {
                // if the command starts with insert and is "simple" enough, then
                // we can use the multi-value form of insert
                if (String.Compare(CommandText.Substring(0, 6), "INSERT", true) == 0)
                {
                    MySqlCommand cmd = new MySqlCommand("SELECT @@sql_mode", Connection);
                    string sql_mode = cmd.ExecuteScalar().ToString().ToUpper(CultureInfo.InvariantCulture);
                    MySqlTokenizer tokenizer = new MySqlTokenizer(CommandText);
                    tokenizer.AnsiQuotes = sql_mode.IndexOf("ANSI_QUOTES") != -1;
                    tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
                    string token = tokenizer.NextToken().ToLower(CultureInfo.InvariantCulture);
                    while (token != null)
                    {
                        if (token.ToUpper(CultureInfo.InvariantCulture) == "VALUES" && 
                            !tokenizer.Quoted)
                        {
                            token = tokenizer.NextToken();
                            Debug.Assert(token == "(");
                            while (token != null && token != ")")
                            {
                                batchableCommandText += token;
                                token = tokenizer.NextToken();
                            }
                            if (token != null)
                                batchableCommandText += token;
                            token = tokenizer.NextToken();
                            if (token != null && (token == "," || 
                                token.ToUpper(CultureInfo.InvariantCulture) == "ON"))
                            {
                                batchableCommandText = null;
                                break;
                            }
                        }
                        token = tokenizer.NextToken();
                    }
                }
            }

            return batchableCommandText;
        }
Example #45
0
    internal string GetCommandTextForBatching()
    {
      if (batchableCommandText == null)
      {
        // if the command starts with insert and is "simple" enough, then
        // we can use the multi-value form of insert
        if (String.Compare(CommandText.Substring(0, 6), "INSERT", StringComparison.OrdinalIgnoreCase) == 0)
        {
          MySqlCommand cmd = new MySqlCommand("SELECT @@sql_mode", Connection);
          string sql_mode = StringUtility.ToUpperInvariant(cmd.ExecuteScalar().ToString());
          MySqlTokenizer tokenizer = new MySqlTokenizer(CommandText);
          tokenizer.AnsiQuotes = sql_mode.IndexOf("ANSI_QUOTES") != -1;
          tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
          string token = StringUtility.ToLowerInvariant(tokenizer.NextToken());
          while (token != null)
          {
            if (StringUtility.ToUpperInvariant(token) == "VALUES" &&
                !tokenizer.Quoted)
            {
              token = tokenizer.NextToken();
              Debug.Assert(token == "(");

              // find matching right paren, and ensure that parens 
              // are balanced.
              int openParenCount = 1;
              while (token != null)
              {
                batchableCommandText += token;
                token = tokenizer.NextToken();

                if (token == "(")
                  openParenCount++;
                else if (token == ")")
                  openParenCount--;

                if (openParenCount == 0)
                  break;
              }

              if (token != null)
                batchableCommandText += token;
              token = tokenizer.NextToken();
              if (token != null && (token == "," ||
                  StringUtility.ToUpperInvariant(token) == "ON"))
              {
                batchableCommandText = null;
                break;
              }
            }
            token = tokenizer.NextToken();
          }
        }
        // Otherwise use the command verbatim
        else batchableCommandText = CommandText;
      }

      return batchableCommandText;
    }
        /// <summary>
        /// GetForeignKeysOnTable retrieves the foreign keys on the given table.
        /// Since MySQL supports foreign keys on versions prior to 5.0, we can't  use
        /// information schema.  MySQL also does not include any type of SHOW command
        /// for foreign keys so we have to resort to use SHOW CREATE TABLE and parsing
        /// the output.
        /// </summary>
        /// <param name="fkTable">The table to store the key info in.</param>
        /// <param name="tableToParse">The table to get the foeign key info for.</param>
        /// <param name="filterName">Only get foreign keys that match this name.</param>
		/// <param name="includeColumns">Should column information be included in the table.</param>
        private void GetForeignKeysOnTable(DataTable fkTable, DataRow tableToParse,
                                           string filterName, bool includeColumns)
        {
            string sqlMode = GetSqlMode();

            if (filterName != null)
                filterName = filterName.ToLower(CultureInfo.InvariantCulture);

            string sql = string.Format("SHOW CREATE TABLE `{0}`.`{1}`",
                                       tableToParse["TABLE_SCHEMA"], tableToParse["TABLE_NAME"]);
            string lowerBody = null, body = null;
            MySqlCommand cmd = new MySqlCommand(sql, connection);
            using (MySqlDataReader reader = cmd.ExecuteReader())
            {
                reader.Read();
                body = reader.GetString(1);
                lowerBody = body.ToLower(CultureInfo.InvariantCulture);
            }

            MySqlTokenizer tokenizer = new MySqlTokenizer(lowerBody);
            tokenizer.AnsiQuotes = sqlMode.IndexOf("ANSI_QUOTES") != -1;
            tokenizer.BackslashEscapes = sqlMode.IndexOf("NO_BACKSLASH_ESCAPES") != -1;
            
            while (true)
            {
                string token = tokenizer.NextToken();
                // look for a starting contraint
                while (token != null && (token != "constraint" || tokenizer.Quoted))
                    token = tokenizer.NextToken();
                if (token == null) break;

                ParseConstraint(fkTable, tableToParse, tokenizer, includeColumns);
            }
        }