Simplify schema

This commit is contained in:
Justin Mazzocchi 2021-01-16 02:04:04 -08:00
parent 8c207b53a6
commit 8831a6c8e6
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
6 changed files with 15 additions and 93 deletions

View file

@ -1,28 +0,0 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Foundation
import GRDB
public struct AccountList: ContentDatabaseRecord {
let id: Id
public init() {
id = Id()
}
}
public extension AccountList {
typealias Id = UUID
}
extension AccountList {
static let joins = hasMany(AccountListJoin.self).order(AccountListJoin.Columns.index)
static let accounts = hasMany(
AccountRecord.self,
through: joins,
using: AccountListJoin.account)
var accounts: QueryInterfaceRequest<AccountInfo> {
AccountInfo.request(request(for: Self.accounts))
}
}

View file

@ -1,21 +0,0 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Foundation
import GRDB
import Mastodon
struct AccountListJoin: ContentDatabaseRecord {
let accountId: Account.Id
let listId: AccountList.Id
let index: Int
static let account = belongsTo(AccountRecord.self)
}
extension AccountListJoin {
enum Columns {
static let accountId = Column(CodingKeys.accountId)
static let listId = Column(CodingKeys.listId)
static let index = Column(CodingKeys.index)
}
}

View file

@ -221,20 +221,6 @@ extension ContentDatabase {
t.primaryKey(["accountId", "statusId"], onConflict: .replace)
}
try db.create(table: "accountList") { t in
t.column("id", .text).primaryKey(onConflict: .replace)
}
try db.create(table: "accountListJoin") { t in
t.column("accountId", .text).indexed().notNull()
.references("accountRecord", onDelete: .cascade)
t.column("listId", .text).indexed().notNull()
.references("accountList", onDelete: .cascade)
t.column("index", .integer).notNull()
t.primaryKey(["accountId", "listId"], onConflict: .replace)
}
}
return migrator

View file

@ -257,27 +257,16 @@ public extension ContentDatabase {
.eraseToAnyPublisher()
}
func append(accounts: [Account], toList list: AccountList) -> AnyPublisher<Never, Error> {
func insert(accounts: [Account]) -> AnyPublisher<Never, Error> {
databaseWriter.writePublisher {
try list.save($0)
let count = try list.accounts.fetchCount($0)
for (index, account) in accounts.enumerated() {
for account in accounts {
try account.save($0)
try AccountListJoin(accountId: account.id, listId: list.id, index: count + index).save($0)
}
}
.ignoreOutput()
.eraseToAnyPublisher()
}
func insert(account: Account) -> AnyPublisher<Never, Error> {
databaseWriter.writePublisher(updates: account.save)
.ignoreOutput()
.eraseToAnyPublisher()
}
func insert(identityProofs: [IdentityProof], id: Account.Id) -> AnyPublisher<Never, Error> {
databaseWriter.writePublisher {
for identityProof in identityProofs {
@ -488,14 +477,6 @@ public extension ContentDatabase {
.eraseToAnyPublisher()
}
func accountListPublisher(_ list: AccountList) -> AnyPublisher<[Account], Error> {
ValueObservation.tracking(list.accounts.fetchAll)
.removeDuplicates()
.map { $0.map(Account.init(info:)) }
.publisher(in: databaseWriter)
.eraseToAnyPublisher()
}
func notificationsPublisher() -> AnyPublisher<[[CollectionItem]], Error> {
ValueObservation.tracking(
NotificationInfo.request(
@ -642,8 +623,6 @@ private extension ContentDatabase {
try StatusRecord.filter(!notificationStatusIds.contains(StatusRecord.Columns.id)).deleteAll($0)
try AccountRecord.filter(!notificationAccountIds.contains(AccountRecord.Columns.id)).deleteAll($0)
}
try AccountList.deleteAll($0)
}
}
}

View file

@ -11,7 +11,7 @@ public struct AccountListService {
public let nextPageMaxId: AnyPublisher<String, Never>
public let navigationService: NavigationService
private let list: AccountList
private let accountList = CurrentValueSubject<[Account], Error>([])
private let endpoint: AccountsEndpoint
private let mastodonAPIClient: MastodonAPIClient
private let contentDatabase: ContentDatabase
@ -22,14 +22,11 @@ public struct AccountListService {
mastodonAPIClient: MastodonAPIClient,
contentDatabase: ContentDatabase,
titleComponents: [String]? = nil) {
list = AccountList()
self.endpoint = endpoint
self.mastodonAPIClient = mastodonAPIClient
self.contentDatabase = contentDatabase
self.titleComponents = titleComponents
sections = contentDatabase.accountListPublisher(list)
.map { [$0.map(CollectionItem.account)] }
.eraseToAnyPublisher()
sections = accountList.map { [$0.map(CollectionItem.account)] }.eraseToAnyPublisher()
nextPageMaxId = nextPageMaxIdSubject.eraseToAnyPublisher()
navigationService = NavigationService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
}
@ -43,7 +40,16 @@ extension AccountListService: CollectionService {
nextPageMaxIdSubject.send(maxId)
})
.flatMap { contentDatabase.append(accounts: $0.result, toList: list) }
.flatMap { response in
contentDatabase.insert(accounts: response.result)
.collect()
.map { _ in
let presentIds = Set(accountList.value.map(\.id))
accountList.value += response.result.filter { !presentIds.contains($0.id) }
}
}
.ignoreOutput()
.eraseToAnyPublisher()
}

View file

@ -67,7 +67,7 @@ public extension ProfileService {
func fetchProfile() -> AnyPublisher<Never, Error> {
Publishers.Merge3(
mastodonAPIClient.request(AccountEndpoint.accounts(id: id))
.flatMap { contentDatabase.insert(account: $0) },
.flatMap { contentDatabase.insert(accounts: [$0]) },
mastodonAPIClient.request(RelationshipsEndpoint.relationships(ids: [id]))
.flatMap { contentDatabase.insert(relationships: $0) },
mastodonAPIClient.request(IdentityProofsEndpoint.identityProofs(id: id))