Database & Repositories
Disapp Core utilizes a Repository Pattern to eradicate the messy boilerplate typically found in standard database drivers, introducing an asynchronous memory layer to your bot. Thanks to its native structures, generating tables or data architectures takes merely seconds.
Spinning Up the Database
To synchronize tables or open your ongoing connections immediately when your Discord bot executes, you must invoke the initializeDatabase method stemming from the core library.
import { initializeDatabase } from "@disapp/core";
async function startBot() {
await initializeDatabase();
await client.start();
}
startBot();
Native Repository Classes
As part of the Core package layout, the 4 most prominently needed data tables in the Discord ecosystem are presented to you fully configured (equipped with ORM mappings):
UserRepository
Manages individualized user data streams. Generally utilized for resolving credits, experience points (XP), and comprehensive profile statuses.
GuildRepository
Preserves server-wide parameters (Guild) inherently supporting custom prefix logs, module scopes, and configuration maps.
VoiceActivityRepository
Documents analytical session timestamps revealing exactly how long users persist inside of vocal channels.
UserStatsRepository
Integrates metrics such as Level scaling systems and compounded message rates effortlessly into a permanent layer.
Creating or Reading Entries
You can invoke any native repository directly into your command scope, issuing immediate CRUD (Create, Read, Update, Delete) directives seamlessly.
import { UserRepository } from '@disapp/core';
async execute(interaction: any) {
const userRepo = new UserRepository();
let userData = await userRepo.getOrCreate(
BigInt(interaction.user.id),
interaction.user.username,
interaction.user.avatar || undefined
);
userData.credits += 50;
await userRepo.update(userData);
await interaction.reply(`Your revised balance is: ${userData.credits}`);
}
Repository Methods
UserRepository
const userRepo = new UserRepository();
await userRepo.getOrCreate(userId: bigint, username: string, avatar?: string)
await userRepo.findById(userId: bigint)
await userRepo.update(user: User)
await userRepo.delete(userId: bigint)
GuildRepository
const guildRepo = new GuildRepository();
await guildRepo.getOrCreate(guildId: bigint, name: string)
await guildRepo.findById(guildId: bigint)
await guildRepo.update(guild: Guild)
await guildRepo.delete(guildId: bigint)
UserStatsRepository
const statsRepo = new UserStatsRepository();
await statsRepo.getOrCreate(userId: bigint, guildId: bigint)
await statsRepo.addXP(userId: bigint, guildId: bigint, amount: number)
await statsRepo.getTopPlayers(guildId: bigint, limit: number)
VoiceActivityRepository
const voiceRepo = new VoiceActivityRepository();
await voiceRepo.startSession(userId: bigint, guildId: bigint, channelId: bigint)
await voiceRepo.endSession(userId: bigint, guildId: bigint)
await voiceRepo.getWeeklyStats(guildId: bigint)
Defense via RequireDatabase Middleware
If operations strictly hinge on database availability, you can secure and protect your endpoints by executing the native middleware to prevent crashes upon database dropout faults.
import { Command, RequireDatabase } from "@disapp/core";
export default class PayCommand extends Command {
constructor() {
super({
name: "pay",
description: "Pay another user",
data: new SlashCommandBuilder()
.setName("pay")
.setDescription("Pay another user"),
middlewares: [RequireDatabase()],
execute: async () => {},
});
}
}
Environment Configuration
Ensure your .env file contains the database URL:
DATABASE_URL=postgresql://user:password@localhost:5432/database
Database Migration
Run migrations to create tables:
pnpm db:migrate
Best Practices
- Always use getOrCreate - Ensures user/guild exists before operations
- Use BigInt for IDs - Discord IDs are too large for regular numbers
- Add RequireDatabase middleware - Prevents crashes when database is unavailable
- Handle errors gracefully - Wrap database operations in try-catch blocks
Learn More
- API Reference - Complete database API
- Examples - Database usage examples
- Middleware - RequireDatabase middleware