This commit is contained in:
Justin Mazzocchi 2020-09-29 16:44:31 -07:00
parent 1d18e0d5e2
commit c616b13dcb
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
13 changed files with 43 additions and 67 deletions

View file

@ -12,16 +12,13 @@ public struct AccountList: Codable, FetchableRecord, PersistableRecord {
} }
extension AccountList { extension AccountList {
static let joins = hasMany( static let joins = hasMany(AccountListJoin.self).order(AccountListJoin.Columns.index)
AccountListJoin.self,
using: ForeignKey([AccountListJoin.Columns.listId]))
.order(AccountListJoin.Columns.index)
static let accounts = hasMany( static let accounts = hasMany(
AccountRecord.self, AccountRecord.self,
through: joins, through: joins,
using: AccountListJoin.account) using: AccountListJoin.account)
var accounts: QueryInterfaceRequest<AccountResult> { var accounts: QueryInterfaceRequest<AccountResult> {
request(for: Self.accounts).accountResultRequest AccountResult.request(request(for: Self.accounts))
} }
} }

View file

@ -8,7 +8,7 @@ struct AccountListJoin: Codable, FetchableRecord, PersistableRecord {
let listId: UUID let listId: UUID
let index: Int let index: Int
static let account = belongsTo(AccountRecord.self, using: ForeignKey([Columns.accountId])) static let account = belongsTo(AccountRecord.self)
} }
extension AccountListJoin { extension AccountListJoin {

View file

@ -8,7 +8,7 @@ struct AccountPinnedStatusJoin: Codable, FetchableRecord, PersistableRecord {
let statusId: String let statusId: String
let index: Int let index: Int
static let status = belongsTo(StatusRecord.self, using: ForeignKey([Columns.statusId])) static let status = belongsTo(StatusRecord.self)
} }
extension AccountPinnedStatusJoin { extension AccountPinnedStatusJoin {

View file

@ -63,10 +63,8 @@ extension AccountRecord: FetchableRecord, PersistableRecord {
} }
extension AccountRecord { extension AccountRecord {
static let moved = belongsTo(AccountRecord.self, key: "moved") static let moved = belongsTo(AccountRecord.self)
static let pinnedStatusJoins = hasMany( static let pinnedStatusJoins = hasMany(AccountPinnedStatusJoin.self)
AccountPinnedStatusJoin.self,
using: ForeignKey([AccountPinnedStatusJoin.Columns.accountId]))
.order(AccountPinnedStatusJoin.Columns.index) .order(AccountPinnedStatusJoin.Columns.index)
static let pinnedStatuses = hasMany( static let pinnedStatuses = hasMany(
StatusRecord.self, StatusRecord.self,
@ -74,7 +72,7 @@ extension AccountRecord {
using: AccountPinnedStatusJoin.status) using: AccountPinnedStatusJoin.status)
var pinnedStatuses: QueryInterfaceRequest<StatusResult> { var pinnedStatuses: QueryInterfaceRequest<StatusResult> {
request(for: Self.pinnedStatuses).statusResultRequest StatusResult.request(request(for: Self.pinnedStatuses))
} }
init(account: Account) { init(account: Account) {

View file

@ -8,9 +8,8 @@ struct AccountResult: Codable, Hashable, FetchableRecord {
let moved: AccountRecord? let moved: AccountRecord?
} }
extension QueryInterfaceRequest where RowDecoder == AccountRecord { extension AccountResult {
var accountResultRequest: QueryInterfaceRequest<AccountResult> { static func request(_ request: QueryInterfaceRequest<AccountRecord>) -> QueryInterfaceRequest<Self> {
including(optional: AccountRecord.moved) request.including(optional: AccountRecord.moved.forKey(CodingKeys.moved)).asRequest(of: self)
.asRequest(of: AccountResult.self)
} }
} }

View file

@ -8,7 +8,7 @@ struct AccountStatusJoin: Codable, FetchableRecord, PersistableRecord {
let statusId: String let statusId: String
let collection: ProfileCollection let collection: ProfileCollection
static let status = belongsTo(StatusRecord.self, using: ForeignKey([Columns.statusId])) static let status = belongsTo(StatusRecord.self)
} }
extension AccountStatusJoin { extension AccountStatusJoin {

View file

@ -190,8 +190,7 @@ public extension ContentDatabase {
func contextObservation(parentID: String) -> AnyPublisher<[[Status]], Error> { func contextObservation(parentID: String) -> AnyPublisher<[[Status]], Error> {
ValueObservation.tracking { db -> [[StatusResult]] in ValueObservation.tracking { db -> [[StatusResult]] in
guard let parent = try StatusRecord.filter(StatusRecord.Columns.id == parentID) guard let parent = try StatusResult.request(StatusRecord.filter(StatusRecord.Columns.id == parentID))
.statusResultRequest
.fetchOne(db) else { .fetchOne(db) else {
return [[]] return [[]]
} }
@ -211,13 +210,12 @@ public extension ContentDatabase {
accountID: String, accountID: String,
collection: ProfileCollection) -> AnyPublisher<[[Status]], Error> { collection: ProfileCollection) -> AnyPublisher<[[Status]], Error> {
ValueObservation.tracking { db -> [[StatusResult]] in ValueObservation.tracking { db -> [[StatusResult]] in
let statuses = try StatusRecord.filter( let statuses = try StatusResult.request(StatusRecord.filter(
AccountStatusJoin AccountStatusJoin
.select(AccountStatusJoin.Columns.statusId, as: String.self) .select(AccountStatusJoin.Columns.statusId, as: String.self)
.filter(sql: "accountId = ? AND collection = ?", arguments: [accountID, collection.rawValue]) .filter(sql: "accountId = ? AND collection = ?", arguments: [accountID, collection.rawValue])
.contains(StatusRecord.Columns.id)) .contains(StatusRecord.Columns.id))
.order(StatusRecord.Columns.createdAt.desc) .order(StatusRecord.Columns.createdAt.desc))
.statusResultRequest
.fetchAll(db) .fetchAll(db)
if if
@ -266,7 +264,7 @@ public extension ContentDatabase {
} }
func accountObservation(id: String) -> AnyPublisher<Account?, Error> { func accountObservation(id: String) -> AnyPublisher<Account?, Error> {
ValueObservation.tracking(AccountRecord.filter(AccountRecord.Columns.id == id).accountResultRequest.fetchOne) ValueObservation.tracking(AccountResult.request(AccountRecord.filter(AccountRecord.Columns.id == id)).fetchOne)
.removeDuplicates() .removeDuplicates()
.publisher(in: databaseWriter) .publisher(in: databaseWriter)
.map { .map {

View file

@ -81,21 +81,17 @@ extension StatusRecord: FetchableRecord, PersistableRecord {
} }
extension StatusRecord { extension StatusRecord {
static let account = belongsTo(AccountRecord.self, key: "account", static let account = belongsTo(AccountRecord.self)
using: ForeignKey([StatusRecord.Columns.accountId]))
static let accountMoved = hasOne(AccountRecord.self, static let accountMoved = hasOne(AccountRecord.self,
through: Self.account, through: Self.account,
using: AccountRecord.moved, using: AccountRecord.moved)
key: "accountMoved")
static let reblogAccount = hasOne(AccountRecord.self, static let reblogAccount = hasOne(AccountRecord.self,
through: Self.reblog, through: Self.reblog,
using: Self.account, using: Self.account)
key: "reblogAccount")
static let reblogAccountMoved = hasOne(AccountRecord.self, static let reblogAccountMoved = hasOne(AccountRecord.self,
through: Self.reblogAccount, through: Self.reblogAccount,
using: AccountRecord.moved, using: AccountRecord.moved)
key: "reblogAccountMoved") static let reblog = belongsTo(StatusRecord.self)
static let reblog = belongsTo(StatusRecord.self, key: "reblog")
static let ancestorJoins = hasMany( static let ancestorJoins = hasMany(
StatusContextJoin.self, StatusContextJoin.self,
using: ForeignKey([StatusContextJoin.Columns.parentId])) using: ForeignKey([StatusContextJoin.Columns.parentId]))
@ -114,11 +110,11 @@ extension StatusRecord {
using: StatusContextJoin.status) using: StatusContextJoin.status)
var ancestors: QueryInterfaceRequest<StatusResult> { var ancestors: QueryInterfaceRequest<StatusResult> {
request(for: Self.ancestors).statusResultRequest StatusResult.request(request(for: Self.ancestors))
} }
var descendants: QueryInterfaceRequest<StatusResult> { var descendants: QueryInterfaceRequest<StatusResult> {
request(for: Self.descendants).statusResultRequest StatusResult.request(request(for: Self.descendants))
} }
init(status: Status) { init(status: Status) {

View file

@ -13,6 +13,15 @@ struct StatusResult: Codable, Hashable, FetchableRecord {
} }
extension StatusResult { extension StatusResult {
static func request(_ request: QueryInterfaceRequest<StatusRecord>) -> QueryInterfaceRequest<Self> {
request.including(required: StatusRecord.account.forKey(CodingKeys.account))
.including(optional: StatusRecord.accountMoved.forKey(CodingKeys.accountMoved))
.including(optional: StatusRecord.reblogAccount.forKey(CodingKeys.reblogAccount))
.including(optional: StatusRecord.reblogAccountMoved.forKey(CodingKeys.reblogAccountMoved))
.including(optional: StatusRecord.reblog.forKey(CodingKeys.reblog))
.asRequest(of: self)
}
var accountResult: AccountResult { var accountResult: AccountResult {
AccountResult(account: account, moved: accountMoved) AccountResult(account: account, moved: accountMoved)
} }
@ -23,14 +32,3 @@ extension StatusResult {
return AccountResult(account: reblogAccount, moved: reblogAccountMoved) return AccountResult(account: reblogAccount, moved: reblogAccountMoved)
} }
} }
extension QueryInterfaceRequest where RowDecoder == StatusRecord {
var statusResultRequest: QueryInterfaceRequest<StatusResult> {
including(required: StatusRecord.account)
.including(optional: StatusRecord.accountMoved)
.including(optional: StatusRecord.reblogAccount)
.including(optional: StatusRecord.reblogAccountMoved)
.including(optional: StatusRecord.reblog)
.asRequest(of: StatusResult.self)
}
}

View file

@ -46,6 +46,6 @@ extension Timeline {
.order(StatusRecord.Columns.createdAt.desc) .order(StatusRecord.Columns.createdAt.desc)
var statuses: QueryInterfaceRequest<StatusResult> { var statuses: QueryInterfaceRequest<StatusResult> {
request(for: Self.statuses).statusResultRequest StatusResult.request(request(for: Self.statuses))
} }
} }

View file

@ -156,10 +156,7 @@ public extension IdentityDatabase {
func identityObservation(id: UUID, immediate: Bool) -> AnyPublisher<Identity, Error> { func identityObservation(id: UUID, immediate: Bool) -> AnyPublisher<Identity, Error> {
ValueObservation.tracking( ValueObservation.tracking(
IdentityRecord IdentityResult.request(IdentityRecord.filter(IdentityRecord.Columns.id == id)).fetchOne)
.filter(IdentityRecord.Columns.id == id)
.identityResultRequest
.fetchOne)
.removeDuplicates() .removeDuplicates()
.publisher(in: databaseWriter, scheduling: immediate ? .immediate : .async(onQueue: .main)) .publisher(in: databaseWriter, scheduling: immediate ? .immediate : .async(onQueue: .main))
.tryMap { .tryMap {
@ -172,10 +169,7 @@ public extension IdentityDatabase {
func identitiesObservation() -> AnyPublisher<[Identity], Error> { func identitiesObservation() -> AnyPublisher<[Identity], Error> {
ValueObservation.tracking( ValueObservation.tracking(
IdentityRecord IdentityResult.request(IdentityRecord.order(IdentityRecord.Columns.lastUsedAt.desc)).fetchAll)
.order(IdentityRecord.Columns.lastUsedAt.desc)
.identityResultRequest
.fetchAll)
.removeDuplicates() .removeDuplicates()
.publisher(in: databaseWriter) .publisher(in: databaseWriter)
.map { $0.map(Identity.init(result:)) } .map { $0.map(Identity.init(result:)) }
@ -184,9 +178,7 @@ public extension IdentityDatabase {
func recentIdentitiesObservation(excluding: UUID) -> AnyPublisher<[Identity], Error> { func recentIdentitiesObservation(excluding: UUID) -> AnyPublisher<[Identity], Error> {
ValueObservation.tracking( ValueObservation.tracking(
IdentityRecord IdentityResult.request(IdentityRecord.order(IdentityRecord.Columns.lastUsedAt.desc))
.order(IdentityRecord.Columns.lastUsedAt.desc)
.identityResultRequest
.filter(IdentityRecord.Columns.id != excluding) .filter(IdentityRecord.Columns.id != excluding)
.limit(9) .limit(9)
.fetchAll) .fetchAll)
@ -207,9 +199,7 @@ public extension IdentityDatabase {
func identitiesWithOutdatedDeviceTokens(deviceToken: Data) -> AnyPublisher<[Identity], Error> { func identitiesWithOutdatedDeviceTokens(deviceToken: Data) -> AnyPublisher<[Identity], Error> {
databaseWriter.readPublisher( databaseWriter.readPublisher(
value: IdentityRecord value: IdentityResult.request(IdentityRecord.order(IdentityRecord.Columns.lastUsedAt.desc))
.order(IdentityRecord.Columns.lastUsedAt.desc)
.identityResultRequest
.filter(IdentityRecord.Columns.lastRegisteredDeviceToken != deviceToken) .filter(IdentityRecord.Columns.lastRegisteredDeviceToken != deviceToken)
.fetchAll) .fetchAll)
.map { $0.map(Identity.init(result:)) } .map { $0.map(Identity.init(result:)) }

View file

@ -29,8 +29,8 @@ extension IdentityRecord {
static let pushSubscriptionAlerts = Column(IdentityRecord.CodingKeys.pushSubscriptionAlerts) static let pushSubscriptionAlerts = Column(IdentityRecord.CodingKeys.pushSubscriptionAlerts)
} }
static let instance = belongsTo(Identity.Instance.self, key: "instance") static let instance = belongsTo(Identity.Instance.self)
static let account = hasOne(Identity.Account.self, key: "account") static let account = hasOne(Identity.Account.self)
var instance: QueryInterfaceRequest<Identity.Instance> { var instance: QueryInterfaceRequest<Identity.Instance> {
request(for: Self.instance) request(for: Self.instance)

View file

@ -10,10 +10,10 @@ struct IdentityResult: Codable, Hashable, FetchableRecord {
let account: Identity.Account? let account: Identity.Account?
} }
extension QueryInterfaceRequest where RowDecoder == IdentityRecord { extension IdentityResult {
var identityResultRequest: QueryInterfaceRequest<IdentityResult> { static func request(_ request: QueryInterfaceRequest<IdentityRecord>) -> QueryInterfaceRequest<Self> {
including(optional: IdentityRecord.instance) request.including(optional: IdentityRecord.instance.forKey(CodingKeys.instance))
.including(optional: IdentityRecord.account) .including(optional: IdentityRecord.account.forKey(CodingKeys.account))
.asRequest(of: IdentityResult.self) .asRequest(of: self)
} }
} }