core/Datastore.js

  1. /**
  2. * DataStore - Superclass for all backing stores
  3. *
  4. * This code is licensed under the MIT License (MIT).
  5. *
  6. * Copyright 2020, 2021, 2022 Rolf Bagge, Janus B. Kristensen, CAVI,
  7. * Center for Advanced Visualization and Interaction, Aarhus University
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the “Software”), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. /**
  29. * Datastores
  30. * @namespace Datastores
  31. */
  32. // superclass for all datastores (mostly empty for potential later introspection code)
  33. class Datastore {
  34. constructor(name, options){
  35. this.name = name;
  36. this.options = options;
  37. this.mappedConcepts = new Map();
  38. }
  39. isConceptMapped(concept){
  40. return this.isConceptTypeMapped(concept.name);
  41. }
  42. isConceptTypeMapped(conceptTypeName){
  43. return this.mappedConcepts.has(conceptTypeName);
  44. }
  45. isPropertyMapped(concept, property){
  46. if (!this.isConceptMapped(concept)) return false;
  47. return this.mappedConcepts.get(concept.name).has(property.name);
  48. }
  49. isPropertyNameMapped(conceptName, propertyName){
  50. if (!this.isConceptTypeMapped(conceptName)) return false;
  51. return this.mappedConcepts.get(conceptName).has(propertyName);
  52. }
  53. internalAddConceptMapping(concept){
  54. if (!this.isConceptMapped(concept))
  55. this.mappedConcepts.set(concept.name, new Map());
  56. }
  57. internalAddPropertyMapping(concept, property, trackingData={}){
  58. if (this.isPropertyMapped(concept, property)){
  59. throw new Error('Already has internal mapping for '+concept+"."+property);
  60. }
  61. this.internalAddConceptMapping(concept);
  62. let propertyMap = this.mappedConcepts.get(concept.name);
  63. propertyMap.set(property.name, trackingData);
  64. }
  65. internalRemovePropertyMapping(concept, property){
  66. if (!this.isConceptMapped(concept)) throw new Error("Concept not mapped when trying to remove "+concept+"."+property);
  67. let propertyMap = this.mappedConcepts.get(concept.name);
  68. propertyMap.delete(property.name);
  69. }
  70. internalPropertyTrackingData(concept, property){
  71. return this.mappedConcepts.get(concept.name).get(property.name);
  72. }
  73. createBackingStore(concept, property) {
  74. throw new Error("createBackingStore, should always be overridden in Datastore subclass - "+this.constructor.name);
  75. }
  76. removeBackingStore(concept, property) {
  77. throw new Error("removeBackingStore, should always be overridden in Datastore subclass - "+this.constructor.name);
  78. }
  79. isShared() {
  80. return true;
  81. }
  82. async init() {
  83. throw new Error("init, should always be overridden in Datastore subclass - "+this.constructor.name);
  84. }
  85. destroy() {
  86. throw new Error("destroy, should always be overridden in Datastore subclass - "+this.constructor.name);
  87. }
  88. /**
  89. *
  90. * @param {String[]} typeNames
  91. * @param {Filter} query
  92. * @param {VarvContext} context
  93. * @param {number} limit
  94. * @param {Concept} localConcept
  95. * @returns {Promise<String[]>}
  96. */
  97. async lookupInstances(typeNames, query, context, limit = 0, localConcept = null) {
  98. throw new Error("Implement [lookupInstances] me in sub datastores! - "+this.constructor.name);
  99. }
  100. /**
  101. * @param {String[]} typeNames
  102. * @param {Filter} query
  103. * @param {VarvContext} context
  104. * @param {Concept} localConcept
  105. * @returns {Promise<number>}
  106. */
  107. async countInstances(typeNames, query, context, localConcept) {
  108. throw new Error("Implement [countInstances] me in sub datastores! - "+this.constructor.name);
  109. }
  110. /**
  111. * @param {String[]} typeNames
  112. * @param {Filter} query
  113. * @param {VarvContext} context
  114. * @param {Concept} localConcept
  115. * @returns {Promise<boolean>}
  116. */
  117. async existsInstance(typeNames, query, context, localConcept) {
  118. throw new Error("Implement [existsInstance] me in sub datastores! - "+this.constructor.name);
  119. }
  120. /**
  121. *
  122. * @param {String} uuid
  123. * @returns {Promise<Concept>}
  124. */
  125. async lookupConcept(uuid) {
  126. throw new Error("Implement [lookupConcept] me in sub datastores! - "+this.constructor.name);
  127. }
  128. static getDatastoreFromName(name) {
  129. return Datastore.datastores.get(name);
  130. }
  131. static registerDatastoreType(name, datastoreType) {
  132. Datastore.datastoreTypes.set(name, datastoreType);
  133. }
  134. static getDatastoreType(name) {
  135. return Datastore.datastoreTypes.get(name);
  136. }
  137. static getAllDatastores() {
  138. return Array.from(Datastore.datastores.values());
  139. }
  140. }
  141. Datastore.DEBUG = false;
  142. Datastore.datastores = new Map();
  143. Datastore.optionalDatastores = ["cauldron"]; // A list of datastores for which there is no warning emitted if not found
  144. Datastore.datastoreTypes = new Map();
  145. window.Datastore = Datastore;