mirror of
https://github.com/zhigang1992/GitHawk.git
synced 2026-06-15 10:07:55 +08:00
92 lines
2.9 KiB
Swift
92 lines
2.9 KiB
Swift
//
|
|
// LocalNotificationsCache.swift
|
|
// Freetime
|
|
//
|
|
// Created by Ryan Nystrom on 8/26/18.
|
|
// Copyright © 2018 Ryan Nystrom. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import FMDB
|
|
import GitHubAPI
|
|
|
|
final class LocalNotificationsCache {
|
|
|
|
private static let sqlitePath: String = {
|
|
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
|
return "\(path)/read-notifications.sqlite"
|
|
}()
|
|
|
|
private let path: String
|
|
private lazy var queue: FMDatabaseQueue = {
|
|
return FMDatabaseQueue(path: self.path)
|
|
}()
|
|
|
|
init(
|
|
path: String = LocalNotificationsCache.sqlitePath
|
|
) {
|
|
self.path = path
|
|
}
|
|
|
|
func update(
|
|
notifications: [V3Notification],
|
|
completion: @escaping ([V3Notification]) -> Void
|
|
) {
|
|
guard notifications.count > 0 else {
|
|
completion([])
|
|
return
|
|
}
|
|
|
|
queue.inDatabase { db in
|
|
let table = "seen"
|
|
let apiCol = "apiID"
|
|
let idCol = "id"
|
|
|
|
var map = [String: V3Notification]()
|
|
notifications.forEach { map[$0.id] = $0 }
|
|
let apiIDs = map.keys.map { $0 }
|
|
|
|
do {
|
|
// attempt to create the table
|
|
try db.executeUpdate(
|
|
"create table if not exists \(table) (\(idCol) integer primary key autoincrement, \(apiCol) text)",
|
|
values: nil
|
|
)
|
|
|
|
// remove notifications that already exist
|
|
let selectSanitized = map.keys.map { _ in "?" }.joined(separator: ", ")
|
|
let rs = try db.executeQuery(
|
|
"select \(apiCol) from \(table) where \(apiCol) in (\(selectSanitized))",
|
|
values: apiIDs
|
|
)
|
|
while rs.next() {
|
|
if let key = rs.string(forColumn: apiCol) {
|
|
map.removeValue(forKey: key)
|
|
}
|
|
}
|
|
|
|
// only perform updates if there are new notifications
|
|
if map.count > 0 {
|
|
// add latest notification ids in the db
|
|
let insertSanitized = map.keys.map { _ in "(?)" }.joined(separator: ", ")
|
|
try db.executeUpdate(
|
|
"insert into \(table) (\(apiCol)) values \(insertSanitized)",
|
|
values: map.keys.map { $0 }
|
|
)
|
|
|
|
// cap the local database to latest 1000 notifications
|
|
try db.executeUpdate(
|
|
"delete from \(table) where \(idCol) not in (select \(idCol) from \(table) order by \(idCol) desc limit 1000)",
|
|
values: nil
|
|
)
|
|
}
|
|
} catch {
|
|
print("failed: \(error.localizedDescription)")
|
|
}
|
|
|
|
completion(map.values.map { $0 })
|
|
}
|
|
}
|
|
|
|
}
|