Skip to content

Commit 44e16d9

Browse files
committed
tree view optimizations
1 parent c4b72ef commit 44e16d9

File tree

6 files changed

+81
-58
lines changed

6 files changed

+81
-58
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
node_modules/
3-
out/
3+
out/
4+
*.vsix

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sqltools-intersystems-driver",
3-
"displayName": "InterSystems IRIS Driver",
3+
"displayName": "SQLTools InterSystems IRIS",
44
"description": "SQLTools Driver for InterSystems IRIS",
55
"version": "0.0.1",
66
"engines": {

src/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import { IDriverAlias } from '@sqltools/types';
44
* Aliases for yout driver. EG: PostgreSQL, PG, postgres can all resolve to your driver
55
*/
66
export const DRIVER_ALIASES: IDriverAlias[] = [
7-
{ displayName: 'InterSystems IRIS Driver', value: 'InterSystems IRIS Driver'},
7+
{ displayName: 'InterSystems IRIS', value: 'InterSystems IRIS'},
88
];

src/ls/driver.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import AbstractDriver from '@sqltools/base-driver';
22
import queries from './queries';
33
import { IConnectionDriver, MConnectionExplorer, NSDatabase, ContextValue, Arg0 } from '@sqltools/types';
44
import { v4 as generateId } from 'uuid';
5-
import IRISdb, { IRISDirect } from './irisdb';
5+
import IRISdb, { IRISDirect, IQueries } from './irisdb';
66
import keywordsCompletion from './keywords';
77
// import { workspace } from "vscode";
88

99
type DriverOptions = any;
10-
1110
export default class IRISDriver extends AbstractDriver<IRISdb, DriverOptions> implements IConnectionDriver {
1211

13-
queries = queries;
12+
queries: IQueries = queries;
1413

1514
public async open() {
1615
if (this.connection) {
@@ -67,7 +66,7 @@ export default class IRISDriver extends AbstractDriver<IRISdb, DriverOptions> im
6766
const resultsAgg: NSDatabase.IResult[] = [];
6867
queriesResults.forEach(queryResult => {
6968
resultsAgg.push({
70-
cols: Object.keys(queryResult[0]),
69+
cols: queryResult.length ? Object.keys(queryResult[0]) : [],
7170
connId: this.getId(),
7271
messages: [{ date: new Date(), message: `Query ok with ${queryResult.length} results` }],
7372
results: queryResult,
@@ -96,36 +95,42 @@ export default class IRISDriver extends AbstractDriver<IRISdb, DriverOptions> im
9695
switch (item.type) {
9796
case ContextValue.CONNECTION:
9897
case ContextValue.CONNECTED_CONNECTION:
99-
return <MConnectionExplorer.IChildItem[]>[
100-
{ label: 'Schemas', type: ContextValue.RESOURCE_GROUP, iconId: 'folder', childType: ContextValue.SCHEMA },
101-
];
102-
case ContextValue.TABLE:
103-
case ContextValue.VIEW:
104-
return this.getColumns(item as NSDatabase.ITable);
105-
case ContextValue.SCHEMA:
10698
return <MConnectionExplorer.IChildItem[]>[
10799
{ label: 'Tables', type: ContextValue.RESOURCE_GROUP, iconId: 'folder', childType: ContextValue.TABLE },
108100
{ label: 'Views', type: ContextValue.RESOURCE_GROUP, iconId: 'folder', childType: ContextValue.VIEW },
101+
{ label: 'Procedures', type: ContextValue.RESOURCE_GROUP, iconId: 'folder', childType: ContextValue.FUNCTION },
109102
];
110103
case ContextValue.RESOURCE_GROUP:
111-
return this.getChildrenForGroup({ item, parent });
104+
return this.getSchemas({ item, parent });
105+
case ContextValue.SCHEMA:
106+
return this.getChildrenForSchema({ item, parent });
107+
case ContextValue.TABLE:
108+
case ContextValue.VIEW:
109+
return this.getColumns(item as NSDatabase.ITable);
112110
}
113111
return [];
114112
}
115113

116-
/**
117-
* This method is a helper to generate the connection explorer tree.
118-
* It gets the child based on child types
119-
*/
120-
private async getChildrenForGroup({ parent, item }: Arg0<IConnectionDriver['getChildrenForItem']>) {
121-
console.log("getChildrenForGroup", parent, item);
114+
private async getSchemas({ item }: Arg0<IConnectionDriver['getChildrenForItem']>) {
115+
switch (item.childType) {
116+
case ContextValue.TABLE:
117+
return this.queryResults(this.queries.fetchTableSchemas());
118+
case ContextValue.VIEW:
119+
return this.queryResults(this.queries.fetchViewSchemas());
120+
case ContextValue.FUNCTION:
121+
return this.queryResults(this.queries.fetchFunctionSchemas());
122+
}
123+
return [];
124+
}
125+
126+
private async getChildrenForSchema({ item }: Arg0<IConnectionDriver['getChildrenForItem']>) {
122127
switch (item.childType) {
123-
case ContextValue.SCHEMA:
124-
return this.queryResults(this.queries.fetchSchemas(parent as NSDatabase.IDatabase));
125128
case ContextValue.TABLE:
126-
return this.queryResults(this.queries.fetchTables(parent as NSDatabase.ISchema));
129+
return this.queryResults(this.queries.fetchTables(item as NSDatabase.ISchema));
127130
case ContextValue.VIEW:
128-
return this.queryResults(this.queries.fetchViews(parent as NSDatabase.ISchema));
131+
return this.queryResults(this.queries.fetchViews(item as NSDatabase.ISchema));
132+
case ContextValue.FUNCTION:
133+
return this.queryResults(this.queries.fetchFunctions(item as NSDatabase.ISchema));
129134
}
130135
return [];
131136
}

src/ls/irisdb.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as httpModule from "http";
22
import * as httpsModule from "https";
33
import requestPromise from "request-promise";
4+
import { QueryBuilder, NSDatabase, IBaseQueries } from "@sqltools/types";
45

56
export class IRISDirect {
67
https?: boolean;
@@ -12,6 +13,14 @@ export class IRISDirect {
1213
password?: string;
1314
}
1415

16+
export interface IQueries extends IBaseQueries {
17+
fetchTableSchemas?: QueryBuilder<NSDatabase.IDatabase, NSDatabase.ISchema>;
18+
fetchViewSchemas?: QueryBuilder<NSDatabase.IDatabase, NSDatabase.ISchema>;
19+
fetchFunctionSchemas?: QueryBuilder<NSDatabase.IDatabase, NSDatabase.ISchema>;
20+
21+
fetchViews: QueryBuilder<NSDatabase.ISchema, NSDatabase.ITable>;
22+
}
23+
1524
export default class IRISdb {
1625

1726
private config: IRISDirect;

src/ls/queries.ts

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import { IBaseQueries, ContextValue } from '@sqltools/types';
1+
import { ContextValue, NSDatabase, QueryBuilder } from '@sqltools/types';
22
import queryFactory from '@sqltools/base-driver/dist/lib/factory';
3+
import { IQueries } from './irisdb';
34

45
/** write your queries here go fetch desired data. This queries are just examples copied from SQLite driver */
56

6-
const describeTable: IBaseQueries['describeTable'] = queryFactory`
7+
const describeTable: IQueries['describeTable'] = queryFactory`
78
SELECT C.*
89
FROM pragma_table_info('${p => p.label}') AS C
910
ORDER BY C.cid ASC
1011
`;
1112

12-
const fetchColumns: IBaseQueries['fetchColumns'] = queryFactory`
13+
const fetchColumns: IQueries['fetchColumns'] = queryFactory`
1314
SELECT
1415
C.COLUMN_NAME AS label,
1516
'${ContextValue.COLUMN}' as type,
@@ -34,41 +35,40 @@ ORDER BY
3435
C.ORDINAL_POSITION
3536
`;
3637

37-
const fetchRecords: IBaseQueries['fetchRecords'] = queryFactory`
38+
const fetchRecords: IQueries['fetchRecords'] = queryFactory`
3839
SELECT TOP ${p => p.limit || 50} *
3940
FROM ${p => p.table.schema}.${p => (p.table.label || p.table)}
4041
`;
4142

42-
const countRecords: IBaseQueries['countRecords'] = queryFactory`
43+
const countRecords: IQueries['countRecords'] = queryFactory`
4344
SELECT count(1) AS total
4445
FROM ${p => p.table.schema}.${p => (p.table.label || p.table)}
4546
`;
4647

47-
const fetchTablesAndViews = (type: ContextValue, tableType = 'BASE TABLE'): IBaseQueries['fetchTables'] => queryFactory`
48-
SELECT
49-
T.TABLE_NAME AS label,
50-
'${type}' as type,
51-
T.TABLE_SCHEMA AS "schema",
52-
'${type === ContextValue.VIEW ? 'TRUE' : 'FALSE'}' AS isView
53-
FROM INFORMATION_SCHEMA.${type === ContextValue.VIEW ? 'VIEWS' : 'TABLES'} AS T
54-
WHERE
55-
T.TABLE_SCHEMA = '${p => p.schema}'
56-
AND T.TABLE_TYPE = '${tableType}'
48+
const fetchAnyItems = <T>(type: ContextValue, isView: boolean, name: string, func: string): QueryBuilder<NSDatabase.ISchema, T> => queryFactory`
49+
SELECT
50+
${name} AS label,
51+
SCHEMA_NAME AS "schema",
52+
'${type}' as "type",
53+
'${isView ? 'TRUE' : 'FALSE'}' as isView
54+
FROM %SQL_MANAGER.${func}()
55+
WHERE SCHEMA_NAME = '${p => p.schema}'
5756
ORDER BY
58-
T.TABLE_NAME
57+
${name}
5958
`;
6059

61-
const fetchTables: IBaseQueries['fetchTables'] = fetchTablesAndViews(ContextValue.TABLE);
62-
const fetchViews: IBaseQueries['fetchTables'] = fetchTablesAndViews(ContextValue.VIEW , 'view');
60+
const fetchTables = fetchAnyItems<NSDatabase.ITable>(ContextValue.TABLE, false, 'TABLE_NAME', 'TablesTree');
61+
const fetchViews = fetchAnyItems<NSDatabase.ITable>(ContextValue.TABLE, true, 'VIEW_NAME', 'ViewsTree');
62+
const fetchFunctions = fetchAnyItems<NSDatabase.IProcedure>(ContextValue.FUNCTION, false, 'PROCEDURE_NAME', 'ProceduresTree');
6363

64-
const searchTables: IBaseQueries['searchTables'] = queryFactory`
64+
const searchTables: IQueries['searchTables'] = queryFactory`
6565
SELECT name AS label,
6666
type
6767
FROM sqlite_master
6868
${p => p.search ? `WHERE LOWER(name) LIKE '%${p.search.toLowerCase()}%'` : ''}
6969
ORDER BY name
7070
`;
71-
const searchColumns: IBaseQueries['searchColumns'] = queryFactory`
71+
const searchColumns: IQueries['searchColumns'] = queryFactory`
7272
SELECT C.name AS label,
7373
T.name AS "table",
7474
C.type AS dataType,
@@ -79,39 +79,47 @@ FROM sqlite_master AS T
7979
LEFT OUTER JOIN pragma_table_info((T.name)) AS C ON 1 = 1
8080
WHERE 1 = 1
8181
${p => p.tables.filter(t => !!t.label).length
82-
? `AND LOWER(T.name) IN (${p.tables.filter(t => !!t.label).map(t => `'${t.label}'`.toLowerCase()).join(', ')})`
83-
: ''
84-
}
82+
? `AND LOWER(T.name) IN (${p.tables.filter(t => !!t.label).map(t => `'${t.label}'`.toLowerCase()).join(', ')})`
83+
: ''
84+
}
8585
${p => p.search
86-
? `AND (
86+
? `AND (
8787
LOWER(T.name || '.' || C.name) LIKE '%${p.search.toLowerCase()}%'
8888
OR LOWER(C.name) LIKE '%${p.search.toLowerCase()}%'
8989
)`
90-
: ''
91-
}
90+
: ''
91+
}
9292
ORDER BY C.name ASC,
9393
C.cid ASC
9494
LIMIT ${p => p.limit || 100}
9595
`;
9696

97-
const fetchSchemas: IBaseQueries['fetchSchemas'] = queryFactory`
98-
SELECT
99-
schema_name AS label,
100-
schema_name AS "schema",
97+
const fetchTypedSchemas = (type: ContextValue, func: string): IQueries['fetchSchemas'] => queryFactory`
98+
SELECT
99+
DISTINCT BY (SCHEMA_NAME)
100+
%EXACT(SCHEMA_NAME) AS label,
101+
%EXACT(SCHEMA_NAME) AS "schema",
101102
'${ContextValue.SCHEMA}' as "type",
103+
'${type}' as "childType",
102104
'folder' as iconId
103-
FROM information_schema.schemata
104-
WHERE schema_name <> 'information_schema'
105+
FROM %SQL_MANAGER.${func}()
105106
`;
106107

108+
const fetchTableSchemas = fetchTypedSchemas(ContextValue.TABLE, 'TablesTree');
109+
const fetchViewSchemas = fetchTypedSchemas(ContextValue.VIEW, 'ViewsTree');
110+
const fetchFunctionSchemas = fetchTypedSchemas(ContextValue.FUNCTION, 'ProceduresTree');
111+
107112
export default {
108113
describeTable,
109114
countRecords,
110115
fetchColumns,
111116
fetchRecords,
112117
fetchTables,
118+
fetchFunctions,
113119
fetchViews,
114120
searchTables,
115121
searchColumns,
116-
fetchSchemas,
122+
fetchTableSchemas,
123+
fetchViewSchemas,
124+
fetchFunctionSchemas,
117125
}

0 commit comments

Comments
 (0)