Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-mysql-query-utils

Package Overview
Dependencies
Maintainers
0
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-mysql-query-utils

A simple MySQL query utils for Node.js

  • 1.0.4
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
0
Created
Source

node-mysql-query-utils

A MySQL helper to provide ways to connect to the database, build SQL queries, and perform common database operations for Node.js.

npm version

Table of contents

Introduction

node-mysql-query-utils is a MySQL query builder and helper for Node.js. It provides a simple and easy way to build and execute MySQL queries.

Installation

npm install node-mysql-query-utils

or

yarn add node-mysql-query-utils

Overview

This package provides three classes to help you manage and interact with your MySQL database:

  1. DatabaseManagement
  2. SQLBuilder
  3. TableModel

Quick Start

Here’s a quick overview of how to make use of this library:

import {
  DatabaseManagement,
  TableModel,
  SQLBuilder,
  sqlHelper,
} from "node-mysql-query-utils";

// entry point of the application e.g. start server
// index.ts
DatabaseManagement.connectMultipleDatabases([
  {
    identifierName: "mainDB",
    config: {
      host: "localhost",
      user: "root",
      password: "password",
      database: "test_db",
    },
    options: {
      verbose: true, // optional, default is true. If true, will log all queries to console
    },
  },
]);

//or

DatabaseManagement.connectSingleDatabase(
  "mainDB",
  {
    host: "localhost",
    user: "root",
    password: "password",
    database: "test_db",
  },
  {
    verbose: true, // optional, default is true. If true, will log all queries to console
  }
);

// model folder
// user.ts
const mainDB = DatabaseManagement.getInstance("mainDB"); // get instance of mainDB
const columns = sqlHelper.createColumns([
  "user_id",
  "ctime",
  "utime",
  "email",
  "mobile",
  "password",
  "is_active",
  "is_deleted",
]);
export const userAccountModel = mainDB.createTableModel({
  tableName: "user_account",
  primaryKey: "user_id",
  columns,
  centralFields: {
    ctimeField: "ctime", // created_at column name in db
    utimeField: "utime", // updated_at column name in db
    isActiveField: "is_active", // is_active column name in db
    isDeletedField: "is_deleted", // is_deleted column name in db
    statusField: "status", // status column name in db
  },
});

// usage of userAccountModel in other files e.g. api-related files
// get user by id

DatabaseManagement

The DatabaseManagement class is a singleton class that helps manage database connections. It supports connecting to single or multiple databases and provides a way to retrieve instances of the connections.

Single database connection
import { DatabaseManagement } from "node-mysql-query-utils";
import { ConnectionOptions } from "mysql2/promise";

// Define connection configurations
const config: ConnectionOptions = {
  host: "localhost",
  user: "root",
  password: "password",
  database: "test_db",
};

// Connect to a single database
DatabaseManagement.connectSingleDatabase("mainDB", config);

// Retrieve the instance and use it to perform database operations
const dbInstance = DatabaseManagement.getInstance("mainDB");
Multiple database connections
import { DatabaseManagement } from "node-mysql-query-utils";
import { type DatabaseConnectionConfig } from "node-mysql-query-utils/dist/dto/types";

// Define multiple connection configurations
const configs: DatabaseConnectionConfig[] = [
  {
    identifierName: "mainDB",
    config: {
      host: "localhost",
      user: "root",
      password: "password",
      database: "main_db",
    },
  },
  {
    identifierName: "analyticsDB",
    config: {
      host: "localhost",
      user: "root",
      password: "password",
      database: "analytics_db",
    },
  },
];

// Connect to multiple databases
DatabaseManagement.connectMultipleDatabases(configs);

// Retrieve instances and use them to perform database operations
const mainDBInstance = DatabaseManagement.getInstance("mainDB");
const analyticsDBInstance = DatabaseManagement.getInstance("analyticsDB");

SQLBuilder Class

The SQLBuilder class provides a way to build SQL queries for various operations such as SELECT, INSERT, UPDATE, DELETE, etc.

To generate the final SQL query and its parameters, you must call the .buildQuery() method at the end of your query-building process.

If the SQLBuilder constructor is provided with a queryFn, you can use the .executeQuery() method to execute the query directly.

Example
import { SQLBuilder, sqlHelper } from "node-mysql-query-utils";

// Define the table name
const tableName = "user_account";

const columns = sqlHelper.createColumns([
  "user_id",
  "ctime",
  "utime",
  "email",
  "mobile",
  "password",
  "is_active",
  "is_deleted",
]);

// typescript
const sqlBuilder = new SQLBuilder<(typeof columns)[number]>();

// Javascript - no type hinting, but still works. Suggest using TableModel class for better type hinting if using Javascript
const sqlBuilder = new SQLBuilder();

// Accept QueryFunction for SQLBuilder to enable query execution
const sqlBuilder = new SQLBuilder(db.query.bind(db)); // Optional: put your own query function here if you don't connect DB by DatabaseManagement class from this package

// Accept second generic type for query function
const sqlBuilder = new SQLBuilder<(typeof columns)[number], any>(
  db.query.bind(db)
); // Optional: put your own query function here if you don't connect DB by DatabaseManagement class from this package

// Call buildQuery to get the SQL query and parameters in the end
const { sql, params } = sqlBuilder.select().from(tableName).buildQuery();
// Can also use array destructuring
const [sql, params] = sqlBuilder.select().from(tableName).buildQuery();
// BuildQuery also accepts an options object. it will return complete query with format. params will be empty array if format is true
const [sql, params] = sqlBuilder
  .select()
  .from(tableName)
  .buildQuery({ format: true });

// run your own query function if you don't connect DB by DatabaseManagement class from this package
const result = await db.query(sql, params);

// if query function is provided in SQLBuilder, you can execute the query directly
const result = await sqlBuilder.select().from(tableName).executeQuery();

.select() Method

// Select all columns, default is '*'
const [sql, params] = sqlBuilder.select().from(tableName).buildQuery();
const [sql, params] = sqlBuilder.select("*").from(tableName).buildQuery();

// Select specific columns
const [sql, params] = sqlBuilder
  .select(["user_id", "email"])
  .from(tableName)
  .buildQuery();

// Select columns with aliases
const [sql, params] = sqlBuilder
  .select([{ user_id: "id", mobile: "user_mobile" }, { email: "user_email" }])
  .from(tableName)
  .buildQuery();

// Select a single column
const [sql, params] = sqlBuilder.select("user_id").from(tableName).buildQuery();

.from() Method

// No alias
const [sql, params] = sqlBuilder.select().from("user_account").buildQuery();

// alias example
const [sql, params] = sqlBuilder
  .select()
  .from("user_account", "u")
  .buildQuery();
const [sql, params] = sqlBuilder.select().from("user_account u").buildQuery();

.join() Method

// Inner join
const [sql, params] = sqlBuilder
  .select()
  .from("user_account", "u")
  .join(
    "INNER",
    "user_profile_pic",
    "up",
    "u.user_profile_pic_id = up.user_profile_pic_id"
  )
  .buildQuery();

// Left join
const [sql, params] = sqlBuilder
  .select()
  .from("user_account", "u")
  .join(
    "LEFT",
    "user_profile_pic",
    "up",
    "u.user_profile_pic_id = up.user_profile_pic_id"
  )
  .buildQuery();

// Right join
const [sql, params] = sqlBuilder
  .select()
  .from("user_account", "u")
  .join(
    "RIGHT",
    "user_profile_pic",
    "up",
    "u.user_profile_pic_id = up.user_profile_pic_id"
  )
  .buildQuery();

Only provide third argument if no alias is needed

// Inner join
const [sql, params] = sqlBuilder
  .select()
  .from("user_account", "u")
  .join(
    "INNER",
    "user_profile_pic",
    "u.user_profile_pic_id = user_profile_pic.user_profile_pic_id"
  )
  .buildQuery();

.where() Method

// All condition examples
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .where({
    email: "123@gmail.com", // equal to '
    email: { "=": "123@gmail.com" }, // equal to '
    email: { "!=": "123@gmail.com" }, // not equal to
    user_id: { ">": 123 },
    user_id: { "<": 123 },
    user_id: { ">=": 123 },
    user_id: { "<=": 123 },
    is_active: { BETWEEN: [0, 1] },
    is_active: { NOT_BETWEEN: [0, 1] },
    status: { IN: [1, 2, 3, 4] },
    status: { NOT_IN: [1, 2, 3, 4] },
    nickname: { IS_NOT_NULL: true }, // must be true, false will throw error
    nickname: { IS_NULL: true }, // must be true, false will throw error
    nickname: { LIKE: { contains: 'name' } }, // contains 'name'
    nickname: { NOT_LIKE: { startsWith: 'name' } }, // not starts with 'name'
    nickname: { LIKE: { endsWith: 'name' } }, // ends with 'name'
    nickname: { LIKE: '%_123' } // custom pattern
    nickname: { REGEXP: '^[a-zA-Z0-9]*$' } // custom pattern
    "u.user_id": { "!=": 1 }, // assume alias is set in From's second parameters (e.g. .from("user_account", "u"))
  })
  .buildQuery();
// AND example
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .where({
    email: "123@gmail.com",
    is_active: 1,
  })
  .buildQuery();

// alternative AND example
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .where({
    AND: [{ email: { LIKE: "%@gmail.com" } }, { username: "jane" }],
  });
// OR example
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .where({
    OR: [{ email: { LIKE: "%@gmail.com" } }, { username: "jane" }],
  });

Supported Operators:

  • =
  • !=
  • >
  • <
  • >=
  • <=
  • LIKE,
  • NOT_LIKE
  • REGEXP,
  • IN,
  • NOT_IN
  • BETWEEN
  • NOT_BETWEEN
  • IS_NULL
  • IS_NOT_NULL

.orderBy() Method

// Single order by
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .orderBy([{ field: "email", direction: "ASC" }])
  .buildQuery();

// Multiple order by
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .orderBy([
    { field: "email", direction: "ASC" },
    { field: "user_id", direction: "DESC" },
  ])
  .buildQuery();

.limit() and .offset() Methods

// Limit
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .limit(10)
  .buildQuery();

// Limit and offset
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .limit(10)
  .offset(5)
  .buildQuery();

.insert() Method

// Insert single row
const [sql, params] = sqlBuilder
  .insert(
    "user_account",
    { email: "123@gmail.com" },
    {
      enableTimestamps = false, // if true, will add ctime and utime to insert object
      ctimeField = "ctime",
      utimeField = "utime",
      ctimeValue = Math.floor(Date.now() / 1000), // default is current unix timestamp
      utimeValue = Math.floor(Date.now() / 1000), // default is current unix timestamp
      insertIgnore = false, // if true, will add IGNORE to the insert query
    }
  )
  .buildQuery();

Insert Options

The insert method accepts options parameter with the following properties:

PropertyTypeDescription
enableTimestampsboolean(Optional) If true, will add ctime and utime to the insert object. Default is false.
ctimeFieldstring(Optional) The field name for the create timestamp. Default is ctime.
utimeFieldstring(Optional) The field name for the update timestamp. Default is utime.
ctimeValueany(Optional) The value for the create timestamp. Default is the current Unix timestamp.
utimeValueany(Optional) The value for the update timestamp. Default is the current Unix timestamp.
insertIgnoreboolean(Optional) If true, will add IGNORE to the insert query. Default is false.

.update() Method

// Update Method 1
const [sql, params] = sqlBuilder
  .update(
    "user_account",
    { email: "123@gmail.com" },
    // Options
    {
      enableTimestamps = false, // if true, will add utime to update object
      utimeField = "utime",
      utimeValue = Math.floor(Date.now() / 1000), // default is current unix timestamp
    }
  )
  .where({ user_id: 1 })
  .buildQuery();

// Update Method 2 (Options not supported yet)
const [sql, params] = sqlBuilder
  .update("user_account")
  .set({ email: "123@gmail.com" })
  .where({ user_id: 1 })
  .buildQuery();

// Increment and Decrement (Added in version v1.0.4)
const [sql, params] = sqlBuilder
  .update("user_account")
  .set({ balance: { increment: 100 } })
  .where({ user_id: 1 })
  .buildQuery();

Update Options

The update method accepts options parameter with the following properties:

PropertyTypeDescription
enableTimestampsboolean(Optional) If true, will add utime to the update object. Default is false.
primaryKeystring(Optional) The primary key field name. For removing primaryKey in update object
utimeFieldstring(Optional) The field name for the update timestamp. Default is utime.
utimeValueany(Optional) The value for the update timestamp. Default is the current Unix timestamp.

.delete() Method

// Delete Whole Table
const [sql, params] = sqlBuilder.deleteFrom("user_account").buildQuery();

// Delete with where
const [sql, params] = sqlBuilder
  .deleteFrom("user_account")
  .where({ user_id: 1 })
  .buildQuery();

// Delete with limit
const [sql, params] = sqlBuilder
  .deleteFrom("user_account")
  .where({ user_id: { ">": 1 } })
  .limit(1)
  .buildQuery();

.buildQuery() Method

// Build query with format
const sqlBuilder = new SQLBuilder<(typeof columns)[number]>();
const [sql, params] = sqlBuilder
  .select()
  .from("user_account")
  .buildQuery({ format: true });

.executeQuery() Method

// Execute query
const sqlBuilder = new SQLBuilder<(typeof columns)[number]>();
const result = await sqlBuilder.select().from("user_account").executeQuery();

Without calling .buildQuery() or .executeQuery()

// Without calling .buildQuery() or .executeQuery() as end of query building
const sqlBuilder = new SQLBuilder<(typeof columns)[number]>();
const result = sqlBuilder.select().from("user_account");

// result will be an instance of SQLBuilder
// SQLBuilder {
//   queryFn: [Function: bound executeQuery] AsyncFunction,
//   message: 'Call .buildQuery() or .executeQuery() to get the result'
// }

// To get the result, call .buildQuery() or .executeQuery()
const [sql, params] = result.buildQuery();
// or
const result = await result.executeQuery(); // if query function is provided in SQLBuilder

TableModel Class

The TableModel class is a wrapper around the SQLBuilder class that provides a way to build and execute common database operations like SELECT, INSERT, UPDATE, DELETE, etc.

To generate the final SQL query and its parameters, you must call the .buildQuery() method at the end of your query-building process. If you have provided a query function, you can use the .executeQuery() method to execute the query directly.

There are two ways to define and use the TableModel class:

1. Using DatabaseManagement to Connect to the Database

Connect database by DatabaseManagement class can refer to the Quick Start example. This method involves connecting to multiple databases using the DatabaseManagement class and then retrieving instances to create table models.

2. Using the TableModel Class Directly

Alternatively, you can define the table model by using the TableModel class directly. This method is useful if you prefer to use your own query function or if you don't connect to the database using the DatabaseManagement class from this package.

// Define the table model by using the TableModel class directly
const userModel = new TableModel({
  tableName: "users",
  primaryKey: "user_id",
  columns: sqlHelper.createColumns(["user_id", "name", "email", "phone"]),
  queryFn: db.query.bind(db), // Optional: put your own query function here if you don't connect DB by DatabaseManagement class from this package
});

Methods

The TableModel class provides the following methods to perform database operations:

| Method | Description | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | | createSelect | Creates a SELECT query. Returns a function that returns an instance of the SQLBuilder class. You can chain the SQLBuilder methods to build your desired query. | | createInsert | Creates an INSERT query. Returns a function that returns an instance of the SQLBuilder class. You can chain the SQLBuilder methods to build your desired query. | | createUpdate | Creates an UPDATE query. Returns a function that returns an instance of the SQLBuilder class. You can chain the SQLBuilder methods to build your desired query. | | createDelete | Creates a DELETE query. Returns a function that returns an instance of the SQLBuilder class. You can chain the SQLBuilder methods to build your desired query. | | createCount | Creates a COUNT query. Returns a function that returns an instance of the SQLBuilder class. You can chain the SQLBuilder methods to build your desired query. | | findOne | Finds a single record. Returns an instance of the SQLBuilder class with the findOne method configured. | | findAll | Finds multiple records. Returns an instance of the SQLBuilder class with the findAll method configured. | | remove | Removes records based on conditions. Returns an instance of the SQLBuilder class with the remove method configured. | | removeOne | Removes a single record based on conditions. Returns an instance of the SQLBuilder class with the removeOne method configured. | | patchSingleField | Updates a single field in records based on conditions. Returns an instance of the SQLBuilder class with the patchSingleField method configured. | | softDeleteOne | Soft deletes a single record based on conditions. Returns an instance of the SQLBuilder class with the softDeleteOne method configured. | | softDelete | Soft deletes multiple records based on conditions. Returns an instance of the SQLBuilder class with the softDelete method configured. | |

The TableModel class provides the following methods to perform database operations.

Methods that start with create (e.g., createSelect, createInsert) return a function that returns an instance of the SQLBuilder class. You can chain the SQLBuilder methods to build your desired query.

Other methods, such as findOne, return an instance of the SQLBuilder class that is already configured with some chained methods. These methods act as wrapper functions for common CRUD operations and are not intended for further chaining.

createSelect
const selectUser = userModel.createSelect();
const result = await selectUser({
  fields: ["user_id", "email", "nickname"],
})
  .where({ user_id: 1 })
  .executeQuery();
createInsert
const insertUser = userModel.createInsert();
const result = await insertUser({
  data: { user_id: 1, email: "123@email.com", nickname: "John Doe" },
}).executeQuery();
createUpdate
const updateUser = userModel.createUpdate();
const result = await updateUser({
  data: { nickname: "John Doe 2" },
  where: { user_id: { "<=": 5 } },
})
  .limit(2)
  .executeQuery();
createDelete
const deleteUser = userModel.createDelete();
const result = await deleteUser({ where: { user_id: 1 } })
  .limit(1)
  .executeQuery();
createCount
const countResult = await countUser("user_id")
  .where({ user_id: { "<": 2 } })
  .executeQuery();

Common Parameters

The following table lists common parameters that many methods accept. Note that some parameters may be available for certain methods while others may not, as each method performs different operations. TypeScript will provide hints for the available parameters for each method.

ParameterTypeDescription
fieldsArrayAn array of strings specifying the columns to select.
whereObjectAn object specifying the conditions for the query.
orderByArrayAn array of objects specifying the columns to order by and the direction (ASC or DESC).
limitNumberA number specifying the maximum number of rows to return.
offsetNumberA number specifying the offset of the first row to return.
optionsObjectAn object specifying additional options for the query. Can be referenced in Update Options.
findOne
const [user] = await userModel
  .findOne({ where: { user_id: 1 } })
  .executeQuery();
findAll
const users = await userModel
  .findAll({
    fields: ["user_id", "email"],
    where: { is_active: true },
    orderBy: [{ column: "user_id", direction: "ASC" }],
    limit: 10,
    offset: 0,
  })
  .executeQuery();
updateOne
const updatedOneUser = await userModel
  .updateOne({
    where: { user_id: 1 },
    data: { email: "123@gmail.com" },
  })
  .executeQuery();
updateAll
const updateAllUsers = await userModel
  .updateAll({
    data: { nickname: "John Doe" },
    where: { user_id: { "<=": 5 } },
    options: { enableTimestamps: true, utimeField: "utime" },
  })
  .executeQuery();
insertRecord
const insertedUser = await userModel
  .insertRecord({
    data: { user_id: 1, email: "123@gmail.com", nickname: "John Doe" },
    options: {
      enableTimestamps: true,
      ctimeField: "ctime",
      utimeField: "utime",
    },
  })
  .executeQuery();
removeOne
const deletedOneUser = await userModel
  .removeOne({
    where: { user_id: { ">": 1 } },
    orderBy: [{ field: "user_id", direction: "ASC" }],
  })
  .executeQuery();
remove
const deletedAllUsers = await userModel
  .remove({ where: { user_id: 1 } })
  .executeQuery();
patchSingleField
const patchedActiveField = await userModel
  .patchSingleField({
    patchField: "is_active",
    where: { user_id: 1 },
    value: 1,
    options: { enableTimestamps: true, utimeField: "utime" },
  })
  .executeQuery();
softDeleteOne
const softDeletedUser = await userModel
  .softDeleteOne({
    where: { user_id: 1 },
    value: 1,
    options: {
      enableTimestamps: true,
      deleteField: "is_deleted",
      utimeField: "utime",
    },
  })
  .executeQuery();
softDelete
const softDeletedUsers = await userModel
  .softDelete({
    where: { user_id: { ">": 1 } },
    value: 1,
    options: {
      enableTimestamps: true,
      deleteField: "is_deleted",
      utimeField: "utime",
    },
  })
  .executeQuery();

Changelog

Detailed changes for each version are documented in the CHANGELOG.md file.

Keywords

FAQs

Package last updated on 08 Oct 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc