goby-database 2.2.24 → 2.2.26
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.d.ts +4 -1
- package/dist/index.js +87 -67
- package/dist/types.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -76,7 +76,10 @@ export default class Project {
|
|
|
76
76
|
property_id: number;
|
|
77
77
|
value: any;
|
|
78
78
|
}[]): void;
|
|
79
|
-
|
|
79
|
+
action_edit_relations(relations: {
|
|
80
|
+
change: 'add' | 'remove';
|
|
81
|
+
sides: [input_1: ItemRelationSide, input_2: ItemRelationSide];
|
|
82
|
+
}[]): void;
|
|
80
83
|
retrieve_class_items({ class_id, class_name, class_data, pagination }: {
|
|
81
84
|
class_id: number;
|
|
82
85
|
class_name?: string;
|
package/dist/index.js
CHANGED
|
@@ -772,24 +772,33 @@ export default class Project {
|
|
|
772
772
|
};
|
|
773
773
|
}
|
|
774
774
|
}
|
|
775
|
-
|
|
775
|
+
action_edit_relations(relations) {
|
|
776
776
|
// NOTE: changes to make to this in the future:
|
|
777
777
|
// - for input readability, allow class_name and prop_name as input options, assuming they’re enforced as unique, and use them to look up IDs
|
|
778
778
|
// - enforce max_values here
|
|
779
779
|
var _a;
|
|
780
|
-
for (let
|
|
781
|
-
|
|
780
|
+
for (let { change, sides } of relations) {
|
|
781
|
+
const [input_1, input_2] = sides;
|
|
782
|
+
const column_names = {
|
|
782
783
|
input_1: junction_col_name(input_1.class_id, input_1.prop_id),
|
|
783
784
|
input_2: junction_col_name(input_2.class_id, input_2.prop_id)
|
|
784
785
|
};
|
|
785
|
-
|
|
786
|
-
const date_added = Date.now();
|
|
786
|
+
const junction_id = (_a = this.junction_cache.find(j => full_relation_match(j.sides, [input_1, input_2]))) === null || _a === void 0 ? void 0 : _a.id;
|
|
787
787
|
if (junction_id) {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
788
|
+
if (change == 'add') {
|
|
789
|
+
const date_added = Date.now();
|
|
790
|
+
this.db.prepare(`
|
|
791
|
+
INSERT INTO junction_${junction_id}
|
|
792
|
+
("${column_names.input_1}", "${column_names.input_2}",date_added)
|
|
793
|
+
VALUES (${input_1.item_id},${input_2.item_id},${date_added})
|
|
794
|
+
`).run();
|
|
795
|
+
}
|
|
796
|
+
else if (change == 'remove') {
|
|
797
|
+
this.db.prepare(`
|
|
798
|
+
DELETE FROM junction_${junction_id}
|
|
799
|
+
WHERE "${column_names.input_1}" = ${input_1.item_id}
|
|
800
|
+
AND "${column_names.input_2}" = ${input_2.item_id}`).run();
|
|
801
|
+
}
|
|
793
802
|
}
|
|
794
803
|
else {
|
|
795
804
|
throw Error('Something went wrong - junction table for relationship not found');
|
|
@@ -802,10 +811,10 @@ export default class Project {
|
|
|
802
811
|
var _a, _b, _c, _d, _e;
|
|
803
812
|
const pagination_defaults = {
|
|
804
813
|
page_size: null,
|
|
805
|
-
property_range: 'all'
|
|
814
|
+
property_range: 'all',
|
|
815
|
+
item_range: 'all'
|
|
806
816
|
};
|
|
807
817
|
pagination = Object.assign(Object.assign({}, pagination_defaults), pagination);
|
|
808
|
-
const slim = pagination.property_range == 'slim';
|
|
809
818
|
if (class_name == undefined || class_data == undefined) {
|
|
810
819
|
class_data = this.lookup_class(class_id);
|
|
811
820
|
class_name = class_data.name;
|
|
@@ -818,66 +827,76 @@ export default class Project {
|
|
|
818
827
|
const cte_joins = [];
|
|
819
828
|
// joined+added between SELECT and FROM, built from relations
|
|
820
829
|
const relation_selections = [];
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
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 {
|
|
840
|
+
return pagination.property_range.includes(prop.id);
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
const relation_properties = retrieved_properties.filter(a => a.type == 'relation');
|
|
844
|
+
const data_properties = retrieved_properties.filter(a => a.type == 'data');
|
|
845
|
+
for (let prop of relation_properties) {
|
|
846
|
+
const target_selects = [];
|
|
847
|
+
let property_junction_column_name = junction_col_name(class_id, prop.id);
|
|
848
|
+
if (prop.relation_targets.length > 0) {
|
|
849
|
+
for (let i = 0; i < prop.relation_targets.length; i++) {
|
|
850
|
+
// find the side that does not match both the class and prop IDs
|
|
851
|
+
let target = prop.relation_targets[i];
|
|
852
|
+
const target_class = this.class_cache.find((a) => a.id == (target === null || target === void 0 ? void 0 : target.class_id));
|
|
853
|
+
if (target && target_class) {
|
|
854
|
+
let target_junction_column_name = junction_col_name(target.class_id, target.prop_id);
|
|
855
|
+
// NOTE: as mentioned elsewhere, possibly allow multiple label props
|
|
856
|
+
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];
|
|
857
|
+
const target_label = target_class === null || target_class === void 0 ? void 0 : target_class.properties.find((p) => p.id == target_label_id);
|
|
858
|
+
const label_sql_string = target_label ? `,'user_${target_label.name}',target_class."user_${target_label.name}"` : '';
|
|
859
|
+
let junction_id = target.junction_id;
|
|
860
|
+
let target_select = `
|
|
861
|
+
SELECT
|
|
862
|
+
"${property_junction_column_name}",
|
|
863
|
+
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
|
|
864
|
+
FROM junction_${junction_id} AS junction
|
|
865
|
+
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
|
|
866
|
+
`;
|
|
867
|
+
target_selects.push(target_select);
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
throw Error('Something went wrong trying to retrieve relationship data');
|
|
851
871
|
}
|
|
852
|
-
// uses built-in aggregate json function instead of group_concat craziness
|
|
853
|
-
const cte = `[${prop.id}_cte] AS (
|
|
854
|
-
SELECT "${property_junction_column_name}", json_group_array( json(target_data) ) AS [user_${prop.name}]
|
|
855
|
-
FROM
|
|
856
|
-
(
|
|
857
|
-
${target_selects.join(`
|
|
858
|
-
UNION
|
|
859
|
-
`)}
|
|
860
|
-
ORDER BY date_added
|
|
861
|
-
)
|
|
862
|
-
GROUP BY "${property_junction_column_name}"
|
|
863
|
-
|
|
864
|
-
)`;
|
|
865
|
-
cte_strings.push(cte);
|
|
866
|
-
relation_selections.push(`[${prop.id}_cte].[user_${prop.name}]`);
|
|
867
|
-
cte_joins.push(`LEFT JOIN [${prop.id}_cte] ON [${prop.id}_cte]."${property_junction_column_name}" = ${class_string}.system_id`);
|
|
868
|
-
}
|
|
869
|
-
else {
|
|
870
|
-
relation_selections.push(`'[]' AS [user_${prop.name}]`);
|
|
871
872
|
}
|
|
873
|
+
// uses built-in aggregate json function instead of group_concat craziness
|
|
874
|
+
const cte = `[${prop.id}_cte] AS (
|
|
875
|
+
SELECT "${property_junction_column_name}", json_group_array( json(target_data) ) AS [user_${prop.name}]
|
|
876
|
+
FROM
|
|
877
|
+
(
|
|
878
|
+
${target_selects.join(`
|
|
879
|
+
UNION
|
|
880
|
+
`)}
|
|
881
|
+
ORDER BY date_added
|
|
882
|
+
)
|
|
883
|
+
GROUP BY "${property_junction_column_name}"
|
|
884
|
+
|
|
885
|
+
)`;
|
|
886
|
+
cte_strings.push(cte);
|
|
887
|
+
relation_selections.push(`[${prop.id}_cte].[user_${prop.name}]`);
|
|
888
|
+
cte_joins.push(`LEFT JOIN [${prop.id}_cte] ON [${prop.id}_cte]."${property_junction_column_name}" = ${class_string}.system_id`);
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
relation_selections.push(`'[]' AS [user_${prop.name}]`);
|
|
872
892
|
}
|
|
873
893
|
}
|
|
874
894
|
let orderby = `ORDER BY ${class_string}.system_order`;
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
table_selection = `system_id,system_order,${label_prop_sql_string}`;
|
|
895
|
+
const data_prop_sql_string = data_properties.map((p) => `[user_${p.name}]`).join(',');
|
|
896
|
+
const table_selection = pagination.property_range == 'all' ? `[class_${class_name}].*` : `system_id,system_order,${data_prop_sql_string}`;
|
|
897
|
+
let filter_by_items = '';
|
|
898
|
+
if (pagination.item_range && pagination.item_range !== 'all') {
|
|
899
|
+
filter_by_items = `WHERE system_id in (${pagination.item_range.join(',')})`;
|
|
881
900
|
}
|
|
882
901
|
let comma_break = `,
|
|
883
902
|
`;
|
|
@@ -886,6 +905,7 @@ export default class Project {
|
|
|
886
905
|
SELECT ${table_selection} ${relation_selections.length > 0 ? ', ' + relation_selections.join(`, `) : ''}
|
|
887
906
|
FROM [class_${class_name}]
|
|
888
907
|
${cte_joins.join(' ')}
|
|
908
|
+
${filter_by_items}
|
|
889
909
|
${orderby}`;
|
|
890
910
|
// possibly elaborate this any type a little more in the future, e.g. a CellValue or SQLCellValue type that expects some wildcards
|
|
891
911
|
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[];
|