connecting via socket for mysql and postgres #358

This commit is contained in:
Jan Prochazka
2022-09-08 14:23:13 +02:00
parent 5eda39cb62
commit 0293766bad
7 changed files with 84 additions and 14 deletions

View File

@@ -72,6 +72,8 @@ export interface EngineDriver {
beforeConnectionSave?: (values: any) => any; beforeConnectionSave?: (values: any) => any;
databaseUrlPlaceholder?: string; databaseUrlPlaceholder?: string;
defaultAuthTypeName?: string; defaultAuthTypeName?: string;
defaultSocketPath?: string;
authTypeLabel?: string;
importExportArgs?: any[]; importExportArgs?: any[];
connect({ server, port, user, password, database }): Promise<any>; connect({ server, port, user, password, database }): Promise<any>;
close(pool): Promise<any>; close(pool): Promise<any>;

View File

@@ -77,7 +77,7 @@
{#if $authTypes && driver?.showConnectionField('authType', $values)} {#if $authTypes && driver?.showConnectionField('authType', $values)}
<FormSelectField <FormSelectField
label="Authentication" label={driver?.authTypeLabel ?? 'Authentication'}
name="authType" name="authType"
isNative isNative
disabled={isConnected} disabled={isConnected}
@@ -106,7 +106,7 @@
name="port" name="port"
disabled={isConnected || disabledFields.includes('port')} disabled={isConnected || disabledFields.includes('port')}
templateProps={{ noMargin: true }} templateProps={{ noMargin: true }}
placeholder={driver && driver.defaultPort} placeholder={driver?.defaultPort}
/> />
</div> </div>
{/if} {/if}
@@ -119,6 +119,15 @@
{/if} {/if}
{/if} {/if}
{#if driver?.showConnectionField('socketPath', $values)}
<FormTextField
label="Socket path"
name="socketPath"
disabled={isConnected || disabledFields.includes('socketPath')}
placeholder={driver?.defaultSocketPath}
/>
{/if}
{#if showUser && showPassword} {#if showUser && showPassword}
<div class="row"> <div class="row">
{#if showUser} {#if showUser}

View File

@@ -81,6 +81,7 @@
'password', 'password',
'defaultDatabase', 'defaultDatabase',
'singleDatabase', 'singleDatabase',
'socketPath',
]; ];
const visibleProps = allProps.filter(x => driver?.showConnectionField(x, $values)); const visibleProps = allProps.filter(x => driver?.showConnectionField(x, $values));
const omitProps = _.difference(allProps, visibleProps); const omitProps = _.difference(allProps, visibleProps);

View File

@@ -29,10 +29,11 @@ const drivers = driverBases.map(driverBase => ({
...driverBase, ...driverBase,
analyserClass: Analyser, analyserClass: Analyser,
async connect({ server, port, user, password, database, ssl, isReadOnly, forceRowsAsObjects }) { async connect({ server, port, user, password, database, ssl, isReadOnly, forceRowsAsObjects, socketPath, authType }) {
const connection = mysql2.createConnection({ const options = {
host: server, host: authType == 'socket' ? null : server,
port, port: authType == 'socket' ? null : port,
socketPath: authType == 'socket' ? socketPath || driverBase.defaultSocketPath : null,
user, user,
password, password,
database, database,
@@ -43,7 +44,9 @@ const drivers = driverBases.map(driverBase => ({
dateStrings: true, dateStrings: true,
// TODO: test following options // TODO: test following options
// multipleStatements: true, // multipleStatements: true,
}); };
const connection = mysql2.createConnection(options);
connection._database_name = database; connection._database_name = database;
if (isReadOnly) { if (isReadOnly) {
await this.query(connection, 'SET SESSION TRANSACTION READ ONLY'); await this.query(connection, 'SET SESSION TRANSACTION READ ONLY');
@@ -182,6 +185,20 @@ const drivers = driverBases.map(driverBase => ({
}); });
return res; return res;
}, },
getAuthTypes() {
return [
{
title: 'Host and port',
name: 'hostPort',
disabledFields: ['socketPath'],
},
{
title: 'Socket',
name: 'socket',
disabledFields: ['server', 'port'],
},
];
},
})); }));
module.exports = drivers; module.exports = drivers;

View File

@@ -102,21 +102,25 @@ const dialect = {
const mysqlDriverBase = { const mysqlDriverBase = {
...driverBase, ...driverBase,
showConnectionField: (field, values) => showConnectionField: (field, values) =>
['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field), ['authType', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field) ||
(values.authType == 'socket' && ['socketPath'].includes(field)) ||
(values.authType != 'socket' && ['server', 'port'].includes(field)),
dumperClass: Dumper, dumperClass: Dumper,
dialect, dialect,
defaultPort: 3306, defaultPort: 3306,
getQuerySplitterOptions: () => mysqlSplitterOptions, getQuerySplitterOptions: () => mysqlSplitterOptions,
readOnlySessions: true, readOnlySessions: true,
supportsDatabaseDump: true, supportsDatabaseDump: true,
authTypeLabel: 'Connection mode',
defaultAuthTypeName: 'hostPort',
defaultSocketPath: '/var/run/mysqld/mysqld.sock',
getNewObjectTemplates() { getNewObjectTemplates() {
return [ return [
{ label: 'New view', sql: 'CREATE VIEW myview\nAS\nSELECT * FROM table1' }, { label: 'New view', sql: 'CREATE VIEW myview\nAS\nSELECT * FROM table1' },
{ {
label: 'New procedure', label: 'New procedure',
sql: sql: 'DELIMITER //\n\nCREATE PROCEDURE myproc (IN arg1 INT)\nBEGIN\n SELECT * FROM table1;\nEND\n\nDELIMITER ;',
'DELIMITER //\n\nCREATE PROCEDURE myproc (IN arg1 INT)\nBEGIN\n SELECT * FROM table1;\nEND\n\nDELIMITER ;',
}, },
{ label: 'New function', sql: 'CREATE FUNCTION myfunc (arg1 INT)\nRETURNS INT DETERMINISTIC\nRETURN 1' }, { label: 'New function', sql: 'CREATE FUNCTION myfunc (arg1 INT)\nRETURNS INT DETERMINISTIC\nRETURN 1' },
]; ];

View File

@@ -31,7 +31,20 @@ const drivers = driverBases.map(driverBase => ({
...driverBase, ...driverBase,
analyserClass: Analyser, analyserClass: Analyser,
async connect({ engine, server, port, user, password, database, databaseUrl, useDatabaseUrl, ssl, isReadOnly }) { async connect({
engine,
server,
port,
user,
password,
database,
databaseUrl,
useDatabaseUrl,
ssl,
isReadOnly,
authType,
socketPath,
}) {
let options = null; let options = null;
if (engine == 'redshift@dbgate-plugin-postgres') { if (engine == 'redshift@dbgate-plugin-postgres') {
@@ -56,8 +69,8 @@ const drivers = driverBases.map(driverBase => ({
connectionString: databaseUrl, connectionString: databaseUrl,
} }
: { : {
host: server, host: authType == 'socket' ? socketPath || driverBase.defaultSocketPath : server,
port, port: authType == 'socket' ? null : port,
user, user,
password, password,
database: database || 'postgres', database: database || 'postgres',
@@ -65,6 +78,8 @@ const drivers = driverBases.map(driverBase => ({
}; };
} }
console.log('OPTIONS', options);
const client = new pg.Client(options); const client = new pg.Client(options);
await client.connect(); await client.connect();
@@ -233,6 +248,19 @@ const drivers = driverBases.map(driverBase => ({
const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false'); const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false');
return rows; return rows;
}, },
getAuthTypes() {
return [
{
title: 'Host and port',
name: 'hostPort',
},
{
title: 'Socket',
name: 'socket',
},
];
},
})); }));
module.exports = drivers; module.exports = drivers;

View File

@@ -115,7 +115,12 @@ const postgresDriverBase = {
if (values.useDatabaseUrl) { if (values.useDatabaseUrl) {
return ['databaseUrl', 'isReadOnly'].includes(field); return ['databaseUrl', 'isReadOnly'].includes(field);
} }
return ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field);
return (
['authType', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field) ||
(values.authType == 'socket' && ['socketPath'].includes(field)) ||
(values.authType != 'socket' && ['server', 'port'].includes(field))
);
}, },
beforeConnectionSave: connection => { beforeConnectionSave: connection => {
@@ -159,6 +164,10 @@ $$ LANGUAGE plpgsql;`,
}, },
]; ];
}, },
authTypeLabel: 'Connection mode',
defaultAuthTypeName: 'hostPort',
defaultSocketPath: '/var/run/postgresql',
}; };
/** @type {import('dbgate-types').EngineDriver} */ /** @type {import('dbgate-types').EngineDriver} */