goby-database 2.2.25 → 2.2.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -811,10 +811,10 @@ export default class Project {
811
811
  var _a, _b, _c, _d, _e;
812
812
  const pagination_defaults = {
813
813
  page_size: null,
814
- property_range: 'all'
814
+ property_range: 'all',
815
+ item_range: 'all'
815
816
  };
816
817
  pagination = Object.assign(Object.assign({}, pagination_defaults), pagination);
817
- const slim = pagination.property_range == 'slim';
818
818
  if (class_name == undefined || class_data == undefined) {
819
819
  class_data = this.lookup_class(class_id);
820
820
  class_name = class_data.name;
@@ -827,66 +827,79 @@ export default class Project {
827
827
  const cte_joins = [];
828
828
  // joined+added between SELECT and FROM, built from relations
829
829
  const relation_selections = [];
830
- // NOTE: in the future, if a property_range is defined, first filter class_data.properties by those IDs
831
- let relation_properties = class_data.properties.filter(a => a.type == 'relation');
832
- if (!slim) {
833
- for (let prop of relation_properties) {
834
- const target_selects = [];
835
- let property_junction_column_name = junction_col_name(class_id, prop.id);
836
- if (prop.relation_targets.length > 0) {
837
- for (let i = 0; i < prop.relation_targets.length; i++) {
838
- // find the side that does not match both the class and prop IDs
839
- let target = prop.relation_targets[i];
840
- const target_class = this.class_cache.find((a) => a.id == (target === null || target === void 0 ? void 0 : target.class_id));
841
- if (target && target_class) {
842
- let target_junction_column_name = junction_col_name(target.class_id, target.prop_id);
843
- // NOTE: as mentioned elsewhere, possibly allow multiple label props
844
- const target_label_id = (_b = (_a = target_class === null || target_class === void 0 ? void 0 : target_class.metadata) === null || _a === void 0 ? void 0 : _a.label) === null || _b === void 0 ? void 0 : _b.properties[0];
845
- const target_label = target_class === null || target_class === void 0 ? void 0 : target_class.properties.find((p) => p.id == target_label_id);
846
- const label_sql_string = target_label ? `,'user_${target_label.name}',target_class."user_${target_label.name}"` : '';
847
- let junction_id = target.junction_id;
848
- let target_select = `
849
- SELECT
850
- "${property_junction_column_name}",
851
- json_object('class_id',${target.class_id},'system_id',junction."${target_junction_column_name}"${label_sql_string}) AS target_data, junction.date_added AS date_added
852
- FROM junction_${junction_id} AS junction
853
- LEFT JOIN "class_${target_class === null || target_class === void 0 ? void 0 : target_class.name}" AS target_class ON junction."${target_junction_column_name}" = target_class.system_id
854
- `;
855
- target_selects.push(target_select);
856
- }
857
- else {
858
- throw Error('Something went wrong trying to retrieve relationship data');
859
- }
830
+ const label_prop_ids = (_b = (_a = class_data.metadata.label) === null || _a === void 0 ? void 0 : _a.properties) !== null && _b !== void 0 ? _b : [];
831
+ // if a property_range is defined, first filter class_data.properties by those IDs
832
+ const retrieved_properties = class_data.properties.filter((prop) => {
833
+ if (pagination.property_range == 'all' || !pagination.property_range) {
834
+ return true;
835
+ }
836
+ else if (pagination.property_range == 'slim') {
837
+ return label_prop_ids.includes(prop.id);
838
+ }
839
+ else if (pagination.property_range.length > 0) {
840
+ return pagination.property_range.includes(prop.id);
841
+ }
842
+ else {
843
+ return true;
844
+ }
845
+ });
846
+ const relation_properties = retrieved_properties.filter(a => a.type == 'relation');
847
+ const data_properties = retrieved_properties.filter(a => a.type == 'data');
848
+ for (let prop of relation_properties) {
849
+ const target_selects = [];
850
+ let property_junction_column_name = junction_col_name(class_id, prop.id);
851
+ if (prop.relation_targets.length > 0) {
852
+ for (let i = 0; i < prop.relation_targets.length; i++) {
853
+ // find the side that does not match both the class and prop IDs
854
+ let target = prop.relation_targets[i];
855
+ const target_class = this.class_cache.find((a) => a.id == (target === null || target === void 0 ? void 0 : target.class_id));
856
+ if (target && target_class) {
857
+ let target_junction_column_name = junction_col_name(target.class_id, target.prop_id);
858
+ // NOTE: as mentioned elsewhere, possibly allow multiple label props
859
+ const target_label_id = (_d = (_c = target_class === null || target_class === void 0 ? void 0 : target_class.metadata) === null || _c === void 0 ? void 0 : _c.label) === null || _d === void 0 ? void 0 : _d.properties[0];
860
+ const target_label = target_class === null || target_class === void 0 ? void 0 : target_class.properties.find((p) => p.id == target_label_id);
861
+ const label_sql_string = target_label ? `,'user_${target_label.name}',target_class."user_${target_label.name}"` : '';
862
+ let junction_id = target.junction_id;
863
+ let target_select = `
864
+ SELECT
865
+ "${property_junction_column_name}",
866
+ json_object('class_id',${target.class_id},'system_id',junction."${target_junction_column_name}"${label_sql_string}) AS target_data, junction.date_added AS date_added
867
+ FROM junction_${junction_id} AS junction
868
+ LEFT JOIN "class_${target_class === null || target_class === void 0 ? void 0 : target_class.name}" AS target_class ON junction."${target_junction_column_name}" = target_class.system_id
869
+ `;
870
+ target_selects.push(target_select);
871
+ }
872
+ else {
873
+ throw Error('Something went wrong trying to retrieve relationship data');
860
874
  }
861
- // uses built-in aggregate json function instead of group_concat craziness
862
- const cte = `[${prop.id}_cte] AS (
863
- SELECT "${property_junction_column_name}", json_group_array( json(target_data) ) AS [user_${prop.name}]
864
- FROM
865
- (
866
- ${target_selects.join(`
867
- UNION
868
- `)}
869
- ORDER BY date_added
870
- )
871
- GROUP BY "${property_junction_column_name}"
872
-
873
- )`;
874
- cte_strings.push(cte);
875
- relation_selections.push(`[${prop.id}_cte].[user_${prop.name}]`);
876
- cte_joins.push(`LEFT JOIN [${prop.id}_cte] ON [${prop.id}_cte]."${property_junction_column_name}" = ${class_string}.system_id`);
877
- }
878
- else {
879
- relation_selections.push(`'[]' AS [user_${prop.name}]`);
880
875
  }
876
+ // uses built-in aggregate json function instead of group_concat craziness
877
+ const cte = `[${prop.id}_cte] AS (
878
+ SELECT "${property_junction_column_name}", json_group_array( json(target_data) ) AS [user_${prop.name}]
879
+ FROM
880
+ (
881
+ ${target_selects.join(`
882
+ UNION
883
+ `)}
884
+ ORDER BY date_added
885
+ )
886
+ GROUP BY "${property_junction_column_name}"
887
+
888
+ )`;
889
+ cte_strings.push(cte);
890
+ relation_selections.push(`[${prop.id}_cte].[user_${prop.name}]`);
891
+ cte_joins.push(`LEFT JOIN [${prop.id}_cte] ON [${prop.id}_cte]."${property_junction_column_name}" = ${class_string}.system_id`);
892
+ }
893
+ else {
894
+ relation_selections.push(`'[]' AS [user_${prop.name}]`);
881
895
  }
882
896
  }
883
897
  let orderby = `ORDER BY ${class_string}.system_order`;
884
- let table_selection = `[class_${class_name}].*`;
885
- if (slim) {
886
- const label_prop_ids = (_d = (_c = class_data.metadata.label) === null || _c === void 0 ? void 0 : _c.properties) !== null && _d !== void 0 ? _d : [];
887
- const label_props = class_data.properties.filter((p) => label_prop_ids.includes(p.id));
888
- const label_prop_sql_string = label_props.map((p) => `[user_${p.name}]`).join(',');
889
- table_selection = `system_id,system_order,${label_prop_sql_string}`;
898
+ const data_prop_sql_string = data_properties.map((p) => `[user_${p.name}]`).join(',');
899
+ const table_selection = pagination.property_range == 'all' ? `[class_${class_name}].*` : `system_id,system_order,${data_prop_sql_string}`;
900
+ let filter_by_items = '';
901
+ if (pagination.item_range && pagination.item_range !== 'all') {
902
+ filter_by_items = `WHERE system_id in (${pagination.item_range.join(',')})`;
890
903
  }
891
904
  let comma_break = `,
892
905
  `;
@@ -895,6 +908,7 @@ export default class Project {
895
908
  SELECT ${table_selection} ${relation_selections.length > 0 ? ', ' + relation_selections.join(`, `) : ''}
896
909
  FROM [class_${class_name}]
897
910
  ${cte_joins.join(' ')}
911
+ ${filter_by_items}
898
912
  ${orderby}`;
899
913
  // possibly elaborate this any type a little more in the future, e.g. a CellValue or SQLCellValue type that expects some wildcards
900
914
  let items = this.db.prepare(query).all();
package/dist/types.d.ts CHANGED
@@ -145,7 +145,10 @@ export type ClassList = ClassData[];
145
145
  export type ItemPagination = {
146
146
  page_size?: number | null;
147
147
  page_range?: [start: number, end?: number];
148
+ /** Filters props by ID. If not specified, pulls all. "slim" pulls the ID and label */
148
149
  property_range?: number[] | 'slim' | 'all';
150
+ /** Filter by item IDs. If not specified, pulls all */
151
+ item_range?: number[] | 'all';
149
152
  };
150
153
  export type PaginatedItems = ItemPagination & {
151
154
  loaded: ClassRow[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goby-database",
3
- "version": "2.2.25",
3
+ "version": "2.2.27",
4
4
  "description": "This will hold the core better-sqlite3-powered application for creating and modifying goby databases",
5
5
  "main": "dist/index.js",
6
6
  "files": [