Tuesday, 21 May 2019

this.parent.acquire is not a function on prepared statements

I use the mssql (https://www.npmjs.com/package/mssql) module for my database. Normally I use postgres databases which lead to pg (https://www.npmjs.com/package/pg).

I want to setup prepared statements for the mssql database. When using the pg module it's quite easy.


This is how I do it with pg:

I setup my databaseManager

const { Pool } = require('pg');
const db = require('../config/database.js');
const pool = new Pool(db);

function queryResponse(result, err) {
  return {
    result,
    err
  };
}

module.exports = async (text, values) => {
  try {
    const result = await pool.query(text, values);
    return queryResponse(result.rows, null);
  } catch (err) {
    return queryResponse(null, err);
  }
};

and whenever I want to query the database I can call this module and pass in my statement and values. An example for todo apps would be

todos.js (query file)

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

module.exports = {
  getAllTodosFromUser: values => {
    const text = `
        SELECT
            id,
            name,
            is_completed AS "isCompleted"
        FROM
            todo
        WHERE
            owner_id = $1;
    `;

    return db(text, values);
  }
};


I wanted to create an mssql equivalent. From the docs I see that the module differs from the pg module.

I changed my databaseManager to

const sql = require('mssql');
const config = require('../config/database.js');
const pool = new sql.ConnectionPool(config).connect();

module.exports = async (queryBuilder) => {
    try {
      const preparedStatement = await new sql.PreparedStatement(pool);

      return queryBuilder(sql, preparedStatement, async (query, values) => {
        await preparedStatement.prepare(query);
        const result = await preparedStatement.execute(values);
        await preparedStatement.unprepare();

        return {
            result: result.rows,
            err: null
        };
      });
    } catch (err) {
        return {
            result: null,
            err
        }
    }
};

and my query file would pass in the required parameters for the preparedStatement object

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

module.exports = {
  getUserByName: username => db((dataTypes, statementConfigurator, processor) => {
    statementConfigurator.input('username', dataTypes.VarChar);

    const query = `
        SELECT
          *
        FROM
          person
        WHERE
          username = @username;
    `;

    return processor(query, { username });
  })
};

I was hoping that this approach would return the desired result but I get the error

this.parent.acquire is not a function

and don't know if my code is wrong. If it is, how can I setup my prepared statements correctly?


Edit:

I just found out that the error comes from this line of code

await preparedStatement.prepare(query);

but I think I took it correctly from the docs

https://tediousjs.github.io/node-mssql/#prepared-statement



from this.parent.acquire is not a function on prepared statements

No comments:

Post a Comment