Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lupennat/lupdo
Database Abstraction Layer for Node js
https://github.com/lupennat/lupdo
database lupdo mysql nodejs pdo sql sqlite transaction
Last synced: 3 months ago
JSON representation
Database Abstraction Layer for Node js
- Host: GitHub
- URL: https://github.com/lupennat/lupdo
- Owner: Lupennat
- License: mit
- Created: 2022-10-19T09:34:48.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-27T13:13:29.000Z (4 months ago)
- Last Synced: 2024-10-11T07:01:28.127Z (3 months ago)
- Topics: database, lupdo, mysql, nodejs, pdo, sql, sqlite, transaction
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/lupdo
- Size: 705 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Lupdo
> Lupennat Data Objects
Lupdo is an abstraction layer used for accessing databases, similar to PHP Data Objects exposes a set of APIs.\
Lupdo is not an ORM, Lupdo aims to be a stable layer through which to build an ORM or a Query Builder.\
Lupdo create a Pool of connection By Default.
Lupdo offers the possibility of creating drivers for any database that accepts sql like syntax.- [Third Party Library](#third-party-library)
- [Available Drivers](DRIVER.md)
- [Usage](#usage)
- [Pdo](#pdo)
- [Constants & Attributes](#pdo-constants--attributes)
- [Raw Pool Connection](#pdo-raw-pool-connection)
- [Pool Options](#pool-options)
- [Transaction](#transaction)
- [Statement](#statement)
- [Fetched Object](#fetched-object)
- [Fetch Examples](FETCH.md)
- [Prepared Statement](#prepared-statement)
- [Valid Bindings](#valid-bindings)
- [Primitives Binding](#primitives-binding)
- [Typed Binding](#typed-binding)
- [Params](#params)
- [Logger](#logger)
- [Debug](#debug)
- [BigInt & JSON](#bigint--json)
- [Api](https://lupdo.lupennat.com/api/classes/Pdo.html)## Third Party Library
Lupdo, under the hood, uses stable and performant npm packages:
- [tarn.js](https://github.com/vincit/tarn.js)
## Usage
Base Example with sqlite driver, here you can find the list of [Available Drivers](DRIVER.md)
```js
const { createSqlitePdo } = require('lupdo-sqlite');
// ES6 or Typescrypt
import { createSqlitePdo } from 'ludpo-sqlite';const pdo = createSqlitePdo({ path: ':memory' }, { min: 2, max: 3 });
const run = async () => {
const statement = await pdo.query('SELECT 2');
const res = statement.fetchArray().all();
console.log(res);
await pdo.disconnect();
};run();
```## Pdo
- constructor(driver: [string](#available-drivers), driverOptions: [DriverOptions](#driver-options),PoolOptions: [PoolOptions](#pool-options), attributes: [PdoAttributes](#pdo-constants--attributes))
- setLogger(logger: [PdoLogger](#logger)): void
- getAvailableDrivers(): [string[]](#available-drivers)
- addDriver(driverName: string, driver: [PdoDriverConstructor](DRIVER.md)): void
- prototype.beginTransaction() :Promise<[PdoTransactionI](#transaction)>
- prototype.exec(sql: string): Promise
- prototype.prepare(sql: string): Promise<[PdoPreparedStatementI](#prepared-statement)>
- prototype.query(sql: string): Promise<[PdoStatementI](#statement)>
- prototype.getAttribute([attribute](#pdo-attributes): string): string | number;
- prototype.setAttribute([attribute](#pdo-attributes): string, value: number | string): boolean;
- prototype.disconnect(): Promise
- prototype.reconnect(): void
- prototype.getRawPoolConnection(): Promise<[RawPoolConnection](#pdo-raw-pool-connection)>
- [prototype.getRawDriverConnection(): Promise](#pdo-raw-driver-connection)### Pdo Constants & Attributes
- `ATTR_DEBUG` Determines if DEBUG mode is enabled. Can take one of the following values: [Default DEBUG_DISABLED]
- `DEBUG_DISABLED` Disable DEBUG mode
- `DEBUG_ENABLED` Enable DEBUG mode
- `ATTR_CASE` Force column names to a specific case. Can take one of the following values: [Default CASE_NATURAL]
- `CASE_NATURAL` Leave column names as returned by the database driver.
- `CASE_LOWER` Force column names to upper case.
- `CASE_UPPER` Force column names to lower case.
- `ATTR_NULLS` Determines if and how null and empty strings should be converted. Can take one of the following values: [Default NULL_NATURAL]
- `NULL_NATURAL` No conversion takes place.
- `NULL_EMPTY_STRING` Empty strings get converted to null.
- `NULL_TO_STRING` null gets converted to an empty string.
- `ATTR_FETCH_DIRECTION` Determines which direction Fetch retrieve data. Can take one of the following values: [Default FETCH_FORWARD]
- `FETCH_FORWARD` Fetch the next row in the result set.
- `FETCH_BACKWARD` Fetch the previous row in the result set.
- `ATTR_DRIVER_NAME` Returns the name of the driver.### Pdo Raw Pool Connection
Lupdo offers the possibility of retrieving a raw connection from the pool, to perform any unexposed operations.\
The connection returned is the original [Driver Connection](#available-drivers) used behind the scenes by Lupdo.```ts
interface RawPoolConnection {
release: () => Promise;
connection: PoolConnection;
}
```> **Warning**
> Once the connection has been used, the connection must be released, otherwise the pool will not be able to disconnect.> **Note**
> Because connection is acquired from the pool and should be resusable by Lupdo, integrated Drivers may ignore/force certain third-party driver configuration properties in order to work correctly with Lupdo.### Pdo Raw Driver Connection
Lupdo offers the possibility of retrieving a raw connection from the driver, to perform any unexposed operations.\
The connection returned is the original [Driver Connection](#available-drivers) used behind the scenes by Lupdo.> **Note**
> Since the connection does not come from the pool, it is possible to terminate the job correctly even without invoking pdo.disconnect().
> All third-party driver configuration properties defined by the user are respected.> **Warning**
> Once the connection has been used, you should manually close the connection.```ts
const { createSqlitePdo } = require('lupdo-sqlite');
// ES6 or Typescrypt
import { createSqlitePdo } from 'ludpo-sqlite';const pdo = createSqlitePdo({ path: ':memory' }, { min: 2, max: 3 });
const run = async () => {
const rawConnection = await pdo.getRawDriverConnection();
// do whatever you want
rawConnection.close();
};run();
```## Driver Options
Each driver uses the connection options of the corresponding npm package.\
Debug mode, is defined through Pdo Attributes, custom debug connection options, will be ignored.## Pool Options
- `min` minimum pool size [Default = 2].
- `max` maximum pool size [Default = 10].
- `acquireTimeoutMillis` acquire promises are rejected after this many milliseconds if a resource cannot be acquired [Default 10000].
- `createTimeoutMillis` create operations are cancelled after this many milliseconds if a resource cannot be acquired [Default 5000].
- `destroyTimeoutMillis` destroy operations are awaited for at most this many milliseconds new resources will be created after this timeout [Default 5000].
- `killTimeoutMillis` when pool destroy is executed, connection will be released and brutaly killed after this timeut [Default 10000].
- `killResource` enable/disable killTimeout [Default false].
- `idleTimeoutMillis` Free resources are destroyed after this many milliseconds. Note that if min > 0, some resources may be kept alive for longer. To reliably destroy all idle resources, set min to 0 [Default 30000].
- `createRetryIntervalMillis` how long to idle after failed create before trying again [Default 200].
- `reapIntervalMillis` how often to check for idle resources to destroy [Default 500].
- `created` Define Custom Created Callback.
- `destroyed` Define Custom Destroyed Callback.
- `acquired` Define Custom Acquired Callback.
- `released` Define Custom Release Callback.
- `killed` Define Custom Kill Callback.> **Warning**
> property `killResource` should always be false, before activating this option, verify that you have committed or rolled back all transactions and verified that you have closed all prepared statments
> When 'beginTransaction()' is called connection will be released to the pool only after 'commit()' or 'rollback()' is called.
> When 'prepare()' is called, connection will be released to the pool only after 'close()' is called.
> killResource might not be supported by all drivers> **Warning**
> callback `created` should be used only to set session variables on the connection before it gets used.```js
{
created: async (uuid, connection) => {
await connection.query('SET SESSION auto_increment_increment=1');
};
}
```## Transaction
- prototype.commit(): Promise;
- prototype.rollback(): Promise;
- prototype.exec(sql: string): Promise
- prototype.prepare(sql: string): Promise<[PdoTransactionPreparedStatementI](#prepared-statement)>
- prototype.query(sql: string): Promise<[PdoStatement](#statement)>
- prototype.disconnect(): Promise## Statement
- prototype.getAttribute([attribute](#pdo-attributes): string): string | number;
- prototype.setAttribute([attribute](#pdo-attributes): string, value: number | string): boolean;
- prototype.columnCount(): number;
- prototype.debug(): string;
- prototype.debugSent(): string;
- prototype.fetchDictionary(): [Fetched](#fetched-object);
- prototype.fetchArray(): [Fetched](#fetched-object);
- prototype.fetchBoth(): [Fetched](#fetched-object);
- prototype.fetchColumn(column: number): [Fetched](#fetched-object);
- prototype.fetchObject(abstract: Newable, constructorArgs?: any[]): [Fetched](#fetched-object);
- prototype.fetchClosure(fn: (...args: PdoColumnValue[]) => T): [Fetched](#fetched-object);
- prototype.fecthNamed(): [Fetched](#fetched-object);
- prototype.fetchPair(): Pair;
- prototype.resetCursor(): void;
- prototype.getColumnMeta(column: number): ColumnData | null;
- prototype.rowCount(): number;
- prototype.lastInsertId(name?: string): Promise;
- prototype.nextRowset(): boolean;> **Note**
> statement.debug() will return SQL and Params Reflecting user input, statement.debugSent() will return SQL and Params Adapted by the Driver.### Fetched Object
- get: () => T | undefined;
- all: () => T[];
- group: () => Group;
- unique: () => Unique;> **Note**
> Fetched Object is an Iterable Object. [Here](FETCH.md) you can find a more comprehensive guide.## Prepared Statement
extends [Statement](#statement)
- prototype.bindValue(key: string | number, value: [ValidBindings](#valid-bindings)): void;
- prototype.execute(params?: [Params](#params)): Promise;
- prototype.close(): Promise> **Warning**
> Prepared Statement do not release the connection automatically to take advantage of cached statement. You must close manually the connection through `close()` method when you finish `execute()` sequences.
> Prepared Statement inside a transaction doesn't expose `close()` method, connection will be release only on `commit()` or `rollback()`### Valid Bindings
- [Primitives](#primitives-binding)
- [BaseTypedBinding](#typed-binding)#### Primitives Binding
- number
- string
- bigint
- Buffer
- Date
- boolean
- null#### Typed Binding
In some cases, it is not possible to perform parameter binding, relying solely on the javascript type of the value passed, using `TypedBinding` interface it is possible to identify the type of database column for which the value is being bound.
```ts
const {
NumericTypedBinding,
LengthTypedBinding,
PrecisionTypedBinding,
TypedBinding,
PARAM_INTEGER,
PARAM_DECIMAL,
PARAM_VARBINARY,
PARAM_DATETIME,
} = require('lupdo');
const { createSqlitePdo } = require('lupdo-sqlite');
// ES6 or Typescrypt
import { createSqlitePdo } from 'ludpo-sqlite';
import {
LengthTypedBinding,
NumericTypedBinding,
PARAM_DATETIME,
PARAM_DECIMAL,
PARAM_INTEGER,
PARAM_VARBINARY,
PrecisionTypedBinding,
TypedBinding,
} from 'lupdo';const pdo = createSqlitePdo({ path: ':memory' }, { min: 2, max: 3 });
const run = async () => {
const statement = await pdo.prepare(
'INSERT "test" (`int`,`real`, `nullable_blob`) VALUES (?,?,?)',
);
await statment.execute([
new TypedBinding(PARAM_INTEGER, '10'),
new NumericTypedBinding(PARAM_DECIMAL, '103232.231232112', {
total: 10,
places: 5,
}),
new PrecisionTypedBinding(PARAM_DATETIME, '2024-05 12:30:30.123456789', {
precision: 0,
}),
new LengthTypedBinding(PARAM_VARBINARY, null, { length: 'max' }),
]);
console.log(res);
await pdo.disconnect();
};run();
```this is the list of bindings supported by Lupdo
- PARAM_BIGINT
- PARAM_INTEGER
- PARAM_DOUBLE
- PARAM_DECIMAL
- PARAM_NUMERIC
- PARAM_FLOAT
- PARAM_BOOLEAN
- PARAM_TEXT
- PARAM_CHAR
- PARAM_VARCHAR
- PARAM_GEOMETRY
- PARAM_DATE
- PARAM_DATETIME
- PARAM_DATETIMETZ
- PARAM_TIMESTAMP
- PARAM_TIMESTAMPTZ
- PARAM_TIME
- PARAM_TIMETZ
- PARAM_BINARY
- PARAM_VARBINARY> **Note**
> Some drivers may ignore the type, or may only support a subset of types, or may support additional types.
> Each drivers may support custom options.### Params
Array of [ValidBindings](#valid-bindings)\
or a key-value object## Logger
Lupdo by default doesn't log anything, you can assign a custom log for Lupdo to intercept messages.
```js
const { Pdo } = require('lupdo');
// ES6 or Typescrypt
import { Pdo } from 'lupdo';
Pdo.setLogger((level: any, message: any) => {
console.log(level, message);
});
```## Debug
If you are running into problems, one thing that may help is enabling the debug mode for the connection.\
You can enable debug using [ATTR_DEBUG](#pdo-constants--attributes).\
This will print extra information on stdout.## BigInt & JSON
`BigInt` can not be serialized into a JSON string, Lupdo does not implement any serialization Logic.\
[Here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json) you can find some info about it.