From cc12cb76926f2e01eb1c64aa51aa22aedd701d7e Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Wed, 16 Aug 2023 11:11:32 +0200
Subject: [PATCH] WIP: MAINT: refactor retrieve properties (move backend-logic
 to backend)

---
 .../implementation/MySQL/DatabaseUtils.java   |  9 ++++--
 .../MySQL/MySQLInsertEntityProperties.java    | 14 +++++----
 .../implementation/MySQL/Replacement.java     | 16 ++++++++--
 .../java/org/caosdb/server/entity/Entity.java |  6 ++--
 .../caosdb/server/entity/EntityInterface.java |  4 +--
 .../caosdb/server/entity/StatementStatus.java |  8 +----
 .../entity/StatementStatusInterface.java      | 29 +++++++++++++++++++
 .../server/entity/wrapper/EntityWrapper.java  |  8 ++---
 .../server/grpc/CaosDBToGrpcConverters.java   |  5 ++--
 9 files changed, 72 insertions(+), 27 deletions(-)
 create mode 100644 src/main/java/org/caosdb/server/entity/StatementStatusInterface.java

diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java
index 20d43389..c123b467 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java
@@ -297,7 +297,7 @@ public class DatabaseUtils {
     LinkedList<ProtoProperty> result = new LinkedList<>();
     Map<String, ProtoProperty> replacements = new HashMap<>();
     for (ProtoProperty pp : properties) {
-      if (pp.status.equals(StatementStatus.REPLACEMENT.toString())) {
+      if (pp.status.equals(ReplacementStatus.REPLACEMENT.name())) {
         replacements.put(pp.value, null);
       }
     }
@@ -322,7 +322,7 @@ public class DatabaseUtils {
       }
     }
     for (ProtoProperty pp : properties) {
-      if (pp.status.equals(StatementStatus.REPLACEMENT.toString())) {
+      if (pp.status.equals(ReplacementStatus.REPLACEMENT.name())) {
         replace(pp, replacements.get(pp.value), isHead);
       }
       if (pp.collValues != null) {
@@ -342,6 +342,11 @@ public class DatabaseUtils {
     return result;
   }
 
+  /*
+   * This replace function is used during the retrieval of properties. It is
+   * basically the opposite of the Replacement class. It copies the information
+   * from the replacement object back into the Property.
+   */
   private static void replace(ProtoProperty pp, ProtoProperty replacement, boolean isHead) {
     if (replacement == null) {
       if (isHead) {
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java
index f3977068..b57719f5 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java
@@ -46,7 +46,6 @@ import org.caosdb.server.datatype.ReferenceValue;
 import org.caosdb.server.datatype.SingleValue;
 import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.EntityInterface;
-import org.caosdb.server.entity.StatementStatus;
 import org.caosdb.server.entity.wrapper.Property;
 
 public class MySQLInsertEntityProperties extends MySQLTransaction
@@ -116,10 +115,10 @@ public class MySQLInsertEntityProperties extends MySQLTransaction
   }
 
   private void insertStages(
-      final List<Property> stage1Inserts, final EntityID domain, final EntityID entity)
+      final List<Property> inserts, final EntityID domain, final EntityID entity)
       throws TransactionException {
 
-    for (final Property property : stage1Inserts) {
+    for (final Property property : inserts) {
 
       // prepare flat property
       final FlatProperty fp = new FlatProperty();
@@ -129,10 +128,15 @@ public class MySQLInsertEntityProperties extends MySQLTransaction
       fp.idx = property.getPIdx();
       fp.status = property.getStatementStatus().name();
 
-      if (property.getStatementStatus() == StatementStatus.REPLACEMENT) {
-        table = Table.reference_data;
+      if (property.getStatementStatus() == ReplacementStatus.REPLACEMENT) {
+        // special treatment: swap value and id. This is part of the back-end specification for the
+        // representation of replacement.
+
+        // value should be the
         fp.value = fp.id.toString();
+
         fp.id = ((ReferenceValue) property.getValue()).getId().toInteger();
+        table = Table.reference_data;
       } else {
 
         if (property.hasUnit()) {
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java
index fa2fb7cb..61e431ba 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java
@@ -22,9 +22,21 @@ package org.caosdb.server.database.backend.implementation.MySQL;
 import org.caosdb.server.datatype.ReferenceValue;
 import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.RetrieveEntity;
-import org.caosdb.server.entity.StatementStatus;
+import org.caosdb.server.entity.StatementStatusInterface;
 import org.caosdb.server.entity.wrapper.Property;
 
+enum ReplacementStatus implements StatementStatusInterface {
+  REPLACEMENT
+}
+/**
+ * A wrapper of {@link Property} objects used by the back-end implementation for the MySQL/MariaDB
+ * back-end.
+ *
+ * <p>This class helps to transform deeply nested properties, properties with overridden data types,
+ * and much more to the flat (row-like) representation used internally by the back-end (which is an
+ * implementation detail of the back-end or part of the non-public API of the back-end from that
+ * point of view).
+ */
 public class Replacement extends Property {
 
   public Property replacement;
@@ -44,7 +56,7 @@ public class Replacement extends Property {
 
     replacement.setDomain(p.getDomainEntity());
     replacement.setId(new EntityID());
-    replacement.setStatementStatus(StatementStatus.REPLACEMENT);
+    replacement.setStatementStatus(ReplacementStatus.REPLACEMENT);
     replacement.setValue(new ReferenceValue(p.getId()));
     replacement.setPIdx(0);
   }
diff --git a/src/main/java/org/caosdb/server/entity/Entity.java b/src/main/java/org/caosdb/server/entity/Entity.java
index 843449ce..614397c5 100644
--- a/src/main/java/org/caosdb/server/entity/Entity.java
+++ b/src/main/java/org/caosdb/server/entity/Entity.java
@@ -421,7 +421,7 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa
     }
   }
 
-  private StatementStatus statementStatus = null;
+  private StatementStatusInterface statementStatus = null;
 
   /**
    * statementStatus getter.
@@ -429,7 +429,7 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa
    * @return
    */
   @Override
-  public StatementStatus getStatementStatus() {
+  public StatementStatusInterface getStatementStatus() {
     return this.statementStatus;
   }
 
@@ -439,7 +439,7 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa
    * @return
    */
   @Override
-  public void setStatementStatus(final StatementStatus statementStatus) {
+  public void setStatementStatus(final StatementStatusInterface statementStatus) {
     this.statementStatus = statementStatus;
   }
 
diff --git a/src/main/java/org/caosdb/server/entity/EntityInterface.java b/src/main/java/org/caosdb/server/entity/EntityInterface.java
index d97970de..ba77b5c4 100644
--- a/src/main/java/org/caosdb/server/entity/EntityInterface.java
+++ b/src/main/java/org/caosdb/server/entity/EntityInterface.java
@@ -57,9 +57,9 @@ public interface EntityInterface
 
   public abstract boolean hasId();
 
-  public abstract StatementStatus getStatementStatus();
+  public abstract StatementStatusInterface getStatementStatus();
 
-  public abstract void setStatementStatus(StatementStatus statementStatus);
+  public abstract void setStatementStatus(StatementStatusInterface statementStatus);
 
   public abstract void setStatementStatus(String statementStatus);
 
diff --git a/src/main/java/org/caosdb/server/entity/StatementStatus.java b/src/main/java/org/caosdb/server/entity/StatementStatus.java
index 0a797175..83d0c57e 100644
--- a/src/main/java/org/caosdb/server/entity/StatementStatus.java
+++ b/src/main/java/org/caosdb/server/entity/StatementStatus.java
@@ -33,17 +33,11 @@ package org.caosdb.server.entity;
  * href="../../../../../specification/RecordType.html">the documentation of RecordTypes</a> for more
  * information.
  *
- * <p>2. Marking an entity as a ``REPLACEMENT`` which is needed for flat representation of deeply
- * nested properties. This constant is only used for internal processes and has no meaning in the
- * API. That is also the reason why this enum is not called "Importance". Apart from that, in most
- * cases its meaning is identical to the importance of an entity.
- *
  * @author Timm Fitschen (t.fitschen@indiscale.com)
  */
-public enum StatementStatus {
+public enum StatementStatus implements StatementStatusInterface {
   OBLIGATORY,
   RECOMMENDED,
   SUGGESTED,
   FIX,
-  REPLACEMENT
 }
diff --git a/src/main/java/org/caosdb/server/entity/StatementStatusInterface.java b/src/main/java/org/caosdb/server/entity/StatementStatusInterface.java
new file mode 100644
index 00000000..d1596afd
--- /dev/null
+++ b/src/main/java/org/caosdb/server/entity/StatementStatusInterface.java
@@ -0,0 +1,29 @@
+/*
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2023 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2023 Timm Fitschen <t.fitschen@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package org.caosdb.server.entity;
+
+/**
+ * Interface for the StatementStatus. This may be used by back-end implementations to use back-end
+ * specific implementations (e.g.
+ * org.caosdb.server.database.backend.implementation.MySQL.ReplacementStatus).
+ */
+public interface StatementStatusInterface {
+  public String name();
+}
diff --git a/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java b/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java
index f23408df..b294a17e 100644
--- a/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java
+++ b/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java
@@ -38,7 +38,7 @@ import org.caosdb.server.entity.EntityInterface;
 import org.caosdb.server.entity.FileProperties;
 import org.caosdb.server.entity.Message;
 import org.caosdb.server.entity.Role;
-import org.caosdb.server.entity.StatementStatus;
+import org.caosdb.server.entity.StatementStatusInterface;
 import org.caosdb.server.entity.Version;
 import org.caosdb.server.entity.container.ParentContainer;
 import org.caosdb.server.entity.container.PropertyContainer;
@@ -112,13 +112,13 @@ public abstract class EntityWrapper implements EntityInterface {
   }
 
   @Override
-  public StatementStatus getStatementStatus() {
+  public StatementStatusInterface getStatementStatus() {
     return this.entity.getStatementStatus();
   }
 
   @Override
-  public void setStatementStatus(final StatementStatus statementStatus) {
-    this.entity.setStatementStatus(statementStatus);
+  public void setStatementStatus(final StatementStatusInterface replacement) {
+    this.entity.setStatementStatus(replacement);
   }
 
   @Override
diff --git a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java
index 1b70a729..8ab8b057 100644
--- a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java
+++ b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java
@@ -75,6 +75,7 @@ import org.caosdb.server.entity.MagicTypes;
 import org.caosdb.server.entity.Message;
 import org.caosdb.server.entity.Role;
 import org.caosdb.server.entity.StatementStatus;
+import org.caosdb.server.entity.StatementStatusInterface;
 import org.caosdb.server.entity.container.ParentContainer;
 import org.caosdb.server.entity.container.RetrieveContainer;
 import org.caosdb.server.entity.wrapper.Property;
@@ -359,8 +360,8 @@ public class CaosDBToGrpcConverters {
     return convertScalarValue(v.getWrapped()).build();
   }
 
-  private Importance convert(final StatementStatus statementStatus) {
-    switch (statementStatus) {
+  private Importance convert(final StatementStatusInterface statementStatus) {
+    switch ((StatementStatus) statementStatus) {
       case FIX:
         return Importance.IMPORTANCE_FIX;
       case OBLIGATORY:
-- 
GitLab