@snowtop/ent 0.1.0-alpha138 → 0.1.0-alpha139
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/action/action.d.ts +8 -1
- package/action/executor.d.ts +16 -3
- package/action/executor.js +67 -12
- package/action/index.d.ts +1 -1
- package/action/operations.d.ts +125 -0
- package/action/operations.js +684 -0
- package/action/orchestrator.d.ts +13 -7
- package/action/orchestrator.js +109 -42
- package/core/base.d.ts +7 -1
- package/core/db.js +2 -0
- package/core/ent.d.ts +1 -84
- package/core/ent.js +20 -509
- package/index.d.ts +2 -1
- package/index.js +7 -5
- package/package.json +2 -2
- package/parse_schema/parse.js +1 -0
- package/schema/base_schema.d.ts +2 -0
- package/schema/base_schema.js +2 -0
- package/schema/schema.d.ts +2 -1
- package/testutils/action/complex_schemas.d.ts +1 -1
- package/testutils/builder.d.ts +3 -0
- package/testutils/builder.js +6 -0
- package/testutils/db/temp_db.d.ts +2 -1
- package/testutils/db/temp_db.js +41 -5
package/core/ent.js
CHANGED
|
@@ -26,15 +26,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadCustomEdges = exports.getEdgeClauseAndFields = exports.loadEdges = exports.DefaultLimit = exports.loadEdgeDatas = exports.loadEdgeData = exports.assocEdgeLoader = exports.AssocEdgeData = exports.getCursor = exports.AssocEdge = exports.
|
|
30
|
-
exports.getEdgeTypeInGroup = exports.applyPrivacyPolicyForRows = exports.applyPrivacyPolicyForRow = void 0;
|
|
29
|
+
exports.getEdgeTypeInGroup = exports.applyPrivacyPolicyForRows = exports.applyPrivacyPolicyForRow = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadCustomEdges = exports.getEdgeClauseAndFields = exports.loadEdges = exports.DefaultLimit = exports.loadEdgeDatas = exports.loadEdgeData = exports.assocEdgeLoader = exports.AssocEdgeData = exports.getCursor = exports.AssocEdge = exports.deleteRowsSync = exports.deleteRows = exports.editRowSync = exports.editRow = exports.buildUpdateQuery = exports.createRowSync = exports.createRow = exports.buildInsertQuery = exports.buildGroupQuery = exports.buildQuery = exports.loadRows = exports.performRawQuery = exports.___setLogQueryErrorWithError = exports.loadRow = exports.loadRowX = exports.logQuery = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadCustomCount = exports.loadCustomData = exports.loadCustomEnts = exports.loadEntsFromClause = exports.loadEntsList = exports.loadEnts = exports.loadEntXFromClause = exports.loadEntFromClause = exports.loadEntXViaKey = exports.loadEntX = exports.loadEntViaKey = exports.loadEnt = exports.getEntKey = void 0;
|
|
31
30
|
const db_1 = __importStar(require("./db"));
|
|
32
31
|
const privacy_1 = require("./privacy");
|
|
33
32
|
const clause = __importStar(require("./clause"));
|
|
34
|
-
const action_1 = require("../action");
|
|
35
33
|
const logger_1 = require("./logger");
|
|
36
34
|
const dataloader_1 = __importDefault(require("dataloader"));
|
|
37
|
-
const schema_1 = require("../schema/schema");
|
|
38
35
|
const global_schema_1 = require("./global_schema");
|
|
39
36
|
// TODO kill this and createDataLoader
|
|
40
37
|
class cacheMap {
|
|
@@ -661,489 +658,6 @@ function buildGroupQuery(options) {
|
|
|
661
658
|
];
|
|
662
659
|
}
|
|
663
660
|
exports.buildGroupQuery = buildGroupQuery;
|
|
664
|
-
class RawQueryOperation {
|
|
665
|
-
constructor(queries) {
|
|
666
|
-
this.queries = queries;
|
|
667
|
-
}
|
|
668
|
-
async performWrite(queryer, context) {
|
|
669
|
-
for (const q of this.queries) {
|
|
670
|
-
if (typeof q === "string") {
|
|
671
|
-
logQuery(q, []);
|
|
672
|
-
await queryer.query(q);
|
|
673
|
-
}
|
|
674
|
-
else {
|
|
675
|
-
logQuery(q.query, q.logValues || []);
|
|
676
|
-
await queryer.query(q.query, q.values);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
performWriteSync(queryer, context) {
|
|
681
|
-
for (const q of this.queries) {
|
|
682
|
-
if (typeof q === "string") {
|
|
683
|
-
logQuery(q, []);
|
|
684
|
-
queryer.execSync(q);
|
|
685
|
-
}
|
|
686
|
-
else {
|
|
687
|
-
logQuery(q.query, q.logValues || []);
|
|
688
|
-
queryer.execSync(q.query, q.values);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
exports.RawQueryOperation = RawQueryOperation;
|
|
694
|
-
class EditNodeOperation {
|
|
695
|
-
constructor(options, existingEnt = null) {
|
|
696
|
-
this.options = options;
|
|
697
|
-
this.existingEnt = existingEnt;
|
|
698
|
-
this.row = null;
|
|
699
|
-
this.placeholderID = options.placeholderID;
|
|
700
|
-
}
|
|
701
|
-
resolve(executor) {
|
|
702
|
-
if (!this.options.fieldsToResolve.length) {
|
|
703
|
-
return;
|
|
704
|
-
}
|
|
705
|
-
let fields = this.options.fields;
|
|
706
|
-
this.options.fieldsToResolve.forEach((fieldName) => {
|
|
707
|
-
let value = fields[fieldName];
|
|
708
|
-
if (!value) {
|
|
709
|
-
throw new Error(`trying to resolve field ${fieldName} but not a valid field`);
|
|
710
|
-
}
|
|
711
|
-
let ent = executor.resolveValue(value.placeholderID);
|
|
712
|
-
if (!ent) {
|
|
713
|
-
throw new Error(`couldn't resolve field \`${fieldName}\` with value ${value.placeholderID}`);
|
|
714
|
-
}
|
|
715
|
-
fields[fieldName] = ent.id;
|
|
716
|
-
});
|
|
717
|
-
this.options.fields = fields;
|
|
718
|
-
}
|
|
719
|
-
hasData(data) {
|
|
720
|
-
for (const _k in data) {
|
|
721
|
-
return true;
|
|
722
|
-
}
|
|
723
|
-
return false;
|
|
724
|
-
}
|
|
725
|
-
async performWrite(queryer, context) {
|
|
726
|
-
let options = {
|
|
727
|
-
...this.options,
|
|
728
|
-
context,
|
|
729
|
-
};
|
|
730
|
-
if (this.existingEnt) {
|
|
731
|
-
if (this.hasData(options.fields)) {
|
|
732
|
-
// even this with returning * may not always work if transformed...
|
|
733
|
-
// we can have a transformed flag to see if it should be returned?
|
|
734
|
-
this.row = await editRow(queryer, options, "RETURNING *");
|
|
735
|
-
}
|
|
736
|
-
else {
|
|
737
|
-
// @ts-ignore
|
|
738
|
-
this.row = this.existingEnt["data"];
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
else {
|
|
742
|
-
this.row = await createRow(queryer, options, "RETURNING *");
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
reloadRow(queryer, id, options) {
|
|
746
|
-
// TODO this isn't always an ObjectLoader. should throw or figure out a way to get query
|
|
747
|
-
// and run this on its own...
|
|
748
|
-
const loader = this.options.loadEntOptions.loaderFactory.createLoader(options.context);
|
|
749
|
-
const opts = loader.getOptions();
|
|
750
|
-
let cls = clause.Eq(options.key, id);
|
|
751
|
-
if (opts.clause) {
|
|
752
|
-
let optionClause;
|
|
753
|
-
if (typeof opts.clause === "function") {
|
|
754
|
-
optionClause = opts.clause();
|
|
755
|
-
}
|
|
756
|
-
else {
|
|
757
|
-
optionClause = opts.clause;
|
|
758
|
-
}
|
|
759
|
-
if (optionClause) {
|
|
760
|
-
// @ts-expect-error ID|string mismatch
|
|
761
|
-
cls = clause.And(cls, optionClause);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
const query = buildQuery({
|
|
765
|
-
fields: opts.fields.length ? opts.fields : ["*"],
|
|
766
|
-
tableName: options.tableName,
|
|
767
|
-
clause: cls,
|
|
768
|
-
});
|
|
769
|
-
// special case log here because we're not going through any of the normal
|
|
770
|
-
// methods here because those are async and this is sync
|
|
771
|
-
// this is the only place we're doing this so only handling here
|
|
772
|
-
logQuery(query, [id]);
|
|
773
|
-
const r = queryer.querySync(query, [id]);
|
|
774
|
-
if (r.rows.length === 1) {
|
|
775
|
-
this.row = r.rows[0];
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
performWriteSync(queryer, context) {
|
|
779
|
-
let options = {
|
|
780
|
-
...this.options,
|
|
781
|
-
context,
|
|
782
|
-
};
|
|
783
|
-
if (this.existingEnt) {
|
|
784
|
-
if (this.hasData(this.options.fields)) {
|
|
785
|
-
editRowSync(queryer, options, "RETURNING *");
|
|
786
|
-
this.reloadRow(queryer, this.existingEnt.id, options);
|
|
787
|
-
}
|
|
788
|
-
else {
|
|
789
|
-
// @ts-ignore
|
|
790
|
-
this.row = this.existingEnt["data"];
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
else {
|
|
794
|
-
createRowSync(queryer, options, "RETURNING *");
|
|
795
|
-
const id = options.fields[options.key];
|
|
796
|
-
this.reloadRow(queryer, id, options);
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
returnedRow() {
|
|
800
|
-
return this.row;
|
|
801
|
-
}
|
|
802
|
-
createdEnt(viewer) {
|
|
803
|
-
if (!this.row) {
|
|
804
|
-
return null;
|
|
805
|
-
}
|
|
806
|
-
return new this.options.loadEntOptions.ent(viewer, this.row);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
exports.EditNodeOperation = EditNodeOperation;
|
|
810
|
-
class EdgeOperation {
|
|
811
|
-
constructor(builder, edgeInput, options) {
|
|
812
|
-
this.builder = builder;
|
|
813
|
-
this.edgeInput = edgeInput;
|
|
814
|
-
this.options = options;
|
|
815
|
-
}
|
|
816
|
-
async preFetch(queryer, context) {
|
|
817
|
-
let edgeData = await loadEdgeData(this.edgeInput.edgeType);
|
|
818
|
-
if (!edgeData) {
|
|
819
|
-
throw new Error(`error loading edge data for ${this.edgeInput.edgeType}`);
|
|
820
|
-
}
|
|
821
|
-
this.edgeData = edgeData;
|
|
822
|
-
}
|
|
823
|
-
async performWrite(queryer, context) {
|
|
824
|
-
if (!this.edgeData) {
|
|
825
|
-
throw new Error(`error fetching edgeData for type ${this.edgeInput.edgeType}`);
|
|
826
|
-
}
|
|
827
|
-
switch (this.options.operation) {
|
|
828
|
-
case action_1.WriteOperation.Delete:
|
|
829
|
-
return this.performDeleteWrite(queryer, this.edgeData, this.edgeInput, context);
|
|
830
|
-
case action_1.WriteOperation.Insert:
|
|
831
|
-
case action_1.WriteOperation.Edit:
|
|
832
|
-
return this.performInsertWrite(queryer, this.edgeData, this.edgeInput, context);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
performWriteSync(queryer, context) {
|
|
836
|
-
if (!this.edgeData) {
|
|
837
|
-
throw new Error(`error fetching edgeData for type ${this.edgeInput.edgeType}`);
|
|
838
|
-
}
|
|
839
|
-
switch (this.options.operation) {
|
|
840
|
-
case action_1.WriteOperation.Delete:
|
|
841
|
-
return this.performDeleteWriteSync(queryer, this.edgeData, this.edgeInput, context);
|
|
842
|
-
case action_1.WriteOperation.Insert:
|
|
843
|
-
case action_1.WriteOperation.Edit:
|
|
844
|
-
return this.performInsertWriteSync(queryer, this.edgeData, this.edgeInput, context);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
getDeleteRowParams(edgeData, edge, context) {
|
|
848
|
-
let transformed = null;
|
|
849
|
-
let op = schema_1.SQLStatementOperation.Delete;
|
|
850
|
-
let updateData = null;
|
|
851
|
-
// TODO respect disableTransformations
|
|
852
|
-
const transformedEdgeWrite = (0, global_schema_1.__getGlobalSchema)()?.transformEdgeWrite;
|
|
853
|
-
if (transformedEdgeWrite) {
|
|
854
|
-
transformed = transformedEdgeWrite({
|
|
855
|
-
op: schema_1.SQLStatementOperation.Delete,
|
|
856
|
-
edge,
|
|
857
|
-
});
|
|
858
|
-
if (transformed) {
|
|
859
|
-
op = transformed.op;
|
|
860
|
-
if (transformed.op === schema_1.SQLStatementOperation.Insert) {
|
|
861
|
-
throw new Error(`cannot currently transform a delete into an insert`);
|
|
862
|
-
}
|
|
863
|
-
if (transformed.op === schema_1.SQLStatementOperation.Update) {
|
|
864
|
-
if (!transformed.data) {
|
|
865
|
-
throw new Error(`cannot transform a delete into an update without providing data`);
|
|
866
|
-
}
|
|
867
|
-
updateData = transformed.data;
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
return {
|
|
872
|
-
op,
|
|
873
|
-
updateData,
|
|
874
|
-
options: {
|
|
875
|
-
tableName: edgeData.edgeTable,
|
|
876
|
-
context,
|
|
877
|
-
},
|
|
878
|
-
clause: clause.And(clause.Eq("id1", edge.id1), clause.Eq("id2", edge.id2), clause.Eq("edge_type", edge.edgeType)),
|
|
879
|
-
};
|
|
880
|
-
}
|
|
881
|
-
async performDeleteWrite(q, edgeData, edge, context) {
|
|
882
|
-
const params = this.getDeleteRowParams(edgeData, edge, context);
|
|
883
|
-
if (params.op === schema_1.SQLStatementOperation.Delete) {
|
|
884
|
-
return deleteRows(q, params.options, params.clause);
|
|
885
|
-
}
|
|
886
|
-
else {
|
|
887
|
-
if (params.op !== schema_1.SQLStatementOperation.Update) {
|
|
888
|
-
throw new Error(`invalid operation ${params.op}`);
|
|
889
|
-
}
|
|
890
|
-
await editRow(q, {
|
|
891
|
-
tableName: params.options.tableName,
|
|
892
|
-
whereClause: params.clause,
|
|
893
|
-
fields: params.updateData,
|
|
894
|
-
fieldsToLog: params.updateData,
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
performDeleteWriteSync(q, edgeData, edge, context) {
|
|
899
|
-
const params = this.getDeleteRowParams(edgeData, edge, context);
|
|
900
|
-
if (params.op === schema_1.SQLStatementOperation.Delete) {
|
|
901
|
-
return deleteRowsSync(q, params.options, params.clause);
|
|
902
|
-
}
|
|
903
|
-
else {
|
|
904
|
-
if (params.op !== schema_1.SQLStatementOperation.Update) {
|
|
905
|
-
throw new Error(`invalid operation ${params.op}`);
|
|
906
|
-
}
|
|
907
|
-
editRowSync(q, {
|
|
908
|
-
tableName: params.options.tableName,
|
|
909
|
-
whereClause: params.clause,
|
|
910
|
-
fields: params.updateData,
|
|
911
|
-
});
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
getInsertRowParams(edgeData, edge, context) {
|
|
915
|
-
const fields = {
|
|
916
|
-
id1: edge.id1,
|
|
917
|
-
id2: edge.id2,
|
|
918
|
-
id1_type: edge.id1Type,
|
|
919
|
-
id2_type: edge.id2Type,
|
|
920
|
-
edge_type: edge.edgeType,
|
|
921
|
-
data: edge.data || null,
|
|
922
|
-
};
|
|
923
|
-
if (edge.time) {
|
|
924
|
-
fields["time"] = edge.time.toISOString();
|
|
925
|
-
}
|
|
926
|
-
else {
|
|
927
|
-
// todo make this a schema field like what we do in generated base files...
|
|
928
|
-
// maybe when actions exist?
|
|
929
|
-
fields["time"] = new Date().toISOString();
|
|
930
|
-
}
|
|
931
|
-
const onConflictFields = ["data"];
|
|
932
|
-
const extraEdgeFields = (0, global_schema_1.__getGlobalSchema)()?.extraEdgeFields;
|
|
933
|
-
if (extraEdgeFields) {
|
|
934
|
-
for (const name in extraEdgeFields) {
|
|
935
|
-
const f = extraEdgeFields[name];
|
|
936
|
-
if (f.defaultValueOnCreate) {
|
|
937
|
-
const storageKey = (0, schema_1.getStorageKey)(f, name);
|
|
938
|
-
fields[storageKey] = f.defaultValueOnCreate(this.builder, {});
|
|
939
|
-
// onconflict make sure we override the default values
|
|
940
|
-
// e.g. setting deleted_at = null for soft delete
|
|
941
|
-
onConflictFields.push(storageKey);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
// TODO respect disableTransformations
|
|
946
|
-
let transformed = null;
|
|
947
|
-
const transformEdgeWrite = (0, global_schema_1.__getGlobalSchema)()?.transformEdgeWrite;
|
|
948
|
-
if (transformEdgeWrite) {
|
|
949
|
-
transformed = transformEdgeWrite({
|
|
950
|
-
op: schema_1.SQLStatementOperation.Insert,
|
|
951
|
-
edge,
|
|
952
|
-
});
|
|
953
|
-
if (transformed) {
|
|
954
|
-
throw new Error(`transforming an insert edge not currently supported`);
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
return [
|
|
958
|
-
{
|
|
959
|
-
tableName: edgeData.edgeTable,
|
|
960
|
-
fields: fields,
|
|
961
|
-
fieldsToLog: fields,
|
|
962
|
-
context,
|
|
963
|
-
},
|
|
964
|
-
`ON CONFLICT(id1, edge_type, id2) DO UPDATE SET ${onConflictFields
|
|
965
|
-
.map((f) => `${f} = EXCLUDED.${f}`)
|
|
966
|
-
.join(", ")}`,
|
|
967
|
-
];
|
|
968
|
-
}
|
|
969
|
-
async performInsertWrite(q, edgeData, edge, context) {
|
|
970
|
-
const [options, suffix] = this.getInsertRowParams(edgeData, edge, context);
|
|
971
|
-
await createRow(q, options, suffix);
|
|
972
|
-
}
|
|
973
|
-
performInsertWriteSync(q, edgeData, edge, context) {
|
|
974
|
-
const [options, suffix] = this.getInsertRowParams(edgeData, edge, context);
|
|
975
|
-
createRowSync(q, options, suffix);
|
|
976
|
-
}
|
|
977
|
-
resolveImpl(executor, placeholder, desc) {
|
|
978
|
-
let ent = executor.resolveValue(placeholder);
|
|
979
|
-
if (!ent) {
|
|
980
|
-
throw new Error(`could not resolve placeholder value ${placeholder} for ${desc} for edge ${this.edgeInput.edgeType}`);
|
|
981
|
-
}
|
|
982
|
-
if (ent.id === undefined) {
|
|
983
|
-
throw new Error(`id of resolved ent is not defined`);
|
|
984
|
-
}
|
|
985
|
-
return [ent.id, ent.nodeType];
|
|
986
|
-
}
|
|
987
|
-
resolve(executor) {
|
|
988
|
-
if (this.options.id1Placeholder) {
|
|
989
|
-
[this.edgeInput.id1, this.edgeInput.id1Type] = this.resolveImpl(executor, this.edgeInput.id1, "id1");
|
|
990
|
-
}
|
|
991
|
-
if (this.options.id2Placeholder) {
|
|
992
|
-
[this.edgeInput.id2, this.edgeInput.id2Type] = this.resolveImpl(executor, this.edgeInput.id2, "id2");
|
|
993
|
-
}
|
|
994
|
-
if (this.options.dataPlaceholder) {
|
|
995
|
-
if (!this.edgeInput.data) {
|
|
996
|
-
throw new Error(`data placeholder set but edgeInput data undefined`);
|
|
997
|
-
}
|
|
998
|
-
let [data, _] = this.resolveImpl(executor, this.edgeInput.data.toString(), "data");
|
|
999
|
-
this.edgeInput.data = data.toString();
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
symmetricEdge() {
|
|
1003
|
-
return new EdgeOperation(this.builder, {
|
|
1004
|
-
id1: this.edgeInput.id2,
|
|
1005
|
-
id1Type: this.edgeInput.id2Type,
|
|
1006
|
-
id2: this.edgeInput.id1,
|
|
1007
|
-
id2Type: this.edgeInput.id1Type,
|
|
1008
|
-
edgeType: this.edgeInput.edgeType,
|
|
1009
|
-
time: this.edgeInput.time,
|
|
1010
|
-
data: this.edgeInput.data,
|
|
1011
|
-
}, {
|
|
1012
|
-
operation: this.options.operation,
|
|
1013
|
-
id1Placeholder: this.options.id2Placeholder,
|
|
1014
|
-
id2Placeholder: this.options.id1Placeholder,
|
|
1015
|
-
dataPlaceholder: this.options.dataPlaceholder,
|
|
1016
|
-
});
|
|
1017
|
-
}
|
|
1018
|
-
inverseEdge(edgeData) {
|
|
1019
|
-
return new EdgeOperation(this.builder, {
|
|
1020
|
-
id1: this.edgeInput.id2,
|
|
1021
|
-
id1Type: this.edgeInput.id2Type,
|
|
1022
|
-
id2: this.edgeInput.id1,
|
|
1023
|
-
id2Type: this.edgeInput.id1Type,
|
|
1024
|
-
edgeType: edgeData.inverseEdgeType,
|
|
1025
|
-
time: this.edgeInput.time,
|
|
1026
|
-
data: this.edgeInput.data,
|
|
1027
|
-
}, {
|
|
1028
|
-
operation: this.options.operation,
|
|
1029
|
-
id1Placeholder: this.options.id2Placeholder,
|
|
1030
|
-
id2Placeholder: this.options.id1Placeholder,
|
|
1031
|
-
dataPlaceholder: this.options.dataPlaceholder,
|
|
1032
|
-
});
|
|
1033
|
-
}
|
|
1034
|
-
static resolveIDs(srcBuilder, // id1
|
|
1035
|
-
destID) {
|
|
1036
|
-
let destIDVal;
|
|
1037
|
-
let destPlaceholder = false;
|
|
1038
|
-
if (this.isBuilder(destID)) {
|
|
1039
|
-
destIDVal = destID.placeholderID;
|
|
1040
|
-
destPlaceholder = true;
|
|
1041
|
-
}
|
|
1042
|
-
else {
|
|
1043
|
-
destIDVal = destID;
|
|
1044
|
-
}
|
|
1045
|
-
let srcIDVal;
|
|
1046
|
-
let srcType;
|
|
1047
|
-
let srcPlaceholder = false;
|
|
1048
|
-
if (srcBuilder.existingEnt) {
|
|
1049
|
-
srcIDVal = srcBuilder.existingEnt.id;
|
|
1050
|
-
srcType = srcBuilder.existingEnt.nodeType;
|
|
1051
|
-
}
|
|
1052
|
-
else {
|
|
1053
|
-
srcPlaceholder = true;
|
|
1054
|
-
// get placeholder.
|
|
1055
|
-
srcIDVal = srcBuilder.placeholderID;
|
|
1056
|
-
// expected to be filled later
|
|
1057
|
-
srcType = "";
|
|
1058
|
-
}
|
|
1059
|
-
return [srcIDVal, srcType, srcPlaceholder, destIDVal, destPlaceholder];
|
|
1060
|
-
}
|
|
1061
|
-
static isBuilder(val) {
|
|
1062
|
-
return val.placeholderID !== undefined;
|
|
1063
|
-
}
|
|
1064
|
-
static resolveData(data) {
|
|
1065
|
-
if (!data) {
|
|
1066
|
-
return [undefined, false];
|
|
1067
|
-
}
|
|
1068
|
-
if (this.isBuilder(data)) {
|
|
1069
|
-
return [data.placeholderID.toString(), true];
|
|
1070
|
-
}
|
|
1071
|
-
return [data, false];
|
|
1072
|
-
}
|
|
1073
|
-
static inboundEdge(builder, edgeType, id1, nodeType, options) {
|
|
1074
|
-
let [id2Val, id2Type, id2Placeholder, id1Val, id1Placeholder] = EdgeOperation.resolveIDs(builder, id1);
|
|
1075
|
-
let [data, dataPlaceholder] = EdgeOperation.resolveData(options?.data);
|
|
1076
|
-
const edge = {
|
|
1077
|
-
id1: id1Val,
|
|
1078
|
-
edgeType: edgeType,
|
|
1079
|
-
id2: id2Val,
|
|
1080
|
-
id2Type: id2Type,
|
|
1081
|
-
id1Type: nodeType,
|
|
1082
|
-
...options,
|
|
1083
|
-
};
|
|
1084
|
-
if (data) {
|
|
1085
|
-
edge.data = data;
|
|
1086
|
-
}
|
|
1087
|
-
return new EdgeOperation(builder, edge, {
|
|
1088
|
-
operation: action_1.WriteOperation.Insert,
|
|
1089
|
-
id2Placeholder,
|
|
1090
|
-
id1Placeholder,
|
|
1091
|
-
dataPlaceholder,
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
static outboundEdge(builder, edgeType, id2, nodeType, options) {
|
|
1095
|
-
let [id1Val, id1Type, id1Placeholder, id2Val, id2Placeholder] = EdgeOperation.resolveIDs(builder, id2);
|
|
1096
|
-
let [data, dataPlaceholder] = EdgeOperation.resolveData(options?.data);
|
|
1097
|
-
const edge = {
|
|
1098
|
-
id1: id1Val,
|
|
1099
|
-
edgeType: edgeType,
|
|
1100
|
-
id2: id2Val,
|
|
1101
|
-
id2Type: nodeType,
|
|
1102
|
-
id1Type: id1Type,
|
|
1103
|
-
...options,
|
|
1104
|
-
};
|
|
1105
|
-
if (data) {
|
|
1106
|
-
edge.data = data;
|
|
1107
|
-
}
|
|
1108
|
-
return new EdgeOperation(builder, edge, {
|
|
1109
|
-
operation: action_1.WriteOperation.Insert,
|
|
1110
|
-
id1Placeholder,
|
|
1111
|
-
id2Placeholder,
|
|
1112
|
-
dataPlaceholder,
|
|
1113
|
-
});
|
|
1114
|
-
}
|
|
1115
|
-
static removeInboundEdge(builder, edgeType, id1) {
|
|
1116
|
-
if (!builder.existingEnt) {
|
|
1117
|
-
throw new Error("cannot remove an edge from a non-existing ent");
|
|
1118
|
-
}
|
|
1119
|
-
const edge = {
|
|
1120
|
-
id1: id1,
|
|
1121
|
-
edgeType: edgeType,
|
|
1122
|
-
id2: builder.existingEnt.id,
|
|
1123
|
-
id2Type: "",
|
|
1124
|
-
id1Type: "",
|
|
1125
|
-
};
|
|
1126
|
-
return new EdgeOperation(builder, edge, {
|
|
1127
|
-
operation: action_1.WriteOperation.Delete,
|
|
1128
|
-
});
|
|
1129
|
-
}
|
|
1130
|
-
static removeOutboundEdge(builder, edgeType, id2) {
|
|
1131
|
-
if (!builder.existingEnt) {
|
|
1132
|
-
throw new Error("cannot remove an edge from a non-existing ent");
|
|
1133
|
-
}
|
|
1134
|
-
const edge = {
|
|
1135
|
-
id2: id2,
|
|
1136
|
-
edgeType: edgeType,
|
|
1137
|
-
id1: builder.existingEnt.id,
|
|
1138
|
-
id2Type: "",
|
|
1139
|
-
id1Type: "",
|
|
1140
|
-
};
|
|
1141
|
-
return new EdgeOperation(builder, edge, {
|
|
1142
|
-
operation: action_1.WriteOperation.Delete,
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
exports.EdgeOperation = EdgeOperation;
|
|
1147
661
|
function isSyncQueryer(queryer) {
|
|
1148
662
|
return queryer.execSync !== undefined;
|
|
1149
663
|
}
|
|
@@ -1213,8 +727,26 @@ function buildInsertQuery(options, suffix) {
|
|
|
1213
727
|
const cols = fields.join(", ");
|
|
1214
728
|
const vals = valsString.join(", ");
|
|
1215
729
|
let query = `INSERT INTO ${options.tableName} (${cols}) VALUES (${vals})`;
|
|
730
|
+
if (options.onConflict) {
|
|
731
|
+
let onConflict = "";
|
|
732
|
+
if (options.onConflict.onConflictConstraint) {
|
|
733
|
+
onConflict = `ON CONFLICT ON CONSTRAINT ${options.onConflict.onConflictConstraint}`;
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
onConflict = `ON CONFLICT(${options.onConflict.onConflictCols.join(", ")})`;
|
|
737
|
+
}
|
|
738
|
+
if (options.onConflict.updateCols?.length) {
|
|
739
|
+
onConflict += ` DO UPDATE SET ${options.onConflict.updateCols
|
|
740
|
+
.map((f) => `${f} = EXCLUDED.${f}`)
|
|
741
|
+
.join(", ")}`;
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
onConflict += ` DO NOTHING`;
|
|
745
|
+
}
|
|
746
|
+
query = query + " " + onConflict;
|
|
747
|
+
}
|
|
1216
748
|
if (suffix) {
|
|
1217
|
-
query
|
|
749
|
+
query += " " + suffix;
|
|
1218
750
|
}
|
|
1219
751
|
return [query, values, logValues];
|
|
1220
752
|
}
|
|
@@ -1321,27 +853,6 @@ function deleteRowsSync(queryer, options, cls) {
|
|
|
1321
853
|
mutateRowSync(queryer, query, cls.values(), cls.logValues(), options);
|
|
1322
854
|
}
|
|
1323
855
|
exports.deleteRowsSync = deleteRowsSync;
|
|
1324
|
-
class DeleteNodeOperation {
|
|
1325
|
-
constructor(id, options) {
|
|
1326
|
-
this.id = id;
|
|
1327
|
-
this.options = options;
|
|
1328
|
-
}
|
|
1329
|
-
async performWrite(queryer, context) {
|
|
1330
|
-
let options = {
|
|
1331
|
-
...this.options,
|
|
1332
|
-
context,
|
|
1333
|
-
};
|
|
1334
|
-
return deleteRows(queryer, options, clause.Eq("id", this.id));
|
|
1335
|
-
}
|
|
1336
|
-
performWriteSync(queryer, context) {
|
|
1337
|
-
let options = {
|
|
1338
|
-
...this.options,
|
|
1339
|
-
context,
|
|
1340
|
-
};
|
|
1341
|
-
return deleteRowsSync(queryer, options, clause.Eq("id", this.id));
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
exports.DeleteNodeOperation = DeleteNodeOperation;
|
|
1345
856
|
class AssocEdge {
|
|
1346
857
|
constructor(data) {
|
|
1347
858
|
this.id1 = data.id1;
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./core/base";
|
|
2
|
-
export { loadEnt, loadCustomData, loadCustomEnts, loadCustomCount, loadEntX, loadEnts, CustomQuery, loadDerivedEnt, loadDerivedEntX, loadEntViaKey, loadEntXViaKey, performRawQuery, loadRowX, loadRow, loadRows,
|
|
2
|
+
export { loadEnt, loadCustomData, loadCustomEnts, loadCustomCount, loadEntX, loadEnts, CustomQuery, loadDerivedEnt, loadDerivedEntX, loadEntViaKey, loadEntXViaKey, performRawQuery, loadRowX, loadRow, loadRows, AssocEdge, AssocEdgeData, loadEdgeData, loadEdgeDatas, loadEdges, loadUniqueEdge, loadUniqueNode, loadRawEdgeCountX, loadEdgeForID2, loadNodesByEdge, getEdgeTypeInGroup, } from "./core/ent";
|
|
3
|
+
export { DataOperation, EditNodeOptions, EditNodeOperation, RawQueryOperation, EdgeOperation, DeleteNodeOperation, AssocEdgeInputOptions, AssocEdgeInput, } from "./action/operations";
|
|
3
4
|
export { setGlobalSchema } from "./core/global_schema";
|
|
4
5
|
import DB from "./core/db";
|
|
5
6
|
export * from "./core/loaders";
|
package/index.js
CHANGED
|
@@ -29,7 +29,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.setGlobalSchema = exports.
|
|
32
|
+
exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.setGlobalSchema = exports.DeleteNodeOperation = exports.EdgeOperation = exports.RawQueryOperation = exports.EditNodeOperation = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.loadEntXViaKey = exports.loadEntViaKey = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadEnts = exports.loadEntX = exports.loadCustomCount = exports.loadCustomEnts = exports.loadCustomData = exports.loadEnt = void 0;
|
|
33
33
|
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = exports.DenyIfViewerInboundEdgeDoesNotExistRule = exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = void 0;
|
|
34
34
|
__exportStar(require("./core/base"), exports);
|
|
35
35
|
var ent_1 = require("./core/ent");
|
|
@@ -48,10 +48,6 @@ Object.defineProperty(exports, "performRawQuery", { enumerable: true, get: funct
|
|
|
48
48
|
Object.defineProperty(exports, "loadRowX", { enumerable: true, get: function () { return ent_1.loadRowX; } });
|
|
49
49
|
Object.defineProperty(exports, "loadRow", { enumerable: true, get: function () { return ent_1.loadRow; } });
|
|
50
50
|
Object.defineProperty(exports, "loadRows", { enumerable: true, get: function () { return ent_1.loadRows; } });
|
|
51
|
-
Object.defineProperty(exports, "EditNodeOperation", { enumerable: true, get: function () { return ent_1.EditNodeOperation; } });
|
|
52
|
-
Object.defineProperty(exports, "RawQueryOperation", { enumerable: true, get: function () { return ent_1.RawQueryOperation; } });
|
|
53
|
-
Object.defineProperty(exports, "EdgeOperation", { enumerable: true, get: function () { return ent_1.EdgeOperation; } });
|
|
54
|
-
Object.defineProperty(exports, "DeleteNodeOperation", { enumerable: true, get: function () { return ent_1.DeleteNodeOperation; } });
|
|
55
51
|
Object.defineProperty(exports, "AssocEdge", { enumerable: true, get: function () { return ent_1.AssocEdge; } });
|
|
56
52
|
Object.defineProperty(exports, "AssocEdgeData", { enumerable: true, get: function () { return ent_1.AssocEdgeData; } });
|
|
57
53
|
Object.defineProperty(exports, "loadEdgeData", { enumerable: true, get: function () { return ent_1.loadEdgeData; } });
|
|
@@ -63,6 +59,12 @@ Object.defineProperty(exports, "loadRawEdgeCountX", { enumerable: true, get: fun
|
|
|
63
59
|
Object.defineProperty(exports, "loadEdgeForID2", { enumerable: true, get: function () { return ent_1.loadEdgeForID2; } });
|
|
64
60
|
Object.defineProperty(exports, "loadNodesByEdge", { enumerable: true, get: function () { return ent_1.loadNodesByEdge; } });
|
|
65
61
|
Object.defineProperty(exports, "getEdgeTypeInGroup", { enumerable: true, get: function () { return ent_1.getEdgeTypeInGroup; } });
|
|
62
|
+
// TODO should these even be exported from the root?
|
|
63
|
+
var operations_1 = require("./action/operations");
|
|
64
|
+
Object.defineProperty(exports, "EditNodeOperation", { enumerable: true, get: function () { return operations_1.EditNodeOperation; } });
|
|
65
|
+
Object.defineProperty(exports, "RawQueryOperation", { enumerable: true, get: function () { return operations_1.RawQueryOperation; } });
|
|
66
|
+
Object.defineProperty(exports, "EdgeOperation", { enumerable: true, get: function () { return operations_1.EdgeOperation; } });
|
|
67
|
+
Object.defineProperty(exports, "DeleteNodeOperation", { enumerable: true, get: function () { return operations_1.DeleteNodeOperation; } });
|
|
66
68
|
var global_schema_1 = require("./core/global_schema");
|
|
67
69
|
Object.defineProperty(exports, "setGlobalSchema", { enumerable: true, get: function () { return global_schema_1.setGlobalSchema; } });
|
|
68
70
|
const db_1 = __importDefault(require("./core/db"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowtop/ent",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-alpha139",
|
|
4
4
|
"description": "snowtop ent framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"memoizee": "^0.4.15",
|
|
22
22
|
"minimist": "^1.2.7",
|
|
23
23
|
"pascal-case": "^3.1.2",
|
|
24
|
-
"pg": "^8.
|
|
24
|
+
"pg": "^8.11.0",
|
|
25
25
|
"prettier": "^2.8.1",
|
|
26
26
|
"snake-case": "^3.0.4",
|
|
27
27
|
"ts-node": "^10.9.1",
|
package/parse_schema/parse.js
CHANGED
|
@@ -268,6 +268,7 @@ async function parseSchema(potentialSchemas, globalSchema) {
|
|
|
268
268
|
assocEdges: [],
|
|
269
269
|
assocEdgeGroups: [],
|
|
270
270
|
customGraphQLInterfaces: schema.customGraphQLInterfaces,
|
|
271
|
+
supportUpsert: schema.supportUpsert,
|
|
271
272
|
};
|
|
272
273
|
// let's put patterns first just so we have id, created_at, updated_at first
|
|
273
274
|
// ¯\_(ツ)_/¯
|
package/schema/base_schema.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare class EntSchema implements Schema {
|
|
|
20
20
|
indices: Index[] | undefined;
|
|
21
21
|
hideFromGraphQL?: boolean;
|
|
22
22
|
customGraphQLInterfaces?: string[] | undefined;
|
|
23
|
+
supportUpsert?: boolean | undefined;
|
|
23
24
|
constructor(cfg: SchemaConfig);
|
|
24
25
|
}
|
|
25
26
|
export declare class EntSchemaWithTZ implements Schema {
|
|
@@ -38,6 +39,7 @@ export declare class EntSchemaWithTZ implements Schema {
|
|
|
38
39
|
indices: Index[] | undefined;
|
|
39
40
|
hideFromGraphQL?: boolean;
|
|
40
41
|
customGraphQLInterfaces?: string[] | undefined;
|
|
42
|
+
supportUpsert?: boolean | undefined;
|
|
41
43
|
constructor(cfg: SchemaConfig);
|
|
42
44
|
}
|
|
43
45
|
export declare abstract class BaseEntSchema {
|
package/schema/base_schema.js
CHANGED
|
@@ -90,6 +90,7 @@ class EntSchema {
|
|
|
90
90
|
this.hideFromGraphQL = cfg.hideFromGraphQL;
|
|
91
91
|
// TODO annoying that have to list these...
|
|
92
92
|
this.customGraphQLInterfaces = cfg.customGraphQLInterfaces;
|
|
93
|
+
this.supportUpsert = cfg.supportUpsert;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
exports.EntSchema = EntSchema;
|
|
@@ -119,6 +120,7 @@ class EntSchemaWithTZ {
|
|
|
119
120
|
this.hideFromGraphQL = cfg.hideFromGraphQL;
|
|
120
121
|
// TODO annoying that have to list these...
|
|
121
122
|
this.customGraphQLInterfaces = cfg.customGraphQLInterfaces;
|
|
123
|
+
this.supportUpsert = cfg.supportUpsert;
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
exports.EntSchemaWithTZ = EntSchemaWithTZ;
|