Skip to content

Commit e234214

Browse files
authored
migrate to react, show encrypt option for mssql (#13)
Now the webview is rendered with react, which will make it easier to support driver-specific configuration in the connection configuration form. Closes #7
1 parent 45272d3 commit e234214

16 files changed

+1017
-813
lines changed

.eslintrc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
},
88
"plugins": ["@typescript-eslint"],
99
"rules": {
10-
"@typescript-eslint/naming-convention": "warn",
10+
"@typescript-eslint/naming-convention": "off",
1111
"@typescript-eslint/semi": "warn",
1212
"curly": "warn",
1313
"eqeqeq": "warn",

.gitattributes

-2
This file was deleted.

.github/workflows/publish.yml

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
on:
2-
create:
2+
push:
33
tags: "v*"
44
name: Publish Extension
55

@@ -16,7 +16,7 @@ permissions:
1616
statuses: none
1717

1818
jobs:
19-
deploy:
19+
publish:
2020
runs-on: ubuntu-latest
2121
steps:
2222
- uses: actions/checkout@v2
@@ -33,7 +33,11 @@ jobs:
3333
with:
3434
name: sqlnotebook-${{ env.RELEASE_VERSION }}.vsix
3535
path: sqlnotebook-${{ env.RELEASE_VERSION }}.vsix
36-
- name: Publish Extension
36+
- name: Publish Extension to Microsoft Marketplace
3737
run: vsce publish --packagePath ./sqlnotebook-${{ env.RELEASE_VERSION }}.vsix
3838
env:
3939
VSCE_PAT: ${{ secrets.VSCE_CREDENTIALS }}
40+
- name: Install OpenVSX CLI
41+
run: npm install -g ovsx
42+
- name: Publish to OpenVSX
43+
run: npx ovsx publish ./sqlnotebook-${{ env.RELEASE_VERSION }}.vsix -p ${{ secrets.OPEN_VSX_CREDENTIALS }}

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
out
22
node_modules
3-
.vscode-test/
43
*.vsix

media/webview/form.js

-33
This file was deleted.

package.json

+14-15
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,7 @@
6060
"when": "view == sqlnotebook-connections && viewItem == database"
6161
}
6262
],
63-
"view/title": [
64-
{
65-
"command": "sqlnotebook.addNewConnectionConfiguration",
66-
"when": "view == sqlnotebook-connections",
67-
"group": "navigation"
68-
}
69-
]
63+
"view/title": []
7064
},
7165
"commands": [
7266
{
@@ -79,11 +73,12 @@
7973
},
8074
{
8175
"command": "sqlnotebook.deleteConnectionConfiguration",
82-
"title": "Delete Connection Configuration"
76+
"title": "Delete SQL Connection Configuration"
8377
},
8478
{
8579
"command": "sqlnotebook.refreshConnectionPanel",
86-
"title": "Refresh Connection Panel"
80+
"title": "Refresh SQL Connection Panel",
81+
"shortTitle": "Refresh"
8782
}
8883
],
8984
"viewsContainers": {
@@ -123,9 +118,9 @@
123118
},
124119
"scripts": {
125120
"vscode:prepublish": "npm run compile",
126-
"compile": "tsc -b",
121+
"compile": "tsc -b ./src & webpack --config ./webview/webpack.config.js",
127122
"lint": "eslint src --ext ts",
128-
"watch": "tsc -b --watch",
123+
"watch": "tsc -b ./src --watch & webpack --watch --config ./webview/webpack.config.js",
129124
"fmt": "npx prettier --write ./*.{jsx,ts,tsx,json,yaml,yml,md}"
130125
},
131126
"devDependencies": {
@@ -135,6 +130,8 @@
135130
"@types/mssql": "^7.1.3",
136131
"@types/node": "14.x",
137132
"@types/pg": "^8.6.1",
133+
"@types/react": "^17.0.37",
134+
"@types/react-dom": "^17.0.11",
138135
"@types/vscode": "^1.59.0",
139136
"@types/vscode-notebook-renderer": "^1.57.8",
140137
"@types/webpack-env": "^1.16.0",
@@ -147,18 +144,20 @@
147144
"glob": "^7.1.7",
148145
"mocha": "^8.4.0",
149146
"style-loader": "^1.2.1",
150-
"ts-loader": "^9.2.2",
147+
"ts-loader": "^9.2.6",
151148
"typescript": "^4.3.2",
152149
"vscode-notebook-error-overlay": "^1.0.1",
153150
"vscode-test": "^1.5.2",
154-
"webpack": "^5.38.1",
155-
"webpack-cli": "^4.7.0"
151+
"webpack": "^5.65.0",
152+
"webpack-cli": "^4.9.1"
156153
},
157154
"dependencies": {
158155
"@vscode/webview-ui-toolkit": "^0.8.4",
159156
"mssql": "^7.2.1",
160157
"mysql2": "^2.3.0",
161-
"pg": "^8.7.1"
158+
"pg": "^8.7.1",
159+
"react": "^17.0.2",
160+
"react-dom": "^17.0.2"
162161
},
163162
"prettier": {
164163
"semi": true,

src/commands.ts

+4-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
ConnectionListItem,
55
SQLNotebookConnections,
66
} from './connections';
7-
import { getDriver } from './driver';
7+
import { getPool, PoolConfig } from './driver';
88
import { storageKey, globalConnPool } from './extension';
99

1010
export const deleteConnectionConfiguration =
@@ -48,6 +48,7 @@ export const connectToDatabase =
4848
} else {
4949
selectedName = item.config.name;
5050
}
51+
5152
const match = context.globalState
5253
.get<ConnData[]>(storageKey, [])
5354
.find(({ name }) => name === selectedName);
@@ -64,14 +65,7 @@ export const connectToDatabase =
6465
);
6566
return;
6667
}
67-
const driver = getDriver(match.driver);
68-
globalConnPool.pool = await driver.createPool({
69-
host: match.host,
70-
port: match.port,
71-
user: match.user,
72-
password,
73-
database: match.database,
74-
});
68+
globalConnPool.pool = await getPool({ ...match, password } as PoolConfig);
7569
try {
7670
const conn = await globalConnPool.pool.getConnection();
7771
await conn.query('SELECT 1'); // essentially a ping to see if the connection works
@@ -87,4 +81,4 @@ export const connectToDatabase =
8781
globalConnPool.pool = null;
8882
connectionsSidepanel.setActive(null);
8983
}
90-
};
84+
};;

src/connections.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,17 @@ export class SQLNotebookConnections
7373
}
7474
}
7575

76-
export interface ConnData {
76+
export type ConnData = {
77+
driver: DriverKey;
7778
name: string;
7879
host: string;
7980
port: number;
8081
user: string;
8182
passwordKey: string;
8283
database: string;
83-
driver: DriverKey;
84-
}
84+
} & {
85+
[key: string]: any;
86+
};
8587

8688
export class ConnectionListItem extends vscode.TreeItem {
8789
constructor(

src/driver.ts

+60-63
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as mysql from 'mysql2/promise';
22
import * as pg from 'pg';
33
import * as mssql from 'mssql';
44

5-
export const supportedDrivers = ['mysql', 'postgres', 'mssql'] as const;
5+
const supportedDrivers = ['mysql', 'postgres', 'mssql'] as const;
66

77
export type DriverKey = typeof supportedDrivers[number];
88

@@ -17,51 +17,48 @@ export type Row = { [key: string]: string | number | null };
1717

1818
export type ResultTable = Row[];
1919

20-
export interface Conn {
20+
interface Conn {
2121
release: () => void;
2222
query: (q: string) => Promise<QueryResult>;
2323
destroy: () => void;
2424
}
2525

26-
interface PoolConfig {
26+
export type PoolConfig = MySQLConfig | MSSQLConfig | PostgresConfig;
27+
28+
interface BaseConfig {
29+
driver: DriverKey;
2730
host: string;
2831
port: number;
2932
user: string;
3033
password?: string;
3134
database?: string;
3235
}
3336

34-
export interface Driver {
35-
createPool: (config: PoolConfig) => Promise<Pool>;
37+
interface MySQLConfig extends BaseConfig {
38+
driver: 'mysql';
3639
}
3740

38-
export const getDriver = (driverKey: DriverKey): Driver => {
39-
switch (driverKey) {
41+
export async function getPool(c: PoolConfig): Promise<Pool> {
42+
switch (c.driver) {
4043
case 'mysql':
41-
return mysqlDriver();
42-
case 'postgres':
43-
return postgresDriver();
44+
return createMySQLPool(c);
4445
case 'mssql':
45-
return mssqlDriver();
46+
return createMSSQLPool(c);
47+
case 'postgres':
48+
return createPostgresPool(c);
4649
default:
47-
throw new Error(`invalid driver key: ${driverKey}`);
50+
throw Error('invalid driver key');
4851
}
49-
};
52+
}
5053

51-
function mysqlDriver(): Driver {
52-
return {
53-
async createPool({
54-
host,
55-
port,
56-
user,
57-
password,
58-
database,
59-
}: PoolConfig): Promise<Pool> {
60-
return mysqlPool(
61-
mysql.createPool({ host, port, user, password, database, })
62-
);
63-
},
64-
};
54+
async function createMySQLPool({
55+
host,
56+
port,
57+
user,
58+
password,
59+
database,
60+
}: MySQLConfig): Promise<Pool> {
61+
return mysqlPool(mysql.createPool({ host, port, user, password, database }));
6562
}
6663

6764
function mysqlPool(pool: mysql.Pool): Pool {
@@ -93,25 +90,25 @@ function mysqlConn(conn: mysql.PoolConnection): Conn {
9390
};
9491
}
9592

96-
function postgresDriver(): Driver {
97-
return {
98-
async createPool({
99-
host,
100-
port,
101-
user,
102-
password,
103-
database,
104-
}: PoolConfig): Promise<Pool> {
105-
const pool = new pg.Pool({
106-
host,
107-
port,
108-
password,
109-
database,
110-
user,
111-
});
112-
return postgresPool(pool);
113-
},
114-
};
93+
interface PostgresConfig extends BaseConfig {
94+
driver: 'postgres';
95+
}
96+
97+
async function createPostgresPool({
98+
host,
99+
port,
100+
user,
101+
password,
102+
database,
103+
}: PostgresConfig): Promise<Pool> {
104+
const pool = new pg.Pool({
105+
host,
106+
port,
107+
password,
108+
database,
109+
user,
110+
});
111+
return postgresPool(pool);
115112
}
116113

117114
function postgresPool(pool: pg.Pool): Pool {
@@ -142,23 +139,23 @@ function postgresConn(conn: pg.PoolClient): Conn {
142139
};
143140
}
144141

145-
function mssqlDriver(): Driver {
146-
return {
147-
async createPool(config: PoolConfig): Promise<Pool> {
148-
const conn = await mssql.connect({
149-
server: config.host,
150-
port: config.port,
151-
user: config.user,
152-
password: config.password,
153-
database: config.database,
154-
options: {
155-
encrypt: false,
156-
trustServerCertificate: true,
157-
},
158-
});
159-
return mssqlPool(conn);
160-
},
161-
};
142+
interface MSSQLConfig extends BaseConfig {
143+
driver: 'mssql';
144+
encrypt: boolean;
145+
}
146+
147+
async function createMSSQLPool(config: MSSQLConfig): Promise<Pool> {
148+
const conn = await mssql.connect({
149+
server: config.host,
150+
port: config.port,
151+
user: config.user,
152+
password: config.password,
153+
database: config.database,
154+
options: {
155+
encrypt: config.encrypt,
156+
},
157+
});
158+
return mssqlPool(conn);
162159
}
163160

164161
function mssqlPool(pool: mssql.ConnectionPool): Pool {

0 commit comments

Comments
 (0)