this.parent.acquire не является функцией готовых операторов - PullRequest
3 голосов
/ 15 апреля 2019

Я использую mssql (https://www.npmjs.com/package/mssql)) для своей базы данных. Обычно я использую базы данных postgres, которые приводят к pg (https://www.npmjs.com/package/pg).

Я хочу настроить подготовленные операторы для базы данных mssql. При использовании модуля pg это довольно просто.


Вот как я это делаю с pg:

Я настраиваю свой менеджер баз данных

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);
  }
};

и всякий раз, когда я хочу запросить базу данных, я могу вызвать этот модуль и передать свое утверждение и значения. Примером приложений todo будет

todos.js (файл запроса)

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);
  }
};

Я хотел создать эквивалент mssql. Из документации я вижу, что модуль отличается от модуля pg.

Я изменил свой databaseManager на

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
        }
    }
};

и мой файл запроса передаст необходимые параметры для preparedStatement объекта

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 });
  })
};

Я надеялся, что этот подход вернет желаемый результат, но я получаю ошибку

this.parent.acquire не является функцией

и не знаю, неверен ли мой код. Если это так, как я могу правильно настроить подготовленные заявления?


Edit:

Я только что узнал, что ошибка исходит из этой строки кода

await preparedStatement.prepare(query);

но я думаю, что я правильно взял из документов

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

Ответы [ 2 ]

1 голос
/ 24 мая 2019

Я думал, что этот вопрос заслуживает немного большего объяснения, чем ответ, который дал ОП.Решение ничем не отличается от того, на которое OP уже ответил.

Проблема остается той же, пул не должен был быть решен из состояния ожидания обещания.Так что его просто нужно ждать.

module.exports = async queryBuilder => {
  try {
    await pool; // Waiting for pool resolve from promise pending state.
    const preparedStatement = await new sql.PreparedStatement(pool);
    // ..
  } catch (err) {
    // ..
  }
};

Когда вы пытаетесь построить подготовленный оператор, вы передаете пул в качестве аргумента его конструктору.В его конструкторе есть строка ниже

this.parent = parent || globalConnection

, после которой, когда вы готовите оператор, поток ведет к этой строке , которая вызовет проблему с того времениЗначение this.parent все еще было обещанием, которое еще не было решено.

this.parent.acquire(this, (err, connection, config) => {
0 голосов
/ 23 мая 2019

Похоже, что pool все еще в ожидании. Поэтому я переименовал переменную

const pool = new sql.ConnectionPool(config).connect();

до poolRequest и в рамках моей функции исполнения я могу ждать этого обещания

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

      // ...
    } catch (err) {
        // ...
    }
};

Кажется, это работает, но, пожалуйста, не стесняйтесь предлагать другие решения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...