CodeFoodPixels / node-promise-mysql

A wrapper for mysqljs/mysql that wraps function calls with Bluebird promises.
MIT License
338 stars 63 forks source link

Missing on(...) method for the Connection interface in index.d.ts #119

Closed philfontaine closed 3 years ago

philfontaine commented 5 years ago

Not 100% sure how to implement it, so that's why i'm opening this issue

CodeFoodPixels commented 5 years ago

Paging our TypeScript expert @move-zig

move-zig commented 5 years ago

I've added the definitions on my end. I copied them from the underlying @types/mysql library.

I'm not sure if it's correct though.

import * as mysql from 'promise-mysql';

const connectionOptions = {
  ...
};

async function poolConnectionTest() {
  try {
    const pool = await mysql.createPool(connectionOptions);
    try {
      const connection = await pool.getConnection();
      try {
        connection.on('connect', () => { console.log('connected!'); });
        connection.on('end', (err: mysql.MysqlError) => {
          if (err) {
            console.log(err);
          }
          console.log('ended!');
        });
        connection.on('fields', (fields: any[]) => { console.log('fields', fields); });
        connection.on('error', (err: mysql.MysqlError) => {
          console.log('got an error', err);
        });
        await connection.query('SELECT 5');
        await connection.query('SELECT * FROM countries LIMIT 5');
        await connection.query('SELECT * FROM table_that_doesnt_exist LIMIT 5');
      } finally {
        pool.releaseConnection(connection);
      }
    } finally {
      pool.end();
    }
  } catch (err) {
    //
  }
}

async function connectionTest() {
  try {
    const connection = await mysql.createConnection(connectionOptions);
    try {
      connection.on('connect', () => { console.log('connected!'); });
      connection.on('end', (err: mysql.MysqlError) => {
        if (err) {
          console.log(err);
        }
        console.log('ended!');
      });
      connection.on('fields', (fields: any[]) => { console.log('fields', fields); });
      connection.on('error', (err: mysql.MysqlError) => {
        console.log('got an error', err);
      });
      await connection.query('SELECT 5');
      await connection.query('SELECT * FROM countries LIMIT 5');
      await connection.query('SELECT * FROM table_that_doesnt_exist LIMIT 5');
    } finally {
      connection.end();
    }
  } catch (err) {
    //
  }
};

connectionTest().then(() => {
  return poolConnectionTest();
})

Output:

ended!
ended!

Expected: some kind of output from the on('error') and on('fields') callbacks.

CodeFoodPixels commented 5 years ago

I'll have a look into this later tonight!

CodeFoodPixels commented 5 years ago

I've just realised what the issue is. In your code, you're doing .on on the connection and then doing a query, whereas you need to be using queryStream with a listener for the fields and error events.

e.g:

const errorQuery = connection.queryStream('SELECT * FROM table_that_doesnt_exist LIMIT 5');
errorQuery.on('error', () => {
  console.log('oh no');
})
move-zig commented 3 years ago

Sorry for not getting around to this sooner!

I see how streaming queries work now. The types for streaming queries are already included.

There are at least two events for the connection object in general though: 'end' and 'error'. An 'end' event triggers when the connection is closed. And an 'error' event triggers if an error occurs that's not handled in the stream:

const connection = await mysql.createConnection(options);
connection.on('error', err => console.log('global error', err); // this will only be triggered if the error isn't handled in the stream below
connection.on('end', () => console.log('global end'));
connection.queryStream('SELECT * FROM unknown_table LIMIT 5')
  .on('error', err => console.log('on error', err) // handle the error in the stream
  .on('result', result => console.log('on result', result))
  .on('end', () => console.log('on end');
connection.end();

I will add this to the Connection interface:

on(ev: 'error', callback: (err: mysql.MysqlError) => void): void;
on(ev: 'end', callback: () => void): void;