From 26dc80f3ca0da78ff6388714826d0d458c150e8e Mon Sep 17 00:00:00 2001 From: texodus Date: Fri, 18 May 2018 00:03:08 -0400 Subject: [PATCH] Re-added remove() feature from bad merge --- .../perspective-jupyterlab/src/ts/index.ts | 13 +++++- packages/perspective/src/cpp/main.cpp | 12 +++-- packages/perspective/src/js/perspective.js | 46 ++++++++++++++++++- .../src/js/perspective.parallel.js | 2 + packages/perspective/test/js/updates.js | 24 ++++++++++ 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/packages/perspective-jupyterlab/src/ts/index.ts b/packages/perspective-jupyterlab/src/ts/index.ts index cb8b924c47..5cc51a076d 100644 --- a/packages/perspective-jupyterlab/src/ts/index.ts +++ b/packages/perspective-jupyterlab/src/ts/index.ts @@ -31,6 +31,7 @@ const PSP_CONTAINER_CLASS = 'jp-PSPContainer'; interface PerspectiveSpec { data: string, + schema: string, layout: string, config: string; } @@ -46,6 +47,7 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer { let psp = ((this.node.querySelector('perspective-viewer'))); let layout = JSON.parse(this._lyt); + for(let key in layout){ if(layout[key]){ if(key !== 'view'){ @@ -56,8 +58,13 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer { } } + if (this._schema !== '') { + let schema = JSON.parse(this._schema); + psp.load(schema); + } + if (this._datatype === 'static') { - psp.load(this._data); + psp.update(this._data); } else if (this._datatype === 'ws' || this._datatype === 'wss') { let config = JSON.parse(this._config); let send = config.send || ''; @@ -111,8 +118,9 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer { } renderModel(model: IRenderMime.IMimeModel): Promise { - const {data, layout, config} = model.data[MIME_TYPE] as any | PerspectiveSpec; + const {data, schema, layout, config} = model.data[MIME_TYPE] as any | PerspectiveSpec; this._lyt = layout; + this._schema = schema; try { this._data = JSON.parse(data) as object; @@ -156,6 +164,7 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer { private _data: object; private _datatype: string; private _datasrc: string; + private _schema: string; private _lyt: string; // not widget layout private _config: string; private _loaded: boolean; diff --git a/packages/perspective/src/cpp/main.cpp b/packages/perspective/src/cpp/main.cpp index 123b69bafb..a83ac2a988 100644 --- a/packages/perspective/src/cpp/main.cpp +++ b/packages/perspective/src/cpp/main.cpp @@ -503,7 +503,8 @@ make_table( val j_data, t_uint32 offset, t_str index, - t_bool is_arrow + t_bool is_arrow, + t_bool is_delete ) { // Create the input and port schemas t_svec colnames = vecFromJSArray(j_colnames); @@ -518,8 +519,13 @@ make_table( _fill_data(tbl, colnames, j_data, dtypes, offset, is_arrow); // Set up pkey and op columns - auto op_col = tbl->add_column("psp_op", DTYPE_UINT8, false); - op_col->raw_fill(OP_INSERT); + if (is_delete) { + auto op_col = tbl->add_column("psp_op", DTYPE_UINT8, false); + op_col->raw_fill(OP_DELETE); + } else { + auto op_col = tbl->add_column("psp_op", DTYPE_UINT8, false); + op_col->raw_fill(OP_INSERT); + } if (index == "") { diff --git a/packages/perspective/src/js/perspective.js b/packages/perspective/src/js/perspective.js index de83c21de5..947cae064f 100644 --- a/packages/perspective/src/js/perspective.js +++ b/packages/perspective/src/js/perspective.js @@ -1071,7 +1071,7 @@ table.prototype.update = function (data) { try { tbl = __MODULE__.make_table(pdata.row_count || 0, pdata.names, pdata.types, pdata.cdata, - this.gnode.get_table().size(), this.index || "", pdata.is_arrow); + this.gnode.get_table().size(), this.index || "", pdata.is_arrow, false); // Add any computed columns this._calculate_computed(tbl, this.computed); @@ -1089,6 +1089,48 @@ table.prototype.update = function (data) { } } +/** + * Removes the rows of a {@link table}. Removed rows are pushed down to any + * derived {@link view} objects. + * + * @param {Array} data An array of primary keys to remove. + * + * @see {@link table} + */ +table.prototype.remove = function (data) { + let pdata; + let cols = this._columns(); + let schema = this.gnode.get_tblschema(); + let types = schema.types(); + + data = data.map(idx => ({[this.index]: idx})); + + if (data instanceof ArrayBuffer) { + pdata = load_arrow_buffer(data, [this.index], types); + } + else { + pdata = parse_data(data, [this.index], types); + } + + let tbl; + try { + tbl = __MODULE__.make_table(pdata.row_count || 0, + pdata.names, pdata.types, pdata.cdata, + this.gnode.get_table().size(), this.index || "", pdata.is_arrow, true); + + __MODULE__.fill(this.pool, this.gnode, tbl); + this.initialized = true; + } catch (e) { + console.error(e); + } finally { + if (tbl) { + tbl.delete(); + } + schema.delete(); + types.delete(); + } +} + /** * Create a new table with the addition of new computed columns (defined as javascript functions) */ @@ -1403,7 +1445,7 @@ const perspective = { // Fill t_table with data tbl = __MODULE__.make_table(pdata.row_count || 0, pdata.names, pdata.types, pdata.cdata, - 0, options.index, pdata.is_arrow); + 0, options.index, pdata.is_arrow, false); gnode = __MODULE__.make_gnode(tbl); pool.register_gnode(gnode); diff --git a/packages/perspective/src/js/perspective.parallel.js b/packages/perspective/src/js/perspective.parallel.js index caac8becf6..f3c4547a13 100644 --- a/packages/perspective/src/js/perspective.parallel.js +++ b/packages/perspective/src/js/perspective.parallel.js @@ -160,6 +160,8 @@ table.prototype.delete = async_queue('delete', "table_method"); table.prototype.on_delete = subscribe('on_delete', 'table_method', true); +table.prototype.remove = async_queue('remove', "table_method"); + table.prototype.update = function(data) { return new Promise( (resolve, reject) => { this._worker.handlers[++this._worker.msg_id] = {resolve, reject}; diff --git a/packages/perspective/test/js/updates.js b/packages/perspective/test/js/updates.js index 7dfe38485a..a486b307f9 100644 --- a/packages/perspective/test/js/updates.js +++ b/packages/perspective/test/js/updates.js @@ -50,6 +50,30 @@ var arrow_indexed_result = [ module.exports = (perspective) => { + + describe("Removes", function() { + + it("after an `update()`", async function () { + var table = perspective.table(meta, {index: "x"}); + table.update(data); + var view = table.view(); + table.remove([1, 2]); + let result = await view.to_json(); + expect(result.length).toEqual(2); + expect(data.slice(2, 4)).toEqual(result); + }); + + it("after an regular data load`", async function () { + var table = perspective.table(data, {index: "x"}); + var view = table.view(); + table.remove([1, 2]); + let result = await view.to_json(); + expect(result.length).toEqual(2); + expect(data.slice(2, 4)).toEqual(result); + }); + + }); + describe("Updates", function() { it("Meta constructor then `update()`", async function () {