/
kalugin66
/
FS
Обзор
Документация
Войти
/
kalugin66
/
FS
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
PostgreSQL.js
207 строк
8 KB
kalugin66
finish
20 янв 2026, 20:54
20 янв 2026, 20:54
b4da8e4
Код
Авторство
О чём код?
const { Pool, Client } = require('pg'); require('dotenv').config(); // Глобальная переменная для пула let dbPool = null; // Функция для создания базы данных если она не существует async function createDatabaseIfNotExists() { const adminClient = new Client({ host: process.env.DB_HOST, port: process.env.DB_PORT || 5432, database: 'postgres', user: process.env.DB_USER, password: process.env.DB_PASSWORD, }); try { await adminClient.connect(); const result = await adminClient.query( "SELECT 1 FROM pg_database WHERE datname = $1", [process.env.DB_NAME] ); if (result.rows.length === 0) { console.log(`Создание базы данных "${process.env.DB_NAME}"...`); await adminClient.query(`CREATE DATABASE "${process.env.DB_NAME}"`); console.log(`База данных "${process.env.DB_NAME}" создана успешно`); } else { console.log(`База данных "${process.env.DB_NAME}" уже существует`); } await adminClient.end(); } catch (error) { console.error('Ошибка при создании/проверке базы данных:', error.message); if (error.code === '42501' || error.code === '3D000') { console.log('Недостаточно прав для создания БД. Продолжаем работу...'); } else { throw error; } } finally { if (adminClient && !adminClient._ended) { await adminClient.end(); } } } // Инициализация таблиц async function init() { try { // Сначала пытаемся создать БД если её нет await createDatabaseIfNotExists(); // Инициализируем пул подключений dbPool = new Pool({ host: process.env.DB_HOST, port: process.env.DB_PORT || 5432, database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASSWORD, max: 20, idleTimeoutMillis: 30000, connectionTimeoutMillis: 2000, }); // Обработка ошибок пула dbPool.on('error', (err, client) => { console.error('Ошибка пула PostgreSQL:', err); }); const client = await dbPool.connect(); try { // Пользователи await client.query(` CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, login VARCHAR(100) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, salt VARCHAR(50) NOT NULL, is_admin BOOLEAN DEFAULT FALSE, token VARCHAR(2026), token_expiry TIMESTAMP, created_at TIMESTAMP DEFAULT NOW() ) `); // Файлы await client.query(` CREATE TABLE IF NOT EXISTS files ( id SERIAL PRIMARY KEY, service_name VARCHAR(100) NOT NULL, description TEXT, login VARCHAR(100) NOT NULL, date DATE NOT NULL, time TIME NOT NULL, file_number BIGINT UNIQUE NOT NULL, file_name VARCHAR(255) NOT NULL, file_extension VARCHAR(50) NOT NULL, file_size BIGINT NOT NULL, storage_path TEXT NOT NULL, uploaded_by VARCHAR(100), created_at TIMESTAMP DEFAULT NOW() ) `); // WebDAV настройки await client.query(` CREATE TABLE IF NOT EXISTS webdav_settings ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, url VARCHAR(255) NOT NULL, username VARCHAR(100) NOT NULL, password VARCHAR(255) NOT NULL, root_path VARCHAR(255) NOT NULL, is_active BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW() ) `); // Настройки хранилища await client.query(` CREATE TABLE IF NOT EXISTS storage_settings ( id SERIAL PRIMARY KEY, storage_type VARCHAR(20) DEFAULT 'local', updated_at TIMESTAMP DEFAULT NOW() ) `); // Таблица для сессий (для connect-pg-simple) await client.query(` CREATE TABLE IF NOT EXISTS session ( sid VARCHAR NOT NULL PRIMARY KEY, sess JSON NOT NULL, expire TIMESTAMP(6) NOT NULL ) `); // Создаем индексы await client.query(` CREATE INDEX IF NOT EXISTS idx_files_login ON files(login) `); await client.query(` CREATE INDEX IF NOT EXISTS idx_files_date ON files(date) `); await client.query(` CREATE INDEX IF NOT EXISTS idx_files_extension ON files(file_extension) `); await client.query(` CREATE INDEX IF NOT EXISTS idx_session_expire ON session(expire) `); // Инициализируем настройки хранилища const settingsCheck = await client.query('SELECT * FROM storage_settings'); if (settingsCheck.rows.length === 0) { await client.query("INSERT INTO storage_settings (storage_type) VALUES ('local')"); } // Создаем первого пользователя admin/admin если его нет const adminExists = await client.query('SELECT * FROM users WHERE login = $1', ['admin']); if (adminExists.rows.length === 0) { const crypto = require('crypto'); const salt = crypto.randomBytes(16).toString('hex'); const hash = crypto.createHash('sha256').update('admin' + salt).digest('hex'); await client.query( 'INSERT INTO users (login, password, salt, is_admin, created_at) VALUES ($1, $2, $3, $4, NOW())', ['admin', hash, salt, true] ); console.log('Создан пользователь admin/admin'); } console.log('База данных инициализирована'); } finally { client.release(); } } catch (error) { console.error('Критическая ошибка инициализации БД:', error); throw error; } } // Обертка для запросов async function query(text, params) { if (!dbPool) { throw new Error('Пул подключений не инициализирован'); } const client = await dbPool.connect(); try { const result = await client.query(text, params); return result; } finally { client.release(); } } // Получение пула function getPool() { return dbPool; } module.exports = { init, query, getPool, pool: dbPool // Для обратной совместимости };