Notes/src/becca/entities/abstract_entity.js

171 lines
4.8 KiB
JavaScript
Raw Normal View History

"use strict";
2021-05-17 22:09:49 +02:00
const utils = require('../../services/utils');
const sql = require('../../services/sql');
const entityChangesService = require('../../services/entity_changes');
const eventService = require("../../services/events");
const dateUtils = require("../../services/date_utils");
const cls = require("../../services/cls");
2022-01-31 21:25:18 +01:00
const log = require("../../services/log");
2021-04-25 21:19:18 +02:00
2021-04-30 22:13:13 +02:00
let becca = null;
2021-04-25 21:19:18 +02:00
2022-04-16 00:17:32 +02:00
/**
* Base class for all backend entities.
*/
class AbstractEntity {
2022-06-12 23:29:11 +02:00
/** @protected */
beforeSaving() {
this.generateIdIfNecessary();
}
2022-06-12 23:29:11 +02:00
/** @protected */
generateIdIfNecessary() {
if (!this[this.constructor.primaryKeyName]) {
this[this.constructor.primaryKeyName] = utils.newEntityId();
}
}
2022-06-12 23:29:11 +02:00
/** @protected */
2021-05-08 21:10:58 +02:00
generateHash(isDeleted = false) {
let contentToHash = "";
for (const propertyName of this.constructor.hashedProperties) {
contentToHash += `|${this[propertyName]}`;
}
2021-05-08 21:10:58 +02:00
if (isDeleted) {
contentToHash += "|deleted";
}
return utils.hash(contentToHash).substr(0, 10);
}
2022-06-12 23:29:11 +02:00
/** @protected */
getUtcDateChanged() {
return this.utcDateModified || this.utcDateCreated;
}
/**
* @protected
* @returns {Becca}
*/
2021-04-30 22:13:13 +02:00
get becca() {
if (!becca) {
2022-01-10 17:09:20 +01:00
becca = require('../becca');
2021-04-30 22:13:13 +02:00
}
return becca;
}
2022-06-12 23:29:11 +02:00
/** @protected */
2021-05-08 21:10:58 +02:00
addEntityChange(isDeleted = false) {
entityChangesService.addEntityChange({
entityName: this.constructor.entityName,
entityId: this[this.constructor.primaryKeyName],
hash: this.generateHash(isDeleted),
isErased: false,
utcDateChanged: this.getUtcDateChanged(),
isSynced: this.constructor.entityName !== 'options' || !!this.isSynced
});
}
2022-06-12 23:29:11 +02:00
/** @protected */
getPojoToSave() {
return this.getPojo();
}
2022-04-16 00:17:32 +02:00
/**
* Saves entity - executes SQL, but doesn't commit the transaction on its own
*
* @returns {this}
2022-04-16 00:17:32 +02:00
*/
save() {
2021-05-08 21:10:58 +02:00
const entityName = this.constructor.entityName;
const primaryKeyName = this.constructor.primaryKeyName;
const isNewEntity = !this[primaryKeyName];
if (this.beforeSaving) {
this.beforeSaving();
}
const pojo = this.getPojoToSave();
2021-05-08 21:10:58 +02:00
sql.transactional(() => {
sql.upsert(entityName, primaryKeyName, pojo);
if (entityName === 'recent_notes') {
return;
}
this.addEntityChange(false);
if (!cls.isEntityEventsDisabled()) {
const eventPayload = {
entityName,
entity: this
};
if (isNewEntity) {
eventService.emit(eventService.ENTITY_CREATED, eventPayload);
}
eventService.emit(eventService.ENTITY_CHANGED, eventPayload);
}
});
return this;
}
2021-05-08 21:10:58 +02:00
2022-04-16 00:17:32 +02:00
/**
* Mark the entity as (soft) deleted. It will be completely erased later.
*
* This is a low level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
*
2022-04-16 00:17:32 +02:00
* @param [deleteId=null]
*/
2021-05-08 21:10:58 +02:00
markAsDeleted(deleteId = null) {
2021-05-08 23:31:20 +02:00
const entityId = this[this.constructor.primaryKeyName];
const entityName = this.constructor.entityName;
2021-05-08 21:10:58 +02:00
this.utcDateModified = dateUtils.utcNowDateTime();
2021-05-09 11:12:53 +02:00
sql.execute(`UPDATE ${entityName} SET isDeleted = 1, deleteId = ?, utcDateModified = ?
WHERE ${this.constructor.primaryKeyName} = ?`,
[deleteId, this.utcDateModified, entityId]);
2021-05-09 11:12:53 +02:00
if (this.dateModified) {
this.dateModified = dateUtils.localNowDateTime();
2021-05-09 11:12:53 +02:00
sql.execute(`UPDATE ${entityName} SET dateModified = ? WHERE ${this.constructor.primaryKeyName} = ?`,
[this.dateModified, entityId]);
2021-05-09 11:12:53 +02:00
}
2021-05-08 21:10:58 +02:00
2022-01-31 21:25:18 +01:00
log.info(`Marking ${entityName} ${entityId} as deleted`);
2021-05-08 23:31:20 +02:00
this.addEntityChange(true);
2021-05-08 21:10:58 +02:00
eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this });
2021-05-08 21:10:58 +02:00
}
2022-01-10 17:09:20 +01:00
markAsDeletedSimple() {
const entityId = this[this.constructor.primaryKeyName];
const entityName = this.constructor.entityName;
2022-01-31 21:25:18 +01:00
this.utcDateModified = dateUtils.utcNowDateTime();
2022-01-10 17:09:20 +01:00
sql.execute(`UPDATE ${entityName} SET isDeleted = 1, utcDateModified = ?
WHERE ${this.constructor.primaryKeyName} = ?`,
2022-01-31 21:25:18 +01:00
[this.utcDateModified, entityId]);
log.info(`Marking ${entityName} ${entityId} as deleted`);
2022-01-10 17:09:20 +01:00
this.addEntityChange(true);
eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this });
}
}
module.exports = AbstractEntity;