UNPKG

ts-sql-builder

Version:

A straightforward api for SQL query & schema generation

278 lines (215 loc) 5.75 kB
# SQL Query & Schema Builder for Node.js A straightforward api for SQL query & schema generation. # Overview This npm package provides a versatile SQL query & schema builder for Node.js applications. It supports the creation of SQL queries for common operations like SELECT, INSERT, UPDATE, DELETE and a schema builder api making it easy to create & interact with relational databases. Built with [Typescript](https://www.typescriptlang.org/), but can be used in pure [JavaScript](https://en.wikipedia.org/wiki/JavaScript) as well. - [Installation](#installation) - [Usage](#usage) - [Building Queries](#building-queries) - [Schema Generation](#schema-generation) - [License](#license) ## Installation Install the package using npm: ```bash npm install ts-sql-builder ``` ## Usage ### Building Queries Create a new instance of `QueryBuilder`: ```ts import { createQueryBuilder } from 'ts-sql-builder'; const qb = createQueryBuilder(); ``` Build a SELECT query: ```ts const selectQuery = qb.select('*').from('logs').limit(5).build().getSql(); ``` ```sql SELECT * FROM "logs" logs LIMIT 5 ``` Build an INSERT query: ```ts const insertQuery = qb .clear() // Clear the query builder for reuse (or create a new one) .insertInto('items') .columns('title', 'price', 'isActive') .values(['headset', 359.99, true], ['camera', 1999, true]) .build() .format({ tabWidth: 4 }) // Format the generated query if needed .getSql(); ``` ```sql INSERT INTO items ("title", "price", "isActive") VALUES ('headset', 359.99, true), ('camera', 1999, true) ``` Build an UPDATE query: ```ts const updateQuery = createQueryBuilder() .update('user') .set({ employed: false, profession: 'student' }) .where('user.age <= 16') .build() .format() .getSql(); ``` ```sql UPDATE user SET "employed" = false, "profession" = 'student' WHERE user.age <= 16 ``` Perform a join operation: ```ts const userWithPosts = createQueryBuilder() .select('user.*') .addSelect({ 'JSON_AGG(post.*)': 'posts' }) .from('user') .innerJoin({ name: 'post', condition: 'user.id = post."userId"', }) .groupBy('user.id') .build() .format({ tabWidth: 4 }) .getSql(); ``` ```sql SELECT user.*, JSON_AGG(post.*) AS posts FROM "user" user INNER JOIN "post" post ON (user.id = post."userId") GROUP BY user.id ``` And more usage features like sub-queries, a handful of operations (IN, ALL, ANY, CONCAT, AND, OR), complex joins, sorting, you name it.. ### Schema Generation Important note: - For using schema builder api, you have to enable experimental support for decorators: - using command line: `tsc --experimentalDecorators` - or using compiler options inside `tsconfig.json`: ```json { "compilerOptions": { "experimentalDecorators": true } } ``` Api usage: ```ts import { Column, ForeignKey, Index, PrimaryKey, Table, buildSchema, tableSchema, } from 'ts-sql-builder'; @Table() export class Address { @PrimaryKey() @Column({ type: 'SERIAL' }) id!: number; @Column({ type: 'VARCHAR', unique: true }) rawAddress!: string; @Column({ type: 'VARCHAR' }) city!: string; @Column({ type: 'VARCHAR' }) street!: string; @Column({ type: 'INTEGER' }) zip!: number; } @Index({ name: 'idx_user_email', columns: ['email'], unique: true }) @Index({ name: 'idx_user_username', columns: ['username'], unique: true }) @Table('users') class User { @PrimaryKey() @Column({ type: 'SERIAL' }) id!: number; @Column({ type: 'VARCHAR(255)', nullable: false }) name!: string; @Column({ type: 'VARCHAR(65)', nullable: false, unique: true }) username!: string; @Column({ type: 'INTEGER', check: 'age >= 18' }) age!: number; @Column({ type: 'VARCHAR(255)', unique: true }) email!: string; @Column({ name: 'created_at', type: 'TIMESTAMP', default: () => 'CURRENT_TIMESTAMP', }) createdAt!: Date; @Column({ type: 'BOOLEAN', default: true }) activated!: boolean; @ForeignKey({ reference: 'address(id)', onDelete: 'NO ACTION' }) @Column({ type: 'INTEGER' }) addressId!: number; } ``` To generate schemas in strings: ```ts const addressSchema = tableSchema(Address); const userSchema = tableSchema(User); console.log(addressSchema); console.log(userSchema); ``` Generates: ```sql CREATE TABLE address ( id SERIAL, rawAddress VARCHAR UNIQUE, city VARCHAR, street VARCHAR, zip INTEGER, PRIMARY KEY (id) ); CREATE TABLE users ( id SERIAL, name VARCHAR(255) NOT NULL, username VARCHAR(65) NOT NULL UNIQUE, age INTEGER CHECK (age >= 18), email VARCHAR(255) UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, activated BOOLEAN DEFAULT true, addressId INTEGER, PRIMARY KEY (id), FOREIGN KEY (addressId) REFERENCES address (id) ON DELETE NO ACTION ); CREATE UNIQUE INDEX idx_user_username ON users (username); CREATE UNIQUE INDEX idx_user_email ON users (email); ``` To generate each table schema in a separate file: ```ts // simply call buildSchema and provide the base directory: buildSchema({ dirname: './db/tables/' }); ``` Generates these files: ``` ./db └── tables ├── address.schema.sql └── users.schema.sql ``` To generate the whole database schema in a single file: ```ts // call buildSchema with the path: buildSchema({ path: './db/schema/db.sql' }); ``` Generates a single file: ``` ./db └── schema └── db.sql ``` For detailed usage examples and API documentation, refer to the [full documentation](https://github.com/BlaanTeam/ts-query-builder/#). ## License This package is licensed under the [MIT License](https://github.com/BlaanTeam/ts-query-builder/blob/main/LICENSE).