save connection, list connections

This commit is contained in:
Jan Prochazka 2020-01-01 22:11:35 +01:00
parent 0119d1839f
commit 800f3eec26
5 changed files with 67 additions and 21 deletions

View File

@ -9,6 +9,7 @@
"cross-env": "^6.0.3", "cross-env": "^6.0.3",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"express": "^4.17.1", "express": "^4.17.1",
"fs-extra": "^8.1.0",
"mssql": "^6.0.1", "mssql": "^6.0.1",
"mysql": "^2.17.1", "mysql": "^2.17.1",
"pg": "^7.17.0" "pg": "^7.17.0"

View File

@ -1,23 +1,36 @@
const os = require('os');
const path = require('path');
const fs = require('fs-extra');
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const { fork } = require('child_process'); const { fork } = require('child_process');
const _ = require('lodash');
function datadir() {
return path.join(os.homedir(), 'dbgate-data');
}
router.post('/test', async (req, res) => { router.post('/test', async (req, res) => {
const subprocess = fork(`${__dirname}/connectProcess.js`); const subprocess = fork(`${__dirname}/connectProcess.js`);
subprocess.send(req.body); subprocess.send(req.body);
subprocess.on('message', resp => res.json(resp)); subprocess.on('message', resp => res.json(resp));
});
// const { server, port, user, password } = req.body; router.post('/save', async (req, res) => {
// let pool; await fs.mkdir(datadir());
// try { const fileName = `${new Date().getTime()}.con`;
// pool = await mssql.connect({ server, port, user, password }); await fs.writeFile(path.join(datadir(), fileName), JSON.stringify(req.body));
// const resp = await pool.request().query('SELECT @@VERSION AS version'); res.json({ fileName });
// const { version } = resp.recordset[0]; });
// res.json({ version });
// } catch (e) { router.get('/list', async (req, res) => {
// res.json({ error: e.message }); const files = await fs.readdir(datadir());
// }
// if (pool) await pool.close(); res
.json(
await Promise.all(files.filter(x => x.endsWith('.con')).map(x => fs.readFile(path.join(datadir(), x), 'utf-8')))
)
.map(x => _.omit(JSON.parse(x), 'password'));
}); });
module.exports = router; module.exports = router;

View File

@ -919,6 +919,15 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs.realpath@^1.0.0: fs.realpath@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -996,7 +1005,7 @@ got@^6.7.1:
unzip-response "^2.0.1" unzip-response "^2.0.1"
url-parse-lax "^1.0.0" url-parse-lax "^1.0.0"
graceful-fs@^4.1.11, graceful-fs@^4.1.2: graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
@ -1293,6 +1302,13 @@ json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
optionalDependencies:
graceful-fs "^4.1.6"
jsprim@^1.2.2: jsprim@^1.2.2:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -2302,6 +2318,11 @@ unique-string@^1.0.0:
dependencies: dependencies:
crypto-random-string "^1.0.0" crypto-random-string "^1.0.0"
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
unpipe@1.0.0, unpipe@~1.0.0: unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import axios from 'axios'; import axios from 'axios';
import ModalBase from './ModalBase'; import ModalBase from './ModalBase';
import { FormRow, FormLabel, FormValue, FormTextField, FormSelectField, FormSubmit } from '../utility/forms'; import { FormRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
import { TextField } from '../utility/inputs'; import { TextField } from '../utility/inputs';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
// import FormikForm from '../utility/FormikForm'; // import FormikForm from '../utility/FormikForm';
@ -9,7 +9,7 @@ import { Formik, Form } from 'formik';
export default function ConnectionModal({ modalState }) { export default function ConnectionModal({ modalState }) {
const [sqlConnectResult, setSqlConnectResult] = React.useState('Not connected'); const [sqlConnectResult, setSqlConnectResult] = React.useState('Not connected');
const handleSubmit = async values => { const handleTest = async values => {
const resp = await axios.post('http://localhost:3000/connection/test', values); const resp = await axios.post('http://localhost:3000/connection/test', values);
console.log('resp.data', resp.data); console.log('resp.data', resp.data);
const { error, version } = resp.data; const { error, version } = resp.data;
@ -18,6 +18,13 @@ export default function ConnectionModal({ modalState }) {
// modalState.close(); // modalState.close();
}; };
const handleSubmit = async values => {
const resp = await axios.post('http://localhost:3000/connection/save', values);
console.log('resp.data', resp.data);
// modalState.close();
};
return ( return (
<ModalBase modalState={modalState}> <ModalBase modalState={modalState}>
<h2>Add connection</h2> <h2>Add connection</h2>
@ -34,7 +41,10 @@ export default function ConnectionModal({ modalState }) {
<FormTextField label="Password" name="password" /> <FormTextField label="Password" name="password" />
<FormTextField label="Display name" name="displayName" /> <FormTextField label="Display name" name="displayName" />
<FormSubmit /> <FormRow>
<FormButton text="Test" onClick={handleTest} />
<FormSubmit text="Save" />
</FormRow>
</Form> </Form>
</Formik> </Formik>
<div>Connect result: {sqlConnectResult}</div> <div>Connect result: {sqlConnectResult}</div>

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { TextField, SelectField } from './inputs'; import { TextField, SelectField } from './inputs';
import { Field } from 'formik'; import { Field, useFormikContext } from 'formik';
export const FormRow = styled.div` export const FormRow = styled.div`
display: flex; display: flex;
@ -40,9 +40,10 @@ export function FormSelectField({ label, children, ...other }) {
} }
export function FormSubmit({ text }) { export function FormSubmit({ text }) {
return ( return <input type="submit" value={text} />;
<FormRow> }
<input type="submit" value={text} />
</FormRow> export function FormButton({ text, onClick, ...other }) {
); const { values } = useFormikContext();
return <input type="button" value={text} onClick={() => onClick(values)} {...other} />;
} }