TablePart ParseCreateTable(TokenStream tkstream, TablePart table)
        {
            //TablePart table = new TablePart();
            FieldPart field = new FieldPart();
            KeyPart   key   = new KeyPart();

            ParseIden(tkstream, ref table);
            table.FieldList = new List <FieldPart>();
            table.KeyList   = new List <KeyPart>();

            if (tkstream.CurrentToken.TokenName == MySqlTokenName.ParenOpen)
            {
                ParseOpenParen(tkstream);
            }
            else
            {
                throw new MyParserNotSupportException();
            }
            //..
            //fields ...

            //Token iden = tkstream.CurrentToken;

            while (tkstream.CurrentToken.TokenName != MySqlTokenName.ParenClose)
            {
                string item = tkstream.CurrentToken.ToString();

                /*if (tkstream.CurrentToken.OriginalText == ",")
                 * {
                 *  table.FieldList.Add(field);
                 *
                 *  field = new FieldPart();
                 * }*/

                ParseContent(tkstream, ref table, ref field, ref key);
                //table.FieldList.Add(field);
            }

            //....
            ParseCloseParen(tkstream, ref table, ref key);

            while (tkstream.CurrentToken.TokenName != MySqlTokenName.ParenClose)
            {
                ParseLastContent(tkstream, ref table);
                if (tkstream.IsEnd || tkstream.CurrentToken.TokenName == MySqlTokenName.Drop)
                {
                    break;
                }
            }

            return(table);
        }
        void ParseCloseParen(TokenStream tkstream, ref TablePart table, ref KeyPart key)
        {
            //close
            if (key.IndexKind != null)
            {
                table.KeyList.Add(key);
                key = new KeyPart();
            }

            Token iden = tkstream.CurrentToken;

            tkstream.ReadNext();
        }
        /// <summary>
        /// create index keys of 'current' table
        /// </summary>
        /// <param name="strb"></param>
        /// <param name="KeyList"></param>
        void CreateInterfaceIndexKeys(StringBuilder strb, List <KeyPart> KeyList)
        {
            //use nested namespace
            strb.AppendLine("\tnamespace IndexKeys{");

            strb.AppendLine("\t[IndexOfTable(typeof(" + _table.TableName + "))]");
            strb.AppendLine("\tinterface " + _table.TableName);
            strb.AppendLine("\t{");
            string temp = strb.ToString();

            KeyPart[] keys = KeyList.ToArray();
            for (int i = 0; i < keys.Length; ++i)
            {
                KeyPart key = keys[i];

                strb.Append("\t\t[IndexKey(");
                if (key.IndexName != null)
                {
                    strb.Append("Name=" + '"' + key.IndexName + '"');
                }
                if (key.IndexKind != null)
                {
                    strb.Append(", Kind=" + '"' + key.IndexKind + '"');
                }
                if (key.IndexColumns != null)
                {
                    strb.Append(", Columns=" + '"');
                    for (int k = 0; k < key.IndexColumns.Count; ++k)
                    {
                        if (k > 0)
                        {
                            strb.Append(",");
                        }
                        strb.Append(key.IndexColumns[0]);
                    }
                }
                strb.AppendLine('"' + ")]");
                strb.AppendLine("\t\tstring " + key.IndexName + " { get; set; }");
            }

            strb.AppendLine("\t}");
            //
            strb.AppendLine("\t}");
        }
        void ParseContent(TokenStream tkstream, ref TablePart table, ref FieldPart field, ref KeyPart key)
        {
            //get fields over here
            Token iden = tkstream.CurrentToken;

            switch (tkstream.CurrentToken.OriginalText)
            {
            case ",":
            {
                switch (table.PrimaryKey)
                {
                case null:
                {
                    table.FieldList.Add(field);
                    field = new FieldPart();
                }
                break;

                default:
                {
                    if (key.IndexKind != null)
                    {
                        table.KeyList.Add(key);
                        key = new KeyPart();
                    }
                }
                break;
                }
            }
            break;

            default:
            {
                switch (iden.TokenName)
                {
                case MySqlTokenName.Iden:
                {
                    string[] fieldName = iden.OriginalText.Split(new char[] { '`' }, StringSplitOptions.RemoveEmptyEntries);
                    field.FieldName = fieldName[0];
                }
                break;

                case MySqlTokenName.FieldTypeWithParen:
                {
                    CompoundToken ctk = (CompoundToken)iden;
                    field.Type   = ctk.TypeName;
                    field.Length = ctk.Content;
                }
                break;

                case MySqlTokenName.FieldType:
                {
                    field.Type = iden.OriginalText;
                }
                break;

                case MySqlTokenName.Unsigned:
                {
                    field.HasUnsign = true;
                }
                break;

                case MySqlTokenName.CharacterSet:
                {
                    tkstream.ReadNext();
                    tkstream.ReadNext();
                    Token idenNext = tkstream.CurrentToken;
                    if (idenNext.TokenName == MySqlTokenName.Unknown)
                    {
                        field.CharacterSet = idenNext.OriginalText;
                    }
                }
                break;

                case MySqlTokenName.Not:
                {
                    tkstream.ReadNext();
                    Token idenNext = tkstream.CurrentToken;
                    field.Not = idenNext.OriginalText;
                }
                break;

                case MySqlTokenName.Default:
                {
                    tkstream.ReadNext();
                    Token    idenNext = tkstream.CurrentToken;
                    string[] dfValue  = idenNext.OriginalText.Split(new string[] { "'" }, StringSplitOptions.RemoveEmptyEntries);
                    if (dfValue.Length > 0)
                    {
                        field.FieldDefault = dfValue[0];
                    }
                    else
                    {
                        field.FieldDefault = "";
                    }
                }
                break;

                case MySqlTokenName.Unknown:
                {
                    field.Other = iden.OriginalText;
                }
                break;

                case MySqlTokenName.PrimaryKey:
                {
                    tkstream.ReadNext();
                    key.IndexKind = "PRIMARY";
                }
                    goto case MySqlTokenName.IndexKey;

                case MySqlTokenName.UniqueKey:
                {
                    tkstream.ReadNext();
                    key.IndexKind = "UNIQUE";
                }
                    goto case MySqlTokenName.IndexKey;

                case MySqlTokenName.FulltextKey:
                {
                    tkstream.ReadNext();
                    key.IndexKind = "FULLTEXT";
                }
                    goto case MySqlTokenName.IndexKey;

                case MySqlTokenName.IndexKey:
                {
                    tkstream.ReadNext();
                    if (key.IndexKind == null)
                    {
                        key.IndexKind = "INDEX";
                    }
                    if (key.IndexKind == "PRIMARY")
                    {
                        string[] pkName = tkstream.CurrentToken.OriginalText.Split(new char[] { '`', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
                        table.PrimaryKey = pkName[0];
                    }
                    Token    idenNext = tkstream.CurrentToken;
                    string[] ndName   = idenNext.OriginalText.Split(new char[] { '`', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
                    key.IndexName = ndName[0];

                    key.IndexColumns = new List <string>();

                    if (key.IndexKind != "PRIMARY")
                    {
                        tkstream.ReadNext();
                    }
                    if (tkstream.CurrentToken.OriginalText.StartsWith("("))
                    {
                        string[] temp = tkstream.CurrentToken.OriginalText.Split('(');
                        string   pos  = temp[1];

                        while (!pos.EndsWith(")"))
                        {
                            string[] keyName = pos.Split(new char[] { '`' }, StringSplitOptions.RemoveEmptyEntries);
                            key.IndexColumns.Add(keyName[0]);
                            tkstream.ReadNext();
                            pos = tkstream.CurrentToken.OriginalText;
                        }
                        if (pos.EndsWith(")"))
                        {
                            string[] temp2   = pos.Split(')');
                            string[] keyName = temp2[0].Split(new char[] { '`' }, StringSplitOptions.RemoveEmptyEntries);
                            key.IndexColumns.Add(keyName[0]);
                            break;
                        }
                    }
                }
                break;

                case MySqlTokenName.Using:
                {
                    tkstream.ReadNext();
                    Token idenNext = tkstream.CurrentToken;
                    table.Using = idenNext.OriginalText;
                }
                break;

                case MySqlTokenName.Auto_Increment:
                {
                    field.HasAuto = true;
                }
                break;

                default:
                    field.Other = iden.OriginalText;
                    break;
                }
            }
            break;
            }

            tkstream.ReadNext();
        }