Skip to content

Commit ed11c32

Browse files
Kizzzymsallin
authored andcommitted
#107: escape columnName to avoid reserved keyword conflict
1 parent 8edfe36 commit ed11c32

File tree

8 files changed

+47
-32
lines changed

8 files changed

+47
-32
lines changed

SQLite.CodeFirst.Test/IntegrationTests/SqlGenerationTest.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Data.Common;
1+
using System.Data.Common;
32
using System.Data.Entity;
43
using System.Data.Entity.Infrastructure;
54
using System.Data.SQLite;
@@ -14,18 +13,19 @@ namespace SQLite.CodeFirst.Test.IntegrationTests
1413
public class SqlGenerationTest
1514
{
1615
private const string ReferenceSql =
17-
@"CREATE TABLE ""MyTable"" ([Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [Name] nvarchar NOT NULL, FOREIGN KEY (Id) REFERENCES ""Coaches""(Id));
16+
@"
17+
CREATE TABLE ""MyTable"" ([Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [Name] nvarchar NOT NULL, FOREIGN KEY ([Id]) REFERENCES ""Coaches""([Id]));
1818
CREATE TABLE ""Coaches"" ([Id] INTEGER PRIMARY KEY, [FirstName] nvarchar (50) COLLATE NOCASE, [LastName] nvarchar (50), [Street] nvarchar (100), [City] nvarchar NOT NULL, [CreatedUtc] datetime NOT NULL DEFAULT (DATETIME('now')));
19-
CREATE TABLE ""TeamPlayer"" ([Id] INTEGER PRIMARY KEY, [Number] int NOT NULL, [TeamId] int NOT NULL, [FirstName] nvarchar (50) COLLATE NOCASE, [LastName] nvarchar (50), [Street] nvarchar (100), [City] nvarchar NOT NULL, [CreatedUtc] datetime NOT NULL DEFAULT (DATETIME('now')), [Mentor_Id] int, FOREIGN KEY (Mentor_Id) REFERENCES ""TeamPlayer""(Id), FOREIGN KEY (TeamId) REFERENCES ""MyTable""(Id) ON DELETE CASCADE);
20-
CREATE TABLE ""Stadions"" ([Name] nvarchar (128) NOT NULL, [Street] nvarchar (128) NOT NULL, [City] nvarchar (128) NOT NULL, [Order] int NOT NULL, [Team_Id] int NOT NULL, PRIMARY KEY(Name, Street, City), FOREIGN KEY (Team_Id) REFERENCES ""MyTable""(Id) ON DELETE CASCADE);
21-
CREATE TABLE ""Foos"" ([FooId] INTEGER PRIMARY KEY, [Name] nvarchar, [FooSelf1Id] int, [FooSelf2Id] int, [FooSelf3Id] int, FOREIGN KEY (FooSelf1Id) REFERENCES ""Foos""(FooId), FOREIGN KEY (FooSelf2Id) REFERENCES ""Foos""(FooId), FOREIGN KEY (FooSelf3Id) REFERENCES ""Foos""(FooId));
22-
CREATE TABLE ""FooSelves"" ([FooSelfId] INTEGER PRIMARY KEY, [FooId] int NOT NULL, [Number] int NOT NULL, FOREIGN KEY (FooId) REFERENCES ""Foos""(FooId) ON DELETE CASCADE);
23-
CREATE TABLE ""FooSteps"" ([FooStepId] INTEGER PRIMARY KEY, [FooId] int NOT NULL, [Number] int NOT NULL, FOREIGN KEY (FooId) REFERENCES ""Foos""(FooId) ON DELETE CASCADE);
24-
CREATE TABLE ""FooCompositeKeys"" ([Id] int NOT NULL, [Version] nvarchar (20) NOT NULL, [Name] nvarchar (255), PRIMARY KEY(Id, Version));
19+
CREATE TABLE ""TeamPlayer"" ([Id] INTEGER PRIMARY KEY, [Number] int NOT NULL, [TeamId] int NOT NULL, [FirstName] nvarchar (50) COLLATE NOCASE, [LastName] nvarchar (50), [Street] nvarchar (100), [City] nvarchar NOT NULL, [CreatedUtc] datetime NOT NULL DEFAULT (DATETIME('now')), [Mentor_Id] int, FOREIGN KEY ([Mentor_Id]) REFERENCES ""TeamPlayer""([Id]), FOREIGN KEY ([TeamId]) REFERENCES ""MyTable""([Id]) ON DELETE CASCADE);
20+
CREATE TABLE ""Stadions"" ([Name] nvarchar (128) NOT NULL, [Street] nvarchar (128) NOT NULL, [City] nvarchar (128) NOT NULL, [Order] int NOT NULL, [Team_Id] int NOT NULL, PRIMARY KEY([Name], [Street], [City]), FOREIGN KEY ([Team_Id]) REFERENCES ""MyTable""([Id]) ON DELETE CASCADE);
21+
CREATE TABLE ""Foos"" ([FooId] INTEGER PRIMARY KEY, [Name] nvarchar, [FooSelf1Id] int, [FooSelf2Id] int, [FooSelf3Id] int, FOREIGN KEY ([FooSelf1Id]) REFERENCES ""Foos""([FooId]), FOREIGN KEY ([FooSelf2Id]) REFERENCES ""Foos""([FooId]), FOREIGN KEY ([FooSelf3Id]) REFERENCES ""Foos""([FooId]));
22+
CREATE TABLE ""FooSelves"" ([FooSelfId] INTEGER PRIMARY KEY, [FooId] int NOT NULL, [Number] int NOT NULL, FOREIGN KEY ([FooId]) REFERENCES ""Foos""([FooId]) ON DELETE CASCADE);
23+
CREATE TABLE ""FooSteps"" ([FooStepId] INTEGER PRIMARY KEY, [FooId] int NOT NULL, [Number] int NOT NULL, FOREIGN KEY ([FooId]) REFERENCES ""Foos""([FooId]) ON DELETE CASCADE);
24+
CREATE TABLE ""FooCompositeKeys"" ([Id] int NOT NULL, [Version] nvarchar (20) NOT NULL, [Name] nvarchar (255), PRIMARY KEY([Id], [Version]));
2525
CREATE TABLE ""FooRelationshipAs"" ([Id] INTEGER PRIMARY KEY, [Name] nvarchar (255));
2626
CREATE TABLE ""FooRelationshipBs"" ([Id] INTEGER PRIMARY KEY, [Name] nvarchar (255));
27-
CREATE TABLE ""FooRelationshipAFooCompositeKeys"" ([FooRelationshipA_Id] int NOT NULL, [FooCompositeKey_Id] int NOT NULL, [FooCompositeKey_Version] nvarchar (20) NOT NULL, PRIMARY KEY(FooRelationshipA_Id, FooCompositeKey_Id, FooCompositeKey_Version), FOREIGN KEY (FooRelationshipA_Id) REFERENCES ""FooRelationshipAs""(Id) ON DELETE CASCADE, FOREIGN KEY (FooCompositeKey_Id, FooCompositeKey_Version) REFERENCES ""FooCompositeKeys""(Id, Version) ON DELETE CASCADE);
28-
CREATE TABLE ""FooRelationshipBFooCompositeKeys"" ([FooRelationshipB_Id] int NOT NULL, [FooCompositeKey_Id] int NOT NULL, [FooCompositeKey_Version] nvarchar (20) NOT NULL, PRIMARY KEY(FooRelationshipB_Id, FooCompositeKey_Id, FooCompositeKey_Version), FOREIGN KEY (FooRelationshipB_Id) REFERENCES ""FooRelationshipBs""(Id) ON DELETE CASCADE, FOREIGN KEY (FooCompositeKey_Id, FooCompositeKey_Version) REFERENCES ""FooCompositeKeys""(Id, Version) ON DELETE CASCADE);
27+
CREATE TABLE ""FooRelationshipAFooCompositeKeys"" ([FooRelationshipA_Id] int NOT NULL, [FooCompositeKey_Id] int NOT NULL, [FooCompositeKey_Version] nvarchar (20) NOT NULL, PRIMARY KEY([FooRelationshipA_Id], [FooCompositeKey_Id], [FooCompositeKey_Version]), FOREIGN KEY ([FooRelationshipA_Id]) REFERENCES ""FooRelationshipAs""([Id]) ON DELETE CASCADE, FOREIGN KEY ([FooCompositeKey_Id], [FooCompositeKey_Version]) REFERENCES ""FooCompositeKeys""([Id], [Version]) ON DELETE CASCADE);
28+
CREATE TABLE ""FooRelationshipBFooCompositeKeys"" ([FooRelationshipB_Id] int NOT NULL, [FooCompositeKey_Id] int NOT NULL, [FooCompositeKey_Version] nvarchar (20) NOT NULL, PRIMARY KEY([FooRelationshipB_Id], [FooCompositeKey_Id], [FooCompositeKey_Version]), FOREIGN KEY ([FooRelationshipB_Id]) REFERENCES ""FooRelationshipBs""([Id]) ON DELETE CASCADE, FOREIGN KEY ([FooCompositeKey_Id], [FooCompositeKey_Version]) REFERENCES ""FooCompositeKeys""([Id], [Version]) ON DELETE CASCADE);
2929
CREATE INDEX ""IX_MyTable_Id"" ON ""MyTable"" (""Id"");
3030
CREATE INDEX ""IX_Team_TeamsName"" ON ""MyTable"" (""Name"");
3131
CREATE INDEX ""IX_TeamPlayer_Number"" ON ""TeamPlayer"" (""Number"");
@@ -42,12 +42,13 @@ public class SqlGenerationTest
4242
CREATE INDEX ""IX_FooRelationshipAFooCompositeKey_FooRelationshipA_Id"" ON ""FooRelationshipAFooCompositeKeys"" (""FooRelationshipA_Id"");
4343
CREATE INDEX ""IX_FooRelationshipAFooCompositeKey_FooCompositeKey_Id_FooCompositeKey_Version"" ON ""FooRelationshipAFooCompositeKeys"" (""FooCompositeKey_Id"", ""FooCompositeKey_Version"");
4444
CREATE INDEX ""IX_FooRelationshipBFooCompositeKey_FooRelationshipB_Id"" ON ""FooRelationshipBFooCompositeKeys"" (""FooRelationshipB_Id"");
45-
CREATE INDEX ""IX_FooRelationshipBFooCompositeKey_FooCompositeKey_Id_FooCompositeKey_Version"" ON ""FooRelationshipBFooCompositeKeys"" (""FooCompositeKey_Id"", ""FooCompositeKey_Version"");";
45+
CREATE INDEX ""IX_FooRelationshipBFooCompositeKey_FooCompositeKey_Id_FooCompositeKey_Version"" ON ""FooRelationshipBFooCompositeKeys"" (""FooCompositeKey_Id"", ""FooCompositeKey_Version"");
46+
";
4647

4748
private static string generatedSql;
4849

4950
// Does not work on the build server. No clue why.
50-
51+
5152
[TestMethod]
5253
public void SqliteSqlGeneratorTest()
5354
{

SQLite.CodeFirst.Test/UnitTests/Statement/ColumnStatementTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ public void CreateStatement()
1616

1717
var columnStatement = new ColumnStatement
1818
{
19-
ColumnConstraints = columnConstraintsMock.Object,
2019
ColumnName = "dummyColumnName",
21-
TypeName = "dummyType"
20+
TypeName = "dummyType",
21+
ColumnConstraints = columnConstraintsMock.Object,
2222
};
2323
string output = columnStatement.CreateStatement();
2424
Assert.AreEqual(output, "[dummyColumnName] dummyType dummyColumnConstraint");

SQLite.CodeFirst.Test/UnitTests/Statement/ForeignKeyStatementTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void CreateStatementOneForeignKeyTest()
1919
};
2020

2121
string output = foreignKeyStatement.CreateStatement();
22-
Assert.AreEqual(output, "FOREIGN KEY (dummyForeignKey1) REFERENCES dummyForeignTable(dummForeignPrimaryKey1)");
22+
Assert.AreEqual(output, "FOREIGN KEY ([dummyForeignKey1]) REFERENCES dummyForeignTable([dummForeignPrimaryKey1])");
2323
}
2424

2525
[TestMethod]
@@ -34,7 +34,7 @@ public void CreateStatementOneForeignKeyCascadeDeleteTest()
3434
};
3535

3636
string output = foreignKeyStatement.CreateStatement();
37-
Assert.AreEqual(output, "FOREIGN KEY (dummyForeignKey1) REFERENCES dummyForeignTable(dummForeignPrimaryKey1) ON DELETE CASCADE");
37+
Assert.AreEqual(output, "FOREIGN KEY ([dummyForeignKey1]) REFERENCES dummyForeignTable([dummForeignPrimaryKey1]) ON DELETE CASCADE");
3838
}
3939

4040
[TestMethod]
@@ -49,7 +49,7 @@ public void CreateStatementTwoForeignKeyTest()
4949
};
5050

5151
string output = foreignKeyStatement.CreateStatement();
52-
Assert.AreEqual(output, "FOREIGN KEY (dummyForeignKey1, dummyForeignKey2) REFERENCES dummyForeignTable(dummForeignPrimaryKey1)");
52+
Assert.AreEqual(output, "FOREIGN KEY ([dummyForeignKey1], [dummyForeignKey2]) REFERENCES dummyForeignTable([dummForeignPrimaryKey1])");
5353
}
5454

5555
[TestMethod]
@@ -64,7 +64,7 @@ public void CreateStatementTwoForeignKeyTwoPrimaryKeyTest()
6464
};
6565

6666
string output = foreignKeyStatement.CreateStatement();
67-
Assert.AreEqual(output, "FOREIGN KEY (dummyForeignKey1, dummyForeignKey2) REFERENCES dummyForeignTable(dummForeignPrimaryKey1, dummForeignPrimaryKey2)");
67+
Assert.AreEqual(output, "FOREIGN KEY ([dummyForeignKey1], [dummyForeignKey2]) REFERENCES dummyForeignTable([dummForeignPrimaryKey1], [dummForeignPrimaryKey2])");
6868
}
6969

7070
[TestMethod]
@@ -79,7 +79,7 @@ public void CreateStatementOneForeignKeyTwoPrimaryKeyTest()
7979
};
8080

8181
string output = foreignKeyStatement.CreateStatement();
82-
Assert.AreEqual(output, "FOREIGN KEY (dummyForeignKey1) REFERENCES dummyForeignTable(dummForeignPrimaryKey1, dummForeignPrimaryKey2)");
82+
Assert.AreEqual(output, "FOREIGN KEY ([dummyForeignKey1]) REFERENCES dummyForeignTable([dummForeignPrimaryKey1], [dummForeignPrimaryKey2])");
8383
}
8484
}
8585
}

SQLite.CodeFirst.Test/UnitTests/Statement/PrimaryKeyStatementTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public void CreateStatementWithOneKeyTest()
1414

1515
var primaryKeyStatement = new CompositePrimaryKeyStatement(new List<string> { keyMember1 });
1616
Assert.AreEqual(primaryKeyStatement.Count, 1);
17-
Assert.AreEqual(primaryKeyStatement.CreateStatement(), "PRIMARY KEY(keyMember1)");
17+
Assert.AreEqual(primaryKeyStatement.CreateStatement(), "PRIMARY KEY([keyMember1])");
1818
}
1919

2020
[TestMethod]
@@ -25,7 +25,7 @@ public void CreateStatementWithTwoKeyTest()
2525

2626
var primaryKeyStatement = new CompositePrimaryKeyStatement(new List<string> { keyMember1, keyMember2 });
2727
Assert.AreEqual(primaryKeyStatement.Count, 2);
28-
Assert.AreEqual(primaryKeyStatement.CreateStatement(), "PRIMARY KEY(keyMember1, keyMember2)");
28+
Assert.AreEqual(primaryKeyStatement.CreateStatement(), "PRIMARY KEY([keyMember1], [keyMember2])");
2929
}
3030
}
3131
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Globalization;
2+
3+
namespace SQLite.CodeFirst.Builder.NameCreators
4+
{
5+
internal static class ColumnNameCreator
6+
{
7+
public static string EscapeName(string columnName)
8+
{
9+
return string.Format(CultureInfo.InvariantCulture, "[{0}]", columnName);
10+
}
11+
}
12+
}

SQLite.CodeFirst/Internal/Statement/ColumnStatement.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System.Text;
2+
using SQLite.CodeFirst.Builder.NameCreators;
23
using SQLite.CodeFirst.Statement.ColumnConstraint;
34

45
namespace SQLite.CodeFirst.Statement
56
{
67
internal class ColumnStatement : IStatement
78
{
8-
private const string Template = "[{column-name}] {type-name} {column-constraint}";
9+
private const string Template = "{column-name} {type-name} {column-constraint}";
910

1011
public string ColumnName { get; set; }
1112
public string TypeName { get; set; }
@@ -15,7 +16,7 @@ public string CreateStatement()
1516
{
1617
var sb = new StringBuilder(Template);
1718

18-
sb.Replace("{column-name}", ColumnName);
19+
sb.Replace("{column-name}", ColumnNameCreator.EscapeName(ColumnName));
1920
sb.Replace("{type-name}", TypeName);
2021
sb.Replace("{column-constraint}", ColumnConstraints.CreateStatement());
2122

SQLite.CodeFirst/Internal/Statement/CompositePrimaryKeyStatement.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
using System;
1+
using SQLite.CodeFirst.Builder.NameCreators;
2+
using System;
23
using System.Collections.Generic;
34
using System.Collections.ObjectModel;
5+
using System.Linq;
46

57
namespace SQLite.CodeFirst.Statement
68
{
79
internal class CompositePrimaryKeyStatement : Collection<string>, IStatement
810
{
911
private const string Template = "PRIMARY KEY({primary-keys})";
10-
private const string PrimaryKeyColumnNameSeperator = ", ";
1112

1213
public CompositePrimaryKeyStatement(IEnumerable<string> keyMembers)
1314
{
@@ -19,7 +20,7 @@ public CompositePrimaryKeyStatement(IEnumerable<string> keyMembers)
1920

2021
public string CreateStatement()
2122
{
22-
string primaryKeys = String.Join(PrimaryKeyColumnNameSeperator, this);
23+
string primaryKeys = String.Join(", ", this.Select(c => ColumnNameCreator.EscapeName(c)));
2324
return Template.Replace("{primary-keys}", primaryKeys);
2425
}
2526
}

SQLite.CodeFirst/Internal/Statement/ForeignKeyStatement.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Collections.Generic;
1+
using SQLite.CodeFirst.Builder.NameCreators;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using System.Text;
35

46
namespace SQLite.CodeFirst.Statement
@@ -16,11 +18,9 @@ internal class ForeignKeyStatement : IStatement
1618
public string CreateStatement()
1719
{
1820
var sb = new StringBuilder(Template);
19-
20-
sb.Replace("{foreign-key}", string.Join(", ", ForeignKey));
21+
sb.Replace("{foreign-key}", string.Join(", ", ForeignKey.Select(c => ColumnNameCreator.EscapeName(c))));
2122
sb.Replace("{referenced-table}", ForeignTable);
22-
sb.Replace("{referenced-id}", string.Join(", ", ForeignPrimaryKey));
23-
23+
sb.Replace("{referenced-id}", string.Join(", ", ForeignPrimaryKey.Select(c => ColumnNameCreator.EscapeName(c))));
2424
if (CascadeDelete)
2525
{
2626
sb.Append(" " + CascadeDeleteStatement);

0 commit comments

Comments
 (0)