load field values logic moved to backend

This commit is contained in:
Jan Prochazka 2022-03-17 08:40:09 +01:00
parent 074a75075d
commit 5c4794deae
7 changed files with 98 additions and 108 deletions

View File

@ -151,34 +151,33 @@ module.exports = {
return res.result; return res.result;
}, },
loadKeys_meta: true, async loadDataCore(msgtype, {conid, database, ...args}) {
async loadKeys({ conid, database, root }) {
const opened = await this.ensureOpened(conid, database); const opened = await this.ensureOpened(conid, database);
const res = await this.sendRequest(opened, { msgtype: 'loadKeys', root }); const res = await this.sendRequest(opened, { msgtype, ...args });
if (res.errorMessage) { if (res.errorMessage) {
console.error(res.errorMessage); console.error(res.errorMessage);
} }
return res.result || null; return res.result || null;
}, },
loadKeys_meta: true,
async loadKeys({ conid, database, root }) {
return this.loadDataCore('loadKeys', { conid, database, root });
},
loadKeyInfo_meta: true, loadKeyInfo_meta: true,
async loadKeyInfo({ conid, database, key }) { async loadKeyInfo({ conid, database, key }) {
const opened = await this.ensureOpened(conid, database); return this.loadDataCore('loadKeyInfo', { conid, database, key });
const res = await this.sendRequest(opened, { msgtype: 'loadKeyInfo', key });
if (res.errorMessage) {
console.error(res.errorMessage);
}
return res.result || null;
}, },
loadKeyTableRange_meta: true, loadKeyTableRange_meta: true,
async loadKeyTableRange({ conid, database, key, cursor, count }) { async loadKeyTableRange({ conid, database, key, cursor, count }) {
const opened = await this.ensureOpened(conid, database); return this.loadDataCore('loadKeyTableRange', { conid, database, key, cursor, count });
const res = await this.sendRequest(opened, { msgtype: 'loadKeyTableRange', key, cursor, count }); },
if (res.errorMessage) {
console.error(res.errorMessage); loadFieldValues_meta: true,
} async loadFieldValues({ conid, database, schemaName, pureName, field, search }) {
return res.result || null; return this.loadDataCore('loadFieldValues', { conid, database, schemaName, pureName, field, search });
}, },
callMethod_meta: true, callMethod_meta: true,

View File

@ -172,59 +172,41 @@ async function handleQueryData({ msgid, sql }) {
} }
} }
async function handleCollectionData({ msgid, options }) { async function handleDriverDataCore(msgid, callMethod) {
await waitConnected(); await waitConnected();
const driver = requireEngineDriver(storedConnection); const driver = requireEngineDriver(storedConnection);
try { try {
const result = await driver.readCollection(systemConnection, options); const result = await callMethod(driver);
process.send({ msgtype: 'response', msgid, result }); process.send({ msgtype: 'response', msgid, result });
} catch (err) { } catch (err) {
process.send({ msgtype: 'response', msgid, errorMessage: err.message }); process.send({ msgtype: 'response', msgid, errorMessage: err.message });
} }
} }
async function handleCollectionData({ msgid, options }) {
return handleDriverDataCore(msgid, driver => driver.readCollection(systemConnection, options));
}
async function handleLoadKeys({ msgid, root }) { async function handleLoadKeys({ msgid, root }) {
await waitConnected(); return handleDriverDataCore(msgid, driver => driver.loadKeys(systemConnection, root));
const driver = requireEngineDriver(storedConnection);
try {
const result = await driver.loadKeys(systemConnection, root);
process.send({ msgtype: 'response', msgid, result });
} catch (err) {
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
}
} }
async function handleLoadKeyInfo({ msgid, key }) { async function handleLoadKeyInfo({ msgid, key }) {
await waitConnected(); return handleDriverDataCore(msgid, driver => driver.loadKeyInfo(systemConnection, key));
const driver = requireEngineDriver(storedConnection);
try {
const result = await driver.loadKeyInfo(systemConnection, key);
process.send({ msgtype: 'response', msgid, result });
} catch (err) {
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
}
} }
async function handleCallMethod({ msgid, method, args }) { async function handleCallMethod({ msgid, method, args }) {
await waitConnected(); return handleDriverDataCore(msgid, driver => driver.callMethod(systemConnection, method, args));
const driver = requireEngineDriver(storedConnection);
try {
const result = await driver.callMethod(systemConnection, method, args);
process.send({ msgtype: 'response', msgid, result });
} catch (err) {
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
}
} }
async function handleLoadKeyTableRange({ msgid, key, cursor, count }) { async function handleLoadKeyTableRange({ msgid, key, cursor, count }) {
await waitConnected(); return handleDriverDataCore(msgid, driver => driver.loadKeyTableRange(systemConnection, key, cursor, count));
const driver = requireEngineDriver(storedConnection);
try {
const result = await driver.loadKeyTableRange(systemConnection, key, cursor, count);
process.send({ msgtype: 'response', msgid, result });
} catch (err) {
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
} }
async function handleLoadFieldValues({ msgid, schemaName, pureName, field, search }) {
return handleDriverDataCore(msgid, driver =>
driver.loadFieldValues(systemConnection, { schemaName, pureName }, field, search)
);
} }
async function handleUpdateCollection({ msgid, changeSet }) { async function handleUpdateCollection({ msgid, changeSet }) {
@ -300,6 +282,7 @@ const messageHandlers = {
ping: handlePing, ping: handlePing,
syncModel: handleSyncModel, syncModel: handleSyncModel,
generateDeploySql: handleGenerateDeploySql, generateDeploySql: handleGenerateDeploySql,
loadFieldValues: handleLoadFieldValues,
// runCommand: handleRunCommand, // runCommand: handleRunCommand,
}; };

View File

@ -26,6 +26,7 @@
"devDependencies": { "devDependencies": {
"@types/node": "^13.7.0", "@types/node": "^13.7.0",
"dbgate-types": "^4.1.1", "dbgate-types": "^4.1.1",
"dbgate-sqltree": "^4.1.1",
"jest": "^24.9.0", "jest": "^24.9.0",
"ts-jest": "^25.2.1", "ts-jest": "^25.2.1",
"typescript": "^4.4.3" "typescript": "^4.4.3"

View File

@ -1,5 +1,7 @@
import _compact from 'lodash/compact'
import { SqlDumper } from './SqlDumper'; import { SqlDumper } from './SqlDumper';
import { splitQuery } from 'dbgate-query-splitter'; import { splitQuery } from 'dbgate-query-splitter';
import { dumpSqlSelect } from 'dbgate-sqltree';
const dialect = { const dialect = {
limitSelect: true, limitSelect: true,
@ -51,4 +53,56 @@ export const driverBase = {
} }
return []; return [];
}, },
async loadFieldValues(pool, name, columnName, search) {
const dmp = this.createDumper();
const select = {
commandType: 'select',
distinct: true,
topRecords: 100,
from: {
name,
},
columns: [
{
exprType: 'column',
columnName,
alias: 'value',
},
],
orderBy: [
{
exprType: 'column',
columnName,
},
],
};
if (search) {
const tokens = _compact(search.split(' ').map(x => x.trim()));
if (tokens.length > 0) {
// @ts-ignore
select.where = {
conditionType: 'and',
conditions: tokens.map(token => ({
conditionType: 'like',
left: {
exprType: 'column',
columnName,
},
right: {
exprType: 'value',
value: `%${token}%`,
},
})),
};
}
}
// @ts-ignore
dumpSqlSelect(dmp, select);
const resp = await this.query(pool, dmp.s);
return resp.rows;
},
}; };

View File

@ -79,6 +79,7 @@ export interface EngineDriver {
loadKeys(pool, root: string): Promise; loadKeys(pool, root: string): Promise;
loadKeyInfo(pool, key): Promise; loadKeyInfo(pool, key): Promise;
loadKeyTableRange(pool, key, cursor, count): Promise; loadKeyTableRange(pool, key, cursor, count): Promise;
loadFieldValues(pool: any, name: NamedObjectInfo, field: string, search: string): Promise;
analyseFull(pool: any, serverVersion): Promise<DatabaseInfo>; analyseFull(pool: any, serverVersion): Promise<DatabaseInfo>;
analyseIncremental(pool: any, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>; analyseIncremental(pool: any, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>;
dialect: SqlDialect; dialect: SqlDialect;

View File

@ -266,8 +266,8 @@
class:isOk class:isOk
placeholder="Filter" placeholder="Filter"
/> />
{#if conid && database && driver && driver?.databaseEngineTypes?.includes('sql')} {#if conid && database && driver}
{#if foreignKey} {#if driver?.databaseEngineTypes?.includes('sql') && foreignKey}
<InlineButton on:click={handleShowDictionary} narrow square> <InlineButton on:click={handleShowDictionary} narrow square>
<FontIcon icon="icon dots-horizontal" /> <FontIcon icon="icon dots-horizontal" />
</InlineButton> </InlineButton>

View File

@ -34,64 +34,16 @@
let checkedKeys = []; let checkedKeys = [];
async function reload() { async function reload() {
const dmp = driver.createDumper();
const select = {
commandType: 'select',
distinct: true,
topRecords: 100,
from: {
name: {
schemaName,
pureName,
},
},
columns: [
{
exprType: 'column',
columnName,
},
],
orderBy: [
{
exprType: 'column',
columnName,
},
],
};
if (search) {
const tokens = _.compact(search.split(' ').map(x => x.trim()));
if (tokens.length > 0) {
// @ts-ignore
select.where = {
conditionType: 'and',
conditions: tokens.map(token => ({
conditionType: 'like',
left: {
exprType: 'column',
columnName,
},
right: {
exprType: 'value',
value: `%${token}%`,
},
})),
};
}
}
// @ts-ignore
dumpSqlSelect(dmp, select);
isLoading = true; isLoading = true;
const response = await apiCall('database-connections/query-data', { rows = await apiCall('database-connections/load-field-values', {
conid, conid,
database, database,
sql: dmp.s, search,
schemaName,
pureName,
field: columnName,
}); });
rows = response.rows;
isLoading = false; isLoading = false;
} }
@ -124,7 +76,7 @@
{rows} {rows}
clickable clickable
on:clickrow={e => { on:clickrow={e => {
const value = e.detail[columnName]; const { value } = e.detail;
if (multiselect) { if (multiselect) {
if (checkedKeys.includes(value)) checkedKeys = checkedKeys.filter(x => x != value); if (checkedKeys.includes(value)) checkedKeys = checkedKeys.filter(x => x != value);
else checkedKeys = [...checkedKeys, value]; else checkedKeys = [...checkedKeys, value];
@ -143,7 +95,7 @@
{ {
fieldName: 'value', fieldName: 'value',
header: 'Value', header: 'Value',
formatter: row => (row[columnName] == null ? '(NULL)' : row[columnName]), formatter: row => (row.value == null ? '(NULL)' : row.value),
}, },
]} ]}
> >
@ -151,9 +103,9 @@
type="checkbox" type="checkbox"
let:row let:row
slot="1" slot="1"
checked={checkedKeys.includes(row[columnName])} checked={checkedKeys.includes(row['value'])}
on:change={e => { on:change={e => {
const value = row[columnName]; const value = row['value'];
if (e.target.checked) { if (e.target.checked) {
if (!checkedKeys.includes(value)) checkedKeys = [...checkedKeys, value]; if (!checkedKeys.includes(value)) checkedKeys = [...checkedKeys, value];
} else { } else {