Пример #1
0
        public static void CreateTable(this SurlyDatabase database, string tableName, string line)
        {
            Set(Yellow);

            if (database.Tables.Any(x => x.Name == tableName))
            {
                WriteLine($"\n\tTable {tableName} already exists. Please select a different table name.", Red);
                return;
            }

            var tuples = string.Empty;

            try
            {
                tuples = line.Substring(line.IndexOf("(", StringComparison.Ordinal) + 1,
                                        line.IndexOf(")", StringComparison.Ordinal) - line.IndexOf("(", StringComparison.Ordinal) - 1);
            }
            catch (Exception)
            {
                WriteLine("\n\tSyntax error", Red);
            }

            Set(Green);

            var tableCreated = false;

            foreach (var tuple in tuples.Split(','))
            {
                var parts = tuple.Trim().Split(' ');
                int numMax;

                if (!database.ValidTuple(tableName, parts))
                {
                    return;
                }

                if (!tableCreated)
                {
                    database.Tables.AddLast(new SurlyTable(tableName));
                    tableCreated = true;
                    WriteLine($"\n\tCreating table: {tableName}", Cyan);
                }

                database.Tables.Last.Value.Schema.AddLast(new SurlyAttributeSchema
                {
                    Name    = parts[0],
                    Type    = parts[1].ToSurlyType(),
                    Maximum = int.TryParse(parts[2], out numMax) ? numMax : 0
                });
            }

            database.Tables.Last.Value.Schema.AddFirst(new SurlyAttributeSchema
            {
                Name    = "Id",
                Type    = typeof(int),
                Maximum = 3
            });

            Console.WriteLine();
        }
Пример #2
0
        public static SurlyTableResponse GetTable(this SurlyDatabase database, string tableName)
        {
            var table = database.Tables.SingleOrDefault(x => x.Name == tableName.ToUpper());

            if (table != null)
            {
                return new SurlyTableResponse {
                           Table = table
                }
            }
            ;

            var projection = SurlyProjections.GetInstance().Projections
                             .SingleOrDefault(x => x.ProjectionName == tableName.ToUpper());

            if (projection != null)
            {
                return(new SurlyTableResponse
                {
                    Table = new SurlyTable
                    {
                        Name = projection.ProjectionName,
                        Schema = projection.AttributeNames,
                        Tuples = projection.Tuples,
                    },
                    IsProjection = true,
                    HideIndexes = projection.HideIndex
                });
            }

            WriteLine($"\n\t{tableName.ToUpper()} was not found.", Red);

            return(null);
        }
Пример #3
0
        public static void ExecuteQuery(this SurlyDatabase database, string line)
        {
            Set(Cyan);

            if (line.ToUpper().Contains("PROJECT"))
            {
                database.Project(line);
                return;
            }
            if (line.ToUpper().Contains("VIEW"))
            {
                database.CreateView(line);
                return;
            }
            if (line.ToUpper().Contains("SELECT"))
            {
                database.Select(line);
                return;
            }
            if (line.ToUpper().Contains("JOIN"))
            {
                database.Join(line);
                return;
            }
            if (line.ToUpper().Contains("PRINT CATALOG"))
            {
                database.PrintCatalog();
                return;
            }

            var steps = line.Split(' ').ToList();

            switch (steps[0].ToUpper())
            {
            case "RELATION":
                database.CreateTable(steps[1].ToUpper(), line);
                break;

            case "INSERT":
                database.AddTuples(steps[1].ToUpper(), line);
                break;

            case "PRINT":
                database.Print(line);
                break;

            case "DELETE":
                database.Delete(steps[1], line);
                break;

            case "DESTROY":
                database.DestroyTable(steps[1].Replace(";", "").ToUpper(), line);
                break;

            default:
                WriteLine($"\n\tUnknown command: {steps[0].ToUpper()}, please see help for recognized commands", Red);
                break;
            }
        }
Пример #4
0
        public static void PrintTables(this SurlyDatabase database, IList <SurlyTableResponse> tables)
        {
            foreach (var response in tables)
            {
                if (response == null)
                {
                    continue;
                }

                WriteLine($"\n\t{response.Table.Name}");
                Console.WriteLine();

                Console.Write($"  {(response.IsProjection ? Id.PadRight(8) : "")}");

                var widthReferences = new List <int>();

                foreach (var schema in response.Table.Schema)
                {
                    var tableWidth = Math.Max(schema.Maximum + 2, schema.Name.Length + 2);

                    Console.Write($"{schema.Name.PadRight(tableWidth)}");

                    widthReferences.Add(tableWidth);
                }

                var count = 1;

                WriteLine("\n" + string.Empty.PadRight(widthReferences.Sum() + 10, '='), Green);

                Set(Yellow);

                foreach (var tableTuple in response.Table.Tuples)
                {
                    var index = 0;

                    Console.Write($"  {(response.IsProjection ? count.ToString().PadRight(8) : "")}");

                    foreach (var attribute in tableTuple)
                    {
                        try
                        {
                            Console.Write($"{attribute.Value.ToString().PadRight(widthReferences[index])}");
                            index++;
                        }
                        catch (Exception)
                        {
                            Console.Write($"{attribute.Value.ToString().PadRight(8)}");
                            return;
                        }
                    }

                    Console.WriteLine();

                    count++;
                }
                Console.WriteLine();
            }
        }
Пример #5
0
        public static void Delete(this SurlyDatabase database, string tableName, string line)
        {
            if (line.ToUpper().Contains("WHERE"))
            {
                database.DeleteTableWithConditions(tableName, line);
                return;
            }

            database.DeleteTable(tableName.Replace(";", "").ToUpper(), line);
        }
Пример #6
0
        public static SurlyProjection Validate(SurlyDatabase database, SurlyProjection projection)
        {
            var tableResponse = database.GetTable(projection.TableName);

            if (tableResponse == null)
            {
                return(null);
            }

            var validAttributes =
                projection.AttributeNames.All(attributeName => tableResponse.Table.Schema.Any(x => x.Name == attributeName.Name));

            if (!validAttributes)
            {
                WriteLine("\tColumn name(s) not found.\n", Red);
                return(null);
            }

            bool existingProjection;

            do
            {
                existingProjection = Projections.Projections.Any(x => x.ProjectionName == projection.ProjectionName);

                //Rename projection
                if (!existingProjection)
                {
                    continue;
                }

                Write(
                    $"\nProjection {projection.ProjectionName.ToUpper()} already exists, enter new projection name: ",
                    Yellow);

                string newProjectionName;
                do
                {
                    newProjectionName = Console.ReadLine();

                    if (string.IsNullOrWhiteSpace(newProjectionName))
                    {
                        Write("Please enter a valid projection name: ", Red);
                    }
                } while (string.IsNullOrWhiteSpace(newProjectionName));

                projection.ProjectionName = newProjectionName.ToUpper();

                existingProjection = Projections.Projections.Any(x => x.ProjectionName == projection.ProjectionName);
            } while (existingProjection);

            return(projection);
        }
Пример #7
0
        public static void DeleteTable(this SurlyDatabase database, string tableName, string line)
        {
            var tableResponse = database.GetTable(tableName);

            if (tableResponse.Table == null)
            {
                return;
            }

            tableResponse.Table.Tuples.Clear();

            WriteLine($"\n\tDeleted {tableName.ToUpper()}", Green);
        }
Пример #8
0
        public static void PrintDatabase(this SurlyDatabase database)
        {
            const string id = "Id";

            WriteLine("\n\n\t*** FULL DATABASE ***\n");

            if (database.Tables.Count == 0)
            {
                WriteLine("\t<--EMPTY-->\n\n", Red);
            }

            foreach (var table in database.Tables)
            {
                WriteLine($"\n\tTable: {table.Name}\n");

                Console.Write($"  ");//{id.PadRight(8)}");

                var widthReferences = new List <int>();

                foreach (var schema in table.Schema)
                {
                    var tableWidth = Math.Max(schema.Maximum + 2, schema.Name.Length + 2);

                    Console.Write($"{schema.Name.PadRight(tableWidth)}");
                    widthReferences.Add(tableWidth);
                }

                var count = 1;

                WriteLine("\n" + string.Empty.PadRight(100, '='), Green);

                Set(Yellow);

                foreach (var tableTuple in table.Tuples)
                {
                    var index = 0;
                    Console.Write($"  ");//{count.ToString().PadRight(8)}");

                    foreach (var attribute in tableTuple)
                    {
                        Console.Write($"{attribute.Value.ToString().PadRight(widthReferences[index])}");
                        index++;
                    }

                    Console.WriteLine();

                    count++;
                }
                Console.WriteLine();
            }
        }
Пример #9
0
        public static void DeleteTableWithConditions(this SurlyDatabase database, string tableName, string line)
        {
            var tableResponse = database.GetTable(tableName);

            if (tableResponse.Table == null)
            {
                return;
            }

            string[] conditions = null;
            try
            {
                conditions = new Regex("where (.+);", RegexOptions.IgnoreCase)
                             .Match(line)
                             .Groups[1]
                             .Captures[0]
                             .ToString()
                             .ToUpper()
                             .Split(' ');
            }
            catch (Exception)
            {
                WriteLine("Invalid syntax, please see help.", Red);
            }

            if (conditions == null)
            {
                return;
            }
            var success = false;

            tableResponse.Table.Tuples.ToList().ForEach(tableRow =>
            {
                var match = OperatorHelper.Chain(tableRow, true, conditions, 0);

                if (match)
                {
                    tableResponse.Table.Tuples.Remove(tableRow);
                    success = true;
                }
            });

            if (success)
            {
                WriteLine("\n\tSuccess", Green);
            }
            else
            {
                WriteLine("No rows affected.");
            }
        }
Пример #10
0
        public static void DestroyTable(this SurlyDatabase database, string tableName, string line)
        {
            var tableResponse = database.GetTable(tableName);

            if (tableResponse.IsProjection)
            {
                var projection = SurlyProjections.GetInstance().Projections.Single(x => x.ProjectionName == tableName);
                SurlyProjections.GetInstance().Projections.Remove(projection);
            }
            else
            {
                database.Tables.Remove(tableResponse.Table);
            }

            WriteLine($"\n\tDestroyed {tableName.ToUpper()}", Green);
        }
Пример #11
0
        public static void Print(this SurlyDatabase database, string line)
        {
            var query = line
                        .Replace(",", "")
                        .Replace(";", "")
                        .Split(' ')
                        .ToList();

            query.RemoveAt(0);

            var tablesQueryResponse = query
                                      .Select(database.GetTable)
                                      .ToList();

            database.PrintTables(tablesQueryResponse);
        }
Пример #12
0
        public static void AddTuples(this SurlyDatabase database, string tableName, string line)
        {
            if (database.Tables.All(x => x.Name != tableName))
            {
                WriteLine($"\n\tTable {tableName.ToUpper()} was not found.", Red);
                return;
            }

            var tuples = string.Format(new SurlyFormatter(), "{0:insert}", line).SplitValues();
            var table  = database.Tables.Single(x => x.Name == tableName);
            var schema = table.Schema.ToArray();

            var newTuple = new LinkedList <SurlyAttribute>();

            newTuple.AddLast(new SurlyAttribute
            {
                Name  = "Id",
                Value = table.Tuples.Count + 1
            });

            for (var i = 0; i < schema.Length; i++)
            {
                if (schema[i].Name == "Id")
                {
                    continue;
                }

                newTuple.AddLast(new SurlyAttribute
                {
                    Value = tuples[i - 1].To(schema[i].Type, schema[i].Maximum),
                    Name  = schema[i].Name
                });
            }


            if (newTuple.Count <= 0)
            {
                return;
            }

            table.Tuples.AddLast(newTuple);

            WriteLine($"\tRow added to {tableName.ToUpper()}", Green);
        }
Пример #13
0
        public static void Join(this SurlyDatabase database, string query)
        {
            var projection = CreateJoinProjection(database, query);

            if (projection == null)
            {
                WriteLine("\n\tError adding projection", Red);
                return;
            }

            if (ProjectionsContainer.Projections.Any(x => x.ProjectionName == projection.ProjectionName))
            {
                WriteLine(
                    $"\n\tProjection {projection.ProjectionName.ToUpper()} already exists, please try a different name.",
                    Red);
                return;
            }

            ProjectionsContainer.Projections.AddLast(projection);
            WriteLine($"\n\t{projection.ProjectionName.ToUpper()} build successful", Green);
        }
Пример #14
0
        public static bool ValidTuple(this SurlyDatabase database, string tableName, string[] parts)
        {
            if (parts.Any(string.IsNullOrWhiteSpace))
            {
                WriteLine("Invalid syntax in schema definition", Red);
                return(false);
            }

            var table = database.Tables.SingleOrDefault(x => x.Name == tableName);

            if (table != null && table.Schema
                .Any(x => x.Name == parts?[0]))
            {
                WriteLine($"{parts[0]} already exists. Please select a different attribute name.", Red);
                return(false);
            }

            try
            {
                if (parts[1].ToSurlyType() == null)
                {
                    WriteLine($"{parts[1]} is not a recognized type.", Red);
                    return(false);
                }
            }
            catch (Exception)
            {
                if (parts.Length < 2)
                {
                    WriteLine("Invalid syntax, please reference Help section for correct syntax", Red);
                    return(false);
                }

                WriteLine($"{parts[1]} is not a recognized type.", Red);
                return(false);
            }
            return(true);
        }
Пример #15
0
        public static void PrintCatalog(this SurlyDatabase database)
        {
            const string idHeader   = "Id";
            const string nameHeader = "Name";
            const string typeHeader = "Type";
            const string maxHeader  = "Maximum";

            WriteLine("\n\n\t*** CURRENT CATALOG ***\n");

            if (database.Tables.Count == 0)
            {
                WriteLine("\t<--EMPTY-->\n\n", Red);
            }

            foreach (var table in database.Tables)
            {
                var count = 1;

                WriteLine($"\n\tTable: {table.Name}", Blue);

                Console.WriteLine();

                WriteLine(
                    $"  {idHeader.PadRight(5)}{nameHeader.PadRight(20)}{typeHeader.PadRight(20)}{maxHeader}",
                    Yellow);

                WriteLine($"{string.Empty.PadRight(100, '=')}");

                foreach (var schema in table.Schema)
                {
                    WriteLine(
                        $"  {count.ToString().PadRight(5)}{schema.Name.PadRight(20)}{schema.Type.Name.PadRight(20)}{schema.Maximum}",
                        Green);
                    count++;
                }
            }
        }
Пример #16
0
        public static void Select(this SurlyDatabase database, string query)
        {
            _resultSet = new LinkedList <LinkedList <SurlyAttribute> >();
            string tableName, conditions, projectionName = null;
            var    printProjection = false;

            try
            {
                try
                {
                    projectionName = new Regex("(\\w+) = select", RegexOptions.IgnoreCase)
                                     .Match(query)
                                     .Groups[1]
                                     .Captures[0]
                                     .ToString()
                                     .ToUpper();
                }
                catch (Exception)
                {
                    printProjection = true;
                }

                tableName = new Regex("select (\\w+) where", RegexOptions.IgnoreCase)
                            .Match(query)
                            .Groups[1]
                            .Captures[0]
                            .ToString()
                            .ToUpper();

                conditions = new Regex("where (.+);", RegexOptions.IgnoreCase)
                             .Match(query)
                             .Groups[1]
                             .Captures[0]
                             .ToString()
                             .ToUpper();
            }
            catch (Exception)
            {
                WriteLine("Invalid SELECT syntax, please see help", Red);
                return;
            }

            var tableResponse = database.GetTable(tableName);

            if (tableResponse.Table == null)
            {
                WriteLine($"{tableName.ToUpper()} not found.", Red);
                return;
            }

            if (!printProjection &&
                SurlyProjections.GetInstance().Projections.Any(x => x.ProjectionName.ToUpper() == projectionName?.ToUpper()))
            {
                WriteLine($"\n\t{projectionName?.ToUpper()} already exists, please choose a different name", Red);
                return;
            }

            var conditionSteps = conditions.Split(' ').ToList();

            tableResponse.Table.Tuples.ToList().ForEach(tableRow =>
            {
                var valid = OperatorHelper.Chain(tableRow, true, conditionSteps.ToArray(), 0);

                if (valid)
                {
                    var trimmedRow = new LinkedList <SurlyAttribute>(tableRow);

                    var rowId = trimmedRow.SingleOrDefault(x => x.Name == "Id");
                    trimmedRow.Remove(rowId);

                    _resultSet.AddLast(trimmedRow);
                }
            });

            if (_resultSet.Count == 0)
            {
                WriteLine("\n\tQuery yielded no results.", Yellow);
                return;
            }

            var schema = new LinkedList <SurlyAttributeSchema>(tableResponse.Table.Schema);
            var id     = schema.SingleOrDefault(x => x.Name == "Id");

            schema.Remove(id);

            if (printProjection)
            {
                var response = new SurlyTableResponse
                {
                    Table = new SurlyTable
                    {
                        Schema = schema,
                        Name   = "Results",
                        Tuples = _resultSet
                    },
                    //HideIndexes = true
                };

                database.PrintTables(new List <SurlyTableResponse> {
                    response
                });

                return;
            }

            SurlyProjections.GetInstance().Projections.AddLast(new SurlyProjection
            {
                AttributeNames = schema,
                HideIndex      = true,
                ProjectionName = projectionName,
                TableName      = tableResponse.Table.Name,
                Tuples         = _resultSet
            });

            WriteLine($"\n\t{projectionName.ToUpper()} build successful.", Green);
        }
Пример #17
0
        //In Development...
        public static void CreateView(this SurlyDatabase database, string query)
        {
            WriteLine("The VIEW command is still in development, please try again later.", Yellow);
            return;

            //If the syntax is wrong, the regex with throw an exception
            try
            {
                var projectionNameRegex = new Regex("(\\w+) =").Match(query);

                var projectionName = projectionNameRegex
                                     .Groups[1]
                                     .Captures[0]
                                     .ToString()
                                     .ToUpper()
                                     .Trim();

                var attributeNamesRegex = new Regex("view (.+) from", RegexOptions.IgnoreCase)
                                          .Match(query)
                                          .Groups[1]
                                          .Captures[0]
                                          .ToString()
                                          .ToUpper()
                                          .Split(',')
                                          .ToList();

                var attributeNames = new LinkedList <string>();

                foreach (var name in attributeNamesRegex)
                {
                    attributeNames.AddLast(name.Trim());
                }

                var tableName = new Regex("(\\w+);", RegexOptions.IgnoreCase)
                                .Match(query)
                                .Groups[1]
                                .Captures[0]
                                .ToString()
                                .ToUpper()
                                .Trim();

                //Verify tables/attributes exist
                var projection = new SurlyProjection
                {
                    ProjectionName = projectionName,
                    TableName      = tableName,
                    // AttributeNames = attributeNames
                };

                projection = Validate(database, projection);

                if (projection == null)
                {
                    return;
                }

                //Add projection definition
                Projections.Projections.AddLast(projection);

                WriteLine($"\n\tNew view added: {projection.ProjectionName}", Green);
            }
            catch (Exception)
            {
                Console.WriteLine("Invalid syntax for VIEW, see help.");
            }
        }
Пример #18
0
        public static SurlyProjection CreateJoinProjection(SurlyDatabase database, string query)
        {
            string        projectionName;
            List <string> tableNamesRegex;

            string[] joinCondition;

            try
            {
                var projectionNameRegex = new Regex("(\\w+) =").Match(query);

                projectionName = projectionNameRegex
                                 .Groups[1]
                                 .Captures[0]
                                 .ToString()
                                 .ToUpper()
                                 .Trim();

                tableNamesRegex = new Regex("join (.+) on", RegexOptions.IgnoreCase)
                                  .Match(query)
                                  .Groups[1]
                                  .Captures[0]
                                  .ToString()
                                  .ToUpper()
                                  .Split(',')
                                  .ToList();

                joinCondition = new Regex(" on (.+);", RegexOptions.IgnoreCase)
                                .Match(query)
                                .Groups[1]
                                .Captures[0]
                                .ToString()
                                .ToUpper()
                                .Trim()
                                .Split(' ');
            }
            catch (Exception)
            {
                Console.WriteLine("\n\tInvalid syntax for JOIN, see help.");
                return(null);
            }

            var tableNames     = new LinkedList <string>();
            var tables         = new List <SurlyTable>();
            var attributeNames = new LinkedList <SurlyAttributeSchema>();
            var resultSet      = new LinkedList <LinkedList <SurlyAttribute> >();

            foreach (var tableName in tableNamesRegex)
            {
                tableNames.AddLast(tableName.Trim());

                var tempTableResponse = database.GetTable(tableName.Trim());

                if (tempTableResponse.Table == null)
                {
                    WriteLine($"{tableName.Trim()} not found", Red);
                    return(null);
                }

                attributeNames.Combine(new LinkedList <SurlyAttributeSchema>(tempTableResponse.Table.Schema));

                tables.Add(tempTableResponse.Table);
            }

            var leftTableRows  = new LinkedList <LinkedList <SurlyAttribute> >(tables[0].Tuples).ToList();
            var rightTableRows = new LinkedList <LinkedList <SurlyAttribute> >(tables[1].Tuples);

            leftTableRows.ForEach(
                row => resultSet = resultSet.Combine(row.ApplyCondition(rightTableRows, joinCondition)));

            var projection = new SurlyProjection
            {
                ProjectionName = projectionName.ToUpper(),
                TableName      = projectionName.ToUpper(),
                AttributeNames = attributeNames,
                Tuples         = resultSet,
                HideIndex      = true
            };

            return(projection);
        }
Пример #19
0
        public static void Project(this SurlyDatabase database, string query)
        {
            try
            {
                var projectionNameRegex = new Regex("(\\w+) =").Match(query);

                var projectionName = projectionNameRegex
                                     .Groups[1]
                                     .Captures[0]
                                     .ToString()
                                     .ToUpper()
                                     .Trim();

                var attributeNamesRegex = new Regex("project (.+) from", RegexOptions.IgnoreCase)
                                          .Match(query)
                                          .Groups[1]
                                          .Captures[0]
                                          .ToString()
                                          .ToUpper()
                                          .Split(',')
                                          .ToList();

                var attributeNames = new LinkedList <string>();

                foreach (var name in attributeNamesRegex)
                {
                    attributeNames.AddLast(name.Trim());
                }

                var tableName = new Regex("(\\w+);", RegexOptions.IgnoreCase)
                                .Match(query)
                                .Groups[1]
                                .Captures[0]
                                .ToString()
                                .ToUpper()
                                .Trim();

                //Verify tables/attributes exist
                var projection = new SurlyProjection
                {
                    ProjectionName = projectionName,
                    TableName      = tableName,
                    AttributeNames = new LinkedList <SurlyAttributeSchema>(),
                    Tuples         = new LinkedList <LinkedList <SurlyAttribute> >()
                };

                projection = Validate(database, projection);

                //Clone selected data to new projection
                var schemaDefinition = new LinkedList <SurlyAttributeSchema>();
                var castedList       = new LinkedList <LinkedList <SurlyAttribute> >();

                var tableResponse = database.GetTable(tableName);

                foreach (var attributeName in attributeNames)
                {
                    var selectedTuplesSchemata = tableResponse.Table.Schema.Single(x => x.Name == attributeName);

                    schemaDefinition.AddLast(new SurlyAttributeSchema
                    {
                        Maximum = selectedTuplesSchemata.Maximum,
                        Name    = selectedTuplesSchemata.Name
                    });
                }

                var selectedTuples = tableResponse.Table.Tuples
                                     .Select(x => x
                                             .Where(y => attributeNames
                                                    .Any(a => a == y.Name)));

                foreach (var tupleList in selectedTuples)
                {
                    var list = new LinkedList <SurlyAttribute>();

                    foreach (var attribute in tupleList)
                    {
                        list.AddLast(attribute);
                    }
                    castedList.AddLast(list);
                }

                projection.AttributeNames = schemaDefinition;
                projection.Tuples         = castedList;

                //Add projection
                Projections.Projections.AddLast(projection);

                WriteLine($"\n\tNew projection added: {projection.ProjectionName}", Green);
            }
            catch (Exception)
            {
                Console.WriteLine("Invalid syntax for PROJECT, see help.");
            }
        }