SeriousLee
SeriousLee

Reputation: 1371

Node.js - Converting a SQL query into Knex.js

I have a SQL query (Postgres) containing several joins that I'm having trouble converting into a single Knex.js statement. Here's the SQL query:

SELECT 
    User.id, User.name, User.email,
    Role.name AS r_name,
    UserPofile.id AS p_id, UserPofile.date_of_birth AS p_dob,
    AuthToken.id AS at_id, AuthToken.token AS at_token, AuthToken.platform AS at_platform
FROM public."user" User
    LEFT JOIN public."user_role" UserRole ON User.id = UserRole.user_id
    LEFT JOIN public."role" Role ON UserRole.role_id = Role.id
    LEFT JOIN public."application" Application ON UserProfile.app_id = Application.id
    LEFT JOIN public."user_profile" UserProfile ON User.id = UserProfile.user_id
    LEFT JOIN public."auth_token" AuthToken ON User.id = AuthToken.user_id
WHERE 
    User.email LIKE '[email protected]' AND
    Application.name LIKE 'awesome-application' AND
    AuthToken.platform LIKE 'mobile';

Here's my Knex.js code:

    return knex('user').where({ email:'[email protected]' })
    .select([
        'user.id', 'user.name', 'user.email' // User
        'role.name AS rName' // Roles
        'user_profile.id AS pId', 'user_profile.date_of_birth AS pDob' // UserProfiles
        'auth_token.id AS atId' 'auth_token.platform AS atPlatform', 'auth_token.token AS atToken' // AuthTokens
    ])
    .leftJoin('user_profile', 'user_profile.user_id', 'user.id')
    .leftJoin('user_role', 'user_role.user_id', 'user.id')
    .leftJoin('role', 'role.id', 'user_role.role_id')
    .leftJoin('auth_token', 'auth_token.user_id', 'user.id')
    .then(users => {

        users = users.filter(user => { 
            return user.pApp_id === appId && user.atApp_id === appId && user.atPlatform === platform; 
        });
        return users;
    });

This produces the same result that the SQL query does, but the problem is that I have to filter the returned users in the .then() clause of the Knex call because I don't know how to add WHERE conditions for the Application.name and AuthToken.platform.

Question:

Can someone please help me figure out how to structure my Knex code's .where() clause to have it be equivalent to the SQL query?

Notes:

Upvotes: 2

Views: 8578

Answers (2)

Grynets
Grynets

Reputation: 2525

To debug you can use .toSQL() to debug your knex queries documentation.
Also, nice cheatsheet

As hot fix solution you can use .raw() and paste your SQL code there.

About WHERE conditions, you can just chain them in the end of your knex query.
Something like this:

return knex('user')
  .select('user.id', 'user.name', 'user.email', 
    'role.name AS rName'
    'user_profile.id AS pId', 'user_profile.date_of_birth AS pDob', 
    'auth_token.id AS atId' 'auth_token.platform AS atPlatform', 'auth_token.token AS atToken'
   )
  .leftJoin('user_profile', 'user_profile.user_id', 'user.id')
  .leftJoin('user_role', 'user_role.user_id', 'user.id')
  .leftJoin('role', 'role.id', 'user_role.role_id')
  .leftJoin('auth_token', 'auth_token.user_id', 'user.id') 
  .where('user.email', 'like', '%[email protected]%')
  .andWhere('application.name', 'like' '%awesome-application%')

//...etc

Upvotes: 5

Artem Mirchenko
Artem Mirchenko

Reputation: 2170

Simplest solution is use .whereRaw():

knex whereRaw

Example:

.leftJoin('auth_token', 'auth_token.user_id', 'user.id')
.whereRaw('User.email LIKE ?', `${your_param_here}`)
.andWhereRaw('AuthToken.platform LIKE ?', `${your_param_here}`)

Upvotes: 1

Related Questions