Skip to content
Snippets Groups Projects
Commit 4940f585 authored by Florian Spreckelsen's avatar Florian Spreckelsen
Browse files

Revert "Revert "Merge branch 'f-state-change' into 'dev'""

This reverts commit a355a425.
parent a355a425
No related branches found
No related tags found
2 merge requests!58REL: prepare release 0.7.2,!55Re-Merge branch 'f-state-change' into 'dev'
Pipeline #19981 passed
Showing
with 187 additions and 11 deletions
...@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Missing serialization of file descriptors in the GRPC-API during retrievals. * Missing serialization of file descriptors in the GRPC-API during retrievals.
* [caosdb-server#131](https://gitlab.com/caosdb/caosdb-server/-/issues/131) * [caosdb-server#131](https://gitlab.com/caosdb/caosdb-server/-/issues/131)
Query: AND does not work with sub-properties Query: AND does not work with sub-properties
* Add previously missing `Value.equals` functions
* [caosdb-server#132](https://gitlab.com/caosdb/caosdb-server/-/issues/132) * [caosdb-server#132](https://gitlab.com/caosdb/caosdb-server/-/issues/132)
Query: subproperties should not require parentheses Query: subproperties should not require parentheses
......
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
*/ */
package org.caosdb.datetime; package org.caosdb.datetime;
import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
import org.caosdb.server.datatype.Value;
public abstract class FragmentDateTime implements DateTimeInterface { public abstract class FragmentDateTime implements DateTimeInterface {
...@@ -53,4 +55,13 @@ public abstract class FragmentDateTime implements DateTimeInterface { ...@@ -53,4 +55,13 @@ public abstract class FragmentDateTime implements DateTimeInterface {
this.nanosecond = nanosecond; this.nanosecond = nanosecond;
this.timeZone = tz; this.timeZone = tz;
} }
@Override
public boolean equals(Value val) {
if (val instanceof FragmentDateTime) {
FragmentDateTime that = (FragmentDateTime) val;
return Objects.equals(that.toDatabaseString(), this.toDatabaseString());
}
return false;
}
} }
...@@ -25,8 +25,10 @@ package org.caosdb.datetime; ...@@ -25,8 +25,10 @@ package org.caosdb.datetime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
import org.caosdb.server.datatype.AbstractDatatype.Table; import org.caosdb.server.datatype.AbstractDatatype.Table;
import org.caosdb.server.datatype.Value;
import org.jdom2.Element; import org.jdom2.Element;
public class UTCDateTime implements Interval { public class UTCDateTime implements Interval {
...@@ -360,4 +362,13 @@ public class UTCDateTime implements Interval { ...@@ -360,4 +362,13 @@ public class UTCDateTime implements Interval {
public boolean hasNanoseconds() { public boolean hasNanoseconds() {
return this.nanoseconds != null; return this.nanoseconds != null;
} }
@Override
public boolean equals(Value val) {
if (val instanceof UTCDateTime) {
UTCDateTime that = (UTCDateTime) val;
return Objects.equals(that.toDatabaseString(), this.toDatabaseString());
}
return false;
}
} }
...@@ -52,7 +52,15 @@ public abstract class AbstractEnumValue implements SingleValue { ...@@ -52,7 +52,15 @@ public abstract class AbstractEnumValue implements SingleValue {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (obj instanceof AbstractEnumValue) { if (obj instanceof AbstractEnumValue) {
final AbstractEnumValue that = (AbstractEnumValue) obj; return equals((AbstractEnumValue) obj);
}
return false;
}
@Override
public boolean equals(Value val) {
if (val instanceof AbstractEnumValue) {
final AbstractEnumValue that = (AbstractEnumValue) val;
return Objects.equal(that.value, this.value); return Objects.equal(that.value, this.value);
} }
return false; return false;
......
...@@ -80,4 +80,23 @@ public class CollectionValue implements Value, Iterable<IndexedSingleValue> { ...@@ -80,4 +80,23 @@ public class CollectionValue implements Value, Iterable<IndexedSingleValue> {
public int size() { public int size() {
return list.size(); return list.size();
} }
@Override
public boolean equals(Value val) {
if (val instanceof CollectionValue) {
CollectionValue that = (CollectionValue) val;
sort();
that.sort();
return this.list.equals(that.list);
}
return false;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Value) {
return this.equals((Value) obj);
}
return false;
}
} }
...@@ -89,8 +89,16 @@ public class GenericValue implements SingleValue { ...@@ -89,8 +89,16 @@ public class GenericValue implements SingleValue {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (obj instanceof GenericValue) { if (obj instanceof Value) {
final GenericValue that = (GenericValue) obj; return equals((Value) obj);
}
return false;
}
@Override
public boolean equals(Value val) {
if (val instanceof GenericValue) {
final GenericValue that = (GenericValue) val;
return Objects.equal(that.value, this.value); return Objects.equal(that.value, this.value);
} }
return false; return false;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
*/ */
package org.caosdb.server.datatype; package org.caosdb.server.datatype;
import java.util.Objects;
import org.caosdb.server.datatype.AbstractDatatype.Table; import org.caosdb.server.datatype.AbstractDatatype.Table;
import org.jdom2.Element; import org.jdom2.Element;
...@@ -78,4 +79,21 @@ public class IndexedSingleValue implements SingleValue, Comparable<IndexedSingle ...@@ -78,4 +79,21 @@ public class IndexedSingleValue implements SingleValue, Comparable<IndexedSingle
public SingleValue getWrapped() { public SingleValue getWrapped() {
return this.wrapped; return this.wrapped;
} }
@Override
public boolean equals(Value val) {
if (val instanceof IndexedSingleValue) {
IndexedSingleValue that = (IndexedSingleValue) val;
return Objects.equals(that.wrapped, this.wrapped);
}
return false;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Value) {
return this.equals((Value) obj);
}
return false;
}
} }
...@@ -199,13 +199,21 @@ public class ReferenceValue implements SingleValue { ...@@ -199,13 +199,21 @@ public class ReferenceValue implements SingleValue {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (obj instanceof ReferenceValue) { if (obj instanceof Value) {
final ReferenceValue that = (ReferenceValue) obj; return equals((Value) obj);
}
return false;
}
@Override
public boolean equals(Value val) {
if (val instanceof ReferenceValue) {
final ReferenceValue that = (ReferenceValue) val;
if (that.getId() != null && getId() != null) { if (that.getId() != null && getId() != null) {
return that.getId().equals(getId()) return that.getId().equals(getId())
&& Objects.deepEquals(that.getVersion(), this.getVersion()); && Objects.deepEquals(that.getVersion(), this.getVersion());
} else if (that.getName() != null && getName() != null) { } else if (that.getName() != null && getName() != null) {
return that.getName().equals(getName()); return Objects.equals(that.getName(), this.getName());
} }
} }
return false; return false;
......
...@@ -26,4 +26,6 @@ import org.jdom2.Element; ...@@ -26,4 +26,6 @@ import org.jdom2.Element;
public interface Value { public interface Value {
public void addToElement(Element e); public void addToElement(Element e);
public abstract boolean equals(Value val);
} }
...@@ -41,6 +41,7 @@ import org.caosdb.server.entity.DeleteEntity; ...@@ -41,6 +41,7 @@ import org.caosdb.server.entity.DeleteEntity;
import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.EntityInterface;
import org.caosdb.server.entity.FileProperties; import org.caosdb.server.entity.FileProperties;
import org.caosdb.server.entity.InsertEntity; import org.caosdb.server.entity.InsertEntity;
import org.caosdb.server.entity.Message;
import org.caosdb.server.entity.RetrieveEntity; import org.caosdb.server.entity.RetrieveEntity;
import org.caosdb.server.entity.UpdateEntity; import org.caosdb.server.entity.UpdateEntity;
import org.caosdb.server.entity.container.TransactionContainer; import org.caosdb.server.entity.container.TransactionContainer;
...@@ -400,7 +401,8 @@ public class WriteTransaction extends Transaction<WritableContainer> ...@@ -400,7 +401,8 @@ public class WriteTransaction extends Transaction<WritableContainer>
} }
// entity role // entity role
if (newEntity.hasRole() if (!(newEntity instanceof Property && oldEntity instanceof Property)
&& newEntity.hasRole()
&& oldEntity.hasRole() && oldEntity.hasRole()
&& !newEntity.getRole().equals(oldEntity.getRole()) && !newEntity.getRole().equals(oldEntity.getRole())
|| newEntity.hasRole() ^ oldEntity.hasRole()) { || newEntity.hasRole() ^ oldEntity.hasRole()) {
...@@ -409,10 +411,18 @@ public class WriteTransaction extends Transaction<WritableContainer> ...@@ -409,10 +411,18 @@ public class WriteTransaction extends Transaction<WritableContainer>
} }
// entity value // entity value
if (newEntity.hasValue() if (newEntity.hasValue() && oldEntity.hasValue()) {
&& oldEntity.hasValue() try {
&& !newEntity.getValue().equals(oldEntity.getValue()) newEntity.parseValue();
|| newEntity.hasValue() ^ oldEntity.hasValue()) { oldEntity.parseValue();
} catch (Message m) {
// ignore, parsing is handled elsewhere
}
if (!newEntity.getValue().equals(oldEntity.getValue())) {
needPermissions.add(EntityPermission.UPDATE_VALUE);
updatetable = true;
}
} else if (newEntity.hasValue() ^ oldEntity.hasValue()) {
needPermissions.add(EntityPermission.UPDATE_VALUE); needPermissions.add(EntityPermission.UPDATE_VALUE);
updatetable = true; updatetable = true;
} }
......
...@@ -25,16 +25,22 @@ package org.caosdb.server.transaction; ...@@ -25,16 +25,22 @@ package org.caosdb.server.transaction;
import static org.caosdb.server.utils.EntityStatus.QUALIFIED; import static org.caosdb.server.utils.EntityStatus.QUALIFIED;
import static org.caosdb.server.utils.EntityStatus.VALID; import static org.caosdb.server.utils.EntityStatus.VALID;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import org.caosdb.server.CaosDBException; import org.caosdb.server.CaosDBException;
import org.caosdb.server.CaosDBServer; import org.caosdb.server.CaosDBServer;
import org.caosdb.server.datatype.CollectionValue;
import org.caosdb.server.datatype.GenericValue; import org.caosdb.server.datatype.GenericValue;
import org.caosdb.server.datatype.ReferenceValue;
import org.caosdb.server.entity.Entity; import org.caosdb.server.entity.Entity;
import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.EntityInterface;
import org.caosdb.server.entity.StatementStatus; import org.caosdb.server.entity.StatementStatus;
import org.caosdb.server.entity.wrapper.Property; import org.caosdb.server.entity.wrapper.Property;
import org.caosdb.server.permissions.EntityPermission;
import org.caosdb.server.permissions.Permission;
import org.caosdb.server.utils.EntityStatus; import org.caosdb.server.utils.EntityStatus;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
...@@ -176,4 +182,78 @@ public class UpdateTest { ...@@ -176,4 +182,78 @@ public class UpdateTest {
assertEquals(newEntity.getEntityStatus(), QUALIFIED); assertEquals(newEntity.getEntityStatus(), QUALIFIED);
assertEquals(newProperty.getEntityStatus(), QUALIFIED); assertEquals(newProperty.getEntityStatus(), QUALIFIED);
} }
@Test
public void testDeriveUpdate_Collections()
throws NoSuchAlgorithmException, CaosDBException, IOException {
final Entity newEntity = new Entity();
final Property newProperty = new Property(1);
newProperty.setDatatype("List<Person>");
CollectionValue newValue = new CollectionValue();
newValue.add(new ReferenceValue(1234));
newValue.add(null);
newValue.add(new GenericValue(2345));
newValue.add(new GenericValue(3465));
newProperty.setValue(newValue);
newEntity.addProperty(newProperty);
newEntity.setEntityStatus(QUALIFIED);
newProperty.setEntityStatus(QUALIFIED);
// old entity represents the stored entity.
final Entity oldEntity = new Entity();
final Property oldProperty = new Property(1);
oldProperty.setDatatype("List<Person>");
CollectionValue oldValue = new CollectionValue();
// Values are shuffled but have the correct index
oldValue.add(1, null);
oldValue.add(3, new GenericValue(3465));
oldValue.add(2, new ReferenceValue(2345));
oldValue.add(0, new ReferenceValue(1234));
oldProperty.setValue(oldValue);
oldEntity.addProperty(oldProperty);
HashSet<Permission> permissions = new WriteTransaction(null).deriveUpdate(newEntity, oldEntity);
// Both have been identified as equals
assertTrue(permissions.isEmpty());
assertEquals(newEntity.getEntityStatus(), VALID);
assertEquals(newProperty.getEntityStatus(), VALID);
// NEW TEST CASE
newValue.add(null); // newValue has another null
newProperty.setValue(newValue);
oldEntity.addProperty(oldProperty); // Add again, because deriveUpdate throws it away
newEntity.setEntityStatus(QUALIFIED);
newProperty.setEntityStatus(QUALIFIED);
HashSet<Permission> permissions2 =
new WriteTransaction(null).deriveUpdate(newEntity, oldEntity);
HashSet<Permission> expected = new HashSet<Permission>();
expected.add(EntityPermission.UPDATE_ADD_PROPERTY);
expected.add(EntityPermission.UPDATE_REMOVE_PROPERTY);
assertEquals(expected, permissions2);
assertEquals(newEntity.getEntityStatus(), QUALIFIED);
assertEquals(newProperty.getEntityStatus(), QUALIFIED);
// NEW TEST CASE
// now change the order of oldValue
CollectionValue oldValue2 = new CollectionValue();
// Values are shuffled but have the correct index
oldValue2.add(0, null);
oldValue2.add(1, new GenericValue(3465));
oldValue2.add(2, new ReferenceValue(2345));
oldValue2.add(3, new ReferenceValue(1234));
oldValue2.add(4, null);
oldProperty.setValue(oldValue2);
oldEntity.addProperty(oldProperty); // Add again, because deriveUpdate throws it away
newEntity.setEntityStatus(QUALIFIED);
newProperty.setEntityStatus(QUALIFIED);
HashSet<Permission> permissions3 =
new WriteTransaction(null).deriveUpdate(newEntity, oldEntity);
assertEquals(expected, permissions3);
assertEquals(newEntity.getEntityStatus(), QUALIFIED);
assertEquals(newProperty.getEntityStatus(), QUALIFIED);
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment