diff --git a/packages/api/src/controllers/jsldata.js b/packages/api/src/controllers/jsldata.js index 0ab2f2ec..dbace5a2 100644 --- a/packages/api/src/controllers/jsldata.js +++ b/packages/api/src/controllers/jsldata.js @@ -7,6 +7,7 @@ const DatastoreProxy = require('../utility/DatastoreProxy'); const { saveFreeTableData } = require('../utility/freeTableStorage'); const getJslFileName = require('../utility/getJslFileName'); const JsonLinesDatastore = require('../utility/JsonLinesDatastore'); +const requirePluginFunction = require('../utility/requirePluginFunction'); const socket = require('../utility/socket'); function readFirstLine(file) { @@ -99,10 +100,11 @@ module.exports = { // return readerInfo; // }, - async ensureDatastore(jslid) { + async ensureDatastore(jslid, formatterFunction) { + const rowFormatter = requirePluginFunction(formatterFunction); let datastore = this.datastores[jslid]; if (!datastore) { - datastore = new JsonLinesDatastore(getJslFileName(jslid)); + datastore = new JsonLinesDatastore(getJslFileName(jslid), rowFormatter); // datastore = new DatastoreProxy(getJslFileName(jslid)); this.datastores[jslid] = datastore; } @@ -131,8 +133,8 @@ module.exports = { }, getRows_meta: true, - async getRows({ jslid, offset, limit, filters }) { - const datastore = await this.ensureDatastore(jslid); + async getRows({ jslid, offset, limit, filters, formatterFunction }) { + const datastore = await this.ensureDatastore(jslid, formatterFunction); return datastore.getRows(offset, limit, _.isEmpty(filters) ? null : filters); }, @@ -150,8 +152,8 @@ module.exports = { }, loadFieldValues_meta: true, - async loadFieldValues({ jslid, field, search }) { - const datastore = await this.ensureDatastore(jslid); + async loadFieldValues({ jslid, field, search, formatterFunction }) { + const datastore = await this.ensureDatastore(jslid, formatterFunction); const res = new Set(); await datastore.enumRows(row => { if (!filterName(search, row[field])) return true; diff --git a/packages/api/src/utility/JsonLinesDatastore.js b/packages/api/src/utility/JsonLinesDatastore.js index 68fec945..b3a2005d 100644 --- a/packages/api/src/utility/JsonLinesDatastore.js +++ b/packages/api/src/utility/JsonLinesDatastore.js @@ -22,8 +22,9 @@ function fetchNextLineFromReader(reader) { } class JsonLinesDatastore { - constructor(file) { + constructor(file, rowFormatter) { this.file = file; + this.rowFormatter = rowFormatter; this.reader = null; this.readedDataRowCount = 0; this.readedSchemaRow = false; @@ -62,6 +63,11 @@ class JsonLinesDatastore { ); } + parseLine(line) { + const res = JSON.parse(line); + return this.rowFormatter ? this.rowFormatter(res) : res; + } + async _readLine(parse) { // if (this.firstRowToBeReturned) { // const res = this.firstRowToBeReturned; @@ -84,14 +90,14 @@ class JsonLinesDatastore { } } if (this.currentFilter) { - const parsedLine = JSON.parse(line); + const parsedLine = this.parseLine(line); if (evaluateCondition(this.currentFilter, parsedLine)) { this.readedDataRowCount += 1; return parse ? parsedLine : true; } } else { this.readedDataRowCount += 1; - return parse ? JSON.parse(line) : true; + return parse ? this.parseLine(line) : true; } } diff --git a/packages/api/src/utility/requirePluginFunction.js b/packages/api/src/utility/requirePluginFunction.js new file mode 100644 index 00000000..11f9e33e --- /dev/null +++ b/packages/api/src/utility/requirePluginFunction.js @@ -0,0 +1,16 @@ +const _ = require('lodash'); +const requirePlugin = require('../shell/requirePlugin'); + +function requirePluginFunction(functionName) { + if (!functionName) return null; + if (functionName.includes('@')) { + const [shortName, packageName] = functionName.split('@'); + const plugin = requirePlugin(packageName); + if (plugin.functions) { + return plugin.functions[shortName]; + } + } + return null; +} + +module.exports = requirePluginFunction; diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index f3d5ce67..1976e9d3 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -78,6 +78,7 @@ export interface EngineDriver { supportsDatabaseDump?: boolean; supportsServerSummary?: boolean; supportsDatabaseProfiler?: boolean; + profilerFormatterFunction?: string; isElectronOnly?: boolean; supportedCreateDatabase?: boolean; showConnectionField?: (field: string, values: any) => boolean; diff --git a/packages/web/src/datagrid/JslDataGridCore.svelte b/packages/web/src/datagrid/JslDataGridCore.svelte index cb2afde3..f3e95722 100644 --- a/packages/web/src/datagrid/JslDataGridCore.svelte +++ b/packages/web/src/datagrid/JslDataGridCore.svelte @@ -12,12 +12,13 @@ }); async function loadDataPage(props, offset, limit) { - const { jslid, display } = props; + const { jslid, display, formatterFunction } = props; const response = await apiCall('jsldata/get-rows', { jslid, offset, limit, + formatterFunction, filters: display ? display.compileFilters() : null, }); @@ -34,6 +35,9 @@ const response = await apiCall('jsldata/get-stats', { jslid }); return response.rowCount; } + + export let formatterPlugin; + export let formatterFunction;