From f1ab605ad2056944eee80cb7cf55f5b94f17e74e Mon Sep 17 00:00:00 2001 From: Justin Meiners Date: Thu, 24 Feb 2022 09:49:20 -0700 Subject: [PATCH 1/3] improve performance of prefixed column resolution - Previously this allocated arrays every time it was accessed. It will now only allocate in one of the error cases. - It also keeps track of the columnName index for both key and value so it doesn't need to look it up twice. --- Sources/SQLite/Typed/Query.swift | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Sources/SQLite/Typed/Query.swift b/Sources/SQLite/Typed/Query.swift index 2d88db63..ecb501af 100644 --- a/Sources/SQLite/Typed/Query.swift +++ b/Sources/SQLite/Typed/Query.swift @@ -1169,16 +1169,25 @@ public struct Row { } guard let idx = columnNames[column.template] else { - let similar = Array(columnNames.keys).filter { $0.hasSuffix(".\(column.template)") } - - switch similar.count { - case 0: + func match(_ s: String) -> Bool { + return s.hasSuffix(".\(column.template)") + } + + guard let firstIndex = columnNames.firstIndex(where: { match($0.key) }) else { throw QueryError.noSuchColumn(name: column.template, columns: columnNames.keys.sorted()) - case 1: - return valueAtIndex(columnNames[similar[0]]!) - default: - throw QueryError.ambiguousColumn(name: column.template, similar: similar) } + + let secondIndex = columnNames + .suffix(from: columnNames.index(after: firstIndex)) + .firstIndex(where: { match($0.key) }) + + guard secondIndex == nil else { + throw QueryError.ambiguousColumn( + name: column.template, + similar: columnNames.keys.filter(match).sorted() + ) + } + return valueAtIndex(columnNames[firstIndex].value) } return valueAtIndex(idx) From 55bf2c10e10b84855ac3a26c10dc601271c6d171 Mon Sep 17 00:00:00 2001 From: Justin Meiners Date: Thu, 24 Feb 2022 09:52:56 -0700 Subject: [PATCH 2/3] rename match -> similar to follow convention --- Sources/SQLite/Typed/Query.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/SQLite/Typed/Query.swift b/Sources/SQLite/Typed/Query.swift index ecb501af..6dd07ac4 100644 --- a/Sources/SQLite/Typed/Query.swift +++ b/Sources/SQLite/Typed/Query.swift @@ -1169,22 +1169,22 @@ public struct Row { } guard let idx = columnNames[column.template] else { - func match(_ s: String) -> Bool { + func similar(_ s: String) -> Bool { return s.hasSuffix(".\(column.template)") } - guard let firstIndex = columnNames.firstIndex(where: { match($0.key) }) else { + guard let firstIndex = columnNames.firstIndex(where: { similar($0.key) }) else { throw QueryError.noSuchColumn(name: column.template, columns: columnNames.keys.sorted()) } let secondIndex = columnNames .suffix(from: columnNames.index(after: firstIndex)) - .firstIndex(where: { match($0.key) }) + .firstIndex(where: { similar($0.key) }) guard secondIndex == nil else { throw QueryError.ambiguousColumn( name: column.template, - similar: columnNames.keys.filter(match).sorted() + similar: columnNames.keys.filter(similar).sorted() ) } return valueAtIndex(columnNames[firstIndex].value) From c659dc9256f1b80505d0bd5bbca026005cd43af2 Mon Sep 17 00:00:00 2001 From: Justin Meiners Date: Thu, 24 Feb 2022 13:46:25 -0700 Subject: [PATCH 3/3] Fix lint issues --- Sources/SQLite/Typed/Query.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/SQLite/Typed/Query.swift b/Sources/SQLite/Typed/Query.swift index 6dd07ac4..93dc2a73 100644 --- a/Sources/SQLite/Typed/Query.swift +++ b/Sources/SQLite/Typed/Query.swift @@ -1169,18 +1169,18 @@ public struct Row { } guard let idx = columnNames[column.template] else { - func similar(_ s: String) -> Bool { - return s.hasSuffix(".\(column.template)") + func similar(_ name: String) -> Bool { + return name.hasSuffix(".\(column.template)") } - + guard let firstIndex = columnNames.firstIndex(where: { similar($0.key) }) else { throw QueryError.noSuchColumn(name: column.template, columns: columnNames.keys.sorted()) } - + let secondIndex = columnNames .suffix(from: columnNames.index(after: firstIndex)) .firstIndex(where: { similar($0.key) }) - + guard secondIndex == nil else { throw QueryError.ambiguousColumn( name: column.template,