Database
Using the database is straight forward, and a utility structure is passed into commands by default that exposes predefined database requests based on interaction context.
You use the database by accessing the singleton instance of it.
import Database
let db = Database.shared
The database stores models, which are structs that conform to DatabaseModel
(it’s just Codable
).
struct UserPrefs: DatabaseModel { /// Whether the user likes cheese or not var theyReallyLikeCheese: Bool /// The user's XP points var xp: UInt
// helpful for setting default values quickly static var `default`: UserPrefs { UserPrefs(theyReallyLikeCheese: false, xp: 0) }}
You can then use the database to store and retrieve data in the format of said models.
// in your bot
Command("cheese") { i in // defer, since database operations can be held up by other accesses try await i.respond(with: .deferredChannelMessageWithSource()) // get option data let bool = try i.options.requireOption(named: "bool").requireBool() // get the user's prefs, this means it shares across servers. let req = i.dbRequests.user(ofType: UserPrefs.self) let prefs = try await db.transaction() { prefs in var prefs = prefs ?? .default // if the user doesn't have prefs, use default prefs.theyReallyLikeCheese = bool return prefs // return modified prefs to be saved }! // force unwrap, we know it exists // the prefs returned from the transaction are the updated prefs we returned from the closure // so we can use them here in the response. try await i.respond { Message { MessageEmbed { Title("Cheese") Description { Text("You \(prefs.theyReallyLikeCheese ? "like" : "don't like") cheese.") } } .setColor(prefs.theyReallyLikeCheese ? .yellow : .red) } }}.integrationType(.all, contexts: .all).isUsableInDMS(true)
The transaction
method is used to ensure that the data is not
modified by another command while it is being modified by this one.
If another thread tries to modify the same data while the transaction is in
progress, it will wait until the existing transaction is complete before modifying the data.
The reqs object is of type DatabaseBranches
, which is a utility structure that
contains all the predefined database requests based on interaction context.