{"id":25245888,"url":"https://github.com/lupennat/ludo","last_synced_at":"2026-02-09T16:31:13.593Z","repository":{"id":62101222,"uuid":"554122752","full_name":"Lupennat/ludo","owner":"Lupennat","description":"Database Abstraction Layer for Node js","archived":false,"fork":false,"pushed_at":"2025-02-01T15:24:51.000Z","size":812,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-08T11:41:28.476Z","etag":null,"topics":["database","lupdo","mysql","nodejs","pdo","sql","sqlite","transaction"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/lupdo","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lupennat.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T09:34:48.000Z","updated_at":"2025-02-02T15:40:27.000Z","dependencies_parsed_at":"2024-09-24T21:42:45.814Z","dependency_job_id":"f9c372d3-0397-47cb-be19-a5b371f64ba3","html_url":"https://github.com/Lupennat/ludo","commit_stats":{"total_commits":81,"total_committers":3,"mean_commits":27.0,"dds":0.2222222222222222,"last_synced_commit":"7a07aa6109c1642f1947ee1d6c6843a1dc4647ea"},"previous_names":["lupennat/ludo","lupennat/lupdo"],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lupennat%2Fludo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lupennat%2Fludo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lupennat%2Fludo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lupennat%2Fludo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lupennat","download_url":"https://codeload.github.com/Lupennat/ludo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238399622,"owners_count":19465491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","lupdo","mysql","nodejs","pdo","sql","sqlite","transaction"],"created_at":"2025-02-12T02:03:17.647Z","updated_at":"2025-10-26T21:30:27.237Z","avatar_url":"https://github.com/Lupennat.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n \u003ca href=\"https://www.npmjs.com/package/lupdo\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/v/lupdo?color=0476bc\u0026label=\" alt=\"NPM version\"\u003e\n    \u003c/a\u003e\n \u003ca href=\"https://www.npmjs.com/package/lupdo\" target=\"_blank\"\u003e\n        \u003cimg alt=\"NPM Downloads\" src=\"https://img.shields.io/npm/dm/lupdo?color=3890aa\u0026label=\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://app.codecov.io/github/Lupennat/lupdo\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://codecov.io/github/Lupennat/lupdo/branch/main/graph/badge.svg?token=FOECLCWQ7F\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://snyk.io/test/github/lupennat/lupdo\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://snyk.io/test/github/lupennat/lupdo/badge.svg\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n# Lupdo\n\n\u003e Lupennat Data Objects\n\nLupdo is an abstraction layer used for accessing databases, similar to PHP Data Objects exposes a set of APIs.\\\nLupdo is not an ORM, Lupdo aims to be a stable layer through which to build an ORM or a Query Builder.\\\nLupdo create a Pool of connection By Default.\nLupdo offers the possibility of creating drivers for any database that accepts sql like syntax.\n\n- [Third Party Library](#third-party-library)\n- [Available Drivers](DRIVER.md)\n- [Usage](#usage)\n- [Pdo](#pdo)\n  - [Constants \u0026 Attributes](#pdo-constants--attributes)\n  - [Raw Pool Connection](#pdo-raw-pool-connection)\n- [Pool Options](#pool-options)\n- [Transaction](#transaction)\n- [Statement](#statement)\n  - [Fetched Object](#fetched-object)\n  - [Fetch Examples](FETCH.md)\n- [Prepared Statement](#prepared-statement)\n  - [Valid Bindings](#valid-bindings)\n    - [Primitives Binding](#primitives-binding)\n    - [Typed Binding](#typed-binding)\n  - [Params](#params)\n- [Logger](#logger)\n- [Debug](#debug)\n- [BigInt \u0026 JSON](#bigint--json)\n- [Api](https://lupdo.lupennat.com/api/classes/Pdo.html)\n\n## Third Party Library\n\nLupdo, under the hood, uses stable and performant npm packages:\n\n- [tarn.js](https://github.com/vincit/tarn.js)\n\n## Usage\n\nBase Example with sqlite driver, here you can find the list of [Available Drivers](DRIVER.md)\n\n```js\nconst { createSqlitePdo } = require('lupdo-sqlite');\n// ES6 or Typescrypt\nimport { createSqlitePdo } from 'ludpo-sqlite';\n\nconst pdo = createSqlitePdo({ path: ':memory' }, { min: 2, max: 3 });\nconst run = async () =\u003e {\n    const statement = await pdo.query('SELECT 2');\n    const res = statement.fetchArray().all();\n    console.log(res);\n    await pdo.disconnect();\n};\n\nrun();\n```\n\n## Pdo\n\n- constructor(driver: [string](#available-drivers), driverOptions: [DriverOptions](#driver-options),PoolOptions: [PoolOptions](#pool-options), attributes: [PdoAttributes](#pdo-constants--attributes))\n- setLogger(logger: [PdoLogger](#logger)): void\n- getAvailableDrivers(): [string[]](#available-drivers)\n- addDriver(driverName: string, driver: [PdoDriverConstructor](DRIVER.md)): void\n- prototype.beginTransaction() :Promise\u003c[PdoTransactionI](#transaction)\u003e\n- prototype.exec(sql: string): Promise\u003cnumber\u003e\n- prototype.prepare(sql: string): Promise\u003c[PdoPreparedStatementI](#prepared-statement)\u003e\n- prototype.query(sql: string): Promise\u003c[PdoStatementI](#statement)\u003e\n- prototype.getAttribute([attribute](#pdo-attributes): string): string | number;\n- prototype.setAttribute([attribute](#pdo-attributes): string, value: number | string): boolean;\n- prototype.disconnect(): Promise\u003cvoid\u003e\n- prototype.reconnect(): void\n- prototype.getRawPoolConnection(): Promise\u003c[RawPoolConnection](#pdo-raw-pool-connection)\u003e\n- [prototype.getRawDriverConnection\u003cT\u003e(): Promise\u003cT\u003e](#pdo-raw-driver-connection)\n\n### Pdo Constants \u0026 Attributes\n\n- `ATTR_DEBUG` Determines if DEBUG mode is enabled. Can take one of the following values: [Default DEBUG_DISABLED]\n  - `DEBUG_DISABLED` Disable DEBUG mode\n  - `DEBUG_ENABLED` Enable DEBUG mode\n- `ATTR_CASE` Force column names to a specific case. Can take one of the following values: [Default CASE_NATURAL]\n  - `CASE_NATURAL` Leave column names as returned by the database driver.\n  - `CASE_LOWER` Force column names to upper case.\n  - `CASE_UPPER` Force column names to lower case.\n- `ATTR_NULLS` Determines if and how null and empty strings should be converted. Can take one of the following values: [Default NULL_NATURAL]\n  - `NULL_NATURAL` No conversion takes place.\n  - `NULL_EMPTY_STRING` Empty strings get converted to null.\n  - `NULL_TO_STRING` null gets converted to an empty string.\n- `ATTR_FETCH_DIRECTION` Determines which direction Fetch retrieve data. Can take one of the following values: [Default FETCH_FORWARD]\n  - `FETCH_FORWARD` Fetch the next row in the result set.\n  - `FETCH_BACKWARD` Fetch the previous row in the result set.\n- `ATTR_DRIVER_NAME` Returns the name of the driver.\n\n### Pdo Raw Pool Connection\n\nLupdo offers the possibility of retrieving a raw connection from the pool, to perform any unexposed operations.\\\nThe connection returned is the original [Driver Connection](#available-drivers) used behind the scenes by Lupdo.\n\n```ts\ninterface RawPoolConnection {\n    release: () =\u003e Promise\u003cvoid\u003e;\n    connection: PoolConnection;\n}\n```\n\n\u003e **Warning**\n\u003e Once the connection has been used, the connection must be released, otherwise the pool will not be able to disconnect.\n\n\u003e **Note**\n\u003e 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.\n\n### Pdo Raw Driver Connection\n\nLupdo offers the possibility of retrieving a raw connection from the driver, to perform any unexposed operations.\\\nThe connection returned is the original [Driver Connection](#available-drivers) used behind the scenes by Lupdo.\n\n\u003e **Note**\n\u003e Since the connection does not come from the pool, it is possible to terminate the job correctly even without invoking pdo.disconnect().\n\u003e All third-party driver configuration properties defined by the user are respected.\n\n\u003e **Warning**\n\u003e Once the connection has been used, you should manually close the connection.\n\n```ts\nconst { createSqlitePdo } = require('lupdo-sqlite');\n// ES6 or Typescrypt\nimport { createSqlitePdo } from 'ludpo-sqlite';\n\nconst pdo = createSqlitePdo({ path: ':memory' }, { min: 2, max: 3 });\nconst run = async () =\u003e {\n    const rawConnection = await pdo.getRawDriverConnection\u003cDatabase\u003e();\n    // do whatever you want\n    rawConnection.close();\n};\n\nrun();\n```\n\n## Driver Options\n\nEach driver uses the connection options of the corresponding npm package.\\\nDebug mode, is defined through Pdo Attributes, custom debug connection options, will be ignored.\n\n## Pool Options\n\n- `min` minimum pool size [Default = 2].\n- `max` maximum pool size [Default = 10].\n- `acquireTimeoutMillis` acquire promises are rejected after this many milliseconds if a resource cannot be acquired [Default 10000].\n- `createTimeoutMillis` create operations are cancelled after this many milliseconds if a resource cannot be acquired [Default 5000].\n- `destroyTimeoutMillis` destroy operations are awaited for at most this many milliseconds new resources will be created after this timeout [Default 5000].\n- `killTimeoutMillis` when pool destroy is executed, connection will be released and brutaly killed after this timeut [Default 10000].\n- `killResource` enable/disable killTimeout [Default false].\n- `idleTimeoutMillis` Free resources are destroyed after this many milliseconds. Note that if min \u003e 0, some resources may be kept alive for longer. To reliably destroy all idle resources, set min to 0 [Default 30000].\n- `createRetryIntervalMillis` how long to idle after failed create before trying again [Default 200].\n- `reapIntervalMillis` how often to check for idle resources to destroy [Default 500].\n- `created` Define Custom Created Callback.\n- `destroyed` Define Custom Destroyed Callback.\n- `acquired` Define Custom Acquired Callback.\n- `released` Define Custom Release Callback.\n- `killed` Define Custom Kill Callback.\n\n\u003e **Warning**\n\u003e 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\n\u003e When 'beginTransaction()' is called connection will be released to the pool only after 'commit()' or 'rollback()' is called.\n\u003e When 'prepare()' is called, connection will be released to the pool only after 'close()' is called.\n\u003e killResource might not be supported by all drivers\n\n\u003e **Warning**\n\u003e callback `created` should be used only to set session variables on the connection before it gets used.\n\n```js\n{\n    created: async (uuid, connection) =\u003e {\n        await connection.query('SET SESSION auto_increment_increment=1');\n    };\n}\n```\n\n## Transaction\n\n- prototype.commit(): Promise\u003cvoid\u003e;\n- prototype.rollback(): Promise\u003cvoid\u003e;\n- prototype.exec(sql: string): Promise\u003cnumber\u003e\n- prototype.prepare(sql: string): Promise\u003c[PdoTransactionPreparedStatementI](#prepared-statement)\u003e\n- prototype.query(sql: string): Promise\u003c[PdoStatement](#statement)\u003e\n- prototype.disconnect(): Promise\u003cvoid\u003e\n\n## Statement\n\n- prototype.getAttribute([attribute](#pdo-attributes): string): string | number;\n- prototype.setAttribute([attribute](#pdo-attributes): string, value: number | string): boolean;\n- prototype.columnCount(): number;\n- prototype.debug(): string;\n- prototype.debugSent(): string;\n- prototype.fetchDictionary(): [Fetched](#fetched-object)\u003cDictionary\u003e;\n- prototype.fetchArray(): [Fetched](#fetched-object)\u003cPdoColumnValue[]\u003e;\n- prototype.fetchBoth(): [Fetched](#fetched-object)\u003cBoth\u003e;\n- prototype.fetchColumn\u003cT extends PdoColumnValue\u003e(column: number): [Fetched](#fetched-object)\u003cT\u003e;\n- prototype.fetchObject\u003cT\u003e(abstract: Newable\u003cT\u003e, constructorArgs?: any[]): [Fetched](#fetched-object)\u003cT\u003e;\n- prototype.fetchClosure\u003cT\u003e(fn: (...args: PdoColumnValue[]) =\u003e T): [Fetched](#fetched-object)\u003cT\u003e;\n- prototype.fecthNamed(): [Fetched](#fetched-object)\u003cNamed\u003e;\n- prototype.fetchPair\u003cT extends PdoColumnValue, U extends PdoColumnValue\u003e(): Pair\u003cT, U\u003e;\n- prototype.resetCursor(): void;\n- prototype.getColumnMeta(column: number): ColumnData | null;\n- prototype.rowCount(): number;\n- prototype.lastInsertId(name?: string): Promise\u003cstring | bigint | number | null\u003e;\n- prototype.nextRowset(): boolean;\n\n\u003e **Note**\n\u003e statement.debug() will return SQL and Params Reflecting user input, statement.debugSent() will return SQL and Params Adapted by the Driver.\n\n### Fetched Object\n\n- get: () =\u003e T | undefined;\n- all: () =\u003e T[];\n- group: () =\u003e Group\u003cT\u003e;\n- unique: () =\u003e Unique\u003cT\u003e;\n\n\u003e **Note**\n\u003e Fetched Object is an Iterable Object. [Here](FETCH.md) you can find a more comprehensive guide.\n\n## Prepared Statement\n\nextends [Statement](#statement)\n\n- prototype.bindValue(key: string | number, value: [ValidBindings](#valid-bindings)): void;\n- prototype.execute(params?: [Params](#params)): Promise\u003cvoid\u003e;\n- prototype.close(): Promise\u003cvoid\u003e\n\n\u003e **Warning**\n\u003e 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.\n\u003e Prepared Statement inside a transaction doesn't expose `close()` method, connection will be release only on `commit()` or `rollback()`\n\n### Valid Bindings\n\n- [Primitives](#primitives-binding)\n- [BaseTypedBinding](#typed-binding)\n\n#### Primitives Binding\n\n- number\n- string\n- bigint\n- Buffer\n- Date\n- boolean\n- null\n\n#### Typed Binding\n\nIn 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.\n\n```ts\nconst {\n  NumericTypedBinding,\n  LengthTypedBinding,\n  PrecisionTypedBinding,\n  TypedBinding,\n  PARAM_INTEGER,\n  PARAM_DECIMAL,\n  PARAM_VARBINARY,\n  PARAM_DATETIME,\n} = require('lupdo');\nconst { createSqlitePdo } = require('lupdo-sqlite');\n// ES6 or Typescrypt\nimport { createSqlitePdo } from 'ludpo-sqlite';\nimport {\n  LengthTypedBinding,\n  NumericTypedBinding,\n  PARAM_DATETIME,\n  PARAM_DECIMAL,\n  PARAM_INTEGER,\n  PARAM_VARBINARY,\n  PrecisionTypedBinding,\n  TypedBinding,\n} from 'lupdo';\n\nconst pdo = createSqlitePdo({ path: ':memory' }, { min: 2, max: 3 });\nconst run = async () =\u003e {\n  const statement = await pdo.prepare(\n    'INSERT \"test\" (`int`,`real`, `nullable_blob`) VALUES (?,?,?)',\n  );\n  await statment.execute([\n    new TypedBinding(PARAM_INTEGER, '10'),\n    new NumericTypedBinding(PARAM_DECIMAL, '103232.231232112', {\n      total: 10,\n      places: 5,\n    }),\n    new PrecisionTypedBinding(PARAM_DATETIME, '2024-05 12:30:30.123456789', {\n      precision: 0,\n    }),\n    new LengthTypedBinding(PARAM_VARBINARY, null, { length: 'max' }),\n  ]);\n  console.log(res);\n  await pdo.disconnect();\n};\n\nrun();\n```\n\nthis is the list of bindings supported by Lupdo\n\n- PARAM_BIGINT\n- PARAM_INTEGER\n- PARAM_DOUBLE\n- PARAM_DECIMAL\n- PARAM_NUMERIC\n- PARAM_FLOAT\n- PARAM_BOOLEAN\n- PARAM_TEXT\n- PARAM_CHAR\n- PARAM_VARCHAR\n- PARAM_GEOMETRY\n- PARAM_DATE\n- PARAM_DATETIME\n- PARAM_DATETIMETZ\n- PARAM_TIMESTAMP\n- PARAM_TIMESTAMPTZ\n- PARAM_TIME\n- PARAM_TIMETZ\n- PARAM_BINARY\n- PARAM_VARBINARY\n\n\u003e **Note**\n\u003e Some drivers may ignore the type, or may only support a subset of types, or may support additional types.\n\u003e Each drivers may support custom options.\n\n### Params\n\nArray of [ValidBindings](#valid-bindings)\\\nor a key-value object\n\n## Logger\n\nLupdo by default doesn't log anything, you can assign a custom log for Lupdo to intercept messages.\n\n```js\nconst { Pdo } = require('lupdo');\n// ES6 or Typescrypt\nimport { Pdo } from 'lupdo';\nPdo.setLogger((level: any, message: any) =\u003e {\n    console.log(level, message);\n});\n```\n\n## Debug\n\nIf you are running into problems, one thing that may help is enabling the debug mode for the connection.\\\nYou can enable debug using [ATTR_DEBUG](#pdo-constants--attributes).\\\nThis will print extra information on stdout.\n\n## BigInt \u0026 JSON\n\n`BigInt` can not be serialized into a JSON string, Lupdo does not implement any serialization Logic.\\\n[Here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json) you can find some info about it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupennat%2Fludo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flupennat%2Fludo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupennat%2Fludo/lists"}