diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift index ddb576ba9..e2a62b8d0 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift @@ -332,7 +332,7 @@ private extension ArticlesDatabase { CREATE INDEX if not EXISTS statuses_starred_index on statuses (starred); - CREATE VIRTUAL TABLE if not EXISTS search using fts4(title, body); + CREATE VIRTUAL TABLE if not EXISTS search using fts4(title, body, authors); CREATE TRIGGER if not EXISTS articles_after_delete_trigger_delete_search_text after delete on articles begin delete from search where rowid = OLD.searchRowID; end; """ diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift index 61c2845ef..0f9533c74 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift @@ -149,7 +149,23 @@ final class ArticlesTable: DatabaseTable { func fetchArticleSearchInfos(_ articleIDs: Set, in database: FMDatabase) -> Set? { let parameters = articleIDs.map { $0 as AnyObject } let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))! - let sql = "select articleID, title, contentHTML, contentText, summary, searchRowID from articles where articleID in \(placeholders);"; + // Aggregating authors names in SQL using a subquery with GROUP_CONCAT + let sql = """ + SELECT + art.articleID, + art.title, + art.contentHTML, + art.contentText, + art.summary, + art.searchRowID, + (SELECT GROUP_CONCAT(name SEPARATOR ' ') + FROM authorLookup as autL + JOIN authors as aut ON autL.authorID = aut.authorID + WHERE art.articleID = autL.articleID + GROUP BY autl.articleID) as authors + FROM articles as art + WHERE articleID in \(placeholders); + """; if let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) { return resultSet.mapToSet { (row) -> ArticleSearchInfo? in @@ -158,6 +174,7 @@ final class ArticlesTable: DatabaseTable { let contentHTML = row.string(forColumn: DatabaseKey.contentHTML) let contentText = row.string(forColumn: DatabaseKey.contentText) let summary = row.string(forColumn: DatabaseKey.summary) + let authors = row.string(forColumn: DatabaseKey.authors) let searchRowIDObject = row.object(forColumnName: DatabaseKey.searchRowID) var searchRowID: Int? = nil @@ -165,7 +182,7 @@ final class ArticlesTable: DatabaseTable { searchRowID = Int(row.longLongInt(forColumn: DatabaseKey.searchRowID)) } - return ArticleSearchInfo(articleID: articleID, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, searchRowID: searchRowID) + return ArticleSearchInfo(articleID: articleID, title: title, authorsNames: authors, contentHTML: contentHTML, contentText: contentText, summary: summary, searchRowID: searchRowID) } } return nil diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift index 9f97a6d69..788ac6418 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift @@ -17,6 +17,7 @@ final class ArticleSearchInfo: Hashable { let articleID: String let title: String? + let authorsNames: String? let contentHTML: String? let contentText: String? let summary: String? @@ -37,9 +38,10 @@ final class ArticleSearchInfo: Hashable { return s.strippingHTML().collapsingWhitespace }() - init(articleID: String, title: String?, contentHTML: String?, contentText: String?, summary: String?, searchRowID: Int?) { + init(articleID: String, title: String?, authorsNames: String?, contentHTML: String?, contentText: String?, summary: String?, searchRowID: Int?) { self.articleID = articleID self.title = title + self.authorsNames = authorsNames self.contentHTML = contentHTML self.contentText = contentText self.summary = summary @@ -47,7 +49,7 @@ final class ArticleSearchInfo: Hashable { } convenience init(article: Article) { - self.init(articleID: article.articleID, title: article.title, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, searchRowID: nil) + self.init(articleID: article.articleID, title: article.title, authorsNames: article.authors?.map({ $0.name }).reduce("", { $0.appending("").appending($1 ?? "") }), contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, searchRowID: nil) } // MARK: Hashable @@ -127,7 +129,7 @@ private extension SearchTable { } func insert(_ article: ArticleSearchInfo, _ database: FMDatabase) -> Int { - let rowDictionary: DatabaseDictionary = [DatabaseKey.body: article.bodyForIndex, DatabaseKey.title: article.title ?? ""] + let rowDictionary: DatabaseDictionary = [DatabaseKey.body: article.bodyForIndex, DatabaseKey.title: article.title ?? "", DatabaseKey.authors: article.authorsNames ?? ""] insertRow(rowDictionary, insertType: .normal, in: database) return Int(database.lastInsertRowId()) }