diff --git a/cpp/perspective/src/cpp/emscripten.cpp b/cpp/perspective/src/cpp/emscripten.cpp index e8de23c94e..38854569f0 100644 --- a/cpp/perspective/src/cpp/emscripten.cpp +++ b/cpp/perspective/src/cpp/emscripten.cpp @@ -31,22 +31,6 @@ namespace binding { return (!item.isUndefined() && !item.isNull()); } - /****************************************************************************** - * - * Data Loading - */ - - template <> - bool - is_valid_filter(t_dtype type, t_val date_parser, t_val filter_term) { - if (type == DTYPE_DATE || type == DTYPE_TIME) { - t_val parsed_date = date_parser.call("parse", filter_term); - return has_value(parsed_date); - } else { - return has_value(filter_term); - } - }; - /****************************************************************************** * * Date Parsing @@ -1313,10 +1297,21 @@ namespace binding { * * View API */ + + template <> + bool + is_valid_filter(t_dtype type, t_val date_parser, t_val filter_term) { + if (type == DTYPE_DATE || type == DTYPE_TIME) { + t_val parsed_date = date_parser.call("parse", filter_term); + return has_value(parsed_date); + } else { + return has_value(filter_term); + } + }; + template <> std::tuple> make_filter_term(t_dtype type, t_val date_parser, std::vector filter) { - // TODO: structure properly std::string col = filter[0].as(); std::string comp_str = filter[1].as(); t_filter_op comp = str_to_filter_op(comp_str); @@ -1385,6 +1380,7 @@ namespace binding { bool column_only = false; + // make sure that primary keys are created for column-only views if (row_pivots.size() == 0 && column_pivots.size() > 0) { row_pivots.push_back("psp_okey"); column_only = true; @@ -1396,11 +1392,14 @@ namespace binding { for (auto f : js_filter) { t_dtype type = schema.get_dtype(f[0].as()); + + // validate the filter before it goes into the core engine if (is_valid_filter(type, date_parser, f[2])) { filter.push_back(make_filter_term(type, date_parser, f)); } } + // create the `t_view_config` t_view_config view_config(row_pivots, column_pivots, aggregates, columns, filter, sort, filter_op, column_only); @@ -1419,44 +1418,16 @@ namespace binding { return view_config; } - template <> - std::shared_ptr> - make_view_zero(std::shared_ptr table, std::string name, std::string separator, - t_val view_config, t_val date_parser) { - auto schema = table->get_schema(); - t_view_config config = make_view_config(schema, date_parser, view_config); - - auto ctx = make_context_zero(table, schema, config, name); - - auto view_ptr = std::make_shared>(table, ctx, name, separator, config); - - return view_ptr; - } - - template <> - std::shared_ptr> - make_view_one(std::shared_ptr
table, std::string name, std::string separator, - t_val view_config, t_val date_parser) { - auto schema = table->get_schema(); - t_view_config config = make_view_config(schema, date_parser, view_config); - - auto ctx = make_context_one(table, schema, config, name); - - auto view_ptr = std::make_shared>(table, ctx, name, separator, config); - - return view_ptr; - } - - template <> - std::shared_ptr> - make_view_two(std::shared_ptr
table, std::string name, std::string separator, + template + std::shared_ptr> + make_view(std::shared_ptr
table, std::string name, std::string separator, t_val view_config, t_val date_parser) { auto schema = table->get_schema(); t_view_config config = make_view_config(schema, date_parser, view_config); - auto ctx = make_context_two(table, schema, config, name); + auto ctx = make_context(table, schema, config, name); - auto view_ptr = std::make_shared>(table, ctx, name, separator, config); + auto view_ptr = std::make_shared>(table, ctx, name, separator, config); return view_ptr; } @@ -1466,8 +1437,9 @@ namespace binding { * Context API */ + template <> std::shared_ptr - make_context_zero(std::shared_ptr
table, const t_schema& schema, + make_context(std::shared_ptr
table, const t_schema& schema, const t_view_config& view_config, std::string name) { auto columns = view_config.get_columns(); auto filter_op = view_config.get_filter_op(); @@ -1487,8 +1459,9 @@ namespace binding { return ctx0; } + template <> std::shared_ptr - make_context_one(std::shared_ptr
table, const t_schema& schema, + make_context(std::shared_ptr
table, const t_schema& schema, const t_view_config& view_config, std::string name) { auto row_pivots = view_config.get_row_pivots(); auto aggspecs = view_config.get_aggspecs(); @@ -1517,8 +1490,9 @@ namespace binding { return ctx1; } + template <> std::shared_ptr - make_context_two(std::shared_ptr
table, const t_schema& schema, + make_context(std::shared_ptr
table, const t_schema& schema, const t_view_config& view_config, std::string name) { bool column_only = view_config.is_column_only(); auto row_pivots = view_config.get_row_pivots(); @@ -1943,9 +1917,9 @@ EMSCRIPTEN_BINDINGS(perspective) { function("scalar_vec_to_string", &scalar_vec_to_string); function("table_add_computed_column", &table_add_computed_column); function("col_to_js_typed_array", &col_to_js_typed_array); - function("make_view_zero", &make_view_zero); - function("make_view_one", &make_view_one); - function("make_view_two", &make_view_two); + function("make_view_zero", &make_view); + function("make_view_one", &make_view); + function("make_view_two", &make_view); function("get_data_slice_zero", &get_data_slice, allow_raw_pointers()); function("get_from_data_slice_zero", &get_from_data_slice, allow_raw_pointers()); function("get_data_slice_one", &get_data_slice, allow_raw_pointers()); diff --git a/cpp/perspective/src/cpp/view_config.cpp b/cpp/perspective/src/cpp/view_config.cpp index 50e8f3e66d..92ca0b01b5 100644 --- a/cpp/perspective/src/cpp/view_config.cpp +++ b/cpp/perspective/src/cpp/view_config.cpp @@ -16,7 +16,8 @@ t_view_config::t_view_config(std::vector row_pivots, tsl::ordered_map aggregates, std::vector columns, std::vector>> filter, std::vector> sort, std::string filter_op, bool column_only) - : m_row_pivots(row_pivots) + : m_init(false) + , m_row_pivots(row_pivots) , m_column_pivots(column_pivots) , m_aggregates(aggregates) , m_columns(columns) @@ -32,76 +33,92 @@ t_view_config::init(const t_schema& schema) { fill_aggspecs(schema); fill_fterm(); fill_sortspec(); + + m_init = true; } void t_view_config::add_filter_term( std::tuple> term) { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); m_filter.push_back(term); } void t_view_config::set_row_pivot_depth(std::int32_t depth) { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); m_row_pivot_depth = depth; } void t_view_config::set_column_pivot_depth(std::int32_t depth) { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); m_column_pivot_depth = depth; } std::vector t_view_config::get_row_pivots() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_row_pivots; } std::vector t_view_config::get_column_pivots() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_column_pivots; } std::vector t_view_config::get_aggspecs() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_aggspecs; } std::vector t_view_config::get_columns() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_columns; } std::vector t_view_config::get_fterm() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_fterm; } std::vector t_view_config::get_sortspec() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_sortspec; } std::vector t_view_config::get_col_sortspec() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_col_sortspec; } t_filter_op t_view_config::get_filter_op() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return str_to_filter_op(m_filter_op); } bool t_view_config::is_column_only() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_column_only; } std::int32_t t_view_config::get_row_pivot_depth() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_row_pivot_depth; } std::int32_t t_view_config::get_column_pivot_depth() const { + PSP_VERBOSE_ASSERT(m_init, "touching uninited object"); return m_column_pivot_depth; } @@ -233,12 +250,4 @@ t_view_config::get_aggregate_index(const std::string& column) const { return t_index(); } -} // end namespace perspective - -namespace std { -std::ostream& -operator<<(std::ostream& os, const perspective::t_view_config& vc) { - os << "t_view_config"; // TODO: finish - return os; -} -} // end namespace std \ No newline at end of file +} // end namespace perspective \ No newline at end of file diff --git a/cpp/perspective/src/include/perspective/binding.h b/cpp/perspective/src/include/perspective/binding.h index 270d13e563..fed8042f73 100644 --- a/cpp/perspective/src/include/perspective/binding.h +++ b/cpp/perspective/src/include/perspective/binding.h @@ -59,24 +59,9 @@ namespace binding { /****************************************************************************** * - * Data Loading + * Manipulate scalar values */ - /** - * @brief For date/datetime values, is the filter term a valid date? - * - * Otherwise, make sure the filter term is not null/undefined - * - * @tparam T - * @param type - * @param date_parser - * @param filter - * @return true - * @return false - */ - template - bool is_valid_filter(t_dtype type, T date_parser, T filter_term); - /** * @brief Converts a `t_scalar` to a value in the binding language. * @@ -240,6 +225,26 @@ namespace binding { template std::shared_ptr
make_computed_table(std::shared_ptr
table, T computed); + /****************************************************************************** + * + * View API + */ + + /** + * @brief For date/datetime values, is the filter term a valid date? + * + * Otherwise, make sure the filter term is not null/undefined. + * + * @tparam T + * @param type + * @param date_parser + * @param filter + * @return true + * @return false + */ + template + bool is_valid_filter(t_dtype type, T date_parser, T filter_term); + /** * @brief Create a filter by parsing the filter term from the binding language. * @@ -265,41 +270,13 @@ namespace binding { t_view_config make_view_config(const t_schema& schema, T date_parser, T config); /** - * @brief Create a new zero-sided view. + * @brief Create a new view. * - * Zero-sided views have no aggregates applied. + * Zero-sided views have no pivots or aggregates applied. * - * @tparam T - * @param table - * @param name - * @param separator - * @param config - * @param date_parser - * @return std::shared_ptr> - */ - template - std::shared_ptr> make_view_zero(std::shared_ptr
table, std::string name, - std::string separator, T view_config, T date_parser); - - /** - * @brief Create a new one-sided view. + * Views are backed by an underlying `t_ctx_*` object, represented by the `CTX_T` template. * - * One-sided views have one or more `row-pivots` applied, - * - * @tparam T - * @param table - * @param name - * @param separator - * @param config - * @param date_parser - * @return std::shared_ptr> - */ - template - std::shared_ptr> make_view_one(std::shared_ptr
table, std::string name, - std::string separator, T view_config, T date_parser); - - /** - * @brief Create a new two-sided view. + * One-sided views have one or more `row-pivots` applied. * * Two sided views have one or more `row-pivots` and `column-pivots` applied, or they have * one or more `column-pivots` applied without any row pivots, hence the term `column_only`. @@ -310,38 +287,26 @@ namespace binding { * @param separator * @param config * @param date_parser - * @return std::shared_ptr> + * @return std::shared_ptr> */ - template - std::shared_ptr> make_view_two(std::shared_ptr
table, std::string name, + template + std::shared_ptr> make_view(std::shared_ptr
table, std::string name, std::string separator, T view_config, T date_parser); /** - * @brief Create a new zero-sided context. + * @brief Create a new context of type `CTX_T`, which will be one of 3 types: * - * Contexts contain the underlying aggregates, sort specifications, filter terms, and other - * metadata allowing for data manipulation and view creation. + * `t_ctx0`, `t_ctx1`, `t_ctx2`. * - * @return std::shared_ptr - */ - std::shared_ptr make_context_zero(std::shared_ptr
table, - const t_schema& schema, const t_view_config& view_config, std::string name); - - /** - * @brief Create a new one-sided context. * - * @return std::shared_ptr - */ - std::shared_ptr make_context_one(std::shared_ptr
table, - const t_schema& schema, const t_view_config& view_config, std::string name); - - /** - * @brief Create a new two-sided context. + * Contexts contain the underlying aggregates, sort specifications, filter terms, and other + * metadata allowing for data manipulation and view creation. * - * @return std::shared_ptr + * @return std::shared_ptr */ - std::shared_ptr make_context_two(std::shared_ptr
table, - const t_schema& schema, const t_view_config& view_config, std::string name); + template + std::shared_ptr make_context(std::shared_ptr
table, const t_schema& schema, + const t_view_config& view_config, std::string name); /** * @brief Get a slice of data for a single column, serialized to t_val. diff --git a/cpp/perspective/src/include/perspective/view_config.h b/cpp/perspective/src/include/perspective/view_config.h index 8d61096077..e50ec0f003 100644 --- a/cpp/perspective/src/include/perspective/view_config.h +++ b/cpp/perspective/src/include/perspective/view_config.h @@ -41,6 +41,12 @@ class t_view_config { std::vector>> filter, std::vector> sort, std::string filter_op, bool column_only); + /** + * @brief Given a `t_schema` specifying the underlying `Table`'s columns, construct the + * abstractions necessary for the core engine. + * + * @param schema + */ void init(const t_schema& schema); /** @@ -81,6 +87,8 @@ class t_view_config { std::int32_t get_column_pivot_depth() const; private: + bool m_init; + /** * @brief Fill the `m_aggspecs` vector with `t_aggspec` objects which define the view's * aggregate settings. @@ -119,6 +127,13 @@ class t_view_config { */ void fill_sortspec(); + /** + * @brief Given a column name, find its position in `m_aggregate_names`. Used for + * determining sort specifications. + * + * @param column + * @return t_index + */ t_index get_aggregate_index(const std::string& column) const; // containers for primitive data that does not need transformation into abstractions @@ -170,8 +185,4 @@ class t_view_config { */ bool m_column_only; }; -} // end namespace perspective - -namespace std { -std::ostream& operator<<(std::ostream& os, const perspective::t_view_config& vc); -} // end namespace std \ No newline at end of file +} // end namespace perspective \ No newline at end of file diff --git a/packages/perspective/src/js/perspective.js b/packages/perspective/src/js/perspective.js index 993aaac856..24f11c9a70 100644 --- a/packages/perspective/src/js/perspective.js +++ b/packages/perspective/src/js/perspective.js @@ -110,7 +110,7 @@ export default function(Module) { const pool = _Table.get_pool(); const table_id = _Table.get_id(); - console.log(table_id); + if (op == __MODULE__.t_op.OP_UPDATE || op == __MODULE__.t_op.OP_DELETE) { _set_process(pool, table_id); } else {