Exemplo n.º 1
0
        public static bool TryParse(string sql, out SqlTableDefinition tableDefinition)
        {
            tableDefinition = null;

            // Parse out the SQL into series of column creation statements
            Result <TokenList <SqlToken> > tokens = SqlTokenizer.Tokenizer.TryTokenize(sql);

            if (!tokens.HasValue)
            {
                return(false);
            }

            if (!TryParseTokenList(tokens.Value, out SqlNode node))
            {
                return(false);
            }

            // Check if this is a create table
            if (!node.Is(0, "CREATE") || !node.Is(1, "TABLE") || !node.Is(2, SqlToken.String) || !node.IsGroup(3))
            {
                return(false);
            }

            SqlTableDefinition def = new SqlTableDefinition(node.GetString(2));

            SqlNode        columns = node.GetGroup(3);
            int            primaryKeyComponents = 0;
            SqlTableColumn primaryKeyColumn     = null;

            for (int columnIndex = 0; columnIndex < columns.Children.Count; columnIndex++)
            {
                SqlNode columnSet = columns.Children[columnIndex];
                if (!columnSet.Children.Any() || !columnSet.Children.First().Is(SqlToken.String))
                {
                    continue;
                }

                string firstToken = columnSet.Children.First().GetString();

                bool   isConstraint = SqlKeywords.NonColumnKeywords.Contains(firstToken);
                string name;
                if (isConstraint)
                {
                    if (columnSet.Is(0, "PRIMARY") && columnSet.Is(1, "KEY") && columnSet.IsGroup(2))
                    {
                        SqlNode pkColumns = columnSet.GetGroup(2);

                        foreach (SqlNode pkColumn in pkColumns.Children)
                        {
                            if (pkColumn.Is(SqlToken.String))
                            {
                                name = pkColumn.GetString();
                            }
                            else if (pkColumn.Is(0, SqlToken.String))
                            {
                                name = pkColumn.GetString(0);
                            }
                            else
                            {
                                return(false);
                            }

                            if (!def.TryGetColumn(name, out SqlTableColumn columnObject))
                            {
                                continue;
                            }

                            columnObject.IsPartOfPrimaryKey = true;

                            primaryKeyComponents++;
                            primaryKeyColumn = columnObject;
                        }
                    }

                    continue;
                }

                name = columnSet.GetString(0);
                string[] typeStrings = columnSet.Children.Skip(1).Where(s => s.Is(SqlToken.String))
                                       .Select(s => s.GetString()).ToArray();

                // Defaults
                Type     identifiedType        = typeof(byte[]);
                string[] identifiedTypeStrings = typeStrings;

                foreach ((string[] words, Type type)candidate in SqlKeywords.TypeKeywords)
                {
                    if (!typeStrings.Take(candidate.words.Length).SequenceEqual(candidate.words))
                    {
                        continue;
                    }

                    identifiedType        = candidate.type;
                    identifiedTypeStrings = candidate.words;
                    break;
                }

                SqlTableColumn sqlTableColumn = new SqlTableColumn(columnIndex, name, string.Join(" ", identifiedTypeStrings), identifiedType);
                def.AddColumn(sqlTableColumn);

                // Is this a primary key?
                if (typeStrings.Contains("PRIMARY", StringComparer.OrdinalIgnoreCase) &&
                    typeStrings.Contains("KEY", StringComparer.OrdinalIgnoreCase))
                {
                    sqlTableColumn.IsPartOfPrimaryKey = true;
                    primaryKeyComponents++;
                    primaryKeyColumn = sqlTableColumn;
                }
            }

            // Identify row-id substitutes
            if (primaryKeyComponents == 1 && primaryKeyColumn.DetectedType == typeof(long))
            {
                def.ConfigureRowIdColumn(primaryKeyColumn);
            }

            tableDefinition = def;
            return(true);
        }
 internal void ConfigureRowIdColumn(SqlTableColumn column)
 {
     RowIdColumn = column;
 }
 public bool TryGetColumn(string name, out SqlTableColumn column)
 {
     return(_columnIndex.TryGetValue(name, out column));
 }
 internal void AddColumn(SqlTableColumn column)
 {
     _columnIndex.Add(column.Name, column);
     _columns.Add(column);
 }