coddyger
Version:
Coddyger est une bibliothèque JavaScript/TypeScript qui fournit des fonctions communes et des plugins pour la gestion des données, la communication entre services, et des utilitaires avancés pour le développement d'applications.
146 lines (130 loc) • 4.64 kB
text/typescript
import { Sequelize, Model, Options, ModelStatic, Dialect } from 'sequelize';
import env from '../../globals';
import coddyger from '../../coddyger';
export class SequelizeDataAccess {
private sequelize: Sequelize | undefined;
private readonly models: Map<string, ModelStatic<Model>> = new Map();
private readonly connectionString: string;
constructor(connectionString?: string) {
// Permet de passer la chaîne de connexion en paramètre, sinon fallback sur l'env
this.connectionString = connectionString || env.database.connectionString;
}
// --- Méthode privée pour créer la base si elle n'existe pas (PostgreSQL) ---
private async ensurePostgresDatabaseExists(connectionString: string) {
if (!connectionString.includes('postgresql://')) return;
const dbNameMatch = RegExp(/\/([a-zA-Z0-9_-]+)(\?.*)?$/).exec(connectionString);
if (!dbNameMatch) return;
const dbName = dbNameMatch[1];
// Connexion temporaire à la base 'postgres'
const adminConnectionString = connectionString.replace(/\/([a-zA-Z0-9_-]+)(\?.*)?$/, '/postgres');
const adminSequelize = new Sequelize(adminConnectionString, { logging: false });
try {
await adminSequelize.query(`CREATE DATABASE "${dbName}"`)
.catch((err: any) => {
if (!/already exists/.test(err.message)) throw err;
});
} finally {
await adminSequelize.close();
}
}
// --- FIN ---
async connect() {
await this.ensurePostgresDatabaseExists(this.connectionString);
// Créer l'instance Sequelize ici, après la création de la base
const options: Options = {
dialect: env.database.dialect as Dialect,
storage: env.database.storage,
logging: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
define: {
timestamps: true,
underscored: true
}
};
this.sequelize = new Sequelize(this.connectionString, options);
try {
await this.sequelize.authenticate();
const config = this.sequelize.config;
const dbInfo = `${config.host}:${config.port}:${config.database}`;
coddyger.konsole(`✅ SQL connecté :: ${dbInfo}`);
} catch (err: any) {
coddyger.konsole('❌ Erreur de connexion SQL', 1);
console.error(err);
throw err;
}
}
getSequelize() {
if (!this.sequelize) throw new Error('Sequelize non connecté');
return this.sequelize;
}
async sync(options?: { force?: boolean; alter?: boolean }) {
if (!this.sequelize) throw new Error('Sequelize non connecté');
try {
await this.sequelize.sync(options);
coddyger.konsole('🔄 Base de données synchronisée');
} catch (err: any) {
coddyger.konsole('Sync error', 1);
console.error(err);
}
}
async close() {
if (!this.sequelize) throw new Error('Sequelize non connecté');
try {
await this.sequelize.close();
coddyger.konsole('🛑 Connexion SQL fermée');
} catch (err: any) {
coddyger.konsole('❌ Erreur lors de la fermeture de la connexion SQL', 1);
console.error(err);
}
}
registerModel(name: string, model: ModelStatic<Model>) {
this.models.set(name, model);
}
getModel(name: string): ModelStatic<Model> | undefined {
return this.models.get(name);
}
// Ajoutez ici des modèles Sequelize pour vos tables de base de données
// Par exemple :
// User = this.sequelize.define('User', {
// firstName: {
// type: DataTypes.STRING,
// },
// lastName: {
// type: DataTypes.STRING,
// },
// });
// Définissez des méthodes pour gérer les opérations CRUD, par exemple, find, create, update, delete.
async isConnected(): Promise<boolean> {
if (!this.sequelize) return false;
try {
await this.sequelize.authenticate();
return true;
} catch {
return false;
}
}
/**
* Exécute une fonction dans une transaction Sequelize (commit/rollback auto)
* @param callback - Fonction asynchrone recevant le transaction object
* @returns Résultat de la fonction callback
*/
async transaction<T>(callback: (t: import('sequelize').Transaction) => Promise<T>): Promise<T> {
if (!this.sequelize) throw new Error('Sequelize non connecté');
return await this.sequelize.transaction(async (t) => {
return await callback(t);
});
}
/**
* Démarre une transaction manuelle (à commit/rollbacker soi-même)
* @returns L'objet Transaction Sequelize
*/
async getTransaction(): Promise<import('sequelize').Transaction> {
if (!this.sequelize) throw new Error('Sequelize non connecté');
return await this.sequelize.transaction();
}
}