diff --git a/conf/core/jobs.csv b/conf/core/jobs.csv index 84795bee8657288473188cd9e7a6af81f6295221..38b273c4f65ce931afd0cf7a4a4a25a3118a0ada 100644 --- a/conf/core/jobs.csv +++ b/conf/core/jobs.csv @@ -22,6 +22,7 @@ # DOMAIN_ID, ENTITY_ID, TRANSACTION, JOB, JOB_FAILURE_SEVERITY # general rules +0,0,INSERT,EntityIdHandler,ERROR 0,0,INSERT,CheckPropValid,ERROR 0,0,INSERT,CheckParValid,ERROR 0,0,INSERT,CheckParOblPropPresent,ERROR diff --git a/src/main/java/org/caosdb/server/database/BackendTransaction.java b/src/main/java/org/caosdb/server/database/BackendTransaction.java index 5addf3f3f3e34a8e3e6a9152b9511046fe4b6a23..eb888241be7570b65fa0661c15a90ada7ad92a54 100644 --- a/src/main/java/org/caosdb/server/database/BackendTransaction.java +++ b/src/main/java/org/caosdb/server/database/BackendTransaction.java @@ -50,6 +50,7 @@ import org.caosdb.server.database.backend.implementation.MySQL.MySQLLogUserVisit import org.caosdb.server.database.backend.implementation.MySQL.MySQLRegisterSubDomain; import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAll; import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAllUncheckedFiles; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveCurrentMaxId; import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveDatatypes; import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveEntityACL; import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveLogRecord; @@ -112,6 +113,7 @@ import org.caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesIm import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; import org.caosdb.server.database.backend.interfaces.RetrieveEntityACLImpl; import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveCurrentMaxIdImpl; import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl; import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; @@ -216,6 +218,7 @@ public abstract class BackendTransaction implements Undoable { setImpl(ListUsersImpl.class, MySQLListUsers.class); setImpl(LogUserVisitImpl.class, MySQLLogUserVisit.class); setImpl(RetrieveEntityACLImpl.class, MySQLRetrieveEntityACL.class); + setImpl(RetrieveCurrentMaxIdImpl.class, MySQLRetrieveCurrentMaxId.class); } } diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java index 6e4295005a5daeaed1b1efec5adfaebe8b21a34a..0a812bdf1187a1095b9b5e6afd7b0dc4846b4d96 100644 --- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java @@ -48,14 +48,14 @@ public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertS final PreparedStatement insertEntityStmt = prepareStatement(STMT_INSERT_SPARSE_ENTITY); final PreparedStatement insertFilePropsStmt = prepareStatement(STMT_INSERT_FILE_PROPERTIES); - insertEntityStmt.setString(1, entity.name); - insertEntityStmt.setString(2, entity.description); - insertEntityStmt.setString(3, entity.role); - insertEntityStmt.setString(4, entity.acl); + insertEntityStmt.setInt(1, entity.id); + insertEntityStmt.setString(2, entity.name); + insertEntityStmt.setString(3, entity.description); + insertEntityStmt.setString(4, entity.role); + insertEntityStmt.setString(5, entity.acl); try (final ResultSet rs = insertEntityStmt.executeQuery()) { if (rs.next()) { - entity.id = rs.getInt("EntityID"); entity.versionId = DatabaseUtils.bytes2UTF8(rs.getBytes("Version")); } else { throw new TransactionException("Didn't get new EntityID back."); diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveCurrentMaxId.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveCurrentMaxId.java new file mode 100644 index 0000000000000000000000000000000000000000..ff4e917584694c4dc733cfdcd5f9bd7cc8335a02 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveCurrentMaxId.java @@ -0,0 +1,39 @@ +package org.caosdb.server.database.backend.implementation.MySQL; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveCurrentMaxIdImpl; +import org.caosdb.server.database.exceptions.TransactionException; + +public class MySQLRetrieveCurrentMaxId extends MySQLTransaction implements RetrieveCurrentMaxIdImpl { + + public MySQLRetrieveCurrentMaxId(Access access) { + super(access); + } + + public static final String STMT = "SELECT max(entity_id) AS max_id FROM transaction_log"; + + @Override + public Integer execute() { +try { + try ( + PreparedStatement stmt = prepareStatement(STMT) + ) { + + try (ResultSet rs = stmt.executeQuery()) { + if(rs.next()) { + return rs.getInt("max_id"); + } else { + return 100; + } + } + } +} catch (SQLException | ConnectionException e) { +throw new TransactionException(e); +} + } + +} diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveCurrentMaxIdImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveCurrentMaxIdImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6d7b2d3ff03a69c54f924f5d1b3c4c1a482ba73e --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveCurrentMaxIdImpl.java @@ -0,0 +1,7 @@ +package org.caosdb.server.database.backend.interfaces; + +public interface RetrieveCurrentMaxIdImpl extends BackendTransactionImpl { + + public Integer execute(); + +} diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveCurrentMaxId.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveCurrentMaxId.java new file mode 100644 index 0000000000000000000000000000000000000000..0efc4f8c7b3d3babd79afa012f17e573ca9bb734 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveCurrentMaxId.java @@ -0,0 +1,20 @@ +package org.caosdb.server.database.backend.transaction; + +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveCurrentMaxIdImpl; + +public class RetrieveCurrentMaxId extends BackendTransaction { + + private Integer maxId; + + @Override + protected void execute() { + RetrieveCurrentMaxIdImpl t = getImplementation(RetrieveCurrentMaxIdImpl.class); + this.maxId = t.execute(); + } + + public Integer getCurrentMaxId() { + return this.maxId; + } + +} diff --git a/src/main/java/org/caosdb/server/entity/EntityID.java b/src/main/java/org/caosdb/server/entity/EntityID.java index 6a2d2ca368088e54c2f3c77ae669c6feda07bb4e..a8867152d9914cb5b9414f018fee91eabdd8c920 100644 --- a/src/main/java/org/caosdb/server/entity/EntityID.java +++ b/src/main/java/org/caosdb/server/entity/EntityID.java @@ -77,4 +77,5 @@ public class EntityID implements Serializable { public static boolean isReserved(final EntityID id) { return id.toInteger() < 100; } + } diff --git a/src/main/java/org/caosdb/server/entity/EntityIdRegistry.java b/src/main/java/org/caosdb/server/entity/EntityIdRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..b3b99498dcb8bb324aa80728d22ded5b2a8972a4 --- /dev/null +++ b/src/main/java/org/caosdb/server/entity/EntityIdRegistry.java @@ -0,0 +1,53 @@ + +package org.caosdb.server.entity; + +import org.caosdb.server.database.backend.transaction.RetrieveCurrentMaxId; +import org.caosdb.server.transaction.Transaction; + +/** + * <p> + * Aufgaben: + * + * <ul> + * <li>Ids generieren + * <ul> + * <li>Pattern (positive Integer, uuid) + * </ul> + * <li> + * </ul> + * + * @author tf + */ + +public class EntityIdRegistry { + + private boolean isInit; + private Integer currentMaxId; + private Transaction<?> transaction; + + public EntityIdRegistry(Transaction<?> t) { + this.transaction = t; + this.isInit = false; + } + + public void init() { + isInit = true; + initCurrentMaxId(); + } + + private void initCurrentMaxId() { + this.currentMaxId = transaction.execute(new RetrieveCurrentMaxId(), transaction.getAccess()).getCurrentMaxId(); + } + + public Integer generate() { + if(!isInit) { + init(); + } + return ++currentMaxId; + } + + + public boolean isUnused(Integer i) { + return i>currentMaxId; + } +} diff --git a/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java b/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java index d396345508a028700db6fd8e973390fd634e54d9..47a0452b9382223795e63b965a676e140e35245b 100644 --- a/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java @@ -122,6 +122,7 @@ public class TransactionContainer extends Container<EntityInterface> private TransactionBenchmark benchmark; private Query query; +private Integer currentMaxId =null; public void setFiles(final HashMap<String, FileProperties> files) { this.files = files; @@ -193,4 +194,6 @@ public class TransactionContainer extends Container<EntityInterface> public Query getQuery() { return query; } + + } diff --git a/src/main/java/org/caosdb/server/jobs/core/EntityIdHandler.java b/src/main/java/org/caosdb/server/jobs/core/EntityIdHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..e8740107926072e4938658eb13c118727914a405 --- /dev/null +++ b/src/main/java/org/caosdb/server/jobs/core/EntityIdHandler.java @@ -0,0 +1,24 @@ + +package org.caosdb.server.jobs.core; + +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.InsertEntity; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.TransactionStage; +import org.caosdb.server.transaction.WriteTransactionInterface; + +@JobAnnotation(stage = TransactionStage.PRE_TRANSACTION) +public class EntityIdHandler extends EntityJob { + + @Override + protected void run() throws Message { + EntityInterface entity = getEntity(); + if(entity instanceof InsertEntity && getTransaction() instanceof WriteTransactionInterface) { + Integer id = ((WriteTransactionInterface) getTransaction()).generateId(); + entity.getId().setId(id); + } + } +} + diff --git a/src/main/java/org/caosdb/server/transaction/UpdateACL.java b/src/main/java/org/caosdb/server/transaction/UpdateACL.java index 84c73080550d8899f4f1a5156bebb2a44c39df6a..89640addc023ea93bb1b09b8fce3b5423f96b29c 100644 --- a/src/main/java/org/caosdb/server/transaction/UpdateACL.java +++ b/src/main/java/org/caosdb/server/transaction/UpdateACL.java @@ -143,4 +143,9 @@ public class UpdateACL extends Transaction<TransactionContainer> public String getSRID() { return getContainer().getRequestId(); } + + @Override + public Integer generateId() { + throw new UnsupportedOperationException("This is not implemented on purpose. This exception indicates a usage error of this UpdateACL class."); + } } diff --git a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java index 47b7a53c71ddebb7c1b062c2c8599cf44eabe039..b1b1153aa380ef04517d47739377d87e2f943697 100644 --- a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java @@ -40,6 +40,7 @@ import org.caosdb.server.database.backend.transaction.UpdateEntityTransaction; import org.caosdb.server.database.misc.RollBackHandler; import org.caosdb.server.entity.DeleteEntity; import org.caosdb.server.entity.EntityID; +import org.caosdb.server.entity.EntityIdRegistry; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.FileProperties; import org.caosdb.server.entity.InsertEntity; @@ -73,6 +74,7 @@ public class WriteTransaction extends Transaction<WritableContainer> implements WriteTransactionInterface { private boolean noIdIsError = true; +private EntityIdRegistry idRegistry; public WriteTransaction(final WritableContainer container) { super(container); @@ -593,4 +595,13 @@ public class WriteTransaction extends Transaction<WritableContainer> public String getSRID() { return getContainer().getRequestId(); } + +@Override +public Integer generateId() { + if (this.idRegistry == null) { + this.idRegistry = new EntityIdRegistry(getAccess()); + } + + return this.idRegistry.generate(); +} } diff --git a/src/main/java/org/caosdb/server/transaction/WriteTransactionInterface.java b/src/main/java/org/caosdb/server/transaction/WriteTransactionInterface.java index 4e2938e18d061cbd1a7575baa59322356731859a..ccc6a83bbadd695a94a8f24cba52098542e33c50 100644 --- a/src/main/java/org/caosdb/server/transaction/WriteTransactionInterface.java +++ b/src/main/java/org/caosdb/server/transaction/WriteTransactionInterface.java @@ -10,4 +10,6 @@ public interface WriteTransactionInterface extends TransactionInterface { public Subject getTransactor(); public String getSRID(); + +public Integer generateId(); }