235 lines
9.1 KiB
JavaScript
235 lines
9.1 KiB
JavaScript
const { Pool } = require('pg');
|
|
require('dotenv').config();
|
|
|
|
class DatabaseManager {
|
|
constructor() {
|
|
this.pool = new Pool({
|
|
connectionString: process.env.DATABASE_URL,
|
|
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
|
|
});
|
|
}
|
|
|
|
async initialize() {
|
|
try {
|
|
await this.createTables();
|
|
console.log('Tabele bazy danych utworzone pomyślnie');
|
|
} catch (error) {
|
|
console.error('Błąd podczas inicjalizacji bazy danych:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async createTables() {
|
|
const createTablesSQL = `
|
|
-- Tabela serwerów Discord
|
|
CREATE TABLE IF NOT EXISTS guilds (
|
|
id VARCHAR(20) PRIMARY KEY,
|
|
name VARCHAR(100) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Tabela kanałów powitalnych
|
|
CREATE TABLE IF NOT EXISTS welcome_channels (
|
|
id SERIAL PRIMARY KEY,
|
|
guild_id VARCHAR(20) REFERENCES guilds(id) ON DELETE CASCADE,
|
|
channel_id VARCHAR(20) NOT NULL,
|
|
channel_name VARCHAR(100),
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(guild_id)
|
|
);
|
|
|
|
-- Tabela wiadomości powitalnych
|
|
CREATE TABLE IF NOT EXISTS welcome_messages (
|
|
id SERIAL PRIMARY KEY,
|
|
guild_id VARCHAR(20) REFERENCES guilds(id) ON DELETE CASCADE,
|
|
content TEXT NOT NULL,
|
|
embed_data JSONB,
|
|
message_id VARCHAR(20),
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Tabela użytkowników panelu web
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id SERIAL PRIMARY KEY,
|
|
discord_id VARCHAR(20) UNIQUE NOT NULL,
|
|
username VARCHAR(32) NOT NULL,
|
|
discriminator VARCHAR(4),
|
|
avatar VARCHAR(255),
|
|
email VARCHAR(255),
|
|
role VARCHAR(20) DEFAULT 'viewer',
|
|
is_active BOOLEAN DEFAULT true,
|
|
last_login TIMESTAMP,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Tabela historii wersji wiadomości
|
|
CREATE TABLE IF NOT EXISTS message_revisions (
|
|
id SERIAL PRIMARY KEY,
|
|
message_id INTEGER REFERENCES welcome_messages(id) ON DELETE CASCADE,
|
|
content TEXT NOT NULL,
|
|
embed_data JSONB,
|
|
user_id INTEGER REFERENCES users(id),
|
|
revision_number INTEGER NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Tabela uprawnień użytkowników do serwerów
|
|
CREATE TABLE IF NOT EXISTS user_guild_permissions (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
guild_id VARCHAR(20) REFERENCES guilds(id) ON DELETE CASCADE,
|
|
role VARCHAR(20) DEFAULT 'viewer',
|
|
granted_by INTEGER REFERENCES users(id),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(user_id, guild_id)
|
|
);
|
|
|
|
-- Indeksy dla wydajności
|
|
CREATE INDEX IF NOT EXISTS idx_guilds_id ON guilds(id);
|
|
CREATE INDEX IF NOT EXISTS idx_welcome_channels_guild_id ON welcome_channels(guild_id);
|
|
CREATE INDEX IF NOT EXISTS idx_welcome_messages_guild_id ON welcome_messages(guild_id);
|
|
CREATE INDEX IF NOT EXISTS idx_users_discord_id ON users(discord_id);
|
|
CREATE INDEX IF NOT EXISTS idx_message_revisions_message_id ON message_revisions(message_id);
|
|
CREATE INDEX IF NOT EXISTS idx_user_guild_permissions_user_guild ON user_guild_permissions(user_id, guild_id);
|
|
`;
|
|
|
|
await this.pool.query(createTablesSQL);
|
|
}
|
|
|
|
// Metody dla zarządzania serwerami
|
|
async addGuild(guildId, guildName) {
|
|
const query = `
|
|
INSERT INTO guilds (id, name)
|
|
VALUES ($1, $2)
|
|
ON CONFLICT (id) DO UPDATE SET
|
|
name = EXCLUDED.name,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
`;
|
|
await this.pool.query(query, [guildId, guildName]);
|
|
}
|
|
|
|
async getGuild(guildId) {
|
|
const query = 'SELECT * FROM guilds WHERE id = $1';
|
|
const result = await this.pool.query(query, [guildId]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
// Metody dla kanałów powitalnych
|
|
async setWelcomeChannel(guildId, channelId, channelName) {
|
|
const query = `
|
|
INSERT INTO welcome_channels (guild_id, channel_id, channel_name)
|
|
VALUES ($1, $2, $3)
|
|
ON CONFLICT (guild_id) DO UPDATE SET
|
|
channel_id = EXCLUDED.channel_id,
|
|
channel_name = EXCLUDED.channel_name,
|
|
is_active = true,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
`;
|
|
await this.pool.query(query, [guildId, channelId, channelName]);
|
|
}
|
|
|
|
async getWelcomeChannel(guildId) {
|
|
const query = 'SELECT * FROM welcome_channels WHERE guild_id = $1 AND is_active = true';
|
|
const result = await this.pool.query(query, [guildId]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
// Metody dla wiadomości powitalnych
|
|
async saveWelcomeMessage(guildId, content, embedData = null, messageId = null) {
|
|
const query = `
|
|
INSERT INTO welcome_messages (guild_id, content, embed_data, message_id)
|
|
VALUES ($1, $2, $3, $4)
|
|
RETURNING *
|
|
`;
|
|
const result = await this.pool.query(query, [guildId, content, embedData, messageId]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
async updateWelcomeMessage(guildId, content, embedData = null, messageId = null) {
|
|
const query = `
|
|
UPDATE welcome_messages
|
|
SET content = $2, embed_data = $3, message_id = $4, updated_at = CURRENT_TIMESTAMP
|
|
WHERE guild_id = $1 AND is_active = true
|
|
RETURNING *
|
|
`;
|
|
const result = await this.pool.query(query, [guildId, content, embedData, messageId]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
async getWelcomeMessage(guildId) {
|
|
const query = 'SELECT * FROM welcome_messages WHERE guild_id = $1 AND is_active = true ORDER BY created_at DESC LIMIT 1';
|
|
const result = await this.pool.query(query, [guildId]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
// Metody dla użytkowników
|
|
async saveUser(discordUser) {
|
|
const query = `
|
|
INSERT INTO users (discord_id, username, discriminator, avatar, email)
|
|
VALUES ($1, $2, $3, $4, $5)
|
|
ON CONFLICT (discord_id) DO UPDATE SET
|
|
username = EXCLUDED.username,
|
|
discriminator = EXCLUDED.discriminator,
|
|
avatar = EXCLUDED.avatar,
|
|
email = EXCLUDED.email,
|
|
last_login = CURRENT_TIMESTAMP,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
RETURNING *
|
|
`;
|
|
const result = await this.pool.query(query, [
|
|
discordUser.id,
|
|
discordUser.username,
|
|
discordUser.discriminator || '0000',
|
|
discordUser.avatar,
|
|
discordUser.email
|
|
]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
async getUser(discordId) {
|
|
const query = 'SELECT * FROM users WHERE discord_id = $1';
|
|
const result = await this.pool.query(query, [discordId]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
// Metody dla historii wersji
|
|
async saveMessageRevision(messageId, content, embedData, userId) {
|
|
// Pobierz aktualny numer rewizji
|
|
const revisionQuery = 'SELECT COALESCE(MAX(revision_number), 0) + 1 as next_revision FROM message_revisions WHERE message_id = $1';
|
|
const revisionResult = await this.pool.query(revisionQuery, [messageId]);
|
|
const nextRevision = revisionResult.rows[0].next_revision;
|
|
|
|
const query = `
|
|
INSERT INTO message_revisions (message_id, content, embed_data, user_id, revision_number)
|
|
VALUES ($1, $2, $3, $4, $5)
|
|
RETURNING *
|
|
`;
|
|
const result = await this.pool.query(query, [messageId, content, embedData, userId, nextRevision]);
|
|
return result.rows[0];
|
|
}
|
|
|
|
async getMessageRevisions(messageId) {
|
|
const query = `
|
|
SELECT mr.*, u.username
|
|
FROM message_revisions mr
|
|
LEFT JOIN users u ON mr.user_id = u.id
|
|
WHERE mr.message_id = $1
|
|
ORDER BY mr.revision_number DESC
|
|
`;
|
|
const result = await this.pool.query(query, [messageId]);
|
|
return result.rows;
|
|
}
|
|
|
|
async close() {
|
|
await this.pool.end();
|
|
}
|
|
}
|
|
|
|
module.exports = { DatabaseManager };
|