Skip to content

Commit

Permalink
fix: child relationships persist in datalayer
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelTaylor3D committed Jan 29, 2022
1 parent dffd736 commit 5280982
Show file tree
Hide file tree
Showing 31 changed files with 337 additions and 328 deletions.
4 changes: 0 additions & 4 deletions seeders/20211209205139-add-units.cjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
'use strict';

/* TODO: Fix seeddata for latest models
const UnitStub = require('../src/models/units/units.stub.json');
const LabelUnitStub = require('../src/models/labelUnits/labelUnits.stub.json');
*/

module.exports = {
// eslint-disable-next-line no-unused-vars
up: async (queryInterface) => {
/*
await queryInterface.bulkInsert('units', UnitStub, {});
await queryInterface.bulkInsert('label_unit', LabelUnitStub, {});
*/
},

down: async (queryInterface) => {
Expand Down
26 changes: 26 additions & 0 deletions src/controllers/project.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,32 @@ export const create = async (req, res) => {
const { orgUid } = await Organization.getHomeOrg();
newRecord.orgUid = orgUid;

const childRecords = [
'projectLocations',
'issuances',
'coBenefits',
'relatedProjects',
'projectRatings',
'estimations',
'labels',
];

childRecords.forEach((childRecordKey) => {
if (newRecord[childRecordKey]) {
newRecord[childRecordKey].map((childRecord) => {
childRecord.id = uuidv4();
childRecord.orgUid = orgUid;

// labels use a junction table
if (childRecordKey !== 'labels') {
childRecord.warehouseProjectId = uuid;
}

return childRecord;
});
}
});

// The new project is getting created in this registry
newRecord.currentRegistry = orgUid;

Expand Down
11 changes: 8 additions & 3 deletions src/controllers/staging.controller.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import _ from 'lodash';

import { Staging } from '../models';
import { assertStagingRecordExists } from '../utils/data-assertions';
import {
assertStagingRecordExists,
assertHomeOrgExists,
} from '../utils/data-assertions';

export const findAll = async (req, res) => {
try {
Expand Down Expand Up @@ -35,20 +38,21 @@ export const findAll = async (req, res) => {

export const commit = async (req, res) => {
try {
await assertHomeOrgExists();

await Staging.pushToDataLayer();
res.json({ message: 'Staging Table committed to full node' });
} catch (error) {
res.status(400).json({
message: 'Error commiting staging table',
error: error.message,
});

console.trace(error);
}
};

export const destroy = async (req, res) => {
try {
await assertHomeOrgExists();
await assertStagingRecordExists(req.body.uuid);
await Staging.destroy({
where: {
Expand All @@ -68,6 +72,7 @@ export const destroy = async (req, res) => {

export const clean = async (req, res) => {
try {
await assertHomeOrgExists();
await Staging.destroy({
where: {},
truncate: true,
Expand Down
19 changes: 19 additions & 0 deletions src/controllers/units.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,25 @@ export const create = async (req, res) => {
const { orgUid } = await Organization.getHomeOrg();
newRecord.orgUid = orgUid;

if (newRecord.labels) {
newRecord.labels.map((childRecord) => {
childRecord.id = uuidv4();
childRecord.orgUid = orgUid;
childRecord.label_unit = {};
childRecord.label_unit.id = uuidv4();
childRecord.label_unit.orgUid = orgUid;
childRecord.label_unit.warehouseUnitId = uuid;
childRecord.label_unit.labelId = childRecord.id;

return childRecord;
});
}

if (newRecord.issuance) {
newRecord.labels.id = uuidv4();
newRecord.labels.orgUid = orgUid;
}

const stagedData = {
uuid,
action: 'INSERT',
Expand Down
134 changes: 77 additions & 57 deletions src/fullnode/syncService.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import {
ProjectLocation,
LabelUnit,
Staging,
Rating,
} from '../models';

import { sequelize, sequelizeMirror } from '../models/database';

import * as dataLayer from './persistance';
import * as simulator from './simulator';

Expand Down Expand Up @@ -63,63 +62,84 @@ export const syncDataLayerStoreToClimateWarehouse = async (storeId) => {

try {
// Create a transaction for both the main db and the mirror db
await sequelize.transaction(async () => {
return sequelizeMirror.transaction(async () => {
if (organizationToTrucate) {
await Promise.all([
// the child table records should cascade delete so we only need to
// truncate the primary tables
Unit.destroy({ where: { orgUid: organizationToTrucate.orgUid } }),
Project.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
LabelUnit.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
]);
//await sequelize.transaction(async () => {
// return sequelizeMirror.transaction(async () => {
if (organizationToTrucate) {
await Promise.all([
// the child table records should cascade delete so we only need to
// truncate the primary tables
Unit.destroy({ where: { orgUid: organizationToTrucate.orgUid } }),
Project.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
LabelUnit.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
RelatedProject.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
CoBenefit.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
Issuance.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
Label.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
Rating.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
ProjectLocation.destroy({
where: { orgUid: organizationToTrucate.orgUid },
}),
]);
}

await Promise.all(
storeData.keys_values.map(async (kv) => {
const key = new Buffer(
kv.key.replace(`${storeId}_`, ''),
'hex',
).toString();
const value = JSON.parse(new Buffer(kv.value, 'hex').toString());
if (key.includes('unit_')) {
await Unit.upsert(value);
await Staging.destroy({
where: { uuid: value.warehouseUnitId },
});
} else if (key.includes('project_')) {
await Project.upsert(value);
await Staging.destroy({
where: { uuid: value.warehouseProjectId },
});
} else if (key.includes('relatedProjects_')) {
await RelatedProject.upsert(value);
} else if (key.includes('label_units_')) {
await LabelUnit.upsert(value);
} else if (key.includes('coBenefits_')) {
await CoBenefit.upsert(value);
} else if (key.includes('issuances_')) {
await Issuance.upsert(value);
} else if (key.includes('projectLocations_')) {
console.log(value);
await ProjectLocation.upsert(value);
} else if (key.includes('labels_')) {
await Label.upsert(value);
} else if (key.includes('projectRatings_')) {
await Rating.upsert(value);
}

await Promise.all(
storeData.keys_values.map(async (kv) => {
const key = new Buffer(
kv.key.replace(`${storeId}_`, ''),
'hex',
).toString();
const value = JSON.parse(new Buffer(kv.value, 'hex').toString());
if (key.includes('unit')) {
await Unit.upsert(value);
await Staging.destroy({
where: { uuid: value.warehouseUnitId },
});
} else if (key.includes('project')) {
await Project.upsert(value);
await Staging.destroy({
where: { uuid: value.warehouseProjectId },
});
} else if (key.includes('relatedProjects')) {
await RelatedProject.upsert(value);
} else if (key.includes('labels_units')) {
await LabelUnit.upsert(value);
} else if (key.includes('coBenefits')) {
await CoBenefit.upsert(value);
} else if (key.includes('issuances')) {
await Issuance.upsert(value);
} else if (key.includes('projectLocations')) {
await ProjectLocation.upsert(value);
} else if (key.includes('labels')) {
await Label.upsert(value);
}
}),
);

// clean up any staging records than involved delete commands,
// since we cant track that they came in through the uuid,
// we can infer this because diff.original is null instead of empty object.
await Staging.cleanUpCommitedAndInvalidRecords();
});
});
}),
);

// clean up any staging records than involved delete commands,
// since we cant track that they came in through the uuid,
// we can infer this because diff.original is null instead of empty object.
await Staging.cleanUpCommitedAndInvalidRecords();
// });
// });
} catch (error) {
console.log('ERROR DURING SYNC TRANSACTION', error);
console.trace('ERROR DURING SYNC TRANSACTION', error);
}
};

Expand Down
1 change: 1 addition & 0 deletions src/models/co-benefits/co-benefits.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand Down
1 change: 1 addition & 0 deletions src/models/estimations/estimations.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand Down
1 change: 1 addition & 0 deletions src/models/issuances/issuances.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand Down
8 changes: 8 additions & 0 deletions src/models/labelUnits/labelUnits.modeltypes.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
const { uuid: uuidv4 } = require('uuidv4');
const Sequelize = require('sequelize');

module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
},
orgUid: {
type: Sequelize.STRING,
required: true,
Expand Down
2 changes: 2 additions & 0 deletions src/models/labelUnits/labelUnits.stub.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[
{
"id": "5c960ac1-a180-45a4-9850-be177e26d2fb",
"warehouseUnitId": "5c960ac1-a180-45a4-9850-be177e26d2fb",
"labelId": "702cafbb-c624-4273-9cdc-c617ad5675df",
"orgUid": "f1c54511-865e-4611-976c-7c3c1f704662"
},
{
"id": "f1c54511-865e-4611-976c-7c3c1f704662",
"warehouseUnitId": "5c960ac1-a180-45a4-9850-be177e26d2fb",
"labelId": "76903895-840e-406c-b2a0-f90244acf02d",
"orgUid": "f1c54511-865e-4611-976c-7c3c1f704662"
Expand Down
3 changes: 2 additions & 1 deletion src/models/labels/labels.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand All @@ -30,7 +31,7 @@ module.exports = {
type: Sequelize.DATE,
require: true,
},
validityStartDate: {
validityPeriodStartDate: {
type: Sequelize.DATE,
require: true,
},
Expand Down
2 changes: 1 addition & 1 deletion src/models/labels/labels.stub.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"warehouseProjectId": "11954678-f7a5-47d2-94f8-f4f3138a529c",
"creditingPeriodStartDate": "2011-10-05T14:48:00.000Z",
"creditingPeriodEndDate": "2022-10-05T14:48:00.000Z",
"validityStartDate": "2022-01-18 00:05:45.701 +00:00",
"validityPeriodStartDate": "2022-01-18 00:05:45.701 +00:00",
"validityPeriodEndDate": "2022-01-18 00:05:45.701 +00:00",
"unitQuantity": 5,
"labelLink": "https://label.link/1",
Expand Down
1 change: 1 addition & 0 deletions src/models/locations/locations.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand Down
5 changes: 3 additions & 2 deletions src/models/projects/projects.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
warehouseProjectId: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand All @@ -26,7 +27,7 @@ module.exports = {
type: Sequelize.STRING,
required: true,
},
// Need to add 'originProjectID' field and make it a required field with type STRING.
// Need to add 'originProjectID' field and make it a required field with type STRING.
// This field could be the exact same as 'projectID', but it could also be different. Both are required fields.
program: {
type: Sequelize.STRING,
Expand Down Expand Up @@ -62,7 +63,7 @@ module.exports = {
ndcInformation: {
type: Sequelize.STRING,
required: true,
// 'ndcInformation' field should be optional.
// 'ndcInformation' field should be optional.
},
projectStatus: {
type: Sequelize.STRING,
Expand Down
1 change: 1 addition & 0 deletions src/models/ratings/ratings.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Sequelize = require('sequelize');
module.exports = {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: () => uuidv4(),
primaryKey: true,
Expand Down
Loading

0 comments on commit 5280982

Please sign in to comment.