Beispiel #1
0
        public void GetSingleKeywordArgumentGeneric_ArgumentNameIsPresentButArgumentIsOfWrongType_ThrowsTinyLispException(bool absenceIsAllowed)
        {
            // Arrange
            var formText = "(foo one two :key three :your-key \"some string\")";

            var tokens     = _lexer.Lexize(formText);
            var reader     = new TinyLispPseudoReader();
            var pseudoList = reader.Read(tokens).Single().AsPseudoList();

            // Act
            var ex = Assert.Throws <TinyLispException>(() =>
                                                       pseudoList.GetSingleKeywordArgument <Symbol>(":your-key", absenceIsAllowed));

            // Assert
            Assert.That(ex.Message, Is.EqualTo("Argument for ':your-key' was found, but it appears to be of type 'TauCode.Parsing.TinyLisp.Data.StringAtom' instead of expected type 'TauCode.Parsing.TinyLisp.Data.Symbol'."));
        }
        public void Build_EmptySeq_ThrowsTinyLispException()
        {
            // Arrange
            var lisp = "(defblock :name foo :is-top t (seq))";

            var          tokens     = _lexer.Lexize(lisp);
            var          reader     = new TinyLispPseudoReader();
            var          pseudoList = reader.Read(tokens);
            ITreeBuilder builder    = new TreeBuilder();
            INodeFactory factory    = new SqlNodeFactory();

            // Act
            var ex = Assert.Throws <TinyLispException>(() => builder.Build(factory, pseudoList));

            // Assert
            Assert.That(ex.Message, Is.EqualTo("Free arguments not found."));
        }
Beispiel #3
0
        public void GetSingleArgumentAsBool_ItemIsOfInvalidType_ThrowsTinyLispException(string badItem)
        {
            // Arrange
            var formText = $"(foo one two :key {badItem} one two \"three\" :your-key \"some string\")";

            var tokens     = _lexer.Lexize(formText);
            var reader     = new TinyLispPseudoReader();
            var pseudoList = reader.Read(tokens).Single().AsPseudoList();

            // Act
            var ex = Assert.Throws <TinyLispException>(() => pseudoList.GetSingleArgumentAsBool(":key"));

            // Assert
            var wrongItem = reader.Read(_lexer.Lexize(badItem)).Single().ToString();

            Assert.That(ex.Message, Is.EqualTo($"Keyword ':key' was found, but it appeared to be '{wrongItem}' instead of NIL or T."));
        }
Beispiel #4
0
        public void GetAllKeywordArguments_ArgumentIsNotKeyword_ThrowsArgumentException(string badKeywordName)
        {
            // Arrange
            var formText = "(foo one two :key one two \"three\" :your-key \"some string\")";

            var tokens     = _lexer.Lexize(formText);
            var reader     = new TinyLispPseudoReader();
            var pseudoList = reader.Read(tokens).Single().AsPseudoList();


            // Act
            var ex = Assert.Throws <ArgumentException>(() => pseudoList.GetAllKeywordArguments(badKeywordName));

            // Assert
            Assert.That(ex.Message, Does.StartWith($"'{badKeywordName}' is not a valid keyword."));
            Assert.That(ex.ParamName, Is.EqualTo("argumentName"));
        }
Beispiel #5
0
        public void GetSingleKeywordArgument_ArgumentNameIsPresentButIsAtEnd_ThrowsTinyLispException(
            bool absenceIsAllowed)
        {
            // Arrange
            var formText = "(foo one two :key three :your-key)";

            var tokens     = _lexer.Lexize(formText);
            var reader     = new TinyLispPseudoReader();
            var pseudoList = reader.Read(tokens).Single().AsPseudoList();

            // Act
            var ex = Assert.Throws <TinyLispException>(() =>
                                                       pseudoList.GetSingleKeywordArgument(":your-key", absenceIsAllowed));

            // Assert
            Assert.That(ex.Message, Is.EqualTo("Keyword ':your-key' was found, but at the end of the list."));
        }
Beispiel #6
0
        private INode BuildRoot()
        {
            var    nodeFactory = new SQLiteNodeFactory();
            var    input       = this.GetType().Assembly.GetResourceText("sql-sqlite-grammar.lisp", true);
            ILexer lexer       = new TinyLispLexer();
            var    tokens      = lexer.Lexize(input);

            var reader = new TinyLispPseudoReader();
            var list   = reader.Read(tokens);

            ITreeBuilder builder = new TreeBuilder();
            var          root    = builder.Build(nodeFactory, list);

            this.ChargeRoot(root);

            return(root);
        }
Beispiel #7
0
        public void Read_SqlGrammar_ProducesExpectedResult()
        {
            // Arrange
            var input = this.GetType().Assembly.GetResourceText("sql-grammar.lisp", true);


            var tokens = _lexer.Lexize(input);

            var reader = new TinyLispPseudoReader();

            // Act
            var list = reader.Read(tokens);

            // Assert
            Assert.That(list, Has.Count.EqualTo(10));

            var expectedTexts = this.GetType().Assembly
                                .GetResourceText("sql-grammar-expected.lisp", true)
                                .Split(";;; splitting comment", StringSplitOptions.RemoveEmptyEntries)
                                .Select(x => x.Trim())
                                .ToList();

            Assert.That(expectedTexts, Has.Count.EqualTo(list.Count()));

            for (int i = 0; i < list.Count; i++)
            {
                var actual = list[i].ToString();

                var alteredActual = actual
                                    .Replace(" )", ")")
                                    .Replace(" )", ")")
                                    .Replace(" (", "(")
                                    .Replace(" (", "(");

                var expected = expectedTexts[i]
                               .Replace(Environment.NewLine, " ")
                               .Replace("\t", "")
                               .Replace(" )", ")")
                               .Replace(" )", ")")
                               .Replace(" (", "(")
                               .Replace(" (", "(");

                Assert.That(alteredActual, Is.EqualTo(expected).IgnoreCase);
            }
        }
Beispiel #8
0
        public void Read_UnsupportedToken_ThrowsTinyLispException()
        {
            // Arrange
            var form = "(some good form)";

            var tokens = _lexer.Lexize(form);

            var badToken = new EnumToken <int>(1488, Position.Zero, 4);

            tokens.Insert(1, badToken);
            var reader = new TinyLispPseudoReader();

            // Act
            var ex = Assert.Throws <TinyLispException>(() => reader.Read(tokens));

            // Assert
            Assert.That(ex.Message, Is.EqualTo($"Could not read token of type '{badToken.GetType().FullName}'."));
        }
Beispiel #9
0
        public void GetAllKeywordArguments_ValidArguments_ReturnsExpectedResult()
        {
            // Arrange
            var formText = "(foo one two :key one two \"three\" :your-key \"some string\")";

            var tokens     = _lexer.Lexize(formText);
            var reader     = new TinyLispPseudoReader();
            var pseudoList = reader.Read(tokens).Single().AsPseudoList();

            // Act
            var args = pseudoList.GetAllKeywordArguments(":key");

            // Assert
            CollectionAssert.AreEqual(
                new Element[]
            {
                Symbol.Create("one"),
                Symbol.Create("two"),
                new StringAtom("three"),
            },
                args);
        }
Beispiel #10
0
        protected CliExecutorBase(
            string grammar,
            string version,
            bool supportsHelp)
            : base(ExtractName(grammar), version, supportsHelp)
        {
            var tinyLispLexer        = new TinyLispLexer();
            var tinyLispPseudoReader = new TinyLispPseudoReader();
            var lispTokens           = tinyLispLexer.Lexize(grammar);

            _form = tinyLispPseudoReader.Read(lispTokens);

            this.Descriptor = (new CliExecutorDescriptorBuilder(grammar)).Build();

            if (this.Name == null)
            {
                if (this.Version != null)
                {
                    throw new ArgumentException("Nameless executor cannot support version.", nameof(version));
                }

                if (this.SupportsHelp)
                {
                    throw new ArgumentException("Nameless executor cannot support help.", nameof(supportsHelp));
                }
            }

            try
            {
                var helper = new CliExecutorDescriptorBuilder(grammar);
                this.Descriptor = helper.Build();
            }
            catch (CliException)
            {
                // couldn't build descriptor
            }
        }
        public void SqlParser_ValidInput_Parses()
        {
            // Arrange
            var nodeFactory = new SqlNodeFactory();
            var input       = this.GetType().Assembly.GetResourceText("sql-grammar.lisp", true);

            var tokens = _tinyLispLexer.Lexize(input);

            var          reader  = new TinyLispPseudoReader();
            var          list    = reader.Read(tokens);
            ITreeBuilder builder = new TreeBuilder();
            var          root    = builder.Build(nodeFactory, list);

            IParser parser = new Parser
            {
                Root = root,
            };

            var allSqlNodes = root.FetchTree();

            var exactTextNodes = allSqlNodes
                                 .Where(x => x is ExactTextNode)
                                 .Cast <ExactTextNode>()
                                 .ToList();

            #region assign job to nodes

            // table
            var createTable = (ActionNode)allSqlNodes.Single(x =>
                                                             string.Equals(x.Name, "do-create-table", StringComparison.InvariantCultureIgnoreCase));
            createTable.Action = (node, token, accumulator) =>
            {
                var tableInfo = new TableInfo();
                accumulator.AddResult(tableInfo);
            };

            var tableName = (ActionNode)allSqlNodes.Single(x =>
                                                           string.Equals(x.Name, "table-name", StringComparison.InvariantCultureIgnoreCase));
            tableName.Action = (node, token, accumulator) =>
            {
                var tableInfo = accumulator.GetLastResult <TableInfo>();
                tableInfo.Name = ((TextToken)token).Text;
            };

            var columnName = (ActionNode)allSqlNodes.Single(x =>
                                                            string.Equals(x.Name, "column-name", StringComparison.InvariantCultureIgnoreCase));
            columnName.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var columnInfo = new ColumnInfo
                {
                    Name = ((TextToken)token).Text,
                };
                tableInfo.Columns.Add(columnInfo);
            };

            var typeName = (ActionNode)allSqlNodes.Single(x =>
                                                          string.Equals(x.Name, "type-name", StringComparison.InvariantCultureIgnoreCase));
            typeName.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var columnInfo = tableInfo.Columns.Last();
                columnInfo.TypeName = ((TextToken)token).Text;
            };

            var precision = (ActionNode)allSqlNodes.Single(x =>
                                                           string.Equals(x.Name, "precision", StringComparison.InvariantCultureIgnoreCase));
            precision.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var columnInfo = tableInfo.Columns.Last();
                columnInfo.Precision = ((IntegerToken)token).Value.ToInt32();
            };

            var scale = (ActionNode)allSqlNodes.Single(x =>
                                                       string.Equals(x.Name, "scale", StringComparison.InvariantCultureIgnoreCase));
            scale.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var columnInfo = tableInfo.Columns.Last();
                columnInfo.Scale = ((IntegerToken)token).Value.ToInt32();
            };

            var nullToken = (ActionNode)allSqlNodes.Single(x =>
                                                           string.Equals(x.Name, "null", StringComparison.InvariantCultureIgnoreCase));
            nullToken.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var columnInfo = tableInfo.Columns.Last();
                columnInfo.IsNullable = true;
            };

            var notNullToken = (ActionNode)allSqlNodes.Single(x =>
                                                              string.Equals(x.Name, "not-null", StringComparison.InvariantCultureIgnoreCase));
            notNullToken.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var columnInfo = tableInfo.Columns.Last();
                columnInfo.IsNullable = false;
            };

            var constraintName = (ActionNode)allSqlNodes.Single(x =>
                                                                string.Equals(x.Name, "constraint-name", StringComparison.InvariantCultureIgnoreCase));
            constraintName.Action = (node, token, accumulator) =>
            {
                var tableInfo = accumulator.GetLastResult <TableInfo>();
                tableInfo.LastConstraintName = ((TextToken)token).Text;
            };

            var pk = (ActionNode)allSqlNodes.Single(x =>
                                                    string.Equals(x.Name, "do-primary-key", StringComparison.InvariantCultureIgnoreCase));
            pk.Action = (node, token, accumulator) =>
            {
                var tableInfo = accumulator.GetLastResult <TableInfo>();
                tableInfo.PrimaryKey = new PrimaryKeyInfo
                {
                    Name = tableInfo.LastConstraintName,
                };
            };

            var pkColumnName = (ActionNode)allSqlNodes.Single(x =>
                                                              string.Equals(x.Name, "pk-column-name", StringComparison.InvariantCultureIgnoreCase));
            pkColumnName.Action = (node, token, accumulator) =>
            {
                var tableInfo   = accumulator.GetLastResult <TableInfo>();
                var primaryKey  = tableInfo.PrimaryKey;
                var indexColumn = new IndexColumnInfo
                {
                    ColumnName = ((TextToken)token).Text,
                };
                primaryKey.Columns.Add(indexColumn);
            };

            var pkColumnAscOrDesc = (ActionNode)allSqlNodes.Single(x =>
                                                                   string.Equals(x.Name, "pk-asc-or-desc", StringComparison.InvariantCultureIgnoreCase));
            pkColumnAscOrDesc.Action = (node, token, accumulator) =>
            {
                var tableInfo   = accumulator.GetLastResult <TableInfo>();
                var primaryKey  = tableInfo.PrimaryKey;
                var indexColumn = primaryKey.Columns.Last();

                indexColumn.SortDirection = Enum.Parse <SortDirection>(
                    ((TextToken)token).Text.ToLowerInvariant(),
                    true);
            };

            var fk = (ActionNode)allSqlNodes.Single(x =>
                                                    string.Equals(x.Name, "do-foreign-key", StringComparison.InvariantCultureIgnoreCase));
            fk.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var foreignKey = new ForeignKeyInfo
                {
                    Name = tableInfo.LastConstraintName,
                };
                tableInfo.ForeignKeys.Add(foreignKey);
            };

            var fkTableName = (ActionNode)allSqlNodes.Single(x =>
                                                             string.Equals(x.Name, "fk-referenced-table-name", StringComparison.InvariantCultureIgnoreCase));
            fkTableName.Action = (node, token, accumulator) =>
            {
                var tableInfo           = accumulator.GetLastResult <TableInfo>();
                var foreignKey          = tableInfo.ForeignKeys.Last();
                var foreignKeyTableName = ((TextToken)token).Text;
                foreignKey.TableName = foreignKeyTableName;
            };

            var fkColumnName = (ActionNode)allSqlNodes.Single(x =>
                                                              string.Equals(x.Name, "fk-column-name", StringComparison.InvariantCultureIgnoreCase));
            fkColumnName.Action = (node, token, accumulator) =>
            {
                var tableInfo            = accumulator.GetLastResult <TableInfo>();
                var foreignKey           = tableInfo.ForeignKeys.Last();
                var foreignKeyColumnName = ((TextToken)token).Text;
                foreignKey.ColumnNames.Add(foreignKeyColumnName);
            };

            var fkReferencedColumnName = (ActionNode)allSqlNodes.Single(x =>
                                                                        string.Equals(x.Name, "fk-referenced-column-name", StringComparison.InvariantCultureIgnoreCase));
            fkReferencedColumnName.Action = (node, token, accumulator) =>
            {
                var tableInfo  = accumulator.GetLastResult <TableInfo>();
                var foreignKey = tableInfo.ForeignKeys.Last();
                var foreignKeyReferencedColumnName = ((TextToken)token).Text;
                foreignKey.ReferencedColumnNames.Add(foreignKeyReferencedColumnName);
            };

            // index
            var createUniqueIndex = (ActionNode)allSqlNodes.Single(x =>
                                                                   string.Equals(x.Name, "do-create-unique-index", StringComparison.InvariantCultureIgnoreCase));
            createUniqueIndex.Action = (node, token, accumulator) =>
            {
                var index = new IndexInfo
                {
                    IsUnique = true,
                };
                accumulator.AddResult(index);
            };

            var createIndex = (ActionNode)allSqlNodes.Single(x =>
                                                             string.Equals(x.Name, "do-create-index", StringComparison.InvariantCultureIgnoreCase));
            createIndex.Action = (node, token, accumulator) =>
            {
                bool brandNewIndex;

                if (accumulator.Count == 0)
                {
                    brandNewIndex = true;
                }
                else
                {
                    var result = accumulator.Last();
                    if (result is IndexInfo indexInfo)
                    {
                        brandNewIndex = indexInfo.IsCreationFinalized;
                    }
                    else
                    {
                        brandNewIndex = true;
                    }
                }

                if (brandNewIndex)
                {
                    var newIndex = new IndexInfo
                    {
                        IsCreationFinalized = true,
                    };

                    accumulator.AddResult(newIndex);
                }
                else
                {
                    var existingIndexInfo = accumulator.GetLastResult <IndexInfo>();
                    existingIndexInfo.IsCreationFinalized = true;
                }
            };

            var indexName = (ActionNode)allSqlNodes.Single(x =>
                                                           string.Equals(x.Name, "index-name", StringComparison.InvariantCultureIgnoreCase));
            indexName.Action = (node, token, accumulator) =>
            {
                var index = accumulator.GetLastResult <IndexInfo>();
                index.Name = ((TextToken)token).Text;
            };

            var indexTableName = (ActionNode)allSqlNodes.Single(x =>
                                                                string.Equals(x.Name, "index-table-name", StringComparison.InvariantCultureIgnoreCase));
            indexTableName.Action = (node, token, accumulator) =>
            {
                var index = accumulator.GetLastResult <IndexInfo>();
                index.TableName = ((TextToken)token).Text;
            };

            var indexColumnName = (ActionNode)allSqlNodes.Single(x =>
                                                                 string.Equals(x.Name, "index-column-name", StringComparison.InvariantCultureIgnoreCase));
            indexColumnName.Action = (node, token, accumulator) =>
            {
                var index      = accumulator.GetLastResult <IndexInfo>();
                var columnInfo = new IndexColumnInfo
                {
                    ColumnName = ((TextToken)token).Text,
                };
                index.Columns.Add(columnInfo);
            };

            var indexColumnAscOrDesc = (ActionNode)allSqlNodes.Single(x =>
                                                                      string.Equals(x.Name, "index-column-asc-or-desc", StringComparison.InvariantCultureIgnoreCase));
            indexColumnAscOrDesc.Action = (node, token, accumulator) =>
            {
                var index      = accumulator.GetLastResult <IndexInfo>();
                var columnInfo = index.Columns.Last();
                columnInfo.SortDirection = Enum.Parse <SortDirection>(
                    ((TextToken)token).Text.ToLowerInvariant(),
                    true);
            };

            #endregion

            var objectNameTokens = allSqlNodes
                                   .Where(x =>
                                          x is TextNode textNode &&
                                          x.Name.EndsWith("-name", StringComparison.InvariantCultureIgnoreCase))
                                   .Cast <TextNode>()
                                   .ToList();

            var sql =
                @"
CREATE Table my_tab(
    id int NOT NULL,
    name varchar(30) NOT NULL,
    Salary decimal(12, 3) NULL,
    CONSTRAINT [my_tab_pk] PRIMARY KEY(id Desc, [NAME] ASC, salary),
    CONSTRAINT [fk_other] FOREIGN KEY([id]) references other_table(otherId),
    CONSTRAINT fk_cool FOREIGN KEY([id], name) references [other_table](otherId, [birthday])
)

CREATE TABLE [other_table](
    [otherId] nvarchar(10),
    [birthday] [datetime],
    CONSTRAINT pk_otherTable PRIMARY KEY([otherId])
)

CREATE UNIQUE INDEX [UX_name] ON my_tab(id Desc, name, Salary asc)

CREATE INDEX IX_id ON [my_tab](id)

CREATE INDEX [IX_Salary] ON my_tab([salary])

";

            var sqlTokens = _sqlLexer.Lexize(sql);

            // Act
            parser.Root = root;
            var sqlResults = parser.Parse(sqlTokens);

            // Assert
            Assert.That(sqlResults, Has.Length.EqualTo(5));

            // create table: my_tab
            var createTableResult = (TableInfo)sqlResults[0];
            Assert.That(createTableResult.Name, Is.EqualTo("my_tab"));
            var tableColumns = createTableResult.Columns;
            Assert.That(tableColumns, Has.Count.EqualTo(3));

            var column = tableColumns[0];
            Assert.That(column.Name, Is.EqualTo("id"));
            Assert.That(column.TypeName, Is.EqualTo("int"));
            Assert.That(column.Precision, Is.Null);
            Assert.That(column.Scale, Is.Null);
            Assert.That(column.IsNullable, Is.False);

            column = tableColumns[1];
            Assert.That(column.Name, Is.EqualTo("name"));
            Assert.That(column.TypeName, Is.EqualTo("varchar"));
            Assert.That(column.Precision, Is.EqualTo(30));
            Assert.That(column.Scale, Is.Null);
            Assert.That(column.IsNullable, Is.False);

            column = tableColumns[2];
            Assert.That(column.Name, Is.EqualTo("Salary"));
            Assert.That(column.TypeName, Is.EqualTo("decimal"));
            Assert.That(column.Precision, Is.EqualTo(12));
            Assert.That(column.Scale, Is.EqualTo(3));
            Assert.That(column.IsNullable, Is.True);

            var tablePrimaryKey = createTableResult.PrimaryKey;
            Assert.That(tablePrimaryKey.Name, Is.EqualTo("my_tab_pk"));
            var pkColumns = tablePrimaryKey.Columns;
            Assert.That(pkColumns, Has.Count.EqualTo(3));

            var pkIndexColumn = pkColumns[0];
            Assert.That(pkIndexColumn.ColumnName, Is.EqualTo("id"));
            Assert.That(pkIndexColumn.SortDirection, Is.EqualTo(SortDirection.Desc));

            pkIndexColumn = pkColumns[1];
            Assert.That(pkIndexColumn.ColumnName, Is.EqualTo("NAME"));
            Assert.That(pkIndexColumn.SortDirection, Is.EqualTo(SortDirection.Asc));

            pkIndexColumn = pkColumns[2];
            Assert.That(pkIndexColumn.ColumnName, Is.EqualTo("salary"));
            Assert.That(pkIndexColumn.SortDirection, Is.EqualTo(SortDirection.Asc));

            var foreignKeys = createTableResult.ForeignKeys;
            Assert.That(foreignKeys, Has.Count.EqualTo(2));

            var tableForeignKey = foreignKeys[0];
            Assert.That(tableForeignKey.Name, Is.EqualTo("fk_other"));
            Assert.That(tableForeignKey.TableName, Is.EqualTo("other_table"));
            CollectionAssert.AreEquivalent(tableForeignKey.ColumnNames, new[] { "id" });
            CollectionAssert.AreEquivalent(tableForeignKey.ReferencedColumnNames, new[] { "otherId" });

            tableForeignKey = foreignKeys[1];
            Assert.That(tableForeignKey.Name, Is.EqualTo("fk_cool"));
            Assert.That(tableForeignKey.TableName, Is.EqualTo("other_table"));
            CollectionAssert.AreEquivalent(tableForeignKey.ColumnNames, new[] { "id", "name" });
            CollectionAssert.AreEquivalent(tableForeignKey.ReferencedColumnNames, new[] { "otherId", "birthday" });

            // create table: other_table
            createTableResult = (TableInfo)sqlResults[1];
            Assert.That(createTableResult.Name, Is.EqualTo("other_table"));
            tableColumns = createTableResult.Columns;
            Assert.That(tableColumns, Has.Count.EqualTo(2));

            column = tableColumns[0];
            Assert.That(column.Name, Is.EqualTo("otherId"));
            Assert.That(column.TypeName, Is.EqualTo("nvarchar"));
            Assert.That(column.Precision, Is.EqualTo(10));
            Assert.That(column.Scale, Is.Null);
            Assert.That(column.IsNullable, Is.True);

            column = tableColumns[1];
            Assert.That(column.Name, Is.EqualTo("birthday"));
            Assert.That(column.TypeName, Is.EqualTo("datetime"));
            Assert.That(column.Precision, Is.Null);
            Assert.That(column.Scale, Is.Null);
            Assert.That(column.IsNullable, Is.True);

            tablePrimaryKey = createTableResult.PrimaryKey;
            Assert.That(tablePrimaryKey.Name, Is.EqualTo("pk_otherTable"));
            pkColumns = tablePrimaryKey.Columns;
            Assert.That(pkColumns, Has.Count.EqualTo(1));

            pkIndexColumn = pkColumns[0];
            Assert.That(pkIndexColumn.ColumnName, Is.EqualTo("otherId"));
            Assert.That(pkIndexColumn.SortDirection, Is.EqualTo(SortDirection.Asc));

            foreignKeys = createTableResult.ForeignKeys;
            Assert.That(foreignKeys, Is.Empty);

            // create index: UX_name
            var createIndexResult = (IndexInfo)sqlResults[2];
            Assert.That(createIndexResult.Name, Is.EqualTo("UX_name"));
            Assert.That(createIndexResult.TableName, Is.EqualTo("my_tab"));
            Assert.That(createIndexResult.IsUnique, Is.True);
            Assert.That(createIndexResult.IsCreationFinalized, Is.True);

            var indexColumns = createIndexResult.Columns;
            Assert.That(indexColumns, Has.Count.EqualTo(3));

            var indexColumnInfo = indexColumns[0];
            Assert.That(indexColumnInfo.ColumnName, Is.EqualTo("id"));
            Assert.That(indexColumnInfo.SortDirection, Is.EqualTo(SortDirection.Desc));

            indexColumnInfo = indexColumns[1];
            Assert.That(indexColumnInfo.ColumnName, Is.EqualTo("name"));
            Assert.That(indexColumnInfo.SortDirection, Is.EqualTo(SortDirection.Asc));

            indexColumnInfo = indexColumns[2];
            Assert.That(indexColumnInfo.ColumnName, Is.EqualTo("Salary"));
            Assert.That(indexColumnInfo.SortDirection, Is.EqualTo(SortDirection.Asc));

            // create index: IX_id
            createIndexResult = (IndexInfo)sqlResults[3];
            Assert.That(createIndexResult.Name, Is.EqualTo("IX_id"));
            Assert.That(createIndexResult.TableName, Is.EqualTo("my_tab"));
            Assert.That(createIndexResult.IsUnique, Is.False);
            Assert.That(createIndexResult.IsCreationFinalized, Is.True);

            indexColumns = createIndexResult.Columns;
            Assert.That(indexColumns, Has.Count.EqualTo(1));

            indexColumnInfo = indexColumns[0];
            Assert.That(indexColumnInfo.ColumnName, Is.EqualTo("id"));
            Assert.That(indexColumnInfo.SortDirection, Is.EqualTo(SortDirection.Asc));

            // create index: UX_name
            createIndexResult = (IndexInfo)sqlResults[4];
            Assert.That(createIndexResult.Name, Is.EqualTo("IX_Salary"));
            Assert.That(createIndexResult.TableName, Is.EqualTo("my_tab"));
            Assert.That(createIndexResult.IsUnique, Is.False);
            Assert.That(createIndexResult.IsCreationFinalized, Is.True);

            indexColumns = createIndexResult.Columns;
            Assert.That(indexColumns, Has.Count.EqualTo(1));

            indexColumnInfo = indexColumns[0];
            Assert.That(indexColumnInfo.ColumnName, Is.EqualTo("salary"));
            Assert.That(indexColumnInfo.SortDirection, Is.EqualTo(SortDirection.Asc));
        }