Come implementare un ORM di base per PostgreSQL in Node.js

Un ORM (Object-Relational Mapper) permette di interagire con un database utilizzando oggetti JavaScript anziché query SQL esplicite. In questo articolo vedremo come implementare un semplice ORM per PostgreSQL utilizzando Node.js e il pacchetto pg.

1. Installazione dei pacchetti necessari

Per prima cosa, crea una nuova directory per il progetto e installa i pacchetti richiesti:

npm init -y
npm install pg

2. Connessione a PostgreSQL

Creiamo un modulo per gestire la connessione al database:

// db.js
const { Pool } = require('pg');

const pool = new Pool({
  user: 'tuo_utente',
  host: 'localhost',
  database: 'tuo_database',
  password: 'tua_password',
  port: 5432,
});

module.exports = {
  query: (text, params) => pool.query(text, params),
};

3. Creazione della classe ORM base

Ora creiamo una classe base che rappresenterà il nostro ORM:

// orm.js
const db = require('./db');

class ORM {
  constructor(tableName) {
    this.tableName = tableName;
  }

  async findAll() {
    const res = await db.query(`SELECT * FROM ${this.tableName}`);
    return res.rows;
  }

  async findById(id) {
    const res = await db.query(
      `SELECT * FROM ${this.tableName} WHERE id = $1`,
      [id]
    );
    return res.rows[0];
  }

  async create(data) {
    const keys = Object.keys(data);
    const values = Object.values(data);
    const placeholders = keys.map((_, i) => `$${i + 1}`).join(', ');

    const res = await db.query(
      `INSERT INTO ${this.tableName} (${keys.join(', ')}) VALUES (${placeholders}) RETURNING *`,
      values
    );
    return res.rows[0];
  }

  async update(id, data) {
    const keys = Object.keys(data);
    const values = Object.values(data);
    const set = keys.map((key, i) => `${key} = $${i + 1}`).join(', ');

    const res = await db.query(
      `UPDATE ${this.tableName} SET ${set} WHERE id = $${keys.length + 1} RETURNING *`,
      [...values, id]
    );
    return res.rows[0];
  }

  async delete(id) {
    const res = await db.query(
      `DELETE FROM ${this.tableName} WHERE id = $1 RETURNING *`,
      [id]
    );
    return res.rows[0];
  }
}

module.exports = ORM;

4. Utilizzo dell'ORM

Ecco un esempio di utilizzo per una tabella chiamata users:

// index.js
const ORM = require('./orm');
const users = new ORM('users');

(async () => {
  const newUser = await users.create({ name: 'Mario', email: 'mario@example.com' });
  console.log('Creato:', newUser);

  const allUsers = await users.findAll();
  console.log('Tutti gli utenti:', allUsers);

  const singleUser = await users.findById(newUser.id);
  console.log('Utente trovato:', singleUser);

  const updated = await users.update(newUser.id, { name: 'Luigi' });
  console.log('Aggiornato:', updated);

  const deleted = await users.delete(newUser.id);
  console.log('Eliminato:', deleted);
})();

Conclusione

Abbiamo visto come costruire un ORM di base per PostgreSQL con Node.js. Anche se molto semplice, questo approccio può essere utile per piccoli progetti o per comprendere meglio il funzionamento degli ORM più avanzati come Sequelize o TypeORM.

Torna su