Passer au contenu

Comment Utiliser SQLite avec Bun

Bun, le runtime JavaScript moderne, offre une intégration native de SQLite qui est à la fois simple à utiliser et très performante. Cette implémentation native élimine le besoin d’installer des dépendances externes et fournit une API synchrone claire. Voici comment utiliser SQLite avec Bun.

Introduction à SQLite dans Bun

L’API SQLite de Bun est intégrée directement dans le runtime, ce qui signifie que vous n’avez pas besoin d’installer de packages supplémentaires pour commencer. Pour l’utiliser, il suffit d’importer le module bun:sqlite.

Installation

Comme SQLite est intégré nativement à Bun, vous n’avez besoin que d’installer Bun lui-même :

Fenêtre de terminal
# Installer Bun (si ce n'est pas déjà fait)
curl -fsSL https://bun.sh/install | bash

Créer et ouvrir une base de données

Pour commencer à utiliser SQLite avec Bun, importez le module Database et créez une instance de base de données :

import { Database } from "bun:sqlite";
// Ouvrir une base de données existante ou en créer une nouvelle
const db = new Database("mydb.sqlite");
// Ou créer une base de données en mémoire (pratique pour les tests)
const memDb = new Database(":memory:");

Exécuter des requêtes simples

Voici comment exécuter des requêtes SQL simples :

// Créer une table
db.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Insérer des données
const insertResult = db.run(`
INSERT INTO users (name, email)
VALUES ('Alice', '[email protected]')
`);
console.log(`ID de la ligne insérée: ${insertResult.lastInsertRowid}`);
console.log(`Nombre de lignes modifiées: ${insertResult.changes}`);
// Exécuter une requête SELECT
const query = db.query("SELECT * FROM users WHERE id = $id");
const user = query.get({ $id: 1 });
console.log(user); // { id: 1, name: 'Alice', email: '[email protected]', created_at: '...' }

Requêtes préparées

Pour optimiser les performances, surtout pour les requêtes répétitives, vous pouvez utiliser des requêtes préparées :

// Préparer une requête d'insertion
const insertUser = db.query(`
INSERT INTO users (name, email)
VALUES ($name, $email)
`);
// Exécuter la requête plusieurs fois avec différentes valeurs
insertUser.run({ $name: "Bob", $email: "[email protected]" });
insertUser.run({ $name: "Charlie", $email: "[email protected]" });
// Récupérer tous les utilisateurs
const getAllUsers = db.query("SELECT * FROM users");
const users = getAllUsers.all();
console.log(users);

Dans cet exemple, $name et $email sont des paramètres nommés qui sont remplacés par les valeurs fournies lors de l’exécution.

Récupérer des données

Bun offre plusieurs méthodes pour récupérer des données :

// Récupérer une seule ligne
const getUser = db.query("SELECT * FROM users WHERE id = $id");
const user = getUser.get({ $id: 1 }); // Retourne un objet ou undefined si non trouvé
// Récupérer toutes les lignes
const allUsers = db.query("SELECT * FROM users").all(); // Retourne un tableau d'objets
// Itérer sur les résultats (utile pour les grands ensembles de données)
const usersQuery = db.query("SELECT * FROM users");
for (const user of usersQuery.iterate()) {
console.log(user);
}

Transactions

Les transactions permettent d’exécuter plusieurs requêtes de manière atomique :

// Créer une transaction
const insertUser = db.query("INSERT INTO users (name, email) VALUES ($name, $email)");
const insertUsers = db.transaction((users) => {
for (const user of users) {
insertUser.run(user);
}
return users.length; // Retourne le nombre d'utilisateurs insérés
});
// Exécuter la transaction
const count = insertUsers([
{ $name: "David", $email: "[email protected]" },
{ $name: "Eva", $email: "[email protected]" },
]);
console.log(`${count} utilisateurs insérés`);

Si une exception est levée dans la fonction de transaction, celle-ci sera automatiquement annulée (rollback).

Mode WAL (Write-Ahead Logging)

Pour améliorer les performances, particulièrement dans les scénarios avec plusieurs lecteurs et un écrivain, activez le mode WAL :

// Activer le mode WAL
db.exec("PRAGMA journal_mode = WAL;");

Mappage des résultats vers des classes

Bun permet de mapper les résultats de requêtes directement vers des instances de classes :

class User {
id;
name;
email;
created_at;
getFullInfo() {
return `${this.name} (${this.email}) - Créé le: ${this.created_at}`;
}
}
const getUsersQuery = db.query("SELECT * FROM users").as(User);
const users = getUsersQuery.all();
// Maintenant, users est un tableau d'instances de User
for (const user of users) {
console.log(user.getFullInfo());
}

Fermeture de la base de données

Il est important de fermer la connexion à la base de données lorsque vous avez terminé :

// Fermer la connexion
db.close();

Avec Bun, vous pouvez également utiliser la déclaration using pour garantir que les ressources sont correctement libérées :

{
using db = new Database("mydb.sqlite");
using query = db.query("SELECT * FROM users");
console.log(query.all());
// La base de données sera automatiquement fermée à la fin de ce bloc
}

Conclusion

L’API SQLite native de Bun offre une solution simple, rapide et puissante pour travailler avec des bases de données SQLite. Avec son API synchrone et ses performances élevées, elle constitue un excellent choix pour les applications qui nécessitent une base de données locale.

Pour plus d’informations, consultez la documentation officielle de Bun sur SQLite.