Динамически создайте .where функцию knexjs - PullRequest
0 голосов
/ 21 марта 2020

Есть ли способ динамически использовать .while с knex? У меня есть следующее:

const user = await Users.findOne({id}, "id username email");

Что делает

findOne(data, returns) {
    return knex("users").select(returns && typeof returns === "string" ? returns.split(" ") : "*").where(data).first();
}

Это прекрасно работает. Если я хочу, чтобы id и username соответствовали, я могу сделать:

const user = await Users.findOne({id, username}, "id username email");

Однако мне нужно username с учетом регистра. С mon go (Mon goose) я бы сделал:

{username: new RegExp("^" + username + "$", "I")}, но используя knex query-lab: http://michaelavila.com/knex-querylab/ То есть where username = {}

Итак, я обнаружил, что мне нужно сделать where username ilike %username%, что в knex равно

.where('username', 'ilike', `%${username}%`)

Итак, у меня есть новая функция:

//users route
const  user = await Users.findOneByArray(['username', 'ilike', `%${username}%`]);

//queries file
findOneByArray(data) {
    return knex("users").where(...data).first();
}

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

//users route
const user = await Users.findTokenMatchesAccount(['id', '=', `${token.user_id}`], ['username', 'ilike', `%${username}%`], ['email', 'ilike', `%${email}%`]);

//query file
findTokenMatchesAccount(id, username, email) {
    return knex("users").where(...id).where(...username).where(...email).first();
}

3 отдельных .where s для них. Есть ли способ автоматически / динамически создавать такие функции, как:

//users route
const user = await Users.findTokenMatchesAccount([['id', '=', `${token.user_id}`], ['username', 'ilike', `%${username}%`], ['email', 'ilike', `%${email}%`]]);

//query file
findTokenMatchesAccount(data) {
    return knex("users").where(function() {
        for(const i in data) return(where(data[i])}).first();
    }
}

Некоторые волхвы c или около того, чтобы взять все значения в параметре данных и динамически добавить .where к нему. Или мне нужно вручную настроить это как часть моего запроса для чего-то, что мне может понадобиться? (3 .where с, как показано выше, может быть 4 .where с в следующий раз, если у меня будут дополнительные опции, не зависящие от регистра), чтобы найти

Или было бы проще взять массив данных и создать строки и использовать knex.raw? Хотя, я не уверен, что вырвется drop table.

1 Ответ

0 голосов
/ 22 марта 2020

Похоже, что knex реализован с помощью Pattern Builder. Может быть, попытаться использовать .reduce()? Обычно используется для создания цепочек / создания конвейеров.

async function findTokenMatchesAccount(whereStmtArgs) {
  // Store the query
  let query = knex('users');

  // Pick one from the 2 options:  

  // Option 1
  whereStmtArgs.reduce((q, currentWhereStmtArg) => q.where(...currentWhereStmtArg), query);

  // Option 2 (if you're not comfortable with reduce)
  for (const whereStmtArg for whereStmtArgs) {
    query = query.where(...whereStmtArg);
  }

  return query.first();
}

const dynamicWhereStatements = [['id', '=', `${token.user_id}`], ['username', 'ilike', `%${username}%`], ['email', 'ilike', `%${email}%`]];
const user = await findTokenMatchesAccount(dynamicWhereStatements);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...