Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/xnerhu/sql-next

🔎 Mysql client for Node.js with json queries and modern api.
https://github.com/xnerhu/sql-next

javascript js json mysql nodejs nosql sql typescript

Last synced: about 2 months ago
JSON representation

🔎 Mysql client for Node.js with json queries and modern api.

Awesome Lists containing this project

README

        



[![Travis](https://img.shields.io/travis/xnerhu/sql-next.svg?style=flat-square)](https://travis-ci.org/xnerhu/sql-next.svg)
[![NPM](https://img.shields.io/npm/v/sql-next.svg?style=flat-square)](https://www.npmjs.com/package/sql-next)
[![NPM](https://img.shields.io/npm/dm/sql-next?style=flat-square)](https://www.npmjs.com/package/sql-next)
[![Discord](https://discordapp.com/api/guilds/307605794680209409/widget.png?style=shield)](https://discord.gg/P7Vn4VX)
[![Github](https://img.shields.io/github/followers/xnerhu.svg?style=social&label=Follow)](https://github.com/xnerhu)

SQL-next is a wrapper around [node-mysql](https://github.com/mysqljs/mysql), which provides MongoDB like queries and promise-based api.



### Features

- JSON queries
- Protection from sql-injection
- Selectors _(not yet done)_
- Promise based api

Checkout [roadmap](https://github.com/xnerhu/sql-next/projects/1) to see what's coming.

## Installing

```bash
$ npm install sql-next
```

## Quick start

An example of finding an item:

```ts
import { Client, IConfig } from 'sql-next';

const config: IConfig = {
host: 'example.com',
user: 'username',
password: '123',
port: 8080,
};

interface Item {
_id: number;
header: string;
body: string;
}

async function init() {
const client = new Client();

await client.connect(config);

console.log('Connected!');

const db = client.db('name');
const table = db.table('tests');

const item = await table.findOne({ _id: 2 });

console.log(item);
}

init();
```

Output:

```js
{
_id: 2,
header: 'Hello world!',
body: 'Lorem ipsum...',
}
```

## API

Class `Client`:

- [`Client.connect`](#clientConnect)
- [`Client.close`](#clientClose)
- [`Client.db`](#clientDb)
- [`Client.switchUser`](#clientSwitchUser)
- [`Client.query`](#clientQuery)

Class `Database`:

- [`Database.tables`](#databaseTables)
- [`Database.table`](#databaseTable)

Class `Table`:

- [`Table.find`](#tableFind)
- [`Table.findOne`](#tableFindOne)
- [`Table.count`](#tableCount)
- [`Table.insertOne`](#tableInsertOne)
- [`Table.insert`](#tableInsert)
- [`Table.update`](#tableUpdate)

Interfaces:

- [`IConfig`](#config)
- [`ISSLConfig`](#sslConfig)
- [`IQueryFilter`](#queryFilter)
- [`IQuerySelector`](#querySelector)
- [`IQueryOptions`](#queryOptions)

## Other

- [`Advanced filtering`](#advancedFiltering)

### Class `Client`

#### Methods

- `Client.connect(config: string | IConfig)`


Connects to mysql server.

```js
import { Client } from 'sql-next';

const client = new Client();

try {
await client.connect({
host: 'example.com',
user: 'username',
password: '123',
port: 8080,
});

console.log('Connected!');
} catch (error) {
console.log('Failed to connect!', error);
}
```

- `Client.close()`


Closes connection.

```js
await client.close();

console.log('Closed!');
```

- `Client.db(name: string): Database`


Returns a new database instance that shares the same connection with `Client`.

```js
const client = new Client();
const db = client.db('users');
```

- `Client.switchUser(config: ConnectionOptions)`


Reconnects with new user credentials.

```js
const client = new Client();

client.switchUser({
user: 'seconduser',
password: 'password',
});
```

- `Client.query(sql: string): Promise`


Performs a raw query globally.

```js
const client = new Client();
const news = await client.query('SELECT * from `test`.`news`');
```

### Class `Database`

#### Methods

- `Database.tables(): Promise`


Returns a list of tables in a database.

```js
import { Client } from 'sql-next';

const client = new Client();
const db = client.db('test');
const tables = await db.tables();

console.log(tables); // ['users', 'news', ...]
```

- `Database.table(name: string): Table`


Returns a new table instance that shares the same connection with `Client`.

```js
import { Client } from 'sql-next';

const client = new Client();
const db = client.db('test');
const table = db.table('news');

const news = await table.find();

console.log(news); // [{_id: 1, title: 'lorem ipsum'}, ...]
```

#### Properties

- `Database.name`

### Class `Table`

#### Methods

- `Table.find(filter?: IQueryFilter, options?: IQueryOptions): Promise`


Fetches multiple items from a table. You can also set an offset or a limit, by setting `options`. See **todo** for advanced filtering.

```js
const table = db.table('news');

const news = await table.find({ _authorId: 2 }, { offset: 2, limit: 10 });
```

- `Table.findOne(filter?: IQueryFilter): Promise`


Returns a single item from a table. See **todo** for advanced filtering.

```js
const table = db.table('news');

const item = await table.findOne({ _id: 11 });
```

- `Table.count(filter?: IQueryFilter): Promise`


Counts items in a table.

```js
const table = db.table('news');

const count = await table.count();

console.log(count); // 141
```

- `Table.insert(items: T[]): Promise`


Inserts multiple items to a table and returns each of them with replaced `_id` property.

```js
const table = db.table('news');

const [first, second] = await table.insert([
{ title: 'Hello world!' },
{ title: 'Lorem ipsum' },
]);

console.log(first._id, second._id); // 1, 2
```

- `Table.insertOne(items: T): Promise`


Inserts a single item with replaced `_id` property, coresponding to added record.

```js
const table = db.table('news');

const data = await table.insertOne({ title: 'Cooking tips' });

console.log(data); // { _id: 3, title: 'Cooking tips' }
```

- `Table.update(filter: IQueryFilter, update: IUpdateItem): Promise`


Updates every items matching `filter` and replaces their fields with `update`.

```js
table.update({ _id: 1 }, { content: 'Hello world!' });
```

#### Properties

- `Table.name`

### Interface `IConfig`

```ts
interface IConfig {
user?: string;
password?: string;
port?: number;
ssl?: ISSLConfig;
charset?: string;
insecureAuth?: boolean;
socketPath?: string;
debug?: boolean | string[];
bigNumberStrings?: boolean;
connectTimeout?: number;
dateStrings?: boolean | ('TIMESTAMP' | 'DATETIME' | 'DATE')[];
host?: string;
localAddress?: string;
supportBigNumbers?: boolean;
timeout?: number;
timezone?: number;
trace?: boolean;
}
```

### Interface `ISSLConfig`

```ts
import { SecureContextOptions } from 'tls';

export type ISSLConfig =
| string
| (SecureContextOptions & {
rejectUnauthorized?: boolean;
});
```

### Interface `IQueryFilter`

```ts
export type IQueryFilter = {
[P in keyof T]?: Partial | RegExp;
} &
IQuerySelector;
```

It means that for a type you pass, it will make every key optional and property as original or a regex expression. Also it will include selectors like `$or`.

### Interface `IQuerySelector`

```ts
export interface IQuerySelector {
$or?: IQueryFilter[];
```

### Interface `IQueryOptions`

```ts
export interface IQueryOptions {
limit?: number;
offset?: number;
```

## Other

### Advanced filtering

Let's say we want to find a group of items with `_authorId` field equals to _2_.

We can do it like this:

```ts
const table = db.table('news');

table.find({ _authorId: 2 });
```

And what if we want `_categoryId` to be _1_.

```ts
table.find({
_authorId: 2,
_categoryId: 1,
});
```

You can see, that combining properties together works as **AND** selector.

There are other selectors as well.

#### `$or`

This will search for the items with `_authorId` = _2_ and `_categoryId` = _1_ or _2_.

```ts
table.find({
_authorId: 2,
$or: [{ _categoryId: 1 }, { _categoryId: 2 }],
});
```