Add oracledb package, readme, and config
This commit is contained in:
parent
b78388f771
commit
ab1fb07f86
|
@ -106,6 +106,7 @@
|
|||
"mysql2": "^2.3.1",
|
||||
"node-fetch": "2.6.0",
|
||||
"open": "7.3.0",
|
||||
"oracledb": "^5.3.0",
|
||||
"pg": "8.5.1",
|
||||
"pino-pretty": "4.0.0",
|
||||
"posthog-node": "^1.1.4",
|
||||
|
@ -133,6 +134,7 @@
|
|||
"@types/koa": "^2.13.3",
|
||||
"@types/koa-router": "^7.4.2",
|
||||
"@types/node": "^15.12.4",
|
||||
"@types/oracledb": "^5.2.1",
|
||||
"@typescript-eslint/parser": "4.28.0",
|
||||
"babel-jest": "^27.0.2",
|
||||
"copyfiles": "^2.4.1",
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
### Installation & Management
|
||||
|
||||
To install oracle express edition simply run `docker-compose up`
|
||||
|
||||
- A single instance pluggable database (PDB) will be created named `xepdb`
|
||||
- The default password is configured in the compose file as `oracle`
|
||||
- The `system`, `sys` and `pdbadmin` users all share this password
|
||||
|
||||
To connect to oracle sql command line:
|
||||
|
||||
```bash
|
||||
docker exec -it oracle-xe sqlplus -l system/oracle@localhost/xepdb1
|
||||
```
|
||||
|
||||
To create a new schema (user = schema in oracle)
|
||||
|
||||
```sql
|
||||
define USERNAME = rpowell
|
||||
|
||||
create user &USERNAME;
|
||||
|
||||
alter user &USERNAME
|
||||
default tablespace users
|
||||
temporary tablespace temp
|
||||
quota unlimited on users;
|
||||
|
||||
grant create session,
|
||||
create view,
|
||||
create sequence,
|
||||
create procedure,
|
||||
create table,
|
||||
create trigger,
|
||||
create type,
|
||||
create materialized view
|
||||
to &USERNAME;
|
||||
```
|
||||
|
||||
To set the password
|
||||
|
||||
```sql
|
||||
define USERNAME = rpowell
|
||||
define PASSWORD = rpowell
|
||||
|
||||
alter user &USERNAME identified by &PASSWORD;
|
||||
```
|
||||
|
||||
As before the database schema can now be connected to
|
||||
```bash
|
||||
docker exec -it oracle-xe sqlplus -l rpowell/rpowell@localhost:1521/xepdb1
|
||||
```
|
||||
|
||||
### Oracle Instant Client
|
||||
Before oracle can be connected to from nodejs, the oracle client must be installed.
|
||||
|
||||
<!-- TODO: instructions -->
|
||||
|
||||
### HR Schema
|
||||
|
||||
The `HR` schema is populated with dummy data by default in oracle for testing purposes.
|
||||
To connect to the HR schema first update the user password and unlock the account by performing
|
||||
```sql
|
||||
ALTER USER hr ACCOUNT UNLOCK;
|
||||
ALTER USER hr IDENTIFIED BY hr
|
||||
```
|
||||
You should now be able to connect to the hr schema using the credentials hr/hr
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
docker-compose down
|
||||
docker volume prune -f
|
|
@ -11,7 +11,7 @@ services:
|
|||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
#- pg_data:/var/lib/postgresql/data/
|
||||
- pg_data:/var/lib/postgresql/data/
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
|
||||
pgadmin:
|
||||
|
@ -24,5 +24,5 @@ services:
|
|||
ports:
|
||||
- "5050:80"
|
||||
|
||||
#volumes:
|
||||
# pg_data:
|
||||
volumes:
|
||||
pg_data:
|
||||
|
|
|
@ -45,6 +45,7 @@ export enum SourceNames {
|
|||
MYSQL = "MYSQL",
|
||||
ARANGODB = "ARANGODB",
|
||||
REST = "REST",
|
||||
ORACLE = "ORACLE",
|
||||
}
|
||||
|
||||
export enum IncludeRelationships {
|
||||
|
|
|
@ -290,4 +290,5 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
export default SqlQueryBuilder
|
||||
module.exports = SqlQueryBuilder
|
||||
|
|
|
@ -9,6 +9,7 @@ const airtable = require("./airtable")
|
|||
const mysql = require("./mysql")
|
||||
const arangodb = require("./arangodb")
|
||||
const rest = require("./rest")
|
||||
const oracle = require("./oracle")
|
||||
const { SourceNames } = require("../definitions/datasource")
|
||||
|
||||
const DEFINITIONS = {
|
||||
|
@ -23,6 +24,7 @@ const DEFINITIONS = {
|
|||
[SourceNames.MYSQL]: mysql.schema,
|
||||
[SourceNames.ARANGODB]: arangodb.schema,
|
||||
[SourceNames.REST]: rest.schema,
|
||||
[SourceNames.ORACLE]: oracle.schema,
|
||||
}
|
||||
|
||||
const INTEGRATIONS = {
|
||||
|
@ -37,6 +39,7 @@ const INTEGRATIONS = {
|
|||
[SourceNames.MYSQL]: mysql.integration,
|
||||
[SourceNames.ARANGODB]: arangodb.integration,
|
||||
[SourceNames.REST]: rest.integration,
|
||||
[SourceNames.ORACLE]: oracle.integration,
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -8,20 +8,29 @@ import {
|
|||
import { Table } from "../definitions/common"
|
||||
import { getSqlQuery } from "./utils"
|
||||
import { DatasourcePlus } from "./base/datasourcePlus"
|
||||
import oracledb, { Result } from "oracledb"
|
||||
import { Connection } from "oracledb"
|
||||
import Sql from "./base/sql"
|
||||
import { FieldTypes } from "../constants"
|
||||
import {
|
||||
buildExternalTableId,
|
||||
convertType,
|
||||
finaliseExternalTables
|
||||
} from "./utils"
|
||||
|
||||
module OracleModule {
|
||||
// TODO: oracle js lib
|
||||
// const connection = require("oracle")
|
||||
const Sql = require("./base/sql")
|
||||
const { FieldTypes } = require("../constants")
|
||||
const {
|
||||
buildExternalTableId,
|
||||
convertType,
|
||||
finaliseExternalTables,
|
||||
} = require("./utils")
|
||||
|
||||
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT;
|
||||
|
||||
interface OracleConfig {
|
||||
// TODO: Connection config
|
||||
host: string
|
||||
port: number
|
||||
database: string
|
||||
user: string
|
||||
password: string
|
||||
// ssl?: boolean
|
||||
// ca?: string
|
||||
// rejectUnauthorized?: boolean
|
||||
}
|
||||
|
||||
const SCHEMA: Integration = {
|
||||
|
@ -30,10 +39,57 @@ module OracleModule {
|
|||
friendlyName: "Oracle",
|
||||
description: "description",
|
||||
datasource: {
|
||||
// TODO: datasource config
|
||||
host: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
default: "localhost",
|
||||
required: true,
|
||||
},
|
||||
port: {
|
||||
type: DatasourceFieldTypes.NUMBER,
|
||||
required: true,
|
||||
default: 1521,
|
||||
},
|
||||
database: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
user: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
password: {
|
||||
type: DatasourceFieldTypes.PASSWORD,
|
||||
required: true,
|
||||
},
|
||||
// ssl: {
|
||||
// type: DatasourceFieldTypes.BOOLEAN,
|
||||
// default: false,
|
||||
// required: false,
|
||||
// },
|
||||
// rejectUnauthorized: {
|
||||
// type: DatasourceFieldTypes.BOOLEAN,
|
||||
// default: false,
|
||||
// required: false,
|
||||
// },
|
||||
// ca: {
|
||||
// type: DatasourceFieldTypes.LONGFORM,
|
||||
// default: false,
|
||||
// required: false,
|
||||
// },
|
||||
},
|
||||
query: {
|
||||
// TODO: query config
|
||||
create: {
|
||||
type: QueryTypes.SQL,
|
||||
},
|
||||
read: {
|
||||
type: QueryTypes.SQL,
|
||||
},
|
||||
update: {
|
||||
type: QueryTypes.SQL,
|
||||
},
|
||||
delete: {
|
||||
type: QueryTypes.SQL,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -41,11 +97,27 @@ module OracleModule {
|
|||
// TODO: type map
|
||||
}
|
||||
|
||||
async function internalQuery(client: any, query: SqlQuery) {
|
||||
// TODO: Use oracle lib to run query
|
||||
const rows = []
|
||||
|
||||
return rows
|
||||
const internalQuery = async (connection: Connection, query: SqlQuery): Promise<Result<any> | null>=> {
|
||||
try {
|
||||
const result: Result<any> = await connection.execute(
|
||||
`SELECT manager_id, department_id, department_name
|
||||
FROM departments
|
||||
WHERE manager_id = :id`,
|
||||
[103], // bind value for :id
|
||||
);
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OracleIntegration extends Sql implements DatasourcePlus {
|
||||
|
@ -56,8 +128,18 @@ module OracleModule {
|
|||
|
||||
constructor(config: OracleConfig) {
|
||||
super("oracle")
|
||||
this.config = config
|
||||
//todo init client
|
||||
this.config = config
|
||||
}
|
||||
|
||||
getConnection = async (): Promise<Connection> => {
|
||||
//connectString : "(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))(CONNECT_DATA =(SID= ORCL)))"
|
||||
const connectString = `${this.config.host}:${this.config.port || 1521}/${this.config.database}`
|
||||
const config = {
|
||||
user: this.config.user,
|
||||
password: this.config.user,
|
||||
connectString
|
||||
}
|
||||
return oracledb.getConnection(config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,8 +194,13 @@ module OracleModule {
|
|||
async query(json: QueryJson) {
|
||||
const operation = this._operation(json).toLowerCase()
|
||||
const input = this._query(json)
|
||||
const response = await internalQuery(this.client, input)
|
||||
return response.rows.length ? response.rows : [{ [operation]: true }]
|
||||
const connection = await this.getConnection()
|
||||
const result = await internalQuery(connection, input)
|
||||
if (result && result.rows && result.rows.length) {
|
||||
return result.rows
|
||||
} else {
|
||||
return [{ [operation]: true }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2262,6 +2262,14 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3"
|
||||
integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==
|
||||
|
||||
"@types/oracledb@^5.2.1":
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/oracledb/-/oracledb-5.2.1.tgz#b0c64d1ab68f1be6dc153a310ce0e840b8f333df"
|
||||
integrity sha512-xtN24H9bpGB11ZiswZulAKYJ9xcWrF5BOAGFemcfeZkLmw8qAzVm+TAWT20VVLst6kh9VNxinY239S8EKgRBbA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
dotenv "^8.2.0"
|
||||
|
||||
"@types/prettier@^2.1.5":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3"
|
||||
|
@ -4134,6 +4142,11 @@ dotenv@8.2.0:
|
|||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
|
||||
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
|
||||
|
||||
dotenv@^8.2.0:
|
||||
version "8.6.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
|
||||
integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
|
||||
|
||||
double-ended-queue@2.1.0-0:
|
||||
version "2.1.0-0"
|
||||
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
|
||||
|
@ -8261,6 +8274,11 @@ optionator@^0.8.1, optionator@^0.8.3:
|
|||
type-check "~0.3.2"
|
||||
word-wrap "~1.2.3"
|
||||
|
||||
oracledb@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/oracledb/-/oracledb-5.3.0.tgz#a15e6cd16757d8711a2c006a28bd7ecd3b8466f7"
|
||||
integrity sha512-HMJzQ6lCf287ztvvehTEmjCWA21FQ3RMvM+mgoqd4i8pkREuqFWO+y3ovsGR9moJUg4T0xjcwS8rl4mggWPxmg==
|
||||
|
||||
os-locale@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
|
||||
|
|
Loading…
Reference in New Issue