Skip to content

Commit

Permalink
Support for oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
lroal committed Jan 23, 2024
1 parent d7314f1 commit eaecc71
Show file tree
Hide file tree
Showing 114 changed files with 1,689 additions and 325 deletions.
7 changes: 7 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,12 @@ services:
ports:
- 50000:5000
# restart: always
oracle:
image: gvenzl/oracle-xe
environment:
- ORACLE_PASSWORD=P@assword123
hostname: oracle
ports:
- 1521:1521
volumes:
try-node-node_modules:
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ jobs:
image: larsroald/ase-server
ports:
- 5000:5000
oracle:
image: gvenzl/oracle-xe
env:
ORACLE_PASSWORD: P@assword123
ports:
- 1521:1521
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
![RDB](./docs/logo-sm.jpg)
RDB is the ultimate Object Relational Mapper for Node.js and Typescript, offering seamless integration with popular databases like Postgres, MS SQL, MySQL, Sybase SAP, and SQLite. Whether you're building applications in TypeScript or JavaScript (including both CommonJS and ECMAScript), RDB has got you covered.
RDB is the ultimate Object Relational Mapper for Node.js and Typescript, offering seamless integration with a variety of popular databases. Whether you're building applications in TypeScript or JavaScript (including both CommonJS and ECMAScript), RDB has got you covered.

[![npm version](https://img.shields.io/npm/v/rdb.svg?style=flat-square)](https://www.npmjs.org/package/rdb)
[![Build status](https://github.com/alfateam/rdb/workflows/Node.js%20CI/badge.svg)](https://github.com/alfateam/rdb/actions)
Expand All @@ -19,6 +19,16 @@ RDB is the ultimate Object Relational Mapper for Node.js and Typescript, offerin
- **TypeScript and JavaScript Support**: RDB fully supports both TypeScript and JavaScript, allowing you to leverage the benefits of static typing and modern ECMAScript features.
- **Works in the Browser**: You can securely use RDB in the browser by utilizing the Express.js plugin, which serves to safeguard sensitive database credentials from exposure at the client level. This method mirrors a traditional REST API, augmented with advanced TypeScript tooling for enhanced functionality.

## Supported Databases

- [x] Postgres
- [x] MS SQL
- [x] MySQL
- [x] Oracle
- [x] Sybase SAP
- [x] SQLite


This is the _Modern Typescript Documentation_. Are you looking for the [_Classic Documentation_](https://github.com/alfateam/rdb/blob/master/docs/docs.md) ?

## Sponsorship <span style="font-size: larger; color: darkred;">♡</span>
Expand Down Expand Up @@ -319,6 +329,19 @@ $ npm install pg
import map from './map';
const db = map.pg('postgres://postgres:postgres@postgres/postgres');
```
__Oracle__
```bash
$ npm install oracledb
```
```javascript
import map from './map';
const db = map.oracle({
user: 'sys',
password: 'P@assword123',
connectString: 'oracle/XE',
privilege: 2
});
```
__SAP Adaptive Server__
```bash
$ npm install msnodesqlv8
Expand Down
2 changes: 2 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

## Changelog
__3.5.0__
Support for Oracle.
__3.4.0__
Allow multiple resultset for SAP and mssql. See [#72](https://github.com/alfateam/rdb/issues/72).
__3.3.0__
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rdb",
"version": "3.4.0",
"version": "3.5.0",
"main": "./src/index.js",
"browser": "./src/client/index.mjs",
"bin": {
Expand Down Expand Up @@ -47,6 +47,7 @@
"@lroal/on-change": "^4.0.2",
"@tediousjs/connection-string": "^0.4.1",
"@types/express": "^4.17.13",
"@types/oracledb": "^6.0.4",
"@types/tedious": "^4.0.9",
"ajv": "^6.10.2",
"axios": "^1.6.2",
Expand All @@ -63,6 +64,7 @@
"peerDependencies": {
"msnodesqlv8": "^4.1.0",
"mysql2": "^2.2.5",
"oracledb": "^6.3.0",
"pg": "^8.5.1",
"pg-native": "^3.0.0",
"pg-query-stream": "^3.3.2",
Expand Down Expand Up @@ -104,6 +106,7 @@
"express": "^4.18.2",
"msnodesqlv8": "^4.1.0",
"mysql2": "^2.2.5",
"oracledb": "^6.3.0",
"owasp-dependency-check": "^0.0.21",
"pg": "^8.5.1",
"pg-query-stream": "^3.3.2",
Expand Down
2 changes: 2 additions & 0 deletions src/client/clientMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function map(index, _fn) {
dbMap.mssqlNative = throwDb;
dbMap.mysql = throwDb;
dbMap.sap = throwDb;
dbMap.oracle = throwDb;
dbMap.sqlite = throwDb;

function throwDb() {
Expand All @@ -62,6 +63,7 @@ function map(index, _fn) {
onFinal.mssqlNative = () => index({ db: throwDb, providers: dbMap });
onFinal.mysql = () => index({ db: throwDb, providers: dbMap });
onFinal.sap = () => index({ db: throwDb, providers: dbMap });
onFinal.oracle = () => index({ db: throwDb, providers: dbMap });
onFinal.sqlite = () => index({ db: throwDb, providers: dbMap });

return new Proxy(onFinal, handler);
Expand Down
8 changes: 8 additions & 0 deletions src/client/createProviders.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ function createProviders(index) {
return createPool.bind(null, 'sap');
}
});
Object.defineProperty(dbMap, 'oracle', {
get: function() {
return createPool.bind(null, 'oracle');
}
});
Object.defineProperty(dbMap, 'sqlite', {
get: function() {
return createPool.bind(null, 'sqlite');
Expand Down Expand Up @@ -86,6 +91,9 @@ function negotiateCachedPool(fn, providers) {
get sap() {
return createPool.bind(null, 'sap');
},
get oracle() {
return createPool.bind(null, 'oracle');
},
get sqlite() {
return createPool.bind(null, 'sqlite');
},
Expand Down
1 change: 1 addition & 0 deletions src/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ function rdbClient(options = {}) {
client.postgres = onProvider.bind(null, 'postgres');
client.sqlite = onProvider.bind(null, 'sqlite');
client.sap = onProvider.bind(null, 'sap');
client.oracle = onProvider.bind(null, 'oracle');
client.http = onProvider.bind(null, 'http');//todo
client.mysql = onProvider.bind(null, 'mysql');
client.express = express;
Expand Down
3 changes: 3 additions & 0 deletions src/client/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5022,6 +5022,7 @@ function map$1(index, _fn) {
dbMap.mssqlNative = throwDb;
dbMap.mysql = throwDb;
dbMap.sap = throwDb;
dbMap.oracle = throwDb;
dbMap.sqlite = throwDb;

function throwDb() {
Expand All @@ -5047,6 +5048,7 @@ function map$1(index, _fn) {
onFinal.mssqlNative = () => index({ db: throwDb, providers: dbMap });
onFinal.mysql = () => index({ db: throwDb, providers: dbMap });
onFinal.sap = () => index({ db: throwDb, providers: dbMap });
onFinal.oracle = () => index({ db: throwDb, providers: dbMap });
onFinal.sqlite = () => index({ db: throwDb, providers: dbMap });

return new Proxy(onFinal, handler);
Expand Down Expand Up @@ -5352,6 +5354,7 @@ function rdbClient(options = {}) {
client.postgres = onProvider.bind(null, 'postgres');
client.sqlite = onProvider.bind(null, 'sqlite');
client.sap = onProvider.bind(null, 'sap');
client.oracle = onProvider.bind(null, 'oracle');
client.http = onProvider.bind(null, 'http');//todo
client.mysql = onProvider.bind(null, 'mysql');
client.express = express;
Expand Down
1 change: 1 addition & 0 deletions src/client/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function map(index, context, providers, fn) {
context.mssqlNative = connect.bind(null, 'mssqlNative');
context.mysql = connect.bind(null, 'mysql');
context.sap = connect.bind(null, 'sap');
context.oracle = connect.bind(null, 'oracle');
context.sqlite = connect.bind(null, 'sqlite');
context.http = function(url) {
return index({ db: url, providers});
Expand Down
2 changes: 1 addition & 1 deletion src/getTSDefinition.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ ${row}`;
let name = pascalCase(relationName);
let count = 2;
while (tableNames.has(name)) {
name = name + '_' + count;
name = name + 'x' + count;
count++;
}
rootTablesAdded.set(relation.childTable, name);
Expand Down
2 changes: 2 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Options } from 'ajv';
import { RequestHandler } from 'express';
import { ConnectionConfig } from 'tedious';
import { PoolAttributes } from 'oracledb';
import { AllowedDbMap, DbMapper, MappedDbDef } from './map';

declare function r(config: r.Config): unknown;
Expand All @@ -16,6 +17,7 @@ declare namespace r {
function mssql(connectionString: string, options?: PoolOptions): Pool;
function mssqlNative(connectionString: string, options?: PoolOptions): Pool;
function mysql(connectionString: string, options?: PoolOptions): Pool;
function oracle(config: PoolAttributes, options?: PoolOptions): Pool;
function on(type: 'query', cb: (e: QueryEvent) => void): void;
function off(type: 'query', cb: (e: QueryEvent) => void): void;
function map<V extends AllowedDbMap<V>>(
Expand Down
9 changes: 9 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var _sqlite;
var _mssqlNative;
var _sap;
var _mssql;
var _oracle;
var flags = require('./flags');
var map = require('./client/map');

Expand Down Expand Up @@ -99,6 +100,14 @@ Object.defineProperty(connectViaPool, 'sap', {
}
});

Object.defineProperty(connectViaPool, 'oracle', {
get: function() {
if (!_oracle)
_oracle = require('./oracle/newDatabase');
return _oracle;
}
});

connectViaPool.express = hostExpress;
connectViaPool.useHook = function(bool) {
flags.useHook = bool;
Expand Down
4 changes: 3 additions & 1 deletion src/map.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Options } from 'ajv';
import type { ConnectionConfig } from 'tedious';
import type { PoolAttributes } from 'oracledb';
import type { AxiosInterceptorManager, InternalAxiosRequestConfig, AxiosResponse } from 'axios';

export type MappedDbDef<T> = {
Expand Down Expand Up @@ -35,6 +36,7 @@ type DbConnectable<T> = {
mssql(connectionString: string, options?: PoolOptions): MappedDbInstance<T>;
mssqlNative(connectionString: string, options?: PoolOptions): MappedDbInstance<T>;
mysql(connectionString: string, options?: PoolOptions): MappedDbInstance<T>;
oracle(config: PoolAttributes, options?: PoolOptions): MappedDbInstance<T>;
};

type NegotiateDbInstance<T, C> = C extends WithDb
Expand Down Expand Up @@ -62,7 +64,7 @@ interface Connectors {
sap(connectionString: string, options?: PoolOptions): Pool;
mssql(connectionConfig: ConnectionConfig, options?: PoolOptions): Pool;
mssql(connectionString: string, options?: PoolOptions): Pool;
mysql(connectionString: string, options?: PoolOptions): Pool;
oracle(config: PoolAttributes, options?: PoolOptions): Pool;
}

export interface Pool {
Expand Down
6 changes: 4 additions & 2 deletions src/mssql/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ var deleteFromSql = require('../tedious/deleteFromSql');
var selectForUpdateSql = require('../tedious/selectForUpdateSql');
var outputInsertedSql = require('../tedious/outputInsertedSql');
const limitAndOffset = require('../tedious/limitAndOffset');
const formatDateColumn = require('../tedious/formatDateColumn');
const formatDateOut = require('../tedious/formatDateOut');
const insertSql = require('../tedious/insertSql');
const insert = require('../tedious/insert');

function newResolveTransaction(domain, pool) {
var rdb = {poolFactory: pool};
Expand All @@ -31,11 +32,12 @@ function newResolveTransaction(domain, pool) {
rdb.encodeBoolean = encodeBoolean;
rdb.decodeJSON = decodeJSON;
rdb.encodeJSON = JSON.stringify;
rdb.formatDateColumn = formatDateColumn;
rdb.formatDateOut = formatDateOut;
rdb.deleteFromSql = deleteFromSql;
rdb.selectForUpdateSql = selectForUpdateSql;
rdb.outputInsertedSql = outputInsertedSql;
rdb.insertSql = insertSql;
rdb.insert = insert;
rdb.lastInsertedIsSeparate = false;
rdb.multipleStatements = true;
rdb.begin = 'BEGIN TRANSACTION';
Expand Down
21 changes: 21 additions & 0 deletions src/mySql/insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
let newInsertCommand = require('../table/commands/newInsertCommand');
let newInsertCommandCore = require('../table/commands/newInsertCommandCore');
let newGetLastInsertedCommand = require('../table/commands/newGetLastInsertedCommand');
let executeQueries = require('../table/executeQueries');
let pushCommand = require('../table/commands/pushCommand');


function insertDefault(table, row, options) {
let commands = [];
let insertCmd = newInsertCommand(newInsertCommandCore, table, row, options);
insertCmd.disallowCompress = true;
pushCommand(insertCmd);

let selectCmd = newGetLastInsertedCommand(table, row, insertCmd);
commands.push(selectCmd);

return executeQueries(commands).then((result) => result[result.length - 1]);

}

module.exports = insertDefault;
2 changes: 2 additions & 0 deletions src/mySql/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const selectForUpdateSql = require('./selectForUpdateSql');
const lastInsertedSql = require('./lastInsertedSql');
const limitAndOffset = require('./limitAndOffset');
const insertSql = require('./insertSql');
const insert = require('./insert');

function newResolveTransaction(domain, pool) {
var rdb = {poolFactory: pool};
Expand Down Expand Up @@ -34,6 +35,7 @@ function newResolveTransaction(domain, pool) {
rdb.lastInsertedIsSeparate = true;
rdb.lastInsertedSql = lastInsertedSql;
rdb.insertSql = insertSql;
rdb.insert = insert;
rdb.multipleStatements = false;
rdb.limitAndOffset = limitAndOffset;
rdb.accept = function(caller) {
Expand Down
8 changes: 8 additions & 0 deletions src/oracle/deleteFromSql.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var format = 'delete from %s where %s.rowId in (SELECT %s.rowId FROM %s %s%s)';
var util = require('util');

function deleteFromSql(table, alias, whereSql) {
var name = table._dbName;
return util.format(format, name, name, alias, name, alias, whereSql);
}
module.exports = deleteFromSql;
7 changes: 7 additions & 0 deletions src/oracle/encodeBoolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function encodeBoolean(bool) {
if (bool)
return 1;
return 0;
}

module.exports = encodeBoolean;
7 changes: 7 additions & 0 deletions src/oracle/encodeBuffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//unused because using sql parameters instead
//Remove ?
function encodeBuffer(buffer) {
return 'E\'\\\\x' + buffer.toString('hex') + '\'';
}

module.exports = encodeBuffer;
7 changes: 7 additions & 0 deletions src/oracle/encodeDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function encodeDate(date) {
if (date.toISOString)
return '\'' + date.toISOString() + '\'';
return '\'' + date + '\'';
}

module.exports = encodeDate;
5 changes: 5 additions & 0 deletions src/oracle/formatDateIn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function formatDateColumn(value) {
return `TO_TIMESTAMP(${value}, 'YYYY-MM-DD"T"HH24:MI:SS.FF3')`;
}

module.exports = formatDateColumn;
2 changes: 1 addition & 1 deletion src/pg/formatDateColumn.js → src/oracle/formatDateOut.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function formatDateColumn(column, alias) {
return `${alias}.${column._dbName}::text`;
return `TO_CHAR(${alias}.${column._dbName}, 'YYYY-MM-DD"T"HH24:MI:SS.FF3')`;
}

module.exports = formatDateColumn;
23 changes: 23 additions & 0 deletions src/oracle/insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const newInsertCommand = require('../table/commands/newInsertCommand');
const newInsertCommandCore = require('./newInsertCommandCore');
const setSessionSingleton = require('../table/setSessionSingleton');
const newGetLastInsertedCommand = require('../table/commands/newGetLastInsertedCommand');
const executeQueries = require('../table/executeQueries');

function insert(table, row, options) {

return new Promise((res, rej) => {
const cmd = newInsertCommand(newInsertCommandCore, table, row, options);
cmd.disallowCompress = true;
executeQueries([cmd]).then((result) => result[0]).then(onResult).then(res, rej);

function onResult([result]) {
setSessionSingleton('lastRowid', result.lastRowid);
const selectCmd = newGetLastInsertedCommand(table, row, cmd);
return executeQueries([selectCmd]).then((result) => res(result[0]));
}

});
}

module.exports = insert;
Loading

0 comments on commit eaecc71

Please sign in to comment.