Example #1
0
        public static SqlTableDefinition GetTableDefinition(this Sqlite3SchemaRow schema)
        {
            Dictionary <Sqlite3SchemaRow, SqlTableDefinition> definitionCache = schema.Database.GetProperty(SqlCacheKey, () => new Dictionary <Sqlite3SchemaRow, SqlTableDefinition>());

            if (!definitionCache.TryGetValue(schema, out SqlTableDefinition definition))
            {
                if (!SqlParser.TryParse(schema.Sql, out definition))
                {
                    definitionCache[schema] = null;
                }
                else
                {
                    definitionCache[schema] = definition;
                }
            }

            if (definition == null)
            {
                throw new Exception();
            }

            SqlTableDefinition def = definition;

            return(def);
        }
Example #2
0
        public static bool TryGetValueByName(this Sqlite3Row row, string columnName, out object value)
        {
            value = null;

            SqlTableDefinition tableDefinition = row.Table.GetTableDefinition();

            if (!tableDefinition.TryGetColumn(columnName, out SqlTableColumn column))
            {
                return(false);
            }

            if (row.ColumnData.Length <= column.Ordinal)
            {
                return(false);
            }

            // Special case for row-id
            if (tableDefinition.RowIdColumn != null && columnName.Equals(tableDefinition.RowIdColumn.Name, StringComparison.OrdinalIgnoreCase))
            {
                // Return the row-id
                value = row.RowId;
                return(true);
            }

            value = row.ColumnData[column.Ordinal];
            return(true);
        }
Example #3
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);
        }