Skip to content

Commit f5cb9b6

Browse files
authored
fix(datastore): quote table name in create table-references SQL statement (#1485)
* fix(datastore): quote table name in create table-references SQL statement * fix: quote table name in all SQL statements
1 parent 11839ba commit f5cb9b6

File tree

13 files changed

+208
-33
lines changed

13 files changed

+208
-33
lines changed

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/SQLite/SQLStatement+CreateTable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct CreateTableStatement: SQLStatement {
5757
}
5858
let associatedId = schema.primaryKey
5959
let associatedModelName = schema.name
60-
statement += "references \(associatedModelName)(\"\(associatedId.sqlName)\")\n"
60+
statement += "references \"\(associatedModelName)\"(\"\(associatedId.sqlName)\")\n"
6161
statement += " on delete cascade"
6262
let isNotLastKey = index < foreignKeys.endIndex - 1
6363
if isNotLastKey {

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/SQLite/SQLStatement+Delete.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct DeleteStatement: SQLStatement {
4343

4444
var stringValue: String {
4545
let sql = """
46-
delete from \(modelSchema.name) as \(namespace)
46+
delete from "\(modelSchema.name)" as \(namespace)
4747
"""
4848

4949
if let conditionStatement = conditionStatement {

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/SQLite/SQLStatement+Insert.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct InsertStatement: SQLStatement {
2222
var stringValue: String {
2323
let fields = modelSchema.columns
2424
let columns = fields.map { $0.columnName() }
25-
var statement = "insert into \(modelSchema.name) "
25+
var statement = "insert into \"\(modelSchema.name)\" "
2626
statement += "(\(columns.joined(separator: ", ")))\n"
2727

2828
let variablePlaceholders = Array(repeating: "?", count: columns.count).joined(separator: ", ")

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/SQLite/SQLStatement+Select.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct SelectStatementMetadata {
4040
var sql = """
4141
select
4242
\(joinedAsSelectedColumns(columns))
43-
from \(tableName) as "\(rootNamespace)"
43+
from "\(tableName)" as "\(rootNamespace)"
4444
\(joinStatements.statements.joined(separator: "\n"))
4545
""".trimmingCharacters(in: .whitespacesAndNewlines)
4646

@@ -117,7 +117,7 @@ struct SelectStatementMetadata {
117117
let joinType = foreignKey.isRequired ? "inner" : "left outer"
118118

119119
joinStatements.append("""
120-
\(joinType) join \(associatedTableName) as "\(alias)"
120+
\(joinType) join \"\(associatedTableName)\" as "\(alias)"
121121
on \(associatedColumn) = \(foreignKeyName)
122122
""")
123123
visitAssociations(node: associatedSchema, namespace: alias)

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/SQLite/StorageEngineAdapter+SQLite.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
258258
withId id: Model.Identifier,
259259
predicate: QueryPredicate? = nil) throws -> Bool {
260260
let primaryKey = modelSchema.primaryKey.sqlName
261-
var sql = "select count(\(primaryKey)) from \(modelSchema.name) where \(primaryKey) = ?"
261+
var sql = "select count(\(primaryKey)) from \"\(modelSchema.name)\" where \(primaryKey) = ?"
262262
var variables: [Binding?] = [id]
263263
if let predicate = predicate {
264264
let conditionStatement = ConditionStatement(modelSchema: modelSchema, predicate: predicate)

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/SQLStatementTests.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class SQLStatementTests: XCTestCase {
8585
"content" text not null,
8686
"createdAt" text not null,
8787
"commentPostId" text not null,
88-
foreign key("commentPostId") references Post("id")
88+
foreign key("commentPostId") references "Post"("id")
8989
on delete cascade
9090
);
9191
"""
@@ -106,7 +106,7 @@ class SQLStatementTests: XCTestCase {
106106
create table if not exists "UserProfile" (
107107
"id" text primary key not null,
108108
"accountId" text not null unique,
109-
foreign key("accountId") references UserAccount("id")
109+
foreign key("accountId") references "UserAccount"("id")
110110
on delete cascade
111111
);
112112
"""
@@ -128,9 +128,9 @@ class SQLStatementTests: XCTestCase {
128128
"id" text primary key not null,
129129
"authorId" text not null,
130130
"bookId" text not null,
131-
foreign key("authorId") references Author("id")
131+
foreign key("authorId") references "Author"("id")
132132
on delete cascade
133-
foreign key("bookId") references Book("id")
133+
foreign key("bookId") references "Book"("id")
134134
on delete cascade
135135
);
136136
"""
@@ -153,7 +153,7 @@ class SQLStatementTests: XCTestCase {
153153
let statement = InsertStatement(model: post, modelSchema: post.schema)
154154

155155
let expectedStatement = """
156-
insert into Post ("id", "content", "createdAt", "draft", "rating", "status", "title", "updatedAt")
156+
insert into "Post" ("id", "content", "createdAt", "draft", "rating", "status", "title", "updatedAt")
157157
values (?, ?, ?, ?, ?, ?, ?, ?)
158158
"""
159159
XCTAssertEqual(statement.stringValue, expectedStatement)
@@ -178,7 +178,7 @@ class SQLStatementTests: XCTestCase {
178178
let statement = InsertStatement(model: comment, modelSchema: comment.schema)
179179

180180
let expectedStatement = """
181-
insert into Comment ("id", "content", "createdAt", "commentPostId")
181+
insert into "Comment" ("id", "content", "createdAt", "commentPostId")
182182
values (?, ?, ?, ?)
183183
"""
184184
XCTAssertEqual(statement.stringValue, expectedStatement)
@@ -265,7 +265,7 @@ class SQLStatementTests: XCTestCase {
265265
let statement = DeleteStatement(modelSchema: Post.schema, withId: id)
266266

267267
let expectedStatement = """
268-
delete from Post as root
268+
delete from "Post" as root
269269
where 1 = 1
270270
and "root"."id" = ?
271271
"""
@@ -288,7 +288,7 @@ class SQLStatementTests: XCTestCase {
288288
predicate: Post.keys.content == "content")
289289

290290
let expectedStatement = """
291-
delete from Post as root
291+
delete from "Post" as root
292292
where 1 = 1
293293
and (
294294
"root"."id" = ?
@@ -316,7 +316,7 @@ class SQLStatementTests: XCTestCase {
316316
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
317317
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
318318
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
319-
from Post as "root"
319+
from "Post" as "root"
320320
"""
321321
XCTAssertEqual(statement.stringValue, expectedStatement)
322322
}
@@ -337,7 +337,7 @@ class SQLStatementTests: XCTestCase {
337337
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
338338
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
339339
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
340-
from Post as "root"
340+
from "Post" as "root"
341341
where 1 = 1
342342
and (
343343
"root"."draft" = ?
@@ -373,8 +373,8 @@ class SQLStatementTests: XCTestCase {
373373
"root"."commentPostId" as "commentPostId", "post"."id" as "post.id", "post"."content" as "post.content",
374374
"post"."createdAt" as "post.createdAt", "post"."draft" as "post.draft", "post"."rating" as "post.rating",
375375
"post"."status" as "post.status", "post"."title" as "post.title", "post"."updatedAt" as "post.updatedAt"
376-
from Comment as "root"
377-
inner join Post as "post"
376+
from "Comment" as "root"
377+
inner join "Post" as "post"
378378
on "post"."id" = "root"."commentPostId"
379379
where 1 = 1
380380
and (
@@ -406,8 +406,8 @@ class SQLStatementTests: XCTestCase {
406406
"root"."commentPostId" as "commentPostId", "post"."id" as "post.id", "post"."content" as "post.content",
407407
"post"."createdAt" as "post.createdAt", "post"."draft" as "post.draft", "post"."rating" as "post.rating",
408408
"post"."status" as "post.status", "post"."title" as "post.title", "post"."updatedAt" as "post.updatedAt"
409-
from Comment as "root"
410-
inner join Post as "post"
409+
from "Comment" as "root"
410+
inner join "Post" as "post"
411411
on "post"."id" = "root"."commentPostId"
412412
"""
413413
XCTAssertEqual(statement.stringValue, expectedStatement)
@@ -429,7 +429,7 @@ class SQLStatementTests: XCTestCase {
429429
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
430430
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
431431
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
432-
from Post as "root"
432+
from "Post" as "root"
433433
limit 20 offset 40
434434
"""
435435
XCTAssertEqual(statement.stringValue, expectedStatement)
@@ -452,7 +452,7 @@ class SQLStatementTests: XCTestCase {
452452
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
453453
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
454454
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
455-
from Post as "root"
455+
from "Post" as "root"
456456
order by "root"."id" asc
457457
"""
458458
XCTAssertEqual(statement.stringValue, expectedStatement)
@@ -475,7 +475,7 @@ class SQLStatementTests: XCTestCase {
475475
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
476476
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
477477
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
478-
from Post as "root"
478+
from "Post" as "root"
479479
order by "root"."id" asc, "root"."createdAt" desc
480480
"""
481481
XCTAssertEqual(statement.stringValue, expectedStatement)
@@ -498,7 +498,7 @@ class SQLStatementTests: XCTestCase {
498498
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
499499
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
500500
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
501-
from Post as "root"
501+
from "Post" as "root"
502502
where 1 = 1
503503
and "root"."rating" > ?
504504
order by "root"."id" desc
@@ -524,7 +524,7 @@ class SQLStatementTests: XCTestCase {
524524
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
525525
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
526526
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
527-
from Post as "root"
527+
from "Post" as "root"
528528
order by "root"."id" desc
529529
limit 5 offset 0
530530
"""
@@ -551,7 +551,7 @@ class SQLStatementTests: XCTestCase {
551551
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
552552
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
553553
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
554-
from Post as "root"
554+
from "Post" as "root"
555555
where 1 = 1
556556
and "root"."rating" > ?
557557
order by "root"."id" desc
@@ -701,7 +701,7 @@ class SQLStatementTests: XCTestCase {
701701
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
702702
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
703703
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
704-
from Post as "root"
704+
from "Post" as "root"
705705
where 1 = 1
706706
and (
707707
(
@@ -736,7 +736,7 @@ class SQLStatementTests: XCTestCase {
736736
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
737737
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
738738
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
739-
from Post as "root"
739+
from "Post" as "root"
740740
where 1 = 1
741741
and (
742742
(
@@ -771,7 +771,7 @@ class SQLStatementTests: XCTestCase {
771771
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
772772
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
773773
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
774-
from Post as "root"
774+
from "Post" as "root"
775775
where 1 = 1
776776
and (
777777
(
@@ -810,7 +810,7 @@ class SQLStatementTests: XCTestCase {
810810
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
811811
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
812812
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
813-
from Post as "root"
813+
from "Post" as "root"
814814
where 1 = 1
815815
and (
816816
(
@@ -850,7 +850,7 @@ class SQLStatementTests: XCTestCase {
850850
"root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt",
851851
"root"."draft" as "draft", "root"."rating" as "rating", "root"."status" as "status",
852852
"root"."title" as "title", "root"."updatedAt" as "updatedAt"
853-
from Post as "root"
853+
from "Post" as "root"
854854
where 1 = 1
855855
and (
856856
(

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/SQLiteStorageEngineAdapterTests.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,3 +671,74 @@ class SQLiteStorageEngineAdapterTests: BaseDataStoreTests {
671671
XCTAssertFalse(storageAdapter.shouldIgnoreError(error: dataStoreError))
672672
}
673673
}
674+
675+
// MARK: Reserved words tests
676+
extension SQLiteStorageEngineAdapterTests {
677+
func testSaveWithReservedWords() {
678+
// "Transaction"
679+
let transactionSaved = expectation(description: "Transaction model saved")
680+
storageAdapter.save(Transaction()) { result in
681+
guard case .success = result else {
682+
XCTFail("Failed to save transaction")
683+
return
684+
}
685+
transactionSaved.fulfill()
686+
}
687+
688+
// "Group"
689+
let groupSaved = expectation(description: "Group model saved")
690+
let group = Group()
691+
storageAdapter.save(group) { result in
692+
guard case .success = result else {
693+
XCTFail("Failed to save group")
694+
return
695+
}
696+
groupSaved.fulfill()
697+
}
698+
699+
// "Row"
700+
let rowSaved = expectation(description: "Row model saved")
701+
storageAdapter.save(Row(group: group)) { result in
702+
guard case .success = result else {
703+
XCTFail("Failed to save Row")
704+
return
705+
}
706+
rowSaved.fulfill()
707+
}
708+
709+
wait(for: [transactionSaved, groupSaved, rowSaved], timeout: 1)
710+
}
711+
712+
func testQueryWithReservedWords() {
713+
// "Transaction"
714+
let transactionQueried = expectation(description: "Transaction model queried")
715+
storageAdapter.query(Transaction.self) { result in
716+
guard case .success = result else {
717+
XCTFail("Failed to query Transaction")
718+
return
719+
}
720+
transactionQueried.fulfill()
721+
}
722+
723+
// "Group"
724+
let groupQueried = expectation(description: "Group model queried")
725+
storageAdapter.query(Group.self) { result in
726+
guard case .success = result else {
727+
XCTFail("Failed to query Group")
728+
return
729+
}
730+
groupQueried.fulfill()
731+
}
732+
733+
// "Row"
734+
let rowQueried = expectation(description: "Row model queried")
735+
storageAdapter.query(Row.self) { result in
736+
guard case .success = result else {
737+
XCTFail("Failed to query Row")
738+
return
739+
}
740+
rowQueried.fulfill()
741+
}
742+
wait(for: [transactionQueried, groupQueried, rowQueried], timeout: 1)
743+
}
744+
}

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Migration/SQLiteMutationSyncMetadataMigrationDelegateTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class SQLiteMutationSyncMetadataMigrationDelegateTests: MutationSyncMetadataMigr
3939
let delegate = SQLiteMutationSyncMetadataMigrationDelegate(storageAdapter: storageAdapter,
4040
modelSchemas: modelSchemas)
4141
let sql = try delegate.emptyMutationSyncMetadataStore()
42-
XCTAssertEqual(sql, "delete from MutationSyncMetadata as root")
42+
XCTAssertEqual(sql, "delete from \"MutationSyncMetadata\" as root")
4343
guard let mutationSyncMetadatas = queryMutationSyncMetadata() else {
4444
XCTFail("Could not get metadata")
4545
return
@@ -61,7 +61,7 @@ class SQLiteMutationSyncMetadataMigrationDelegateTests: MutationSyncMetadataMigr
6161
let delegate = SQLiteMutationSyncMetadataMigrationDelegate(storageAdapter: storageAdapter,
6262
modelSchemas: modelSchemas)
6363
let sql = try delegate.emptyModelSyncMetadataStore()
64-
XCTAssertEqual(sql, "delete from ModelSyncMetadata as root")
64+
XCTAssertEqual(sql, "delete from \"ModelSyncMetadata\" as root")
6565
guard let modelSyncMetadatasDeleted = queryModelSyncMetadata() else {
6666
XCTFail("Could not get metadata")
6767
return

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/TestSupport/Mocks/TestModelRegistration.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct TestModelRegistration: AmplifyModelRegistration {
2626

2727
// Models for data conversion testing
2828
registry.register(modelType: ExampleWithEveryType.self)
29+
30+
// Reserved words models
31+
registry.register(modelType: Group.self)
32+
registry.register(modelType: Row.self)
33+
registry.register(modelType: Transaction.self)
2934
}
3035

3136
let version: String = "1"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// Group+Schema.swift
3+
// AmplifyTestCommon
4+
//
5+
// Created by Costantino, Diego on 2021-11-30.
6+
//
7+
8+
import Foundation
9+
import Amplify
10+
11+
extension Group {
12+
// MARK: - CodingKeys
13+
public enum CodingKeys: String, ModelKey {
14+
case id
15+
}
16+
17+
public static let keys = CodingKeys.self
18+
// MARK: - ModelSchema
19+
20+
public static let schema = defineSchema { model in
21+
let group = Group.keys
22+
23+
model.listPluralName = "Groups"
24+
model.syncPluralName = "Groups"
25+
26+
model.fields(
27+
.id()
28+
)
29+
}
30+
}

0 commit comments

Comments
 (0)