102 lines
3.2 KiB
Swift
102 lines
3.2 KiB
Swift
import GRDB
|
|
|
|
public enum DatabaseSetup {
|
|
public static func migrator() -> DatabaseMigrator {
|
|
var migrator = DatabaseMigrator()
|
|
|
|
migrator.registerMigration("v1_initial") { db in
|
|
try db.create(table: "account") { t in
|
|
t.primaryKey("id", .text)
|
|
t.column("name", .text).notNull()
|
|
t.column("email", .text).notNull()
|
|
t.column("imapHost", .text).notNull()
|
|
t.column("imapPort", .integer).notNull()
|
|
}
|
|
|
|
try db.create(table: "mailbox") { t in
|
|
t.primaryKey("id", .text)
|
|
t.belongsTo("account", onDelete: .cascade).notNull()
|
|
t.column("name", .text).notNull()
|
|
t.column("uidValidity", .integer).notNull()
|
|
t.column("uidNext", .integer).notNull()
|
|
}
|
|
|
|
try db.create(table: "message") { t in
|
|
t.primaryKey("id", .text)
|
|
t.belongsTo("account", onDelete: .cascade).notNull()
|
|
t.belongsTo("mailbox", onDelete: .cascade).notNull()
|
|
t.column("uid", .integer).notNull()
|
|
t.column("messageId", .text)
|
|
t.column("inReplyTo", .text)
|
|
t.column("refs", .text)
|
|
t.column("subject", .text)
|
|
t.column("fromAddress", .text)
|
|
t.column("fromName", .text)
|
|
t.column("toAddresses", .text)
|
|
t.column("ccAddresses", .text)
|
|
t.column("date", .text).notNull()
|
|
t.column("snippet", .text)
|
|
t.column("bodyText", .text)
|
|
t.column("bodyHtml", .text)
|
|
t.column("isRead", .boolean).notNull().defaults(to: false)
|
|
t.column("isFlagged", .boolean).notNull().defaults(to: false)
|
|
t.column("size", .integer).notNull().defaults(to: 0)
|
|
t.uniqueKey(["mailboxId", "uid"])
|
|
}
|
|
|
|
try db.create(table: "thread") { t in
|
|
t.primaryKey("id", .text)
|
|
t.belongsTo("account", onDelete: .cascade).notNull()
|
|
t.column("subject", .text)
|
|
t.column("lastDate", .text).notNull()
|
|
t.column("messageCount", .integer).notNull().defaults(to: 0)
|
|
}
|
|
|
|
try db.create(table: "threadMessage") { t in
|
|
t.belongsTo("thread", onDelete: .cascade).notNull()
|
|
t.belongsTo("message", onDelete: .cascade).notNull()
|
|
t.primaryKey(["threadId", "messageId"])
|
|
}
|
|
|
|
try db.create(table: "attachment") { t in
|
|
t.primaryKey("id", .text)
|
|
t.belongsTo("message", onDelete: .cascade).notNull()
|
|
t.column("filename", .text)
|
|
t.column("mimeType", .text).notNull()
|
|
t.column("size", .integer).notNull().defaults(to: 0)
|
|
t.column("contentId", .text)
|
|
t.column("cachePath", .text)
|
|
}
|
|
|
|
try db.create(index: "idx_message_mailbox_uid", on: "message", columns: ["mailboxId", "uid"])
|
|
try db.create(index: "idx_message_messageId", on: "message", columns: ["messageId"])
|
|
try db.create(index: "idx_thread_lastDate", on: "thread", columns: ["lastDate"])
|
|
}
|
|
|
|
migrator.registerMigration("v1_fts5") { db in
|
|
try db.create(virtualTable: "messageFts", using: FTS5()) { t in
|
|
t.synchronize(withTable: "message")
|
|
t.tokenizer = .porter(wrapping: .unicode61())
|
|
t.column("subject")
|
|
t.column("fromName")
|
|
t.column("fromAddress")
|
|
t.column("bodyText")
|
|
}
|
|
}
|
|
|
|
return migrator
|
|
}
|
|
|
|
public static func openDatabase(atPath path: String) throws -> DatabasePool {
|
|
let pool = try DatabasePool(path: path)
|
|
try migrator().migrate(pool)
|
|
return pool
|
|
}
|
|
|
|
public static func openInMemoryDatabase() throws -> DatabaseQueue {
|
|
let queue = try DatabaseQueue()
|
|
try migrator().migrate(queue)
|
|
return queue
|
|
}
|
|
}
|