Skip to content

Commit 66c15ff

Browse files
authored
Merge pull request #252 from codefori/cleanup/filter_params
Cleanup/filter_params
2 parents a99abb0 + 4faa35d commit 66c15ff

File tree

3 files changed

+70
-23
lines changed

3 files changed

+70
-23
lines changed

src/database/schemas.ts

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,33 @@ export const AllSQLTypes: SQLType[] = ["tables", "views", "aliases", "constraint
1616

1717
export const SQL_ESCAPE_CHAR = `\\`;
1818

19-
function getFilterClause(againstColumn: string, filter: string|undefined, noAnd?: boolean): string {
19+
type BasicColumnType = string|number;
20+
interface PartStatementInfo {clause: string, parameters: BasicColumnType[]};
21+
22+
function getFilterClause(againstColumn: string, filter: string, noAnd?: boolean): PartStatementInfo {
2023
if (!filter) {
21-
return ``;
24+
return {clause: ``, parameters: []};
2225
}
2326

24-
let clause = `${noAnd ? '' : 'AND '} UPPER(${againstColumn})`;
27+
let clause = `${noAnd ? '' : 'AND'} UPPER(${againstColumn})`;
28+
let parameters: BasicColumnType[] = [];
2529

2630
if (filter.endsWith(`*`)) {
27-
clause += ` LIKE '${filter.slice(0, -1).toUpperCase()}%'`;
31+
clause += ` LIKE ? CONCAT '%'`;
32+
parameters.push(filter.slice(0, -1).toUpperCase());
2833
} else {
29-
clause += ` LIKE '%${filter.toUpperCase()}%'`;
34+
clause += ` LIKE '%' CONCAT ? CONCAT '%'`;
35+
parameters.push(filter.toUpperCase());
3036
}
3137

32-
clause += ` ESCAPE '${SQL_ESCAPE_CHAR}'`;
38+
if (filter.indexOf('\\') >= 0) {
39+
clause += ` ESCAPE '\\'`;
40+
}
3341

34-
return clause;
42+
return {
43+
clause,
44+
parameters
45+
};
3546
}
3647

3748
export default class Schemas {
@@ -40,6 +51,8 @@ export default class Schemas {
4051
*/
4152
static async getObjects(schema: string, types: SQLType[], details: PageData = {}): Promise<BasicSQLObject[]> {
4253
const selects: string[] = [];
54+
let parameters: (string|number)[] = [];
55+
let filter: PartStatementInfo;
4356

4457
// If there are multiple types, we build a union. It's important that the ordering of the columns in the selects are consistant:
4558
// OBJ_TYPE, NAME, TEXT, SYS_NAME, SYS_SCHEMA, SPECNAME, BASE_SCHEMA, BASE_OBJ
@@ -50,101 +63,135 @@ export default class Schemas {
5063
selects.push([
5164
`select '${type}' as OBJ_TYPE, SCHEMA_NAME as NAME, SCHEMA_TEXT as TEXT, SYSTEM_SCHEMA_NAME as SYS_NAME, '' as SYS_SCHEMA, '' as SPECNAME, '' as BASE_SCHEMA, '' as BASE_OBJ`,
5265
`from QSYS2.SYSSCHEMAS`,
53-
details.filter ? `where UPPER(SCHEMA_NAME) = '${details.filter}' or UPPER(SYSTEM_SCHEMA_NAME) = '${details.filter}'` : ``,
66+
details.filter ? `where UPPER(SCHEMA_NAME) = ? or UPPER(SYSTEM_SCHEMA_NAME) = ?` : ``,
5467
].join(` `));
68+
69+
parameters.push(details.filter, details.filter);
5570
break;
5671

5772
case `tables`:
5873
case `views`:
5974
case `aliases`:
75+
filter = getFilterClause(`TABLE_NAME`, details.filter);
6076
selects.push([
6177
`select '${type}' as OBJ_TYPE, TABLE_NAME as NAME, TABLE_TEXT as TEXT, SYSTEM_TABLE_NAME as SYS_NAME, SYSTEM_TABLE_SCHEMA as SYS_SCHEMA, '' as SPECNAME, BASE_TABLE_SCHEMA as BASE_SCHEMA, BASE_TABLE_NAME as BASE_OBJ`,
6278
`from QSYS2.SYSTABLES`,
63-
`where TABLE_SCHEMA = '${schema}' and TABLE_TYPE in (${typeMap[type].map(item => `'${item}'`).join(`, `)}) ${getFilterClause(`TABLE_NAME`, details.filter)}`,
79+
`where TABLE_SCHEMA = ? and TABLE_TYPE in (${typeMap[type].map(item => `'${item}'`).join(`, `)}) ${filter.clause}`,
6480
].join(` `));
81+
82+
parameters.push(schema, ...filter.parameters);
6583
break;
6684

6785
case `constraints`:
86+
filter = getFilterClause(`CONSTRAINT_NAME`, details.filter);
6887
selects.push([
6988
`select '${type}' as OBJ_TYPE, CONSTRAINT_NAME as NAME, CONSTRAINT_TEXT as TEXT, SYSTEM_TABLE_NAME as SYS_NAME, SYSTEM_TABLE_SCHEMA as SYS_SCHEMA, '' as SPECNAME, TABLE_SCHEMA as BASE_SCHEMA, TABLE_NAME as BASE_OBJ`,
7089
`from QSYS2.SYSCST`,
71-
`where CONSTRAINT_SCHEMA = '${schema}' ${getFilterClause(`CONSTRAINT_NAME`, details.filter)}`,
90+
`where CONSTRAINT_SCHEMA = ? ${filter.clause}`,
7291
].join(` `));
92+
93+
parameters.push(schema, ...filter.parameters);
7394
break;
7495

7596
case `functions`:
97+
filter = getFilterClause(`ROUTINE_NAME`, details.filter);
7698
selects.push([
7799
`select '${type}' as OBJ_TYPE, ROUTINE_NAME as NAME, coalesce(ROUTINE_TEXT, LONG_COMMENT) as TEXT, '' as SYS_NAME, '' as SYS_SCHEMA, SPECIFIC_NAME as SPECNAME, '' as BASE_SCHEMA, '' as BASE_OBJ`,
78100
`from QSYS2.SYSFUNCS`,
79-
`where ROUTINE_SCHEMA = '${schema}' ${getFilterClause(`ROUTINE_NAME`, details.filter)} and FUNCTION_ORIGIN in ('E','U')`,
101+
`where ROUTINE_SCHEMA = ? ${filter.clause} and FUNCTION_ORIGIN in ('E','U')`,
80102
].join(` `));
103+
104+
parameters.push(schema, ...filter.parameters);
81105
break;
82106

83107
case `variables`:
108+
filter = getFilterClause(`VARIABLE_NAME`, details.filter);
84109
selects.push([
85110
`select '${type}' as OBJ_TYPE, VARIABLE_NAME as NAME, VARIABLE_TEXT as TEXT, SYSTEM_VAR_NAME as SYS_NAME, SYSTEM_VAR_SCHEMA as SYS_SCHEMA, '' as SPECNAME, '' as BASE_SCHEMA, '' as BASE_OBJ`,
86111
`from QSYS2.SYSVARIABLES`,
87-
`where VARIABLE_SCHEMA = '${schema}' ${getFilterClause(`VARIABLE_NAME`, details.filter)}`,
112+
`where VARIABLE_SCHEMA = ? ${filter.clause}`,
88113
].join(` `));
114+
115+
parameters.push(schema, ...filter.parameters);
89116
break;
90117

91118
case `indexes`:
119+
filter = getFilterClause(`INDEX_NAME`, details.filter);
92120
selects.push([
93121
`select '${type}' as OBJ_TYPE, INDEX_NAME as NAME, INDEX_TEXT as TEXT, SYSTEM_INDEX_NAME as SYS_NAME, SYSTEM_INDEX_SCHEMA as SYS_SCHEMA, '' as SPECNAME, TABLE_SCHEMA as BASE_SCHEMA, TABLE_NAME as BASE_OBJ`,
94122
`from QSYS2.SYSINDEXES`,
95-
`where INDEX_SCHEMA = '${schema}' ${getFilterClause(`INDEX_NAME`, details.filter)}`,
123+
`where INDEX_SCHEMA = ? ${filter.clause}`,
96124
].join(` `));
125+
126+
parameters.push(schema, ...filter.parameters);
97127
break;
98128

99129
case `procedures`:
130+
filter = getFilterClause(`ROUTINE_NAME`, details.filter);
100131
selects.push([
101132
`select '${type}' as OBJ_TYPE, ROUTINE_NAME as NAME, ROUTINE_TEXT as TEXT, '' as SYS_NAME, '' as SYS_SCHEMA, SPECIFIC_NAME as SPECNAME, '' as BASE_SCHEMA, '' as BASE_OBJ`,
102133
`from QSYS2.SYSPROCS`,
103-
`where ROUTINE_SCHEMA = '${schema}' ${getFilterClause(`ROUTINE_NAME`, details.filter)}`,
134+
`where ROUTINE_SCHEMA = ? ${filter.clause}`,
104135
].join(` `));
136+
137+
parameters.push(schema, ...filter.parameters);
105138
break;
106139

107140
case `sequences`:
141+
filter = getFilterClause(`SEQUENCE_NAME`, details.filter);
108142
selects.push([
109143
`select '${type}' as OBJ_TYPE, SEQUENCE_NAME as NAME, SEQUENCE_TEXT as TEXT, SYSTEM_SEQ_NAME as SYS_NAME, SYSTEM_SEQ_SCHEMA as SYS_SCHEMA, '' as SPECNAME, '' as BASE_SCHEMA, '' as BASE_OBJ`,
110144
`from QSYS2.SYSSEQUENCES`,
111-
`where SEQUENCE_SCHEMA = '${schema}' ${getFilterClause(`SEQUENCE_NAME`, details.filter)}`,
145+
`where SEQUENCE_SCHEMA = ? ${filter.clause}`,
112146
].join(` `));
147+
148+
parameters.push(schema, ...filter.parameters);
113149
break;
114150

115151
// case `packages`:
116152
// selects.push([
117153
// `select '${type}' as OBJ_TYPE, PACKAGE_NAME as NAME, PACKAGE_TEXT as TEXT, PROGRAM_SCHEMA as BASE_SCHEMA, PROGRAM_NAME as BASE_OBJ, `,
118154
// ` '' as SYS_SCHEMA, '' as SYS_NAME, '' as SPECNAME`,
119155
// `from QSYS2.SQLPACKAGE`,
120-
// `where PACKAGE_SCHEMA = '${schema}' ${details.filter ? `and PACKAGE_NAME like '%${details.filter}%'`: ``}`,
156+
// `where PACKAGE_SCHEMA = '${schema}' ${details.filter ? `and PACKAGE_NAME like '%${filter.clause}%'`: ``}`,
121157
// ].join(` `));
122158
// break;
123159

124160
case `triggers`:
161+
filter = getFilterClause(`TRIGGER_NAME`, details.filter);
125162
selects.push([
126163
`select '${type}' as OBJ_TYPE, TRIGGER_NAME as NAME, TRIGGER_TEXT as TEXT, '' as SYS_NAME, '' as SYS_SCHEMA, '' as SPECNAME, EVENT_OBJECT_SCHEMA as BASE_SCHEMA, EVENT_OBJECT_TABLE as BASE_OBJ`,
127164
`from QSYS2.SYSTRIGGERS`,
128-
`where TRIGGER_SCHEMA = '${schema}' ${getFilterClause(`TRIGGER_NAME`, details.filter)}`,
165+
`where TRIGGER_SCHEMA = ? ${filter.clause}`,
129166
].join(` `));
167+
168+
parameters.push(schema, ...filter.parameters);
130169
break;
131170

132171
case `types`:
172+
filter = getFilterClause(`USER_DEFINED_TYPE_NAME`, details.filter);
133173
selects.push([
134174
`select '${type}' as OBJ_TYPE, USER_DEFINED_TYPE_NAME as NAME, TYPE_TEXT as TEXT, SYSTEM_TYPE_NAME as SYS_NAME, SYSTEM_TYPE_SCHEMA as SYS_SCHEMA, '' as SPECNAME, '' as BASE_SCHEMA, '' as BASE_OBJ`,
135175
`from QSYS2.SYSTYPES`,
136-
`where USER_DEFINED_TYPE_SCHEMA = '${schema}' ${getFilterClause(`USER_DEFINED_TYPE_NAME`, details.filter)}`,
176+
`where USER_DEFINED_TYPE_SCHEMA = ? ${filter.clause}`,
137177
].join(` `));
178+
179+
parameters.push(schema, ...filter.parameters);
138180
break;
139181
}
140182
}
141183

142184
const query = `with results as (${selects.join(" UNION ALL ")}) select * from results Order by QSYS2.DELIMIT_NAME(NAME) asc`;
143185

144-
const objects: any[] = await JobManager.runSQL([
186+
const objects: any[] = await JobManager.runSQL(
187+
[
145188
query,
146189
`${details.limit ? `limit ${details.limit}` : ``} ${details.offset ? `offset ${details.offset}` : ``}`
147-
].join(` `));
190+
].join(` `),
191+
{
192+
parameters
193+
}
194+
);
148195

149196
return objects.map(object => ({
150197
type: object.OBJ_TYPE,

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// The module 'vscode' contains the VS Code extensibility API
22
// Import the module and reference it with the alias vscode in your code below
33
import vscode from "vscode"
4-
import schemaBrowser from "./views/schemaBrowser/schemaBrowser";
4+
import schemaBrowser from "./views/schemaBrowser";
55

66
import * as JSONServices from "./language/json";
77
import * as resultsProvider from "./views/results";

src/views/schemaBrowser/schemaBrowser.ts renamed to src/views/schemaBrowser/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ export default class schemaBrowser {
360360
const value = await vscode.window.showInputBox({
361361
title: `Set filter for ${node.schema}`,
362362
value: this.filters[node.schema],
363-
placeHolder: `COOL_IEW, COOL*, COOL\\_, etc`,
364-
prompt: `Show objects that contain this value (case-insensitive). Blank to reset. When using '_', escape it with '${SQL_ESCAPE_CHAR}'. Use '*' for wildcard at end.`,
363+
placeHolder: `COOL, COOL*`,
364+
prompt: `Show objects that contain this value (case-insensitive). Blank to reset. Use '*' for wildcard at end.`,
365365
});
366366

367367
if (value !== undefined) {

0 commit comments

Comments
 (0)