VICE / Server / DBDataModule.js
DBDataModule.js
Raw
import {TableInterface} from "./AzureModule.js"
import cron from 'cron'

export class DBData {

  #table;
  #structure;
  #partition;
  #row;
  #version;
  #list;
  #data = {};

  #refreshDBData = new cron.CronJob('00 00,10,20,30,40,50 * * * *', async () => {
    console.log("Refreshing data from " + this.#partition);
    this.refreshData();
  });

  /*
  within the structure parameter is an object with each property either with an
  example placeholder of what should be in the property
  */
  constructor(structure, table, partition, rowProperty, version = 1.0, optionalStr = "NA") {
    this.#table = new TableInterface(table);

    this.#structure = structure;
    this.#partition = partition;
    this.#row = rowProperty;
    this.optionalStr = optionalStr;
    this.#version = version;

    this.#table.getData(partition)
    .then( (list) => {
      for(var item of list.data) {
        this.#data[item[this.#row]] = item;
      }
      this.#list = list.data;
    });

    this.#refreshDBData.start();
  }

  validateData(data) {
    let properties = Object.getOwnPropertyNames(data);
    let missingProperties = "";
    let versionCheck = "";
    let hasVersion = false;
    let partitionCheck = "";
    let valid = true;
    let result = "";

    for(let property in this.structure) {
      if(!properties.includes(property)) {
        valid = false;
        missingProperties += "\t" + missingProperties + property + "\n";
      }
      if(property === "version") {
        hasVersion = true;
        if(data[property] !== this.#version) {
          versionCheck = "Invalid version\n";
          valid = false;
        }
      }
      if(property === "partitionKey") {
        if(this.#partition !== data[property]) {
          valid = false;
          partitionCheck = "Invalid partition\n";
        }
      }
    }

    result = partitionCheck + versionCheck + "Missing Properties: \n" + missingProperties;

    return { isValid: valid, data: result };
  }

  updateStructure(newStructure, partition, rowProperty, version) {
    this.#structure = newStructure;
    this.#partition = partition;
    this.#row = rowProperty;
    this.#version = version;
    this.refreshData();
  }

  /*
  get a entity from the DB using its row key.
  use -1 for id or leave it undefined to get all entities from a partition
  id: string | row key for the wanted entity
  */
  async getDbData(id = -1) {
    if(id == -1) {
      return {result: "Success", data: this.#list};
    }
    return {result: "Success", data: this.#data[id]};
  }

  /*
  add a entity from the DB using its row key.
  data: object | object with the correct structure in the instance of this class
  */
  async addDbData(data) {
    let validation = this.validateData(data);
    let result = {};

    if(validation.isValid) {
      result = await this.#table.addData(this.#partition, data[this.#row], data);
      this.refreshData();
    }
    else {
      result = {result: "Failed", data: validation.data};
    }

    return result;
  }

  /*
  removes an entity from the partition
  id: string | row key for the wanted entity
  */
  async deleteDbData(id) {
    let data = await this.#table.modData(this.#partition, id);
    this.refreshData();

    return data;
  }

  /*
  updates the data of an entity
  id: string | row key for the entity to change
  changes: object | partial or full object to modify with
  */
  async updateDbData(id, changes) {
    let data = await this.#table.modData(this.#partition, id, 1, changes);
    this.refreshData();

    return data;
  }

  async refreshData() {
    this.#table.getData(this.#partition)
    .then( (list) => {
      for(var item of list.data) {
        this.#data[item[this.#row]] = item;
      }
      this.#list = list.data;
    });
  }

}