mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 09:41:00 +00:00
Cleanup
This commit is contained in:
parent
7335615b64
commit
f5dcb762d1
14 changed files with 195 additions and 71 deletions
|
@ -14,8 +14,8 @@ public struct AccountList: Codable, FetchableRecord, PersistableRecord {
|
||||||
extension AccountList {
|
extension AccountList {
|
||||||
static let joins = hasMany(
|
static let joins = hasMany(
|
||||||
AccountListJoin.self,
|
AccountListJoin.self,
|
||||||
using: ForeignKey([Column("listId")]))
|
using: ForeignKey([AccountListJoin.Columns.listId]))
|
||||||
.order(Column("index"))
|
.order(AccountListJoin.Columns.index)
|
||||||
static let accounts = hasMany(
|
static let accounts = hasMany(
|
||||||
AccountRecord.self,
|
AccountRecord.self,
|
||||||
through: joins,
|
through: joins,
|
||||||
|
|
|
@ -8,5 +8,13 @@ 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([Column("accountId")]))
|
static let account = belongsTo(AccountRecord.self, using: ForeignKey([Columns.accountId]))
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountListJoin {
|
||||||
|
enum Columns {
|
||||||
|
static let accountId = Column(AccountListJoin.CodingKeys.accountId)
|
||||||
|
static let listId = Column(AccountListJoin.CodingKeys.listId)
|
||||||
|
static let index = Column(AccountListJoin.CodingKeys.index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,13 @@ 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([Column("statusId")]))
|
static let status = belongsTo(StatusRecord.self, using: ForeignKey([Columns.statusId]))
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountPinnedStatusJoin {
|
||||||
|
enum Columns {
|
||||||
|
static let accountId = Column(AccountPinnedStatusJoin.CodingKeys.accountId)
|
||||||
|
static let statusId = Column(AccountPinnedStatusJoin.CodingKeys.statusId)
|
||||||
|
static let index = Column(AccountPinnedStatusJoin.CodingKeys.index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,31 @@ struct AccountRecord: Codable, Hashable {
|
||||||
let movedId: String?
|
let movedId: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension AccountRecord {
|
||||||
|
enum Columns {
|
||||||
|
static let id = Column(AccountRecord.CodingKeys.id)
|
||||||
|
static let username = Column(AccountRecord.CodingKeys.username)
|
||||||
|
static let acct = Column(AccountRecord.CodingKeys.acct)
|
||||||
|
static let displayName = Column(AccountRecord.CodingKeys.displayName)
|
||||||
|
static let locked = Column(AccountRecord.CodingKeys.locked)
|
||||||
|
static let createdAt = Column(AccountRecord.CodingKeys.createdAt)
|
||||||
|
static let followersCount = Column(AccountRecord.CodingKeys.followersCount)
|
||||||
|
static let followingCount = Column(AccountRecord.CodingKeys.followingCount)
|
||||||
|
static let statusesCount = Column(AccountRecord.CodingKeys.statusesCount)
|
||||||
|
static let note = Column(AccountRecord.CodingKeys.note)
|
||||||
|
static let url = Column(AccountRecord.CodingKeys.url)
|
||||||
|
static let avatar = Column(AccountRecord.CodingKeys.avatar)
|
||||||
|
static let avatarStatic = Column(AccountRecord.CodingKeys.avatarStatic)
|
||||||
|
static let header = Column(AccountRecord.CodingKeys.header)
|
||||||
|
static let headerStatic = Column(AccountRecord.CodingKeys.headerStatic)
|
||||||
|
static let fields = Column(AccountRecord.CodingKeys.fields)
|
||||||
|
static let emojis = Column(AccountRecord.CodingKeys.emojis)
|
||||||
|
static let bot = Column(AccountRecord.CodingKeys.bot)
|
||||||
|
static let discoverable = Column(AccountRecord.CodingKeys.discoverable)
|
||||||
|
static let movedId = Column(AccountRecord.CodingKeys.movedId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension AccountRecord: FetchableRecord, PersistableRecord {
|
extension AccountRecord: FetchableRecord, PersistableRecord {
|
||||||
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
||||||
MastodonDecoder()
|
MastodonDecoder()
|
||||||
|
@ -41,8 +66,8 @@ extension AccountRecord {
|
||||||
static let moved = belongsTo(AccountRecord.self, key: "moved")
|
static let moved = belongsTo(AccountRecord.self, key: "moved")
|
||||||
static let pinnedStatusJoins = hasMany(
|
static let pinnedStatusJoins = hasMany(
|
||||||
AccountPinnedStatusJoin.self,
|
AccountPinnedStatusJoin.self,
|
||||||
using: ForeignKey([Column("accountId")]))
|
using: ForeignKey([AccountPinnedStatusJoin.Columns.accountId]))
|
||||||
.order(Column("index"))
|
.order(AccountPinnedStatusJoin.Columns.index)
|
||||||
static let pinnedStatuses = hasMany(
|
static let pinnedStatuses = hasMany(
|
||||||
StatusRecord.self,
|
StatusRecord.self,
|
||||||
through: pinnedStatusJoins,
|
through: pinnedStatusJoins,
|
||||||
|
|
|
@ -8,5 +8,13 @@ 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([Column("statusId")]))
|
static let status = belongsTo(StatusRecord.self, using: ForeignKey([Columns.statusId]))
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountStatusJoin {
|
||||||
|
enum Columns {
|
||||||
|
static let accountId = Column(AccountStatusJoin.CodingKeys.accountId)
|
||||||
|
static let statusId = Column(AccountStatusJoin.CodingKeys.statusId)
|
||||||
|
static let collection = Column(AccountStatusJoin.CodingKeys.collection)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,9 +73,9 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
try StatusContextJoin.filter(
|
try StatusContextJoin.filter(
|
||||||
Column("parentId") == parentID
|
StatusContextJoin.Columns.parentId == parentID
|
||||||
&& Column("section") == section.rawValue
|
&& StatusContextJoin.Columns.section == section.rawValue
|
||||||
&& !statuses.map(\.id).contains(Column("statusId")))
|
&& !statuses.map(\.id).contains(StatusContextJoin.Columns.statusId))
|
||||||
.deleteAll($0)
|
.deleteAll($0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,8 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
try AccountPinnedStatusJoin.filter(
|
try AccountPinnedStatusJoin.filter(
|
||||||
Column("accountId") == accountID
|
AccountPinnedStatusJoin.Columns.accountId == accountID
|
||||||
&& !pinnedStatuses.map(\.id).contains(Column("statusId")))
|
&& !pinnedStatuses.map(\.id).contains(AccountPinnedStatusJoin.Columns.statusId))
|
||||||
.deleteAll($0)
|
.deleteAll($0)
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
|
@ -137,8 +137,8 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
try Timeline
|
try Timeline
|
||||||
.filter(!(Timeline.authenticatedDefaults.map(\.id) + lists.map(\.id)).contains(Column("id"))
|
.filter(!(Timeline.authenticatedDefaults.map(\.id) + lists.map(\.id)).contains(Timeline.Columns.id)
|
||||||
&& Column("listTitle") != nil)
|
&& Timeline.Columns.listTitle != nil)
|
||||||
.deleteAll($0)
|
.deleteAll($0)
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
|
@ -152,7 +152,7 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteList(id: String) -> AnyPublisher<Never, Error> {
|
func deleteList(id: String) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher(updates: Timeline.filter(Column("id") == id).deleteAll)
|
databaseWriter.writePublisher(updates: Timeline.filter(Timeline.Columns.id == id).deleteAll)
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ public extension ContentDatabase {
|
||||||
try filter.save($0)
|
try filter.save($0)
|
||||||
}
|
}
|
||||||
|
|
||||||
try Filter.filter(!filters.map(\.id).contains(Column("id"))).deleteAll($0)
|
try Filter.filter(!filters.map(\.id).contains(Filter.Columns.id)).deleteAll($0)
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
@ -176,7 +176,7 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteFilter(id: String) -> AnyPublisher<Never, Error> {
|
func deleteFilter(id: String) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher(updates: Filter.filter(Column("id") == id).deleteAll)
|
databaseWriter.writePublisher(updates: Filter.filter(Filter.Columns.id == id).deleteAll)
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,9 @@ 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(Column("id") == parentID).statusResultRequest.fetchOne(db) else {
|
guard let parent = try StatusRecord.filter(StatusRecord.Columns.id == parentID)
|
||||||
|
.statusResultRequest
|
||||||
|
.fetchOne(db) else {
|
||||||
return [[]]
|
return [[]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,16 +214,16 @@ public extension ContentDatabase {
|
||||||
ValueObservation.tracking { db -> [[StatusResult]] in
|
ValueObservation.tracking { db -> [[StatusResult]] in
|
||||||
let statuses = try StatusRecord.filter(
|
let statuses = try StatusRecord.filter(
|
||||||
AccountStatusJoin
|
AccountStatusJoin
|
||||||
.select(Column("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(Column("id")))
|
.contains(StatusRecord.Columns.id))
|
||||||
.order(Column("createdAt").desc)
|
.order(StatusRecord.Columns.createdAt.desc)
|
||||||
.statusResultRequest
|
.statusResultRequest
|
||||||
.fetchAll(db)
|
.fetchAll(db)
|
||||||
|
|
||||||
if
|
if
|
||||||
case .statuses = collection,
|
case .statuses = collection,
|
||||||
let accountRecord = try AccountRecord.filter(Column("id") == accountID).fetchOne(db) {
|
let accountRecord = try AccountRecord.filter(AccountRecord.Columns.id == accountID).fetchOne(db) {
|
||||||
let pinnedStatuses = try accountRecord.pinnedStatuses.fetchAll(db)
|
let pinnedStatuses = try accountRecord.pinnedStatuses.fetchAll(db)
|
||||||
|
|
||||||
return [pinnedStatuses, statuses]
|
return [pinnedStatuses, statuses]
|
||||||
|
@ -236,8 +238,8 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func listsObservation() -> AnyPublisher<[Timeline], Error> {
|
func listsObservation() -> AnyPublisher<[Timeline], Error> {
|
||||||
ValueObservation.tracking(Timeline.filter(Column("listTitle") != nil)
|
ValueObservation.tracking(Timeline.filter(Timeline.Columns.listTitle != nil)
|
||||||
.order(Column("listTitle").asc)
|
.order(Timeline.Columns.listTitle.asc)
|
||||||
.fetchAll)
|
.fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseWriter)
|
.publisher(in: databaseWriter)
|
||||||
|
@ -245,7 +247,8 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func activeFiltersObservation(date: Date, context: Filter.Context? = nil) -> AnyPublisher<[Filter], Error> {
|
func activeFiltersObservation(date: Date, context: Filter.Context? = nil) -> AnyPublisher<[Filter], Error> {
|
||||||
ValueObservation.tracking(Filter.filter(Column("expiresAt") == nil || Column("expiresAt") > date).fetchAll)
|
ValueObservation.tracking(
|
||||||
|
Filter.filter(Filter.Columns.expiresAt == nil || Filter.Columns.expiresAt > date).fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseWriter)
|
.publisher(in: databaseWriter)
|
||||||
.map {
|
.map {
|
||||||
|
@ -257,14 +260,14 @@ public extension ContentDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func expiredFiltersObservation(date: Date) -> AnyPublisher<[Filter], Error> {
|
func expiredFiltersObservation(date: Date) -> AnyPublisher<[Filter], Error> {
|
||||||
ValueObservation.tracking(Filter.filter(Column("expiresAt") < date).fetchAll)
|
ValueObservation.tracking(Filter.filter(Filter.Columns.expiresAt < date).fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseWriter)
|
.publisher(in: databaseWriter)
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func accountObservation(id: String) -> AnyPublisher<Account?, Error> {
|
func accountObservation(id: String) -> AnyPublisher<Account?, Error> {
|
||||||
ValueObservation.tracking(AccountRecord.filter(Column("id") == id).accountResultRequest.fetchOne)
|
ValueObservation.tracking(AccountRecord.filter(AccountRecord.Columns.id == id).accountResultRequest.fetchOne)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseWriter)
|
.publisher(in: databaseWriter)
|
||||||
.map {
|
.map {
|
||||||
|
@ -424,7 +427,7 @@ private extension ContentDatabase {
|
||||||
|
|
||||||
func clean() {
|
func clean() {
|
||||||
databaseWriter.asyncWrite {
|
databaseWriter.asyncWrite {
|
||||||
try TimelineStatusJoin.filter(Column("timelineId") != Timeline.home.id).deleteAll($0)
|
try TimelineStatusJoin.filter(TimelineStatusJoin.Columns.timelineId != Timeline.home.id).deleteAll($0)
|
||||||
try StatusContextJoin.deleteAll($0)
|
try StatusContextJoin.deleteAll($0)
|
||||||
try AccountPinnedStatusJoin.deleteAll($0)
|
try AccountPinnedStatusJoin.deleteAll($0)
|
||||||
try AccountStatusJoin.deleteAll($0)
|
try AccountStatusJoin.deleteAll($0)
|
||||||
|
|
|
@ -14,5 +14,14 @@ struct StatusContextJoin: Codable, FetchableRecord, PersistableRecord {
|
||||||
let section: Section
|
let section: Section
|
||||||
let index: Int
|
let index: Int
|
||||||
|
|
||||||
static let status = belongsTo(StatusRecord.self, using: ForeignKey([Column("statusId")]))
|
static let status = belongsTo(StatusRecord.self, using: ForeignKey([Columns.statusId]))
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StatusContextJoin {
|
||||||
|
enum Columns {
|
||||||
|
static let parentId = Column(StatusContextJoin.CodingKeys.parentId)
|
||||||
|
static let statusId = Column(StatusContextJoin.CodingKeys.statusId)
|
||||||
|
static let section = Column(StatusContextJoin.CodingKeys.section)
|
||||||
|
static let index = Column(StatusContextJoin.CodingKeys.index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,40 @@ struct StatusRecord: Codable, Hashable {
|
||||||
let pinned: Bool?
|
let pinned: Bool?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension StatusRecord {
|
||||||
|
enum Columns {
|
||||||
|
static let id = Column(StatusRecord.CodingKeys.id)
|
||||||
|
static let uri = Column(StatusRecord.CodingKeys.uri)
|
||||||
|
static let createdAt = Column(StatusRecord.CodingKeys.createdAt)
|
||||||
|
static let accountId = Column(StatusRecord.CodingKeys.accountId)
|
||||||
|
static let content = Column(StatusRecord.CodingKeys.content)
|
||||||
|
static let visibility = Column(StatusRecord.CodingKeys.visibility)
|
||||||
|
static let sensitive = Column(StatusRecord.CodingKeys.sensitive)
|
||||||
|
static let spoilerText = Column(StatusRecord.CodingKeys.spoilerText)
|
||||||
|
static let mediaAttachments = Column(StatusRecord.CodingKeys.mediaAttachments)
|
||||||
|
static let mentions = Column(StatusRecord.CodingKeys.mentions)
|
||||||
|
static let tags = Column(StatusRecord.CodingKeys.tags)
|
||||||
|
static let emojis = Column(StatusRecord.CodingKeys.emojis)
|
||||||
|
static let reblogsCount = Column(StatusRecord.CodingKeys.reblogsCount)
|
||||||
|
static let favouritesCount = Column(StatusRecord.CodingKeys.favouritesCount)
|
||||||
|
static let repliesCount = Column(StatusRecord.CodingKeys.repliesCount)
|
||||||
|
static let application = Column(StatusRecord.CodingKeys.application)
|
||||||
|
static let url = Column(StatusRecord.CodingKeys.url)
|
||||||
|
static let inReplyToId = Column(StatusRecord.CodingKeys.inReplyToId)
|
||||||
|
static let inReplyToAccountId = Column(StatusRecord.CodingKeys.inReplyToAccountId)
|
||||||
|
static let reblogId = Column(StatusRecord.CodingKeys.reblogId)
|
||||||
|
static let poll = Column(StatusRecord.CodingKeys.poll)
|
||||||
|
static let card = Column(StatusRecord.CodingKeys.card)
|
||||||
|
static let language = Column(StatusRecord.CodingKeys.language)
|
||||||
|
static let text = Column(StatusRecord.CodingKeys.text)
|
||||||
|
static let favourited = Column(StatusRecord.CodingKeys.favourited)
|
||||||
|
static let reblogged = Column(StatusRecord.CodingKeys.reblogged)
|
||||||
|
static let muted = Column(StatusRecord.CodingKeys.muted)
|
||||||
|
static let bookmarked = Column(StatusRecord.CodingKeys.bookmarked)
|
||||||
|
static let pinned = Column(StatusRecord.CodingKeys.pinned)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension StatusRecord: FetchableRecord, PersistableRecord {
|
extension StatusRecord: FetchableRecord, PersistableRecord {
|
||||||
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
||||||
MastodonDecoder()
|
MastodonDecoder()
|
||||||
|
@ -47,7 +81,8 @@ extension StatusRecord: FetchableRecord, PersistableRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusRecord {
|
extension StatusRecord {
|
||||||
static let account = belongsTo(AccountRecord.self, key: "account", using: ForeignKey([Column("accountId")]))
|
static let account = belongsTo(AccountRecord.self, key: "account",
|
||||||
|
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,
|
||||||
|
@ -61,12 +96,16 @@ extension StatusRecord {
|
||||||
using: AccountRecord.moved,
|
using: AccountRecord.moved,
|
||||||
key: "reblogAccountMoved")
|
key: "reblogAccountMoved")
|
||||||
static let reblog = belongsTo(StatusRecord.self, key: "reblog")
|
static let reblog = belongsTo(StatusRecord.self, key: "reblog")
|
||||||
static let ancestorJoins = hasMany(StatusContextJoin.self, using: ForeignKey([Column("parentID")]))
|
static let ancestorJoins = hasMany(
|
||||||
.filter(Column("section") == StatusContextJoin.Section.ancestors.rawValue)
|
StatusContextJoin.self,
|
||||||
.order(Column("index"))
|
using: ForeignKey([StatusContextJoin.Columns.parentId]))
|
||||||
static let descendantJoins = hasMany(StatusContextJoin.self, using: ForeignKey([Column("parentID")]))
|
.filter(StatusContextJoin.Columns.section == StatusContextJoin.Section.ancestors.rawValue)
|
||||||
.filter(Column("section") == StatusContextJoin.Section.descendants.rawValue)
|
.order(StatusContextJoin.Columns.index)
|
||||||
.order(Column("index"))
|
static let descendantJoins = hasMany(
|
||||||
|
StatusContextJoin.self,
|
||||||
|
using: ForeignKey([StatusContextJoin.Columns.parentId]))
|
||||||
|
.filter(StatusContextJoin.Columns.section == StatusContextJoin.Section.descendants.rawValue)
|
||||||
|
.order(StatusContextJoin.Columns.index)
|
||||||
static let ancestors = hasMany(StatusRecord.self,
|
static let ancestors = hasMany(StatusRecord.self,
|
||||||
through: ancestorJoins,
|
through: ancestorJoins,
|
||||||
using: StatusContextJoin.status)
|
using: StatusContextJoin.status)
|
||||||
|
|
|
@ -9,3 +9,10 @@ struct TimelineStatusJoin: Codable, FetchableRecord, PersistableRecord {
|
||||||
|
|
||||||
static let status = belongsTo(StatusRecord.self)
|
static let status = belongsTo(StatusRecord.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension TimelineStatusJoin {
|
||||||
|
enum Columns {
|
||||||
|
static let timelineId = Column(TimelineStatusJoin.CodingKeys.timelineId)
|
||||||
|
static let statusId = Column(TimelineStatusJoin.CodingKeys.statusId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,15 @@ import GRDB
|
||||||
import Mastodon
|
import Mastodon
|
||||||
|
|
||||||
extension Filter: FetchableRecord, PersistableRecord {
|
extension Filter: FetchableRecord, PersistableRecord {
|
||||||
|
enum Columns: String, ColumnExpression {
|
||||||
|
case id
|
||||||
|
case phrase
|
||||||
|
case context
|
||||||
|
case expiresAt
|
||||||
|
case irreversible
|
||||||
|
case wholeWord
|
||||||
|
}
|
||||||
|
|
||||||
public static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
public static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
||||||
MastodonDecoder()
|
MastodonDecoder()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
// Copyright © 2020 Metabolist. All rights reserved.
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import GRDB
|
|
||||||
|
|
||||||
extension OrderedRequest {
|
|
||||||
func orderedByIDSequence(_ ids: [String]) -> Self {
|
|
||||||
fatalError()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,8 @@ import Mastodon
|
||||||
|
|
||||||
extension Timeline: FetchableRecord, PersistableRecord {
|
extension Timeline: FetchableRecord, PersistableRecord {
|
||||||
enum Columns: String, ColumnExpression {
|
enum Columns: String, ColumnExpression {
|
||||||
case id, listTitle
|
case id
|
||||||
|
case listTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(row: Row) {
|
public init(row: Row) {
|
||||||
|
@ -42,7 +43,7 @@ extension Timeline {
|
||||||
StatusRecord.self,
|
StatusRecord.self,
|
||||||
through: statusJoins,
|
through: statusJoins,
|
||||||
using: TimelineStatusJoin.status)
|
using: TimelineStatusJoin.status)
|
||||||
.order(Column("createdAt").desc)
|
.order(StatusRecord.Columns.createdAt.desc)
|
||||||
|
|
||||||
var statuses: QueryInterfaceRequest<StatusResult> {
|
var statuses: QueryInterfaceRequest<StatusResult> {
|
||||||
request(for: Self.statuses).statusResultRequest
|
request(for: Self.statuses).statusResultRequest
|
||||||
|
|
|
@ -51,7 +51,7 @@ public extension IdentityDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteIdentity(id: UUID) -> AnyPublisher<Never, Error> {
|
func deleteIdentity(id: UUID) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher(updates: IdentityRecord.filter(Column("id") == id).deleteAll)
|
databaseWriter.writePublisher(updates: IdentityRecord.filter(IdentityRecord.Columns.id == id).deleteAll)
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ public extension IdentityDatabase {
|
||||||
func updateLastUsedAt(identityID: UUID) -> AnyPublisher<Never, Error> {
|
func updateLastUsedAt(identityID: UUID) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher {
|
databaseWriter.writePublisher {
|
||||||
try IdentityRecord
|
try IdentityRecord
|
||||||
.filter(Column("id") == identityID)
|
.filter(IdentityRecord.Columns.id == identityID)
|
||||||
.updateAll($0, Column("lastUsedAt").set(to: Date()))
|
.updateAll($0, IdentityRecord.Columns.lastUsedAt.set(to: Date()))
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
@ -75,8 +75,8 @@ public extension IdentityDatabase {
|
||||||
thumbnail: instance.thumbnail)
|
thumbnail: instance.thumbnail)
|
||||||
.save($0)
|
.save($0)
|
||||||
try IdentityRecord
|
try IdentityRecord
|
||||||
.filter(Column("id") == identityID)
|
.filter(IdentityRecord.Columns.id == identityID)
|
||||||
.updateAll($0, Column("instanceURI").set(to: instance.uri))
|
.updateAll($0, IdentityRecord.Columns.instanceURI.set(to: instance.uri))
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
@ -103,8 +103,8 @@ public extension IdentityDatabase {
|
||||||
func confirmIdentity(id: UUID) -> AnyPublisher<Never, Error> {
|
func confirmIdentity(id: UUID) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher {
|
databaseWriter.writePublisher {
|
||||||
try IdentityRecord
|
try IdentityRecord
|
||||||
.filter(Column("id") == id)
|
.filter(IdentityRecord.Columns.id == id)
|
||||||
.updateAll($0, Column("pending").set(to: false))
|
.updateAll($0, IdentityRecord.Columns.pending.set(to: false))
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
@ -113,7 +113,7 @@ public extension IdentityDatabase {
|
||||||
func updatePreferences(_ preferences: Mastodon.Preferences,
|
func updatePreferences(_ preferences: Mastodon.Preferences,
|
||||||
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
|
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher {
|
databaseWriter.writePublisher {
|
||||||
guard let storedPreferences = try IdentityRecord.filter(Column("id") == identityID)
|
guard let storedPreferences = try IdentityRecord.filter(IdentityRecord.Columns.id == identityID)
|
||||||
.fetchOne($0)?
|
.fetchOne($0)?
|
||||||
.preferences else {
|
.preferences else {
|
||||||
throw IdentityDatabaseError.identityNotFound
|
throw IdentityDatabaseError.identityNotFound
|
||||||
|
@ -136,16 +136,18 @@ public extension IdentityDatabase {
|
||||||
deviceToken: Data? = nil,
|
deviceToken: Data? = nil,
|
||||||
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
|
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher {
|
databaseWriter.writePublisher {
|
||||||
let data = try IdentityRecord.databaseJSONEncoder(for: "pushSubscriptionAlerts").encode(alerts)
|
let data = try IdentityRecord.databaseJSONEncoder(
|
||||||
|
for: IdentityRecord.Columns.pushSubscriptionAlerts.name)
|
||||||
|
.encode(alerts)
|
||||||
|
|
||||||
try IdentityRecord
|
try IdentityRecord
|
||||||
.filter(Column("id") == identityID)
|
.filter(IdentityRecord.Columns.id == identityID)
|
||||||
.updateAll($0, Column("pushSubscriptionAlerts").set(to: data))
|
.updateAll($0, IdentityRecord.Columns.pushSubscriptionAlerts.set(to: data))
|
||||||
|
|
||||||
if let deviceToken = deviceToken {
|
if let deviceToken = deviceToken {
|
||||||
try IdentityRecord
|
try IdentityRecord
|
||||||
.filter(Column("id") == identityID)
|
.filter(IdentityRecord.Columns.id == identityID)
|
||||||
.updateAll($0, Column("lastRegisteredDeviceToken").set(to: deviceToken))
|
.updateAll($0, IdentityRecord.Columns.lastRegisteredDeviceToken.set(to: deviceToken))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
|
@ -155,7 +157,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
|
IdentityRecord
|
||||||
.filter(Column("id") == id)
|
.filter(IdentityRecord.Columns.id == id)
|
||||||
.identityResultRequest
|
.identityResultRequest
|
||||||
.fetchOne)
|
.fetchOne)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
|
@ -171,7 +173,7 @@ public extension IdentityDatabase {
|
||||||
func identitiesObservation() -> AnyPublisher<[Identity], Error> {
|
func identitiesObservation() -> AnyPublisher<[Identity], Error> {
|
||||||
ValueObservation.tracking(
|
ValueObservation.tracking(
|
||||||
IdentityRecord
|
IdentityRecord
|
||||||
.order(Column("lastUsedAt").desc)
|
.order(IdentityRecord.Columns.lastUsedAt.desc)
|
||||||
.identityResultRequest
|
.identityResultRequest
|
||||||
.fetchAll)
|
.fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
|
@ -183,9 +185,9 @@ public extension IdentityDatabase {
|
||||||
func recentIdentitiesObservation(excluding: UUID) -> AnyPublisher<[Identity], Error> {
|
func recentIdentitiesObservation(excluding: UUID) -> AnyPublisher<[Identity], Error> {
|
||||||
ValueObservation.tracking(
|
ValueObservation.tracking(
|
||||||
IdentityRecord
|
IdentityRecord
|
||||||
.order(Column("lastUsedAt").desc)
|
.order(IdentityRecord.Columns.lastUsedAt.desc)
|
||||||
.identityResultRequest
|
.identityResultRequest
|
||||||
.filter(Column("id") != excluding)
|
.filter(IdentityRecord.Columns.id != excluding)
|
||||||
.limit(9)
|
.limit(9)
|
||||||
.fetchAll)
|
.fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
|
@ -195,7 +197,9 @@ public extension IdentityDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func immediateMostRecentlyUsedIdentityIDObservation() -> AnyPublisher<UUID?, Error> {
|
func immediateMostRecentlyUsedIdentityIDObservation() -> AnyPublisher<UUID?, Error> {
|
||||||
ValueObservation.tracking(IdentityRecord.select(Column("id")).order(Column("lastUsedAt").desc).fetchOne)
|
ValueObservation.tracking(
|
||||||
|
IdentityRecord.select(IdentityRecord.Columns.id)
|
||||||
|
.order(IdentityRecord.Columns.lastUsedAt.desc).fetchOne)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseWriter, scheduling: .immediate)
|
.publisher(in: databaseWriter, scheduling: .immediate)
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
@ -204,9 +208,9 @@ public extension IdentityDatabase {
|
||||||
func identitiesWithOutdatedDeviceTokens(deviceToken: Data) -> AnyPublisher<[Identity], Error> {
|
func identitiesWithOutdatedDeviceTokens(deviceToken: Data) -> AnyPublisher<[Identity], Error> {
|
||||||
databaseWriter.readPublisher(
|
databaseWriter.readPublisher(
|
||||||
value: IdentityRecord
|
value: IdentityRecord
|
||||||
.order(Column("lastUsedAt").desc)
|
.order(IdentityRecord.Columns.lastUsedAt.desc)
|
||||||
.identityResultRequest
|
.identityResultRequest
|
||||||
.filter(Column("lastRegisteredDeviceToken") != deviceToken)
|
.filter(IdentityRecord.Columns.lastRegisteredDeviceToken != deviceToken)
|
||||||
.fetchAll)
|
.fetchAll)
|
||||||
.map { $0.map(Identity.init(result:)) }
|
.map { $0.map(Identity.init(result:)) }
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
|
@ -218,11 +222,12 @@ private extension IdentityDatabase {
|
||||||
|
|
||||||
static func writePreferences(_ preferences: Identity.Preferences, id: UUID) -> (Database) throws -> Void {
|
static func writePreferences(_ preferences: Identity.Preferences, id: UUID) -> (Database) throws -> Void {
|
||||||
{
|
{
|
||||||
let data = try IdentityRecord.databaseJSONEncoder(for: "preferences").encode(preferences)
|
let data = try IdentityRecord.databaseJSONEncoder(
|
||||||
|
for: IdentityRecord.Columns.preferences.name).encode(preferences)
|
||||||
|
|
||||||
try IdentityRecord
|
try IdentityRecord
|
||||||
.filter(Column("id") == id)
|
.filter(IdentityRecord.Columns.id == id)
|
||||||
.updateAll($0, Column("preferences").set(to: data))
|
.updateAll($0, IdentityRecord.Columns.preferences.set(to: data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,18 @@ struct IdentityRecord: Codable, Hashable, FetchableRecord, PersistableRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension IdentityRecord {
|
extension IdentityRecord {
|
||||||
|
enum Columns {
|
||||||
|
static let id = Column(IdentityRecord.CodingKeys.id)
|
||||||
|
static let url = Column(IdentityRecord.CodingKeys.url)
|
||||||
|
static let authenticated = Column(IdentityRecord.CodingKeys.authenticated)
|
||||||
|
static let pending = Column(IdentityRecord.CodingKeys.pending)
|
||||||
|
static let lastUsedAt = Column(IdentityRecord.CodingKeys.lastUsedAt)
|
||||||
|
static let preferences = Column(IdentityRecord.CodingKeys.preferences)
|
||||||
|
static let instanceURI = Column(IdentityRecord.CodingKeys.instanceURI)
|
||||||
|
static let lastRegisteredDeviceToken = Column(IdentityRecord.CodingKeys.lastRegisteredDeviceToken)
|
||||||
|
static let pushSubscriptionAlerts = Column(IdentityRecord.CodingKeys.pushSubscriptionAlerts)
|
||||||
|
}
|
||||||
|
|
||||||
static let instance = belongsTo(Identity.Instance.self, key: "instance")
|
static let instance = belongsTo(Identity.Instance.self, key: "instance")
|
||||||
static let account = hasOne(Identity.Account.self, key: "account")
|
static let account = hasOne(Identity.Account.self, key: "account")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue