Skip to content

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.