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); }