-
-
Notifications
You must be signed in to change notification settings - Fork 287
/
index.ts
153 lines (137 loc) · 4.72 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import {
ConnectionDialect,
DatabaseInterface,
} from '../../interface';
import * as Utils from '../../utils';
import queries from './queries';
import OracleDBLib from 'oracledb';
import GenericDialect from '../generic';
const OracleDBLibVersion = '3.1.1';
export default class OracleDB extends GenericDialect<OracleDBLib.IConnection> implements ConnectionDialect {
public static deps: typeof GenericDialect['deps'] = [{
type: 'package',
name: 'oracledb',
version: OracleDBLibVersion,
}];
public static poolMap = new Map<string, boolean>();
public get connection() {
if (!this.poolCreated) return;
return this.lib.getConnection(this.poolName) as Promise<OracleDBLib.IConnection>;
}
queries = queries
private get lib(): typeof OracleDBLib {
const oracledb = __non_webpack_require__('oracledb');
oracledb.fetchAsString = [oracledb.DATE, oracledb.CLOB];
return oracledb;
}
private get poolName(): string {
return Utils.getConnectionId(this.credentials);
}
private get poolCreated(): boolean {
return !!OracleDB.poolMap.get(this.poolName);
}
private registerPool() {
OracleDB.poolMap.set(this.poolName, true);
}
private unregisterPool() {
OracleDB.poolMap.delete(this.poolName);
}
public async open() {
if (this.poolCreated) {
return this.connection;
}
this.needToInstallDependencies();
const connectString = (this.credentials.server && this.credentials.port) ?
`${this.credentials.server}:${this.credentials.port}/${this.credentials.database}` :
this.credentials.database;
await this.lib.createPool({
connectString,
password: this.credentials.password,
user: this.credentials.username,
poolAlias: this.poolName
});
this.registerPool();
return this.connection;
}
public async close() {
if (!this.poolCreated) return Promise.resolve();
await this.lib.getPool(this.poolName).close(10 as any);
this.unregisterPool();
}
public async query(query: string): Promise<DatabaseInterface.QueryResults[]> {
const conn = await this.open();
const queries = query.split(/\s*;\s*(?=([^']*'[^']*')*[^']*$)/g).filter(Boolean);
const results: DatabaseInterface.QueryResults[] = [];
try {
for(let q of queries) {
let res = await conn.execute(q, [], { outFormat: this.lib.OBJECT });
const messages = [];
if (res.rowsAffected) {
messages.push(`${res.rowsAffected} rows were affected.`);
}
results.push({
connId: this.getId(),
cols: (res.rows && res.rows.length) > 0 ? Object.keys(res.rows[0]) : [],
messages,
query: queries[results.length],
results: res.rows,
});
}
} finally {
if (conn) {
try {
await conn.close();
} catch (e) {
console.log(e);
}
}
}
return results;
}
public async testConnection(): Promise<void> {
return this.query('select 1 from dual').then(() => void 0);
}
public getTables(): Promise<DatabaseInterface.Table[]> {
return this.query(this.queries.fetchTables)
.then(([queryRes]) => {
return queryRes.results
.reduce((prev, curr) => prev.concat(curr), [])
.map((obj) => {
return {
name: `${obj.TABLESCHEMA}.${obj.TABLENAME}`,
isView: !!obj.ISVIEW,
numberOfColumns: parseInt(obj.NUMBEROFCOLUMNS, 10),
tableCatalog: obj.TABLECATALOG,
tableDatabase: obj.DBNAME,
tableSchema: obj.TABLESCHEMA,
} as DatabaseInterface.Table;
});
});
}
public getColumns(): Promise<DatabaseInterface.TableColumn[]> {
return this.query(this.queries.fetchColumns)
.then(([queryRes]) => {
return queryRes.results
.reduce((prev, curr) => prev.concat(curr), [])
.map((obj) => {
return {
columnName: obj.COLUMNNAME,
defaultValue: obj.DEFAULTVALUE,
isNullable: !!obj.ISNULLABLE ? obj.ISNULLABLE.toString() === 'yes' : null,
size: obj.size !== null ? parseInt(obj.SIZE, 10) : null,
tableCatalog: obj.TABLECATALOG,
tableDatabase: obj.DBNAME,
tableName: `${obj.TABLESCHEMA}.${obj.TABLENAME}`,
tableSchema: obj.TABLESCHEMA,
type: obj.TYPE,
isPk: obj.CONSTRAINTTYPE === 'P',
isFk: obj.CONSTRAINTTYPE === 'R'
} as DatabaseInterface.TableColumn;
});
});
}
public describeTable(table: string) {
const tableSplit = table.split('.');
return this.query(Utils.replacer(this.queries.describeTable, { schema: tableSplit[0], table: tableSplit[1] }));
}
}