mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
[15x] Remove Draftable support
This commit is contained in:
@@ -1326,104 +1326,6 @@ public interface Database {
|
||||
*/
|
||||
DocumentStore docStore();
|
||||
|
||||
/**
|
||||
* Publish a single bean given its type and id returning the resulting live bean.
|
||||
* <p>
|
||||
* The values are published from the draft to the live bean.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
* @param id the id of the entity bean
|
||||
* @param transaction the transaction the publish process should use (can be null)
|
||||
*/
|
||||
@Nullable
|
||||
<T> T publish(Class<T> beanType, Object id, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Publish a single bean given its type and id returning the resulting live bean.
|
||||
* This will use the current transaction or create one if required.
|
||||
* <p>
|
||||
* The values are published from the draft to the live bean.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
* @param id the id of the entity bean
|
||||
*/
|
||||
@Nullable
|
||||
<T> T publish(Class<T> beanType, Object id);
|
||||
|
||||
/**
|
||||
* Publish the beans that match the query returning the resulting published beans.
|
||||
* <p>
|
||||
* The values are published from the draft beans to the live beans.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to publish
|
||||
* @param transaction the transaction the publish process should use (can be null)
|
||||
*/
|
||||
<T> List<T> publish(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Publish the beans that match the query returning the resulting published beans.
|
||||
* This will use the current transaction or create one if required.
|
||||
* <p>
|
||||
* The values are published from the draft beans to the live beans.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to publish
|
||||
*/
|
||||
<T> List<T> publish(Query<T> query);
|
||||
|
||||
/**
|
||||
* Restore the draft bean back to the live state.
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
* @param id the id of the entity bean to restore
|
||||
* @param transaction the transaction the restore process should use (can be null)
|
||||
*/
|
||||
@Nullable
|
||||
<T> T draftRestore(Class<T> beanType, Object id, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Restore the draft bean back to the live state.
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
* @param id the id of the entity bean to restore
|
||||
*/
|
||||
@Nullable
|
||||
<T> T draftRestore(Class<T> beanType, Object id);
|
||||
|
||||
/**
|
||||
* Restore the draft beans matching the query back to the live state.
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to restore
|
||||
* @param transaction the transaction the restore process should use (can be null)
|
||||
*/
|
||||
<T> List<T> draftRestore(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Restore the draft beans matching the query back to the live state.
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to restore
|
||||
*/
|
||||
<T> List<T> draftRestore(Query<T> query);
|
||||
|
||||
/**
|
||||
* Returns the set of properties/paths that are unknown (do not map to known properties or paths).
|
||||
* <p>
|
||||
|
||||
@@ -106,11 +106,6 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
Query<T> asOf(Timestamp asOf);
|
||||
|
||||
/**
|
||||
* Execute the query against the draft set of tables.
|
||||
*/
|
||||
Query<T> asDraft();
|
||||
|
||||
/**
|
||||
* Convert the query to a DTO bean query.
|
||||
* <p>
|
||||
|
||||
@@ -250,11 +250,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
Query<T> asOf(Timestamp asOf);
|
||||
|
||||
/**
|
||||
* Execute the query against the draft set of tables.
|
||||
*/
|
||||
Query<T> asDraft();
|
||||
|
||||
/**
|
||||
* Convert the query to a DTO bean query.
|
||||
* <p>
|
||||
|
||||
@@ -168,11 +168,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
SOFT_DELETED(false),
|
||||
|
||||
/**
|
||||
* Query runs against draft tables.
|
||||
*/
|
||||
DRAFT(false),
|
||||
|
||||
/**
|
||||
* Query runs against current data (normal).
|
||||
*/
|
||||
@@ -375,11 +370,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
boolean isAsOfQuery();
|
||||
|
||||
/**
|
||||
* Return true if this is a 'As Draft' query.
|
||||
*/
|
||||
boolean isAsDraft();
|
||||
|
||||
/**
|
||||
* Return true if this query includes soft deleted rows.
|
||||
*/
|
||||
|
||||
@@ -178,12 +178,11 @@ final class DefaultBeanLoader {
|
||||
desc.contextPut(pc, id, bean);
|
||||
ebi.setPersistenceContext(pc);
|
||||
}
|
||||
boolean draft = desc.isDraftInstance(bean);
|
||||
if (embeddedOwnerIndex == -1) {
|
||||
if (desc.lazyLoadMany(ebi)) {
|
||||
return;
|
||||
}
|
||||
if (!draft && Mode.LAZYLOAD_BEAN == mode && desc.isBeanCaching()) {
|
||||
if (Mode.LAZYLOAD_BEAN == mode && desc.isBeanCaching()) {
|
||||
// lazy loading and the bean cache is active
|
||||
if (desc.cacheBeanLoad(bean, ebi, id, pc)) {
|
||||
return;
|
||||
@@ -192,9 +191,7 @@ final class DefaultBeanLoader {
|
||||
}
|
||||
SpiQuery<?> query = server.createQuery(desc.type());
|
||||
query.setLazyLoadProperty(ebi.lazyLoadProperty());
|
||||
if (draft) {
|
||||
query.asDraft();
|
||||
} else if (mode == SpiQuery.Mode.LAZYLOAD_BEAN && desc.isSoftDelete()) {
|
||||
if (mode == SpiQuery.Mode.LAZYLOAD_BEAN && desc.isSoftDelete()) {
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
if (embeddedOwnerIndex > -1) {
|
||||
|
||||
@@ -1636,54 +1636,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}, transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query, @Nullable Transaction transaction) {
|
||||
return executeInTrans((txn) -> persister.publish(query, txn), transaction);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T publish(Class<T> beanType, Object id) {
|
||||
return publish(beanType, id, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query) {
|
||||
return publish(query, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T publish(Class<T> beanType, Object id, @Nullable Transaction transaction) {
|
||||
Query<T> query = find(beanType).setId(id);
|
||||
List<T> liveBeans = publish(query, transaction);
|
||||
return (liveBeans.size() == 1) ? liveBeans.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query, @Nullable Transaction transaction) {
|
||||
return executeInTrans((txn) -> persister.draftRestore(query, txn), transaction);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T draftRestore(Class<T> beanType, Object id, @Nullable Transaction transaction) {
|
||||
Query<T> query = find(beanType).setId(id);
|
||||
List<T> beans = draftRestore(query, transaction);
|
||||
return (beans.size() == 1) ? beans.get(0) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T draftRestore(Class<T> beanType, Object id) {
|
||||
return draftRestore(beanType, id, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query) {
|
||||
return draftRestore(query, null);
|
||||
}
|
||||
|
||||
private EntityBean checkEntityBean(Object bean) {
|
||||
return (EntityBean) Objects.requireNonNull(bean);
|
||||
}
|
||||
|
||||
@@ -120,11 +120,10 @@ public final class InternalConfiguration {
|
||||
this.dtoBeanManager = new DtoBeanManager(typeManager);
|
||||
this.beanDescriptorManager = new BeanDescriptorManager(this);
|
||||
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy();
|
||||
Map<String, String> draftTableMap = beanDescriptorManager.draftTableMap();
|
||||
beanDescriptorManager.scheduleBackgroundTrim();
|
||||
this.dataTimeZone = initDataTimeZone();
|
||||
this.binder = getBinder(typeManager, databasePlatform, dataTimeZone);
|
||||
this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping, draftTableMap);
|
||||
this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping);
|
||||
}
|
||||
|
||||
public boolean isJacksonCorePresent() {
|
||||
|
||||
@@ -44,7 +44,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
*/
|
||||
private final Object parentBean;
|
||||
private final boolean dirty;
|
||||
private final boolean publish;
|
||||
private int flags;
|
||||
private boolean saveRecurse;
|
||||
private DocStoreMode docStoreMode;
|
||||
@@ -153,10 +152,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
}
|
||||
}
|
||||
this.concurrencyMode = beanDescriptor.concurrencyMode(intercept);
|
||||
this.publish = Flags.isPublish(flags);
|
||||
if (isMarkDraftDirty(publish)) {
|
||||
beanDescriptor.setDraftDirty(entityBean, true);
|
||||
}
|
||||
this.dirty = intercept.isDirty();
|
||||
}
|
||||
|
||||
@@ -201,13 +196,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return Flags.isRecurse(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the draftDirty property should be set to true for this request.
|
||||
*/
|
||||
private boolean isMarkDraftDirty(boolean publish) {
|
||||
return !publish && type != Type.DELETE && beanDescriptor.isDraftable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction from prior persist request.
|
||||
* Only used when hard deleting draft & associated live beans.
|
||||
@@ -417,7 +405,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
* Set the cache notify status.
|
||||
*/
|
||||
private void setNotifyCache() {
|
||||
this.notifyCache = beanDescriptor.isCacheNotify(type, publish);
|
||||
this.notifyCache = beanDescriptor.isCacheNotify(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -642,28 +630,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return beanDescriptor.createRef(beanId(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean type is a Draftable.
|
||||
*/
|
||||
public boolean isDraftable() {
|
||||
return beanDescriptor.isDraftable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this request is a hard delete of a draftable bean.
|
||||
* If this is true Ebean is expected to auto-publish and delete the associated live bean.
|
||||
*/
|
||||
public boolean isHardDeleteDraft() {
|
||||
if (type == Type.DELETE && beanDescriptor.isDraftable() && !beanDescriptor.isDraftableElement()) {
|
||||
// deleting a top level draftable bean
|
||||
if (beanDescriptor.isLiveInstance(entityBean)) {
|
||||
throw new PersistenceException("Explicit Delete is not allowed on a 'live' bean - only draft beans");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this was a hard/permanent delete request (and should cascade as such).
|
||||
*/
|
||||
@@ -671,16 +637,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return (type == Type.DELETE && beanDescriptor.isSoftDelete());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for @Draftable entity beans with @Draft property that the bean is a 'draft'.
|
||||
* Save or Update is not allowed to execute using 'live' beans - must use publish().
|
||||
*/
|
||||
public void checkDraft() {
|
||||
if (beanDescriptor.isDraftable() && beanDescriptor.isLiveInstance(entityBean)) {
|
||||
throw new PersistenceException("Save or update is not allowed on a 'live' bean - only draft beans");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parent bean for cascading save with unidirectional relationship.
|
||||
*/
|
||||
@@ -928,20 +884,19 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
}
|
||||
|
||||
private void logSummaryMessage() {
|
||||
String draft = (beanDescriptor.isDraftable() && !publish) ? " draft[true]" : "";
|
||||
String name = beanDescriptor.name();
|
||||
switch (type) {
|
||||
case INSERT:
|
||||
transaction.logSummary("Inserted [{0}] [{1}]{2}", name, (idValue == null ? "" : idValue), draft);
|
||||
transaction.logSummary("Inserted [{0}] [{1}]", name, (idValue == null ? "" : idValue));
|
||||
break;
|
||||
case UPDATE:
|
||||
transaction.logSummary("Updated [{0}] [{1}]{2}", name, idValue , draft);
|
||||
transaction.logSummary("Updated [{0}] [{1}]", name, idValue);
|
||||
break;
|
||||
case DELETE:
|
||||
transaction.logSummary("Deleted [{0}] [{1}]{2}", name, idValue , draft);
|
||||
transaction.logSummary("Deleted [{0}] [{1}]", name, idValue);
|
||||
break;
|
||||
case DELETE_SOFT:
|
||||
transaction.logSummary("SoftDelete [{0}] [{1}]{2}", name, idValue , draft);
|
||||
transaction.logSummary("SoftDelete [{0}] [{1}]", name, idValue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -979,9 +934,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
private void postInsert() {
|
||||
// mark all properties as loaded after an insert to support immediate update
|
||||
beanDescriptor.setAllLoaded(entityBean);
|
||||
if (!publish) {
|
||||
beanDescriptor.setDraft(entityBean);
|
||||
}
|
||||
if (transaction.isAutoPersistUpdates() && idValue != null) {
|
||||
// with getGeneratedKeys off we will not have a idValue
|
||||
beanDescriptor.contextPut(transaction.persistenceContext(), idValue, entityBean);
|
||||
@@ -1129,13 +1081,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this request is a 'publish' action.
|
||||
*/
|
||||
public boolean isPublish() {
|
||||
return publish;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key for an update persist request.
|
||||
*/
|
||||
@@ -1152,17 +1097,14 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
key.append('v');
|
||||
}
|
||||
}
|
||||
if (publish) {
|
||||
key.append('p');
|
||||
}
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the table to update depending if the request is a 'publish' one or normal.
|
||||
* Return the table to update.
|
||||
*/
|
||||
public String updateTable() {
|
||||
return publish ? beanDescriptor.baseTable() : beanDescriptor.draftTable();
|
||||
return beanDescriptor.baseTable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1374,7 +1316,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
* Return the SQL used to fetch the last inserted id value.
|
||||
*/
|
||||
public String selectLastInsertedId() {
|
||||
return beanDescriptor.selectLastInsertedId(publish);
|
||||
return beanDescriptor.selectLastInsertedId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,16 +83,6 @@ public interface Persister {
|
||||
*/
|
||||
int executeCallable(CallableSql callable, Transaction t);
|
||||
|
||||
/**
|
||||
* Publish the draft beans matching the given query.
|
||||
*/
|
||||
<T> List<T> publish(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Restore the draft beans back to the matching live beans.
|
||||
*/
|
||||
<T> List<T> draftRestore(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Visit the metrics.
|
||||
*/
|
||||
|
||||
@@ -42,7 +42,6 @@ import io.ebeaninternal.server.query.*;
|
||||
import io.ebeaninternal.server.querydefn.DefaultOrmQuery;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
import io.ebeaninternal.util.SortByClause;
|
||||
import io.ebeaninternal.util.SortByClauseParser;
|
||||
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
|
||||
@@ -103,7 +102,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* getGeneratedKeys is not supported.
|
||||
*/
|
||||
private final String selectLastInsertedId;
|
||||
private final String selectLastInsertedIdDraft;
|
||||
private final boolean autoTunable;
|
||||
private final ConcurrencyMode concurrencyMode;
|
||||
private final IndexDefinition[] indexDefinitions;
|
||||
@@ -115,17 +113,12 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final TableJoin primaryKeyJoin;
|
||||
private final BeanProperty softDeleteProperty;
|
||||
private final boolean softDelete;
|
||||
private final String draftTable;
|
||||
private final PartitionMeta partitionMeta;
|
||||
private final TablespaceMeta tablespaceMeta;
|
||||
private final String storageEngine;
|
||||
private final String dbComment;
|
||||
private final boolean draftable;
|
||||
private final boolean draftableElement;
|
||||
private final BeanProperty unmappedJson;
|
||||
private final BeanProperty tenant;
|
||||
private final BeanProperty draft;
|
||||
private final BeanProperty draftDirty;
|
||||
private final LinkedHashMap<String, BeanProperty> propMap;
|
||||
/**
|
||||
* Map of DB column to property path (for nativeSql mapping).
|
||||
@@ -218,7 +211,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final String baseTableAlias;
|
||||
private final boolean cacheSharableBeans;
|
||||
private final String docStoreQueueId;
|
||||
private final BeanDescriptorDraftHelp<T> draftHelp;
|
||||
private final BeanDescriptorCacheHelp<T> cacheHelp;
|
||||
private final BeanDescriptorJsonHelp<T> jsonHelp;
|
||||
private DocStoreBeanAdapter<T> docStoreAdapter;
|
||||
@@ -253,13 +245,9 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
this.idGeneratedValue = deploy.isIdGeneratedValue();
|
||||
this.idGenerator = deploy.getIdGenerator();
|
||||
this.selectLastInsertedId = deploy.getSelectLastInsertedId();
|
||||
this.selectLastInsertedIdDraft = deploy.getSelectLastInsertedIdDraft();
|
||||
this.concurrencyMode = deploy.getConcurrencyMode();
|
||||
this.indexDefinitions = deploy.getIndexDefinitions();
|
||||
this.draftable = deploy.isDraftable();
|
||||
this.draftableElement = deploy.isDraftableElement();
|
||||
this.historySupport = deploy.isHistorySupport();
|
||||
this.draftTable = deploy.getDraftTable();
|
||||
this.baseTable = InternString.intern(deploy.getBaseTable());
|
||||
this.baseTableAsOf = deploy.getBaseTableAsOf();
|
||||
this.primaryKeyJoin = deploy.getPrimaryKeyJoin();
|
||||
@@ -281,8 +269,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
this.versionProperty = listHelper.getVersionProperty();
|
||||
this.unmappedJson = listHelper.getUnmappedJson();
|
||||
this.tenant = listHelper.getTenant();
|
||||
this.draft = listHelper.getDraft();
|
||||
this.draftDirty = listHelper.getDraftDirty();
|
||||
this.propMap = listHelper.getPropertyMap();
|
||||
this.propertiesTransient = listHelper.getTransients();
|
||||
this.propertiesNonTransient = listHelper.getNonTransients();
|
||||
@@ -311,7 +297,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
this.cacheSharableBeans = noRelationships && deploy.getCacheOptions().isReadOnly();
|
||||
this.cacheHelp = new BeanDescriptorCacheHelp<>(this, owner.cacheManager(), deploy.getCacheOptions(), cacheSharableBeans, propertiesOneImported);
|
||||
this.jsonHelp = initJsonHelp();
|
||||
this.draftHelp = new BeanDescriptorDraftHelp<>(this);
|
||||
this.docStoreAdapter = owner.createDocStoreBeanAdapter(this, deploy);
|
||||
this.docStoreQueueId = docStoreAdapter.queueId();
|
||||
// Check if there are no cascade save associated beans ( subject to change
|
||||
@@ -473,9 +458,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* as they are used to get the imported and exported properties.
|
||||
*/
|
||||
void initialiseId(BeanDescriptorInitContext initContext) {
|
||||
if (draftable) {
|
||||
initContext.addDraft(baseTable, draftTable);
|
||||
}
|
||||
if (historySupport) {
|
||||
// add mapping (used to swap out baseTable for asOf queries)
|
||||
initContext.addHistory(baseTable, baseTableAsOf);
|
||||
@@ -494,10 +476,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* Initialise the exported and imported parts for associated properties.
|
||||
*/
|
||||
public void initialiseOther(BeanDescriptorInitContext initContext) {
|
||||
for (BeanPropertyAssocMany<?> many : propertiesManyToMany) {
|
||||
// register associated draft table for M2M intersection
|
||||
many.registerDraftIntersectionTable(initContext);
|
||||
}
|
||||
if (historySupport) {
|
||||
// history support on this bean so check all associated intersection tables
|
||||
// and if they are not excluded register the associated 'with history' table
|
||||
@@ -1044,24 +1022,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
docStoreAdapter.deleteById(idValue, txn);
|
||||
}
|
||||
|
||||
public T publish(T draftBean, T liveBean) {
|
||||
return draftHelp.publish(draftBean, liveBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset properties on the draft bean based on @DraftDirty and @DraftReset.
|
||||
*/
|
||||
public boolean draftReset(T draftBean) {
|
||||
return draftHelp.draftReset(draftBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draft dirty boolean property or null if there is not one assigned to this bean type.
|
||||
*/
|
||||
BeanProperty draftDirty() {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the query for multi-tenancy check for document store only use.
|
||||
*/
|
||||
@@ -1114,11 +1074,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
/**
|
||||
* Return true if the persist request needs to notify the cache.
|
||||
*/
|
||||
public boolean isCacheNotify(PersistRequest.Type type, boolean publish) {
|
||||
if (draftable && !publish) {
|
||||
// no caching when editing draft beans
|
||||
return false;
|
||||
}
|
||||
public boolean isCacheNotify(PersistRequest.Type type) {
|
||||
return cacheHelp.isCacheNotify(type);
|
||||
}
|
||||
|
||||
@@ -2622,8 +2578,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
@Override
|
||||
public String baseTable(SpiQuery.TemporalMode mode) {
|
||||
switch (mode) {
|
||||
case DRAFT:
|
||||
return draftTable;
|
||||
case VERSIONS:
|
||||
return baseTableVersionsBetween;
|
||||
case AS_OF:
|
||||
@@ -2633,13 +2587,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the associated draft table.
|
||||
*/
|
||||
public String draftTable() {
|
||||
return draftTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoftDelete() {
|
||||
return softDelete;
|
||||
@@ -2671,20 +2618,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this entity type is draftable.
|
||||
*/
|
||||
public boolean isDraftable() {
|
||||
return draftable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this entity type is a draftable element (child).
|
||||
*/
|
||||
public boolean isDraftableElement() {
|
||||
return draftableElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> pathMap(String prefix) {
|
||||
return pathMaps.computeIfAbsent(prefix, s -> {
|
||||
@@ -2750,28 +2683,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the draft to true for this entity bean instance.
|
||||
* This bean is being loaded via asDraft() query.
|
||||
*/
|
||||
@Override
|
||||
public void setDraft(EntityBean entityBean) {
|
||||
if (draft != null) {
|
||||
draft.setValue(entityBean, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean is considered a 'draft' instance (not 'live').
|
||||
*/
|
||||
public boolean isDraftInstance(EntityBean entityBean) {
|
||||
if (draft != null) {
|
||||
return Boolean.TRUE == draft.getValue(entityBean);
|
||||
}
|
||||
// no draft property - so return false
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToManyDirty(EntityBean bean) {
|
||||
final EntityBeanIntercept ebi = bean._ebean_getIntercept();
|
||||
@@ -2786,39 +2697,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean is draftable and considered a 'live' instance.
|
||||
*/
|
||||
public boolean isLiveInstance(EntityBean entityBean) {
|
||||
if (draft != null) {
|
||||
return Boolean.FALSE == draft.getValue(entityBean);
|
||||
}
|
||||
// no draft property - so return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a @DraftDirty property set it's value on the bean.
|
||||
*/
|
||||
public void setDraftDirty(EntityBean entityBean, boolean value) {
|
||||
if (draftDirty != null) {
|
||||
// check to see if the dirty property has already
|
||||
// been set and if so do not set the value
|
||||
if (!entityBean._ebean_getIntercept().isChangedProperty(draftDirty.propertyIndex())) {
|
||||
draftDirty.setValueIntercept(entityBean, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimise the draft query fetching any draftable element relationships.
|
||||
*/
|
||||
public void draftQueryOptimise(Query<T> query) {
|
||||
// use per query PersistenceContext to ensure fresh beans loaded
|
||||
query.setPersistenceContextScope(PersistenceContextScope.QUERY);
|
||||
draftHelp.draftQueryOptimise(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this entity bean has history support.
|
||||
*/
|
||||
@@ -2864,8 +2742,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* This is only used with Identity columns and getGeneratedKeys is not
|
||||
* supported.
|
||||
*/
|
||||
public String selectLastInsertedId(boolean publish) {
|
||||
return publish ? selectLastInsertedId : selectLastInsertedIdDraft;
|
||||
public String selectLastInsertedId() {
|
||||
return selectLastInsertedId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.Query;
|
||||
import io.ebean.bean.EntityBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper for BeanDescriptor that manages draft entity beans.
|
||||
*
|
||||
* @param <T> The entity bean type
|
||||
*/
|
||||
final class BeanDescriptorDraftHelp<T> {
|
||||
|
||||
private final BeanDescriptor<T> desc;
|
||||
private final BeanProperty draftDirty;
|
||||
private final BeanProperty[] resetProperties;
|
||||
|
||||
BeanDescriptorDraftHelp(BeanDescriptor<T> desc) {
|
||||
this.desc = desc;
|
||||
this.draftDirty = desc.draftDirty();
|
||||
this.resetProperties = resetProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the properties that are reset on draft beans after publish.
|
||||
*/
|
||||
private BeanProperty[] resetProperties() {
|
||||
List<BeanProperty> list = new ArrayList<>();
|
||||
for (BeanProperty prop : desc.propertiesNonMany()) {
|
||||
if (prop.isDraftReset()) {
|
||||
list.add(prop);
|
||||
}
|
||||
}
|
||||
return list.toArray(new BeanProperty[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of all the 'reset properties' to null on the draft bean.
|
||||
*/
|
||||
boolean draftReset(T draftBean) {
|
||||
EntityBean draftEntityBean = (EntityBean) draftBean;
|
||||
if (draftDirty != null) {
|
||||
// set @DraftDirty property to false
|
||||
draftDirty.setValueIntercept(draftEntityBean, false);
|
||||
}
|
||||
// set to null on all @DraftReset properties
|
||||
for (BeanProperty resetProperty : resetProperties) {
|
||||
resetProperty.setValueIntercept(draftEntityBean, null);
|
||||
}
|
||||
// return true if the bean is dirty (and should be persisted)
|
||||
return draftEntityBean._ebean_getIntercept().isDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer the values from the draftBean to the liveBean.
|
||||
* <p>
|
||||
* This will recursive transfer values to all @DraftableElement properties.
|
||||
* </p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T publish(T draftBean, T liveBean) {
|
||||
if (liveBean == null) {
|
||||
liveBean = (T) desc.createEntityBean();
|
||||
}
|
||||
EntityBean draft = (EntityBean) draftBean;
|
||||
EntityBean live = (EntityBean) liveBean;
|
||||
BeanProperty idProperty = desc.idProperty();
|
||||
if (idProperty != null) {
|
||||
idProperty.publish(draft, live);
|
||||
}
|
||||
for (BeanProperty prop : desc.propertiesNonMany()) {
|
||||
prop.publish(draft, live);
|
||||
}
|
||||
for (BeanPropertyAssocMany<?> many : desc.propertiesMany()) {
|
||||
if (many.targetDescriptor().isDraftable()) {
|
||||
many.publishMany(draft, live);
|
||||
}
|
||||
}
|
||||
return liveBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch draftable element relationships.
|
||||
*/
|
||||
void draftQueryOptimise(Query<T> query) {
|
||||
for (BeanPropertyAssocOne<?> anOne : desc.propertiesOne()) {
|
||||
if (anOne.targetDescriptor().isDraftableElement()) {
|
||||
query.fetch(anOne.name());
|
||||
}
|
||||
}
|
||||
for (BeanPropertyAssocMany<?> aMany : desc.propertiesMany()) {
|
||||
if (aMany.targetDescriptor().isDraftableElement()) {
|
||||
query.fetch(aMany.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-11
@@ -5,20 +5,14 @@ import java.util.Map;
|
||||
class BeanDescriptorInitContext {
|
||||
|
||||
private final Map<String, String> withHistoryTables;
|
||||
private final Map<String, String> draftTables;
|
||||
private final String asOfViewSuffix;
|
||||
private String embeddedPrefix;
|
||||
|
||||
BeanDescriptorInitContext(Map<String, String> withHistoryTables, Map<String, String> draftTables, String asOfViewSuffix) {
|
||||
BeanDescriptorInitContext(Map<String, String> withHistoryTables, String asOfViewSuffix) {
|
||||
this.withHistoryTables = withHistoryTables;
|
||||
this.draftTables = draftTables;
|
||||
this.asOfViewSuffix = asOfViewSuffix;
|
||||
}
|
||||
|
||||
void addDraft(String baseTable, String draftTable) {
|
||||
draftTables.put(baseTable, draftTable);
|
||||
}
|
||||
|
||||
void addHistory(String baseTable, String baseTableAsOf) {
|
||||
withHistoryTables.put(baseTable, baseTableAsOf);
|
||||
}
|
||||
@@ -27,10 +21,6 @@ class BeanDescriptorInitContext {
|
||||
withHistoryTables.put(intersectionTableName, intersectionTableName + asOfViewSuffix);
|
||||
}
|
||||
|
||||
void addDraftIntersection(String intersectionPublishTable, String intersectionDraftTable) {
|
||||
draftTables.put(intersectionPublishTable, intersectionDraftTable);
|
||||
}
|
||||
|
||||
public void setEmbeddedPrefix(String embeddedPrefix) {
|
||||
this.embeddedPrefix = embeddedPrefix;
|
||||
}
|
||||
|
||||
@@ -106,10 +106,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
* Map of base tables to 'with history views' used to support 'as of' queries.
|
||||
*/
|
||||
private final Map<String, String> asOfTableMap = new HashMap<>();
|
||||
/**
|
||||
* Map of base tables to 'draft' tables.
|
||||
*/
|
||||
private final Map<String, String> draftTableMap = new HashMap<>();
|
||||
|
||||
// temporary collections used during startup and then cleared
|
||||
private Map<Class<?>, DeployBeanInfo<?>> deployInfoMap = new HashMap<>();
|
||||
@@ -269,13 +265,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
return idBinderFactory.createIdBinder(idProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the map of base tables to draft tables.
|
||||
*/
|
||||
public Map<String, String> draftTableMap() {
|
||||
return draftTableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy returning the asOfTableMap (which is required by the SQL builders).
|
||||
*/
|
||||
@@ -417,7 +406,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
// now that all the BeanDescriptors are in their map
|
||||
// we can initialise them which sorts out circular
|
||||
// dependencies for OneToMany and ManyToOne etc
|
||||
BeanDescriptorInitContext initContext = new BeanDescriptorInitContext(asOfTableMap, draftTableMap, asOfViewSuffix);
|
||||
BeanDescriptorInitContext initContext = new BeanDescriptorInitContext(asOfTableMap, asOfViewSuffix);
|
||||
|
||||
// PASS 1:
|
||||
// initialise the ID properties of all the beans
|
||||
@@ -959,13 +948,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
// skip mapping check
|
||||
return;
|
||||
}
|
||||
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
|
||||
if (targetDesc.isDraftableElement()) {
|
||||
// automatically turning on orphan removal and CascadeType.ALL
|
||||
prop.setModifyListenMode(BeanCollection.ModifyListenMode.REMOVALS);
|
||||
prop.getCascadeInfo().setSaveDelete(true, true);
|
||||
}
|
||||
|
||||
if (prop.hasOrderColumn()) {
|
||||
makeOrderColumn(prop);
|
||||
}
|
||||
@@ -991,6 +973,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
String mappedBy = prop.getMappedBy();
|
||||
|
||||
// get the mappedBy property
|
||||
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
|
||||
DeployBeanPropertyAssocOne<?> mappedAssocOne = mappedManyToOne(prop, targetDesc, mappedBy);
|
||||
DeployTableJoin tableJoin = prop.getTableJoin();
|
||||
if (!tableJoin.hasJoinColumns()) {
|
||||
@@ -1032,9 +1015,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
// get the bean descriptor that holds the mappedBy property
|
||||
String mappedBy = prop.getMappedBy();
|
||||
if (mappedBy == null) {
|
||||
if (targetDescriptor(prop).isDraftable()) {
|
||||
prop.setIntersectionDraftTable();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1059,10 +1039,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
DeployTableJoin inverseJoin = new DeployTableJoin();
|
||||
mappedIntJoin.copyTo(inverseJoin, false, intTableName);
|
||||
prop.setInverseJoin(inverseJoin);
|
||||
|
||||
if (targetDesc.isDraftable()) {
|
||||
prop.setIntersectionDraftTable();
|
||||
}
|
||||
}
|
||||
|
||||
private DeployBeanPropertyAssocMany<?> mappedManyToMany(DeployBeanPropertyAssocMany<?> prop, String mappedBy, DeployBeanDescriptor<?> targetDesc) {
|
||||
@@ -1179,8 +1155,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
if (identityMode.isIdentity()) {
|
||||
// used when getGeneratedKeys is not supported (SQL Server 2000, SAP Hana)
|
||||
String selectLastInsertedId = dbIdentity.getSelectLastInsertedId(desc.getBaseTable());
|
||||
String selectLastInsertedIdDraft = (!desc.isDraftable()) ? selectLastInsertedId : dbIdentity.getSelectLastInsertedId(desc.getDraftTable());
|
||||
desc.setSelectLastInsertedId(selectLastInsertedId, selectLastInsertedIdDraft);
|
||||
desc.setSelectLastInsertedId(selectLastInsertedId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,10 +171,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
final boolean jsonDeserialize;
|
||||
private final boolean unmappedJson;
|
||||
private final boolean tenantId;
|
||||
private final boolean draft;
|
||||
private final boolean draftOnly;
|
||||
private final boolean draftDirty;
|
||||
private final boolean draftReset;
|
||||
private final boolean softDelete;
|
||||
private final String softDeleteDbSet;
|
||||
private final String softDeleteDbPredicate;
|
||||
@@ -201,10 +197,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
this.excludedFromHistory = deploy.isExcludedFromHistory();
|
||||
this.unmappedJson = deploy.isUnmappedJson();
|
||||
this.tenantId = deploy.isTenantId();
|
||||
this.draft = deploy.isDraft();
|
||||
this.draftDirty = deploy.isDraftDirty();
|
||||
this.draftOnly = deploy.isDraftOnly();
|
||||
this.draftReset = deploy.isDraftReset();
|
||||
this.secondaryTable = deploy.isSecondaryTable();
|
||||
if (secondaryTable) {
|
||||
this.secondaryTableJoin = new TableJoin(deploy.getSecondaryTableJoin());
|
||||
@@ -296,10 +288,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
this.aggregation = null;
|
||||
this.excludedFromHistory = source.excludedFromHistory;
|
||||
this.tenantId = source.tenantId;
|
||||
this.draft = source.draft;
|
||||
this.draftDirty = source.draftDirty;
|
||||
this.draftOnly = source.draftOnly;
|
||||
this.draftReset = source.draftReset;
|
||||
this.softDelete = source.softDelete;
|
||||
this.softDeleteDbSet = source.softDeleteDbSet;
|
||||
this.softDeleteDbPredicate = source.softDeleteDbPredicate;
|
||||
@@ -483,7 +471,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
ctx.appendFormulaSelect(aggregation);
|
||||
} else if (formula) {
|
||||
ctx.appendFormulaSelect(sqlFormulaSelect);
|
||||
} else if (!isTransient && !ignoreDraftOnlyProperty(ctx.isDraftQuery())) {
|
||||
} else if (!isTransient) {
|
||||
if (secondaryTableJoin != null) {
|
||||
ctx.pushTableAlias(ctx.relativePrefix(secondaryTableJoinPrefix));
|
||||
}
|
||||
@@ -590,17 +578,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
return local;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy/set the property value from the draft bean to the live bean.
|
||||
*/
|
||||
public void publish(EntityBean draftBean, EntityBean liveBean) {
|
||||
if (!version && !draftOnly) {
|
||||
// set property value from draft to live
|
||||
Object value = getValueIntercept(draftBean);
|
||||
setValueIntercept(liveBean, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DB literal expression to set the deleted state to true.
|
||||
*/
|
||||
@@ -1090,16 +1067,8 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
/**
|
||||
* Return true if this property is loadable from a resultSet.
|
||||
*/
|
||||
public boolean isLoadProperty(boolean draftQuery) {
|
||||
return !ignoreDraftOnlyProperty(draftQuery) && (!isTransient || formula);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a draftOnly property on a non-asDraft query and as such this
|
||||
* property should not be included in a sql query.
|
||||
*/
|
||||
private boolean ignoreDraftOnlyProperty(boolean draftQuery) {
|
||||
return draftOnly && !draftQuery;
|
||||
public boolean isLoadProperty() {
|
||||
return !isTransient || formula;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1248,36 +1217,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property only exists on the draft table.
|
||||
*/
|
||||
public boolean isDraftOnly() {
|
||||
return draftOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property is a boolean flag on a draftable bean
|
||||
* indicating if the instance is a draft or live bean.
|
||||
*/
|
||||
public boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property is a boolean flag only on the draft table
|
||||
* indicating that when the draft is different from the published row.
|
||||
*/
|
||||
public boolean isDraftDirty() {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property is reset/cleared on publish (on the draft bean).
|
||||
*/
|
||||
boolean isDraftReset() {
|
||||
return draftReset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property is the soft delete property.
|
||||
*/
|
||||
|
||||
@@ -41,8 +41,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
* Join for manyToMany intersection table.
|
||||
*/
|
||||
private final TableJoin intersectionJoin;
|
||||
private final String intersectionPublishTable;
|
||||
private final String intersectionDraftTable;
|
||||
private final boolean orphanRemoval;
|
||||
private IntersectionTable intersectionTable;
|
||||
/**
|
||||
@@ -102,13 +100,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
this.mapKey = deploy.getMapKey();
|
||||
this.fetchOrderBy = deploy.getFetchOrderBy();
|
||||
this.intersectionJoin = deploy.createIntersectionTableJoin();
|
||||
if (intersectionJoin != null) {
|
||||
this.intersectionPublishTable = intersectionJoin.getTable();
|
||||
this.intersectionDraftTable = deploy.getIntersectionDraftTable();
|
||||
} else {
|
||||
this.intersectionPublishTable = null;
|
||||
this.intersectionDraftTable = null;
|
||||
}
|
||||
this.inverseJoin = deploy.createInverseTableJoin();
|
||||
this.modifyListenMode = deploy.getModifyListenMode();
|
||||
this.jsonHelp = descriptor.isJacksonCorePresent() ? new BeanPropertyAssocManyJsonHelp(this) : null;
|
||||
@@ -375,7 +366,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
}
|
||||
|
||||
private IntersectionTable initIntersectionTable() {
|
||||
IntersectionBuilder row = new IntersectionBuilder(intersectionPublishTable, intersectionDraftTable);
|
||||
IntersectionBuilder row = new IntersectionBuilder(intersectionJoin.getTable());
|
||||
for (ExportedProperty exportedProperty : exportedProperties) {
|
||||
row.addColumn(exportedProperty.getForeignDbColumn());
|
||||
}
|
||||
@@ -434,7 +425,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
StringBuilder sb = new StringBuilder(50).append("from "); // use from to stop parsing on table name
|
||||
SpiQuery<?> query = request.queryRequest().query();
|
||||
if (hasJoinTable()) {
|
||||
sb.append(query.isAsDraft() ? intersectionDraftTable : intersectionPublishTable);
|
||||
sb.append(intersectionJoin.getTable());
|
||||
} else {
|
||||
sb.append(targetDescriptor.baseTable(query.temporalMode()));
|
||||
}
|
||||
@@ -764,37 +755,21 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
return row;
|
||||
}
|
||||
|
||||
public IntersectionRow buildManyToManyDeleteChildren(EntityBean parentBean, boolean publish) {
|
||||
String tableName = publish ? intersectionPublishTable : intersectionDraftTable;
|
||||
public IntersectionRow buildManyToManyDeleteChildren(EntityBean parentBean) {
|
||||
String tableName = intersectionJoin.getTable();
|
||||
IntersectionRow row = new IntersectionRow(tableName);
|
||||
buildExport(row, parentBean);
|
||||
return row;
|
||||
}
|
||||
|
||||
public IntersectionRow buildManyToManyMapBean(EntityBean parent, EntityBean other, boolean publish) {
|
||||
String tableName = publish ? intersectionPublishTable : intersectionDraftTable;
|
||||
public IntersectionRow buildManyToManyMapBean(EntityBean parent, EntityBean other) {
|
||||
String tableName = intersectionJoin.getTable();
|
||||
IntersectionRow row = new IntersectionRow(tableName);
|
||||
buildExport(row, parent);
|
||||
buildImport(row, other);
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the mapping of intersection table to associated draft table.
|
||||
*/
|
||||
void registerDraftIntersectionTable(BeanDescriptorInitContext initContext) {
|
||||
if (hasDraftIntersection()) {
|
||||
initContext.addDraftIntersection(intersectionPublishTable, intersectionDraftTable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the relationship is a ManyToMany with the intersection having an associated draft table.
|
||||
*/
|
||||
private boolean hasDraftIntersection() {
|
||||
return intersectionDraftTable != null && !intersectionDraftTable.equals(intersectionPublishTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the two side of a many to many to the given SqlUpdate.
|
||||
*/
|
||||
@@ -879,55 +854,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
jsonHelp.jsonRead(readJson, parentBean);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void publishMany(EntityBean draft, EntityBean live) {
|
||||
// collections will not be null due to enhancement
|
||||
BeanCollection<T> draftVal = (BeanCollection<T>) getValueIntercept(draft);
|
||||
BeanCollection<T> liveVal = (BeanCollection<T>) getValueIntercept(live);
|
||||
|
||||
// Organise the existing live beans into map keyed by id
|
||||
Map<Object, T> liveBeansAsMap = liveBeansAsMap(liveVal);
|
||||
|
||||
// publish from each draft to live bean creating new live beans as required
|
||||
draftVal.size();
|
||||
Collection<T> actualDetails = draftVal.actualDetails();
|
||||
for (T bean : actualDetails) {
|
||||
Object id = targetDescriptor.id(bean);
|
||||
T liveBean = liveBeansAsMap.remove(id);
|
||||
|
||||
if (isManyToMany()) {
|
||||
if (liveBean == null) {
|
||||
// add new relationship (Map not allowed here)
|
||||
liveVal.addBean(targetDescriptor.createReference(id, null));
|
||||
}
|
||||
} else {
|
||||
// recursively publish the OneToMany child bean
|
||||
T newLive = targetDescriptor.publish(bean, liveBean);
|
||||
if (liveBean == null) {
|
||||
// Map not allowed here
|
||||
liveVal.addBean(newLive);
|
||||
}
|
||||
}
|
||||
}
|
||||
// anything remaining should be deleted (so remove from modify aware collection)
|
||||
Collection<T> values = liveBeansAsMap.values();
|
||||
for (T value : values) {
|
||||
liveVal.removeBean(value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<Object, T> liveBeansAsMap(BeanCollection<?> liveVal) {
|
||||
liveVal.size();
|
||||
Collection<?> liveBeans = liveVal.actualDetails();
|
||||
Map<Object, T> liveMap = new LinkedHashMap<>();
|
||||
for (Object liveBean : liveBeans) {
|
||||
Object id = targetDescriptor.id(liveBean);
|
||||
liveMap.put(id, (T) liveBean);
|
||||
}
|
||||
return liveMap;
|
||||
}
|
||||
|
||||
public boolean isIncludeCascadeSave() {
|
||||
// Note ManyToMany always included as we always 'save'
|
||||
// the relationship via insert/delete of intersection table
|
||||
|
||||
@@ -79,11 +79,6 @@ public interface DbReadContext {
|
||||
*/
|
||||
SpiQuery.Mode queryMode();
|
||||
|
||||
/**
|
||||
* Return true if the underlying query is a 'asDraft' query.
|
||||
*/
|
||||
boolean isDraftQuery();
|
||||
|
||||
/**
|
||||
* Return true if this request disables lazy loading.
|
||||
*/
|
||||
|
||||
@@ -124,11 +124,6 @@ public interface DbSqlContext {
|
||||
*/
|
||||
int asOfTableCount();
|
||||
|
||||
/**
|
||||
* Return true if the query is a 'asDraft' query.
|
||||
*/
|
||||
boolean isDraftQuery();
|
||||
|
||||
/**
|
||||
* Start group by clause.
|
||||
*/
|
||||
|
||||
@@ -8,13 +8,11 @@ import java.util.List;
|
||||
*/
|
||||
public final class IntersectionBuilder {
|
||||
|
||||
private final String publishTable;
|
||||
private final String draftTable;
|
||||
private final String table;
|
||||
private final List<String> columns = new ArrayList<>();
|
||||
|
||||
IntersectionBuilder(String publishTable, String draftTable) {
|
||||
this.publishTable = publishTable;
|
||||
this.draftTable = draftTable;
|
||||
IntersectionBuilder(String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public void addColumn(String column) {
|
||||
@@ -22,18 +20,9 @@ public final class IntersectionBuilder {
|
||||
}
|
||||
|
||||
public IntersectionTable build() {
|
||||
String insertSql = insertSql(publishTable);
|
||||
String deleteSql = deleteSql(publishTable);
|
||||
String draftInsertSql;
|
||||
String draftDeleteSql;
|
||||
if (publishTable.equals(draftTable)) {
|
||||
draftInsertSql = insertSql;
|
||||
draftDeleteSql = deleteSql;
|
||||
} else {
|
||||
draftInsertSql = insertSql(draftTable);
|
||||
draftDeleteSql = deleteSql(draftTable);
|
||||
}
|
||||
return new IntersectionTable(insertSql, deleteSql, draftInsertSql, draftDeleteSql);
|
||||
String insertSql = insertSql(table);
|
||||
String deleteSql = deleteSql(table);
|
||||
return new IntersectionTable(insertSql, deleteSql);
|
||||
}
|
||||
|
||||
private String insertSql(String tableName) {
|
||||
|
||||
@@ -7,28 +7,24 @@ public final class IntersectionTable {
|
||||
|
||||
private final String insertSql;
|
||||
private final String deleteSql;
|
||||
private final String draftInsertSql;
|
||||
private final String draftDeleteSql;
|
||||
|
||||
IntersectionTable(String insertSql, String deleteSql, String draftInsertSql, String draftDeleteSql) {
|
||||
IntersectionTable(String insertSql, String deleteSql) {
|
||||
this.insertSql = insertSql;
|
||||
this.deleteSql = deleteSql;
|
||||
this.draftInsertSql = draftInsertSql;
|
||||
this.draftDeleteSql = draftDeleteSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a SqlUpdate for inserting into the intersection table.
|
||||
*/
|
||||
public SqlUpdate insert(Database server, boolean draft) {
|
||||
return server.sqlUpdate(draft ? draftInsertSql : insertSql);
|
||||
public SqlUpdate insert(Database server) {
|
||||
return server.sqlUpdate(insertSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a SqlUpdate for deleting from the intersection table.
|
||||
*/
|
||||
public SqlUpdate delete(Database server, boolean draft) {
|
||||
return server.sqlUpdate(draft ? draftDeleteSql : deleteSql);
|
||||
public SqlUpdate delete(Database server) {
|
||||
return server.sqlUpdate(deleteSql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-32
@@ -63,7 +63,6 @@ public class DeployBeanDescriptor<T> {
|
||||
* Used with Identity columns but no getGeneratedKeys support.
|
||||
*/
|
||||
private String selectLastInsertedId;
|
||||
private String selectLastInsertedIdDraft;
|
||||
/**
|
||||
* The concurrency mode for beans of this type.
|
||||
*/
|
||||
@@ -76,11 +75,8 @@ public class DeployBeanDescriptor<T> {
|
||||
private String baseTable;
|
||||
private String baseTableAsOf;
|
||||
private String baseTableVersionsBetween;
|
||||
private String draftTable;
|
||||
private String[] dependentTables;
|
||||
private boolean historySupport;
|
||||
private boolean draftable;
|
||||
private boolean draftableElement;
|
||||
private TableName baseTableFull;
|
||||
private String[] properties;
|
||||
/**
|
||||
@@ -217,23 +213,6 @@ public class DeployBeanDescriptor<T> {
|
||||
return tablespaceMeta;
|
||||
}
|
||||
|
||||
public void setDraftable() {
|
||||
draftable = true;
|
||||
}
|
||||
|
||||
public boolean isDraftable() {
|
||||
return draftable;
|
||||
}
|
||||
|
||||
public void setDraftableElement() {
|
||||
draftable = true;
|
||||
draftableElement = true;
|
||||
}
|
||||
|
||||
public boolean isDraftableElement() {
|
||||
return draftableElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the top level doc store deployment information.
|
||||
*/
|
||||
@@ -560,10 +539,6 @@ public class DeployBeanDescriptor<T> {
|
||||
postConstructListeners.add(postConstructListener);
|
||||
}
|
||||
|
||||
public String getDraftTable() {
|
||||
return draftTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* For view based entity return the dependant tables.
|
||||
*/
|
||||
@@ -617,7 +592,6 @@ public class DeployBeanDescriptor<T> {
|
||||
this.baseTable = baseTableFull == null ? null : baseTableFull.getQualifiedName();
|
||||
this.baseTableAsOf = baseTable + asOfSuffix;
|
||||
this.baseTableVersionsBetween = baseTable + versionsBetweenSuffix;
|
||||
this.draftTable = (draftable) ? baseTable + "_draft" : baseTable;
|
||||
}
|
||||
|
||||
public void sortProperties() {
|
||||
@@ -691,16 +665,11 @@ public class DeployBeanDescriptor<T> {
|
||||
return selectLastInsertedId;
|
||||
}
|
||||
|
||||
public String getSelectLastInsertedIdDraft() {
|
||||
return selectLastInsertedIdDraft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SQL used to return the last inserted Id.
|
||||
*/
|
||||
public void setSelectLastInsertedId(String selectLastInsertedId, String selectLastInsertedIdDraft) {
|
||||
public void setSelectLastInsertedId(String selectLastInsertedId) {
|
||||
this.selectLastInsertedId = selectLastInsertedId;
|
||||
this.selectLastInsertedIdDraft = selectLastInsertedIdDraft;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,10 +159,6 @@ public class DeployBeanProperty {
|
||||
private int sortOrder;
|
||||
private boolean excludedFromHistory;
|
||||
private boolean tenantId;
|
||||
private boolean draft;
|
||||
private boolean draftOnly;
|
||||
private boolean draftDirty;
|
||||
private boolean draftReset;
|
||||
private boolean softDelete;
|
||||
private boolean unmappedJson;
|
||||
private String dbComment;
|
||||
@@ -901,41 +897,6 @@ public class DeployBeanProperty {
|
||||
this.excludedFromHistory = true;
|
||||
}
|
||||
|
||||
public void setDraft() {
|
||||
this.draft = true;
|
||||
this.isTransient = true;
|
||||
}
|
||||
|
||||
public boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
public void setDraftOnly() {
|
||||
this.draftOnly = true;
|
||||
}
|
||||
|
||||
public boolean isDraftOnly() {
|
||||
return draftOnly;
|
||||
}
|
||||
|
||||
public void setDraftDirty() {
|
||||
this.draftOnly = true;
|
||||
this.draftDirty = true;
|
||||
this.nullable = false;
|
||||
}
|
||||
|
||||
public boolean isDraftDirty() {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
public void setDraftReset() {
|
||||
this.draftReset = true;
|
||||
}
|
||||
|
||||
public boolean isDraftReset() {
|
||||
return draftReset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primitive boolean check so see if not null default false should be applied.
|
||||
*/
|
||||
|
||||
-15
@@ -38,7 +38,6 @@ public class DeployBeanPropertyAssocMany<T> extends DeployBeanPropertyAssoc<T> {
|
||||
private DeployTableJoin inverseJoin;
|
||||
private String fetchOrderBy;
|
||||
private String mapKey;
|
||||
private String intersectionDraftTable;
|
||||
private DeployOrderColumn orderColumn;
|
||||
/**
|
||||
* Effectively the dynamically created target descriptor (that doesn't have a mapped type/class per say).
|
||||
@@ -191,20 +190,6 @@ public class DeployBeanPropertyAssocMany<T> extends DeployBeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a draft table for intersection between 2 @Draftable entities.
|
||||
*/
|
||||
public String getIntersectionDraftTable() {
|
||||
return (intersectionDraftTable != null) ? intersectionDraftTable : intersectionJoin.getTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* ManyToMany between 2 @Draftable entities to also need draft intersection table.
|
||||
*/
|
||||
public void setIntersectionDraftTable() {
|
||||
this.intersectionDraftTable = intersectionJoin.getTable() + "_draft";
|
||||
}
|
||||
|
||||
public void setOrderColumn(DeployOrderColumn orderColumn) {
|
||||
this.orderColumn = orderColumn;
|
||||
}
|
||||
|
||||
-15
@@ -22,8 +22,6 @@ public final class DeployBeanPropertyLists {
|
||||
|
||||
private BeanProperty versionProperty;
|
||||
private BeanProperty unmappedJson;
|
||||
private BeanProperty draft;
|
||||
private BeanProperty draftDirty;
|
||||
private BeanProperty tenant;
|
||||
private final BeanDescriptor<?> desc;
|
||||
private final LinkedHashMap<String, BeanProperty> propertyMap;
|
||||
@@ -173,9 +171,6 @@ public final class DeployBeanPropertyLists {
|
||||
private void allocateToList(BeanProperty prop) {
|
||||
if (prop.isTransient()) {
|
||||
transients.add(prop);
|
||||
if (prop.isDraft()) {
|
||||
draft = prop;
|
||||
}
|
||||
if (prop.isUnmappedJson()) {
|
||||
unmappedJson = prop;
|
||||
}
|
||||
@@ -226,8 +221,6 @@ public final class DeployBeanPropertyLists {
|
||||
} else {
|
||||
CoreLog.internal.log(WARNING, "Multiple @Version properties - property " + prop.fullName() + " not treated as a version property");
|
||||
}
|
||||
} else if (prop.isDraftDirty()) {
|
||||
draftDirty = prop;
|
||||
}
|
||||
if (!prop.isAggregation()) {
|
||||
baseScalar.add(prop);
|
||||
@@ -324,18 +317,10 @@ public final class DeployBeanPropertyLists {
|
||||
return getMany2Many();
|
||||
}
|
||||
|
||||
public BeanProperty getDraftDirty() {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
public BeanProperty getUnmappedJson() {
|
||||
return unmappedJson;
|
||||
}
|
||||
|
||||
public BeanProperty getDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
public BeanProperty getSoftDeleteProperty() {
|
||||
for (BeanProperty prop : nonManys) {
|
||||
if (prop.isSoftDelete()) {
|
||||
|
||||
@@ -156,11 +156,11 @@ final class AnnotationClass extends AnnotationParser {
|
||||
}
|
||||
Draftable draftable = typeGet(cls, Draftable.class);
|
||||
if (draftable != null) {
|
||||
descriptor.setDraftable();
|
||||
//TODO: Not Supported
|
||||
}
|
||||
DraftableElement draftableElement = typeGet(cls, DraftableElement.class);
|
||||
if (draftableElement != null) {
|
||||
descriptor.setDraftableElement();
|
||||
//TODO: Not Supported
|
||||
}
|
||||
ReadAudit readAudit = typeGet(cls, ReadAudit.class);
|
||||
if (readAudit != null) {
|
||||
|
||||
+1
-10
@@ -205,16 +205,7 @@ final class AnnotationFields extends AnnotationParser {
|
||||
prop.setTenantId();
|
||||
}
|
||||
if (has(prop, Draft.class)) {
|
||||
prop.setDraft();
|
||||
}
|
||||
if (has(prop, DraftOnly.class)) {
|
||||
prop.setDraftOnly();
|
||||
}
|
||||
if (has(prop, DraftDirty.class)) {
|
||||
prop.setDraftDirty();
|
||||
}
|
||||
if (has(prop, DraftReset.class)) {
|
||||
prop.setDraftReset();
|
||||
// TODO: Not Supported
|
||||
}
|
||||
if (has(prop, SoftDelete.class)) {
|
||||
prop.setSoftDelete();
|
||||
|
||||
@@ -257,11 +257,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.asOf(asOf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> asDraft() {
|
||||
return query.asDraft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> DtoQuery<D> asDto(Class<D> dtoClass) {
|
||||
return query.asDto(dtoClass);
|
||||
|
||||
@@ -347,11 +347,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
|
||||
return exprList.asOf(asOf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> asDraft() {
|
||||
return exprList.asDraft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> DtoQuery<D> asDto(Class<D> dtoClass) {
|
||||
return exprList.asDto(dtoClass);
|
||||
|
||||
@@ -25,7 +25,6 @@ public final class DLoadContext implements LoadContext {
|
||||
private final Map<String, DLoadBeanContext> beanMap = new HashMap<>();
|
||||
private final Map<String, DLoadManyContext> manyMap = new HashMap<>();
|
||||
private final DLoadBeanContext rootBeanContext;
|
||||
private final boolean asDraft;
|
||||
private final Timestamp asOf;
|
||||
private final Boolean readOnly;
|
||||
private final CacheMode useBeanCache;
|
||||
@@ -59,7 +58,6 @@ public final class DLoadContext implements LoadContext {
|
||||
this.origin = initOrigin();
|
||||
this.defaultBatchSize = 100;
|
||||
this.useBeanCache = CacheMode.OFF;
|
||||
this.asDraft = false;
|
||||
this.asOf = null;
|
||||
this.readOnly = false;
|
||||
this.disableLazyLoading = false;
|
||||
@@ -86,7 +84,6 @@ public final class DLoadContext implements LoadContext {
|
||||
SpiQuery<?> query = request.query();
|
||||
this.useDocStore = query.isUseDocStore();
|
||||
this.asOf = query.getAsOf();
|
||||
this.asDraft = query.isAsDraft();
|
||||
this.includeSoftDeletes = query.isIncludeSoftDeletes() && query.mode() == SpiQuery.Mode.NORMAL;
|
||||
this.readOnly = query.isReadOnly();
|
||||
this.disableLazyLoading = query.isDisableLazyLoading();
|
||||
@@ -322,9 +319,6 @@ public final class DLoadContext implements LoadContext {
|
||||
}
|
||||
query.setDisableLazyLoading(disableLazyLoading);
|
||||
query.asOf(asOf);
|
||||
if (asDraft) {
|
||||
query.asDraft();
|
||||
}
|
||||
if (includeSoftDeletes) {
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
|
||||
@@ -143,204 +143,6 @@ public final class DefaultPersister implements Persister {
|
||||
return executeOrQueue(new PersistRequestUpdateSql(server, updSql, (SpiTransaction) t, persistExecute, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore draft beans to match live beans given the query.
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query, Transaction transaction) {
|
||||
Class<T> beanType = query.getBeanType();
|
||||
BeanDescriptor<T> desc = server.descriptor(beanType);
|
||||
DraftHandler<T> draftHandler = new DraftHandler<>(desc, transaction);
|
||||
|
||||
query.usingTransaction(transaction);
|
||||
List<T> liveBeans = draftHandler.fetchSourceBeans((SpiQuery<T>) query, false);
|
||||
PUB.log(DEBUG, "draftRestore [{0}] count[{1}]", desc.name(), liveBeans.size());
|
||||
if (liveBeans.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
draftHandler.fetchDestinationBeans(liveBeans, true);
|
||||
BeanManager<T> mgr = beanDescriptorManager.beanManager(beanType);
|
||||
|
||||
for (T liveBean : liveBeans) {
|
||||
T draftBean = draftHandler.publishToDestinationBean(liveBean);
|
||||
// reset @DraftDirty and @DraftReset properties
|
||||
draftHandler.resetDraft(draftBean);
|
||||
|
||||
PUB.log(TRACE, "draftRestore bean [{0}] id[{1}]", desc.name(), draftHandler.getId());
|
||||
update(createRequest(draftBean, transaction, null, mgr, Type.UPDATE, Flags.RECURSE));
|
||||
}
|
||||
|
||||
PUB.log(DEBUG, "draftRestore - complete for [{0}]", desc.name());
|
||||
return draftHandler.getDrafts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to return the list of Id values for the list of beans.
|
||||
*/
|
||||
private <T> List<Object> getBeanIds(BeanDescriptor<T> desc, List<T> beans) {
|
||||
List<Object> idList = new ArrayList<>(beans.size());
|
||||
for (T liveBean : beans) {
|
||||
idList.add(desc.id(liveBean));
|
||||
}
|
||||
return idList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish from draft to live given the query.
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query, Transaction transaction) {
|
||||
Class<T> beanType = query.getBeanType();
|
||||
BeanDescriptor<T> desc = server.descriptor(beanType);
|
||||
DraftHandler<T> draftHandler = new DraftHandler<>(desc, transaction);
|
||||
|
||||
query.usingTransaction(transaction);
|
||||
List<T> draftBeans = draftHandler.fetchSourceBeans((SpiQuery<T>) query, true);
|
||||
PUB.log(DEBUG, "publish [{0}] count[{1}]", desc.name(), draftBeans.size());
|
||||
if (draftBeans.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
draftHandler.fetchDestinationBeans(draftBeans, false);
|
||||
BeanManager<T> mgr = beanDescriptorManager.beanManager(beanType);
|
||||
|
||||
List<T> livePublish = new ArrayList<>(draftBeans.size());
|
||||
for (T draftBean : draftBeans) {
|
||||
T liveBean = draftHandler.publishToDestinationBean(draftBean);
|
||||
livePublish.add(liveBean);
|
||||
|
||||
// reset @DraftDirty and @DraftReset properties
|
||||
draftHandler.resetDraft(draftBean);
|
||||
|
||||
Type persistType = draftHandler.isInsert() ? Type.INSERT : Type.UPDATE;
|
||||
PUB.log(TRACE, "publish bean [{0}] id[{1}] type[{2}]", desc.name(), draftHandler.getId(), persistType);
|
||||
|
||||
PersistRequestBean<T> request = createRequest(liveBean, transaction, null, mgr, persistType, Flags.PUBLISH_RECURSE);
|
||||
if (persistType == Type.INSERT) {
|
||||
insert(request);
|
||||
} else {
|
||||
update(request);
|
||||
}
|
||||
request.resetDepth();
|
||||
}
|
||||
|
||||
draftHandler.updateDrafts(transaction, mgr);
|
||||
PUB.log(DEBUG, "publish - complete for [{0}]", desc.name());
|
||||
return livePublish;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle draft beans (properties reset etc).
|
||||
*/
|
||||
class DraftHandler<T> {
|
||||
|
||||
final BeanDescriptor<T> desc;
|
||||
final Transaction transaction;
|
||||
final List<T> draftUpdates = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Id value of the last published bean.
|
||||
*/
|
||||
Object id;
|
||||
|
||||
/**
|
||||
* True if the last published bean is new/insert.
|
||||
*/
|
||||
boolean insert;
|
||||
|
||||
/**
|
||||
* The destination beans to publish/restore to mapped by id.
|
||||
*/
|
||||
Map<?, T> destBeans;
|
||||
|
||||
DraftHandler(BeanDescriptor<T> desc, Transaction transaction) {
|
||||
this.desc = desc;
|
||||
this.transaction = transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of draft beans with changes (to be persisted).
|
||||
*/
|
||||
List<T> getDrafts() {
|
||||
return draftUpdates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the draft dirty state to false and reset any dirtyReset properties.
|
||||
*/
|
||||
void resetDraft(T draftBean) {
|
||||
if (desc.draftReset(draftBean)) {
|
||||
// draft bean is dirty so collect it for persisting later
|
||||
draftUpdates.add(draftBean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the draft beans (with various properties reset etc).
|
||||
*/
|
||||
void updateDrafts(Transaction transaction, BeanManager<T> mgr) {
|
||||
if (!draftUpdates.isEmpty()) {
|
||||
// update the dirty status on the drafts that have been published
|
||||
PUB.log(DEBUG, "publish - update dirty status on [{0}] drafts", draftUpdates.size());
|
||||
for (T draftUpdate : draftUpdates) {
|
||||
update(createRequest(draftUpdate, transaction, null, mgr, Type.UPDATE, Flags.ZERO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the source beans based on the query.
|
||||
*/
|
||||
List<T> fetchSourceBeans(SpiQuery<T> query, boolean asDraft) {
|
||||
desc.draftQueryOptimise(query);
|
||||
if (asDraft) {
|
||||
query.asDraft();
|
||||
}
|
||||
return server.findList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the destination beans that will be published to.
|
||||
*/
|
||||
void fetchDestinationBeans(List<T> sourceBeans, boolean asDraft) {
|
||||
List<Object> ids = getBeanIds(desc, sourceBeans);
|
||||
SpiQuery<T> destQuery = server.createQuery(desc.type());
|
||||
destQuery.usingTransaction(transaction);
|
||||
destQuery.where().idIn(ids);
|
||||
if (asDraft) {
|
||||
destQuery.asDraft();
|
||||
}
|
||||
desc.draftQueryOptimise(destQuery);
|
||||
this.destBeans = server.findMap(destQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish/restore the values from the sourceBean to the matching destination bean.
|
||||
*/
|
||||
T publishToDestinationBean(T sourceBean) {
|
||||
id = desc.id(sourceBean);
|
||||
T destBean = destBeans.get(id);
|
||||
insert = (destBean == null);
|
||||
// apply changes from liveBean to draftBean
|
||||
return desc.publish(sourceBean, destBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the last publish resulted in an new bean to insert.
|
||||
*/
|
||||
boolean isInsert() {
|
||||
return insert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Id value of the last published/restored bean.
|
||||
*/
|
||||
Object getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively delete the bean. This calls back to the EbeanServer.
|
||||
*/
|
||||
@@ -380,7 +182,6 @@ public final class DefaultPersister implements Persister {
|
||||
@Override
|
||||
public void update(EntityBean entityBean, Transaction t) {
|
||||
PersistRequestBean<?> req = createRequest(entityBean, t, PersistRequest.Type.UPDATE);
|
||||
req.checkDraft();
|
||||
try {
|
||||
req.initTransIfRequiredWithBatchCascade();
|
||||
if (req.isReference()) {
|
||||
@@ -526,15 +327,8 @@ public final class DefaultPersister implements Persister {
|
||||
public int delete(EntityBean bean, Transaction t, boolean permanent) {
|
||||
Type deleteType = permanent ? Type.DELETE_PERMANENT : Type.DELETE;
|
||||
PersistRequestBean<EntityBean> originalRequest = createDeleteRequest(bean, t, deleteType);
|
||||
if (originalRequest.isHardDeleteDraft()) {
|
||||
// a hard delete of a draftable bean so first we need to delete the associated 'live' bean
|
||||
// due to FK constraint and then after that execute the original delete of the draft bean
|
||||
return deleteRequest(createDeleteRequest(originalRequest.createReference(), t, Type.DELETE_PERMANENT, Flags.PUBLISH), originalRequest);
|
||||
|
||||
} else {
|
||||
// normal delete or soft delete
|
||||
return deleteRequest(originalRequest);
|
||||
}
|
||||
// normal delete or soft delete
|
||||
return deleteRequest(originalRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -988,8 +782,8 @@ public final class DefaultPersister implements Persister {
|
||||
}
|
||||
}
|
||||
|
||||
void deleteManyIntersection(EntityBean bean, BeanPropertyAssocMany<?> many, SpiTransaction t, boolean publish, boolean queue) {
|
||||
SpiSqlUpdate sqlDelete = deleteAllIntersection(bean, many, publish);
|
||||
void deleteManyIntersection(EntityBean bean, BeanPropertyAssocMany<?> many, SpiTransaction t, boolean queue) {
|
||||
SpiSqlUpdate sqlDelete = deleteAllIntersection(bean, many);
|
||||
if (queue) {
|
||||
addToFlushQueue(sqlDelete, t, BatchControl.DELETE_QUEUE);
|
||||
} else {
|
||||
@@ -997,8 +791,8 @@ public final class DefaultPersister implements Persister {
|
||||
}
|
||||
}
|
||||
|
||||
private SpiSqlUpdate deleteAllIntersection(EntityBean bean, BeanPropertyAssocMany<?> many, boolean publish) {
|
||||
IntersectionRow intRow = many.buildManyToManyDeleteChildren(bean, publish);
|
||||
private SpiSqlUpdate deleteAllIntersection(EntityBean bean, BeanPropertyAssocMany<?> many) {
|
||||
IntersectionRow intRow = many.buildManyToManyDeleteChildren(bean);
|
||||
return intRow.createDeleteChildren(server);
|
||||
}
|
||||
|
||||
@@ -1047,7 +841,7 @@ public final class DefaultPersister implements Persister {
|
||||
if (many.hasJoinTable()) {
|
||||
if (deleteMode.isHard()) {
|
||||
// delete associated rows from intersection table (but not during soft delete)
|
||||
deleteManyIntersection(parentBean, many, t, request.isPublish(), false);
|
||||
deleteManyIntersection(parentBean, many, t, false);
|
||||
}
|
||||
} else {
|
||||
if (ModifyListenMode.REMOVALS == many.modifyListenMode()) {
|
||||
@@ -1239,7 +1033,7 @@ public final class DefaultPersister implements Persister {
|
||||
BeanDescriptor<T> desc = mgr.getBeanDescriptor();
|
||||
EntityBean entityBean = (EntityBean) bean;
|
||||
PersistRequest.Type type;
|
||||
if (Flags.isPublishMergeOrNormal(flags)) {
|
||||
if (Flags.isMergeOrNormal(flags)) {
|
||||
// just use bean state to determine insert or update
|
||||
type = entityBean._ebean_getIntercept().isUpdate() ? Type.UPDATE : Type.INSERT;
|
||||
} else {
|
||||
|
||||
@@ -17,11 +17,6 @@ public final class Flags {
|
||||
*/
|
||||
public static final int RECURSE = 0x00000002;
|
||||
|
||||
/**
|
||||
* Indicates Publish mode.
|
||||
*/
|
||||
public static final int PUBLISH = 0x00000004;
|
||||
|
||||
/**
|
||||
* Indicates Merge mode.
|
||||
*/
|
||||
@@ -37,9 +32,9 @@ public final class Flags {
|
||||
*/
|
||||
public static final int ZERO = 0;
|
||||
|
||||
public static final int PUBLISH_RECURSE = PUBLISH + RECURSE;
|
||||
// public static final int PUBLISH_RECURSE = PUBLISH + RECURSE;
|
||||
|
||||
private static final int PUBLISH_MERGE_NORMAL = PUBLISH + MERGE + NORMAL;
|
||||
private static final int MERGE_NORMAL = MERGE + NORMAL;
|
||||
|
||||
private static final int INSERT_NORMAL = INSERT + NORMAL;
|
||||
|
||||
@@ -57,25 +52,18 @@ public final class Flags {
|
||||
return isSet(state, RECURSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if part of a Publish.
|
||||
*/
|
||||
public static boolean isPublish(int state) {
|
||||
return isSet(state, PUBLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if part of a Merge.
|
||||
*/
|
||||
public static boolean isMerge(int state) {
|
||||
return isSet(state, PUBLISH);
|
||||
return isSet(state, MERGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if part of a Merge or Publish or Normal (bean state matches persist).
|
||||
*/
|
||||
public static boolean isPublishMergeOrNormal(int state) {
|
||||
return (state & PUBLISH_MERGE_NORMAL) != 0;
|
||||
public static boolean isMergeOrNormal(int state) {
|
||||
return (state & MERGE_NORMAL) != 0;
|
||||
}
|
||||
|
||||
public static boolean isUpdateForce(int state) {
|
||||
@@ -130,17 +118,6 @@ public final class Flags {
|
||||
return unset(state, RECURSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Publish flag.
|
||||
*/
|
||||
public static int setPublish(int state) {
|
||||
return set(state, PUBLISH);
|
||||
}
|
||||
|
||||
public static int unsetPublish(int state) {
|
||||
return unset(state, PUBLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Merge flag.
|
||||
*/
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ final class MergeNodeAssocManyToMany extends MergeNode {
|
||||
|
||||
if (!deletions.isEmpty()) {
|
||||
transaction.flush();
|
||||
SqlUpdate delete = intersectionTable.delete(server, false);
|
||||
SqlUpdate delete = intersectionTable.delete(server);
|
||||
for (EntityBean deletion : deletions) {
|
||||
many.intersectionBind(delete, parentBean, deletion);
|
||||
delete.addBatch();
|
||||
@@ -64,7 +64,7 @@ final class MergeNodeAssocManyToMany extends MergeNode {
|
||||
|
||||
if (!additions.isEmpty()) {
|
||||
transaction.flush();
|
||||
SqlUpdate insert = intersectionTable.insert(server, false);
|
||||
SqlUpdate insert = intersectionTable.insert(server);
|
||||
for (EntityBean addition : additions) {
|
||||
many.intersectionBind(insert, parentBean, addition);
|
||||
insert.addBatch();
|
||||
|
||||
@@ -23,7 +23,6 @@ import static java.lang.System.Logger.Level.WARNING;
|
||||
final class SaveManyBeans extends SaveManyBase {
|
||||
|
||||
private final boolean cascade;
|
||||
private final boolean publish;
|
||||
private final BeanDescriptor<?> targetDescriptor;
|
||||
private final boolean isMap;
|
||||
private final boolean saveRecurseSkippable;
|
||||
@@ -38,7 +37,6 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
SaveManyBeans(DefaultPersister persister, boolean insertedParent, BeanPropertyAssocMany<?> many, EntityBean parentBean, PersistRequestBean<?> request) {
|
||||
super(persister, insertedParent, many, parentBean, request);
|
||||
this.cascade = many.cascadeInfo().isSave();
|
||||
this.publish = request.isPublish();
|
||||
this.targetDescriptor = many.targetDescriptor();
|
||||
this.isMap = many.manyType().isMap();
|
||||
this.saveRecurseSkippable = many.isSaveRecurseSkippable();
|
||||
@@ -258,7 +256,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
if (vanillaCollection || forcedUpdate) {
|
||||
// delete all intersection rows and then treat all
|
||||
// beans in the collection as additions
|
||||
persister.deleteManyIntersection(parentBean, many, transaction, publish, queue);
|
||||
persister.deleteManyIntersection(parentBean, many, transaction, queue);
|
||||
}
|
||||
|
||||
Collection<?> deletions = null;
|
||||
@@ -296,7 +294,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
EntityBean otherDelete = (EntityBean) other;
|
||||
// the object from the 'other' side of the ManyToMany
|
||||
// build a intersection row for 'delete'
|
||||
IntersectionRow intRow = many.buildManyToManyMapBean(parentBean, otherDelete, publish);
|
||||
IntersectionRow intRow = many.buildManyToManyMapBean(parentBean, otherDelete);
|
||||
SpiSqlUpdate sqlDelete = intRow.createDelete(server, DeleteMode.HARD);
|
||||
persister.executeOrQueue(sqlDelete, transaction, queue, BatchControl.DELETE_QUEUE);
|
||||
}
|
||||
@@ -316,7 +314,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
throw new PersistenceException("ManyToMany bean does not have an Id value? " + otherBean);
|
||||
} else {
|
||||
// build a intersection row for 'insert'
|
||||
IntersectionRow intRow = many.buildManyToManyMapBean(parentBean, otherBean, publish);
|
||||
IntersectionRow intRow = many.buildManyToManyMapBean(parentBean, otherBean);
|
||||
SpiSqlUpdate sqlInsert = intRow.createInsert(server);
|
||||
persister.executeOrQueue(sqlInsert, transaction, queue, BatchControl.INSERT_QUEUE);
|
||||
}
|
||||
|
||||
@@ -17,23 +17,12 @@ final class DeleteMeta extends BaseMeta {
|
||||
|
||||
private final String sqlVersion;
|
||||
private final String sqlNone;
|
||||
private final String sqlDraftVersion;
|
||||
private final String sqlDraftNone;
|
||||
|
||||
DeleteMeta(BeanDescriptor<?> desc, BindableId id, Bindable version, Bindable tenantId) {
|
||||
super(id, version, tenantId);
|
||||
|
||||
String tableName = desc.baseTable();
|
||||
this.sqlNone = genSql(ConcurrencyMode.NONE, tableName);
|
||||
this.sqlVersion = genSql(ConcurrencyMode.VERSION, tableName);
|
||||
if (desc.isDraftable()) {
|
||||
String draftTableName = desc.draftTable();
|
||||
this.sqlDraftNone = genSql(ConcurrencyMode.NONE, draftTableName);
|
||||
this.sqlDraftVersion = genSql(ConcurrencyMode.VERSION, draftTableName);
|
||||
} else {
|
||||
this.sqlDraftNone = sqlNone;
|
||||
this.sqlDraftVersion = sqlVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,13 +48,12 @@ final class DeleteMeta extends BaseMeta {
|
||||
throw new IllegalStateException("Can not deleteById on " + request.fullName() + " as no @Id property");
|
||||
}
|
||||
|
||||
boolean publish = request.isPublish();
|
||||
switch (request.concurrencyMode()) {
|
||||
case NONE:
|
||||
return publish ? sqlNone : sqlDraftNone;
|
||||
return sqlNone;
|
||||
|
||||
case VERSION:
|
||||
return publish ? sqlVersion : sqlDraftVersion;
|
||||
return sqlVersion;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Invalid mode " + request.concurrencyMode());
|
||||
|
||||
@@ -69,7 +69,7 @@ public final class InsertHandler extends DmlHandler {
|
||||
|
||||
SpiTransaction t = persistRequest.transaction();
|
||||
// get the appropriate sql
|
||||
sql = meta.getSql(withId, persistRequest.isPublish());
|
||||
sql = meta.getSql(withId);
|
||||
PreparedStatement pstmt;
|
||||
if (persistRequest.isBatched()) {
|
||||
pstmt = pstmtBatch(t, sql, persistRequest, useGeneratedKeys);
|
||||
@@ -77,7 +77,7 @@ public final class InsertHandler extends DmlHandler {
|
||||
pstmt = pstmt(t, sql, useGeneratedKeys);
|
||||
}
|
||||
dataBind = bind(pstmt);
|
||||
meta.bind(this, bean, withId, persistRequest.isPublish());
|
||||
meta.bind(this, bean, withId);
|
||||
if (persistRequest.isBatched()) {
|
||||
batchedPstmt.registerInputStreams(dataBind.getInputStreams());
|
||||
}
|
||||
|
||||
@@ -21,12 +21,9 @@ final class InsertMeta {
|
||||
|
||||
private final String sqlNullId;
|
||||
private final String sqlWithId;
|
||||
private final String sqlDraftNullId;
|
||||
private final String sqlDraftWithId;
|
||||
private final BindableId id;
|
||||
private final Bindable discriminator;
|
||||
private final BindableList all;
|
||||
private final BindableList allExcludeDraftOnly;
|
||||
private final boolean supportsGetGeneratedKeys;
|
||||
private final boolean concatenatedKey;
|
||||
/**
|
||||
@@ -42,13 +39,10 @@ final class InsertMeta {
|
||||
this.discriminator = discriminator(desc);
|
||||
this.id = id;
|
||||
this.all = all;
|
||||
this.allExcludeDraftOnly = all.excludeDraftOnly();
|
||||
this.shadowFKey = shadowFKey;
|
||||
|
||||
String tableName = desc.baseTable();
|
||||
String draftTableName = desc.draftTable();
|
||||
this.sqlWithId = genSql(false, tableName, false);
|
||||
this.sqlDraftWithId = desc.isDraftable() ? genSql(false, draftTableName, true) : sqlWithId;
|
||||
this.sqlWithId = genSql(false, tableName);
|
||||
|
||||
// only available for single Id property
|
||||
if (id.isConcatenated()) {
|
||||
@@ -56,7 +50,6 @@ final class InsertMeta {
|
||||
this.concatenatedKey = true;
|
||||
this.identityDbColumns = null;
|
||||
this.sqlNullId = null;
|
||||
this.sqlDraftNullId = null;
|
||||
this.supportsGetGeneratedKeys = false;
|
||||
this.supportsSelectLastInsertedId = false;
|
||||
|
||||
@@ -72,8 +65,7 @@ final class InsertMeta {
|
||||
this.supportsGetGeneratedKeys = dbPlatform.dbIdentity().isSupportsGetGeneratedKeys();
|
||||
this.supportsSelectLastInsertedId = desc.supportsSelectLastInsertedId();
|
||||
}
|
||||
this.sqlNullId = genSql(true, tableName, false);
|
||||
this.sqlDraftNullId = desc.isDraftable() ? genSql(true, draftTableName, true) : sqlNullId;
|
||||
this.sqlNullId = genSql(true, tableName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +111,7 @@ final class InsertMeta {
|
||||
/**
|
||||
* Bind the request based on whether the id value(s) are null.
|
||||
*/
|
||||
public void bind(DmlHandler request, EntityBean bean, boolean withId, boolean publish) throws SQLException {
|
||||
public void bind(DmlHandler request, EntityBean bean, boolean withId) throws SQLException {
|
||||
if (withId) {
|
||||
id.dmlBind(request, bean);
|
||||
}
|
||||
@@ -129,29 +121,25 @@ final class InsertMeta {
|
||||
if (discriminator != null) {
|
||||
discriminator.dmlBind(request, bean);
|
||||
}
|
||||
if (publish) {
|
||||
allExcludeDraftOnly.dmlBind(request, bean);
|
||||
} else {
|
||||
all.dmlBind(request, bean);
|
||||
}
|
||||
all.dmlBind(request, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the sql based whether the id value(s) are null.
|
||||
*/
|
||||
public String getSql(boolean withId, boolean publish) {
|
||||
public String getSql(boolean withId) {
|
||||
if (withId) {
|
||||
return publish ? sqlWithId : sqlDraftWithId;
|
||||
return sqlWithId;
|
||||
} else {
|
||||
return publish ? sqlNullId : sqlDraftNullId;
|
||||
return sqlNullId;
|
||||
}
|
||||
}
|
||||
|
||||
private String genSql(boolean nullId, String table, boolean draftTable) {
|
||||
private String genSql(boolean nullId, String table) {
|
||||
GenerateDmlRequest request = new GenerateDmlRequest();
|
||||
request.setInsertSetMode();
|
||||
request.append("insert into ").append(table);
|
||||
if (nullId && noColumnsForInsert(draftTable)) {
|
||||
if (nullId && noColumnsForInsert()) {
|
||||
return request.append(defaultValues()).toString();
|
||||
}
|
||||
request.append(" (");
|
||||
@@ -164,11 +152,8 @@ final class InsertMeta {
|
||||
if (discriminator != null) {
|
||||
discriminator.dmlAppend(request);
|
||||
}
|
||||
if (draftTable) {
|
||||
all.dmlAppend(request);
|
||||
} else {
|
||||
allExcludeDraftOnly.dmlAppend(request);
|
||||
}
|
||||
all.dmlAppend(request);
|
||||
|
||||
request.append(") values (");
|
||||
request.append(request.insertBindBuffer());
|
||||
request.append(")");
|
||||
@@ -191,10 +176,10 @@ final class InsertMeta {
|
||||
/**
|
||||
* Return true if the insert actually contains no columns.
|
||||
*/
|
||||
private boolean noColumnsForInsert(boolean draftTable) {
|
||||
private boolean noColumnsForInsert() {
|
||||
return shadowFKey == null
|
||||
&& discriminator == null
|
||||
&& (draftTable ? all.isEmpty() : allExcludeDraftOnly.isEmpty());
|
||||
&& all.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,9 +38,4 @@ public interface Bindable {
|
||||
* when binding a update or delete where clause with ALL concurrency mode.
|
||||
*/
|
||||
void dmlBind(BindableRequest request, EntityBean bean) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return true if the underlying property is 'draft only'.
|
||||
*/
|
||||
boolean isDraftOnly();
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@ class BindableAssocOne implements Bindable {
|
||||
this.importedId = assocOne.importedId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDraftOnly() {
|
||||
return assocOne.isDraftOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(assocOne)) {
|
||||
|
||||
-5
@@ -24,11 +24,6 @@ public final class BindableDiscriminator implements Bindable {
|
||||
this.sqlType = inheritInfo.getDiscriminatorType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
throw new PersistenceException("Never called (only for inserts)");
|
||||
|
||||
@@ -6,7 +6,6 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import io.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -23,11 +22,6 @@ final class BindableEmbedded implements Bindable {
|
||||
this.items = bindList.toArray(new Bindable[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return embProp.isDraftOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dmlAppend(GenerateDmlRequest request) {
|
||||
for (Bindable item : items) {
|
||||
|
||||
-5
@@ -23,11 +23,6 @@ final class BindableEncryptedProperty implements Bindable {
|
||||
this.bindEncryptDataFirst = bindEncryptDataFirst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return prop.isDraftOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(prop)) {
|
||||
|
||||
-5
@@ -28,11 +28,6 @@ final class BindableIdEmbedded implements BindableId {
|
||||
this.matches = matches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
|
||||
@@ -13,11 +13,6 @@ final class BindableIdEmpty implements BindableId {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
// nothing
|
||||
|
||||
@@ -35,11 +35,6 @@ final class BindableIdScalar implements BindableId {
|
||||
return uidProp.dbColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing for BindableId.
|
||||
*/
|
||||
|
||||
@@ -20,28 +20,10 @@ public final class BindableList implements Bindable {
|
||||
items = list.toArray(new Bindable[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bindable list that excludes @DraftOnly properties.
|
||||
*/
|
||||
public BindableList excludeDraftOnly() {
|
||||
List<Bindable> copy = new ArrayList<>(items.length);
|
||||
for (Bindable b : items) {
|
||||
if (!b.isDraftOnly()) {
|
||||
copy.add(b);
|
||||
}
|
||||
}
|
||||
return new BindableList(copy);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return items.length == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addAll(List<Bindable> list) {
|
||||
Collections.addAll(list, items);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,6 @@ class BindableProperty implements Bindable {
|
||||
this.prop = prop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDraftOnly() {
|
||||
return prop.isDraftOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(prop)) {
|
||||
|
||||
-5
@@ -24,11 +24,6 @@ final class BindablePropertyVersion implements Bindable {
|
||||
return prop.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return prop.isDraftOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(prop)) {
|
||||
|
||||
-5
@@ -29,11 +29,6 @@ public final class BindableUnidirectional implements Bindable {
|
||||
this.importedId = unidirectional.importedId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
throw new PersistenceException("Never called (for insert only)");
|
||||
|
||||
@@ -211,11 +211,6 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
return loadContextBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftQuery() {
|
||||
return query.isAsDraft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisableLazyLoading() {
|
||||
return disableLazyLoading;
|
||||
|
||||
@@ -48,17 +48,15 @@ final class CQueryBuilder {
|
||||
private final Binder binder;
|
||||
private final boolean selectCountWithAlias;
|
||||
private final CQueryHistorySupport historySupport;
|
||||
private final CQueryDraftSupport draftSupport;
|
||||
private final DatabasePlatform dbPlatform;
|
||||
private final boolean selectCountWithColumnAlias;
|
||||
|
||||
/**
|
||||
* Create the SqlGenSelect.
|
||||
*/
|
||||
CQueryBuilder(DatabasePlatform dbPlatform, Binder binder, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
|
||||
CQueryBuilder(DatabasePlatform dbPlatform, Binder binder, CQueryHistorySupport historySupport) {
|
||||
this.dbPlatform = dbPlatform;
|
||||
this.binder = binder;
|
||||
this.draftSupport = draftSupport;
|
||||
this.historySupport = historySupport;
|
||||
this.columnAliasPrefix = dbPlatform.columnAliasPrefix();
|
||||
this.sqlLimiter = dbPlatform.sqlLimiter();
|
||||
@@ -221,13 +219,6 @@ final class CQueryBuilder {
|
||||
return query.temporalMode().isHistory() ? historySupport : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draft support (or null) for a 'asDraft' query.
|
||||
*/
|
||||
<T> CQueryDraftSupport draftSupport(SpiQuery<T> query) {
|
||||
return query.temporalMode() == SpiQuery.TemporalMode.DRAFT ? draftSupport : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the row count query.
|
||||
*/
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package io.ebeaninternal.server.query;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Support 'asDraft' queries.
|
||||
*/
|
||||
final class CQueryDraftSupport {
|
||||
|
||||
/**
|
||||
* The mapping of base tables to their matching 'draft' table.
|
||||
*/
|
||||
private final Map<String, String> tableMap;
|
||||
|
||||
CQueryDraftSupport(Map<String, String> tableMap) {
|
||||
this.tableMap = tableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draft table associated to the base table.
|
||||
* <p>
|
||||
* This returns null for entities that are not draftable and in that case
|
||||
* the usual base table is used.
|
||||
*/
|
||||
String draftTable(String table) {
|
||||
return tableMap.get(table);
|
||||
}
|
||||
}
|
||||
@@ -38,13 +38,13 @@ public final class CQueryEngine {
|
||||
private final CQueryHistorySupport historySupport;
|
||||
private final DatabasePlatform dbPlatform;
|
||||
|
||||
public CQueryEngine(DatabaseConfig config, DatabasePlatform dbPlatform, Binder binder, Map<String, String> asOfTableMapping, Map<String, String> draftTableMap) {
|
||||
public CQueryEngine(DatabaseConfig config, DatabasePlatform dbPlatform, Binder binder, Map<String, String> asOfTableMapping) {
|
||||
this.dbPlatform = dbPlatform;
|
||||
this.defaultFetchSizeFindEach = config.getJdbcFetchSizeFindEach();
|
||||
this.defaultFetchSizeFindList = config.getJdbcFetchSizeFindList();
|
||||
this.forwardOnlyHintOnFindIterate = dbPlatform.forwardOnlyHintOnFindIterate();
|
||||
this.historySupport = new CQueryHistorySupport(dbPlatform.historySupport(), asOfTableMapping, config.getAsOfSysPeriod());
|
||||
this.queryBuilder = new CQueryBuilder(dbPlatform, binder, historySupport, new CQueryDraftSupport(draftTableMap));
|
||||
this.queryBuilder = new CQueryBuilder(dbPlatform, binder, historySupport);
|
||||
}
|
||||
|
||||
public int forwardOnlyFetchSize() {
|
||||
@@ -414,9 +414,6 @@ public final class CQueryEngine {
|
||||
if (query.isAutoTuned()) {
|
||||
msg.append("tuned[true] ");
|
||||
}
|
||||
if (query.isAsDraft()) {
|
||||
msg.append(" draft[true] ");
|
||||
}
|
||||
if (originKey != null) {
|
||||
msg.append("origin[").append(originKey).append("] ");
|
||||
}
|
||||
@@ -458,9 +455,6 @@ public final class CQueryEngine {
|
||||
if (query.isAutoTuned()) {
|
||||
msg.append("tuned[true] ");
|
||||
}
|
||||
if (query.isAsDraft()) {
|
||||
msg.append(" draft[true] ");
|
||||
}
|
||||
if (originKey != null) {
|
||||
msg.append("origin[").append(originKey).append("] ");
|
||||
}
|
||||
|
||||
@@ -35,17 +35,15 @@ final class DefaultDbSqlContext implements DbSqlContext {
|
||||
private String currentPrefix;
|
||||
private List<BeanProperty> encryptedProps;
|
||||
private List<SqlTreeJoin> extraJoins;
|
||||
private final CQueryDraftSupport draftSupport;
|
||||
private final CQueryHistorySupport historySupport;
|
||||
private final boolean historyQuery;
|
||||
private boolean joinSuppressed;
|
||||
|
||||
DefaultDbSqlContext(SqlTreeAlias alias, String columnAliasPrefix, CQueryHistorySupport historySupport,
|
||||
CQueryDraftSupport draftSupport, String fromForUpdate) {
|
||||
String fromForUpdate) {
|
||||
this.alias = alias;
|
||||
this.columnAliasPrefix = columnAliasPrefix;
|
||||
this.useColumnAlias = columnAliasPrefix != null;
|
||||
this.draftSupport = draftSupport;
|
||||
this.historySupport = historySupport;
|
||||
this.historyQuery = (historySupport != null);
|
||||
this.fromForUpdate = fromForUpdate;
|
||||
@@ -131,9 +129,7 @@ final class DefaultDbSqlContext implements DbSqlContext {
|
||||
tableJoins.add(joinKey);
|
||||
sb.append(' ').append(type);
|
||||
boolean addAsOfOnClause = false;
|
||||
if (draftSupport != null) {
|
||||
appendTable(table, draftSupport.draftTable(table));
|
||||
} else if (!historyQuery) {
|
||||
if (!historyQuery) {
|
||||
sb.append(' ').append(table).append(' ');
|
||||
} else {
|
||||
// check if there is an associated history table and if so
|
||||
@@ -192,11 +188,6 @@ final class DefaultDbSqlContext implements DbSqlContext {
|
||||
return asOfTableCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDraftQuery() {
|
||||
return draftSupport != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tableAlias(String prefix) {
|
||||
return alias.tableAlias(prefix);
|
||||
|
||||
@@ -150,11 +150,6 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> asDraft() {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> DtoQuery<D> asDto(Class<D> dtoClass) {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
|
||||
@@ -89,11 +89,6 @@ public interface STreeType {
|
||||
*/
|
||||
Object contextPutIfAbsent(PersistenceContext persistenceContext, Object id, EntityBean localBean);
|
||||
|
||||
/**
|
||||
* Set draft status on the entity bean.
|
||||
*/
|
||||
void setDraft(EntityBean localBean);
|
||||
|
||||
/**
|
||||
* Invoke any post load listeners.
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,7 @@ public final class SqlBeanLoad {
|
||||
}
|
||||
|
||||
public Object load(BeanProperty prop) {
|
||||
if (!rawSql && !prop.isLoadProperty(ctx.isDraftQuery())) {
|
||||
if (!rawSql && !prop.isLoadProperty()) {
|
||||
return null;
|
||||
}
|
||||
if ((bean == null)
|
||||
|
||||
@@ -101,9 +101,8 @@ public final class SqlTreeBuilder {
|
||||
this.distinctNoLobs = builder.isPlatformDistinctNoLobs();
|
||||
String fromForUpdate = builder.fromForUpdate(query);
|
||||
CQueryHistorySupport historySupport = builder.historySupport(query);
|
||||
CQueryDraftSupport draftSupport = builder.draftSupport(query);
|
||||
String colAlias = subQuery ? null : columnAliasPrefix;
|
||||
this.ctx = new DefaultDbSqlContext(alias, colAlias, historySupport, draftSupport, fromForUpdate);
|
||||
this.ctx = new DefaultDbSqlContext(alias, colAlias, historySupport, fromForUpdate);
|
||||
this.common = new SqlTreeCommon(temporalMode, disableLazyLoad, readOnly, includeJoin);
|
||||
}
|
||||
|
||||
|
||||
@@ -259,9 +259,6 @@ class SqlTreeLoadBean implements SqlTreeLoad {
|
||||
if (readIdNormal) {
|
||||
createListProxies();
|
||||
}
|
||||
if (temporalMode == SpiQuery.TemporalMode.DRAFT) {
|
||||
localDesc.setDraft(localBean);
|
||||
}
|
||||
localDesc.postLoad(localBean);
|
||||
|
||||
EntityBeanIntercept ebi = localBean._ebean_getIntercept();
|
||||
|
||||
@@ -336,13 +336,6 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query<T> asDraft() {
|
||||
this.temporalMode = TemporalMode.DRAFT;
|
||||
this.useBeanCache = CacheMode.OFF;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query<T> setIncludeSoftDeletes() {
|
||||
this.temporalMode = TemporalMode.SOFT_DELETED;
|
||||
@@ -942,11 +935,6 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return asOf != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAsDraft() {
|
||||
return TemporalMode.DRAFT == temporalMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isIncludeSoftDeletes() {
|
||||
return TemporalMode.SOFT_DELETED == temporalMode;
|
||||
|
||||
@@ -205,8 +205,6 @@ public class OrmQueryPlanKeyTest extends BaseTest {
|
||||
public void equals_when_diffTemporalMode() {
|
||||
|
||||
CQueryPlanKey key1 = planKey(query());
|
||||
CQueryPlanKey key2 = planKey(query().asDraft());
|
||||
assertDifferent(key1, key2);
|
||||
|
||||
CQueryPlanKey key3 = planKey(query().asOf(new Timestamp(System.currentTimeMillis())));
|
||||
assertDifferent(key1, key3);
|
||||
|
||||
+2
-4
@@ -140,10 +140,8 @@ public abstract class DbTriggerBasedHistoryDdl extends DbTableBasedHistoryDdl im
|
||||
protected void createHistoryTableAs(DdlBuffer apply, MTable table) {
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName(table.getName())).append("(").newLine();
|
||||
for (MColumn column : table.allColumns()) {
|
||||
if (!column.isDraftOnly()) {
|
||||
writeColumnDefinition(apply, column.getName(), column.getType());
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
writeColumnDefinition(apply, column.getName(), column.getType());
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
// TODO: We must apply also pending dropped columns. Let's do that in a later step
|
||||
if (table.hasDroppedColumns()) {
|
||||
|
||||
+2
-4
@@ -34,11 +34,9 @@ public class HanaHistoryDdl extends DbTableBasedHistoryDdl implements PlatformHi
|
||||
// create history table
|
||||
Collection<MColumn> cols = table.allColumns();
|
||||
for (MColumn column : cols) {
|
||||
if (!column.isDraftOnly()) {
|
||||
writeColumnDefinition(apply, column.getName(), column.getType(), column.getDefaultValue(), column.isNotnull(),
|
||||
writeColumnDefinition(apply, column.getName(), column.getType(), column.getDefaultValue(), column.isNotnull(),
|
||||
column.isIdentity() ? platformDdl.identitySuffix : null);
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
writeColumnDefinition(apply, systemPeriodStart, "TIMESTAMP", null, false, null);
|
||||
apply.append(",").newLine();
|
||||
|
||||
@@ -93,8 +93,6 @@ public class CurrentModel {
|
||||
ModelBuildBeanVisitor visitor = new ModelBuildBeanVisitor(context);
|
||||
VisitAllUsing visit = new VisitAllUsing(visitor, server);
|
||||
visit.visitAllBeans();
|
||||
// adjust the foreign keys on the 'draft' tables
|
||||
context.adjustDraftReferences();
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,6 @@ public class MColumn {
|
||||
*/
|
||||
private AlterColumn alterColumn;
|
||||
|
||||
private boolean draftOnly;
|
||||
|
||||
private List<DbMigrationInfo> dbMigrationInfos;
|
||||
|
||||
public MColumn(Column column) {
|
||||
@@ -91,7 +89,6 @@ public class MColumn {
|
||||
*/
|
||||
public MColumn copyForDraft() {
|
||||
MColumn copy = new MColumn(name, type);
|
||||
copy.draftOnly = draftOnly;
|
||||
copy.checkConstraint = checkConstraint;
|
||||
copy.checkConstraintName = checkConstraintName;
|
||||
copy.defaultValue = defaultValue;
|
||||
@@ -241,25 +238,11 @@ public class MColumn {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the draftOnly status for this column.
|
||||
*/
|
||||
public void setDraftOnly(boolean draftOnly) {
|
||||
this.draftOnly = draftOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draftOnly status for this column.
|
||||
*/
|
||||
public boolean isDraftOnly() {
|
||||
return draftOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this column should be included in History DB triggers etc.
|
||||
*/
|
||||
public boolean isIncludeInHistory() {
|
||||
return !draftOnly && !historyExclude;
|
||||
return !historyExclude;
|
||||
}
|
||||
|
||||
public void clearForeignKey() {
|
||||
|
||||
@@ -29,12 +29,10 @@ public class MTable {
|
||||
private static final System.Logger logger = AppLog.getLogger(MTable.class);
|
||||
|
||||
private String name;
|
||||
private MTable draftTable;
|
||||
/**
|
||||
* Marked true for draft tables. These need to have their FK references adjusted
|
||||
* after all the draft tables have been identified.
|
||||
*/
|
||||
private boolean draft;
|
||||
private PartitionMeta partitionMeta;
|
||||
private TablespaceMeta tablespaceMeta;
|
||||
private String pkName;
|
||||
@@ -107,25 +105,6 @@ public class MTable {
|
||||
this.storageEngine = storageEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this table structure as a 'draft' table.
|
||||
* <p>
|
||||
* Note that both tables contain @DraftOnly MColumns and these are filtered out
|
||||
* later when creating the CreateTable object.
|
||||
*/
|
||||
public MTable createDraftTable() {
|
||||
draftTable = new MTable(name + "_draft", this.tablespaceMeta, this.storageEngine);
|
||||
draftTable.draft = true;
|
||||
draftTable.whenCreatedColumn = whenCreatedColumn;
|
||||
// compoundKeys
|
||||
// compoundUniqueConstraints
|
||||
draftTable.identityMode = identityMode;
|
||||
for (MColumn col : allColumns()) {
|
||||
draftTable.addColumn(col.copyForDraft());
|
||||
}
|
||||
return draftTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for migration.
|
||||
*/
|
||||
@@ -142,7 +121,6 @@ public class MTable {
|
||||
this.tablespaceMeta = null;
|
||||
}
|
||||
this.withHistory = Boolean.TRUE.equals(createTable.isWithHistory());
|
||||
this.draft = Boolean.TRUE.equals(createTable.isDraft());
|
||||
this.identityMode = fromCreateTable(createTable);
|
||||
List<Column> cols = createTable.getColumn();
|
||||
for (Column column : cols) {
|
||||
@@ -220,14 +198,9 @@ public class MTable {
|
||||
if (withHistory) {
|
||||
createTable.setWithHistory(Boolean.TRUE);
|
||||
}
|
||||
if (draft) {
|
||||
createTable.setDraft(Boolean.TRUE);
|
||||
}
|
||||
|
||||
for (MColumn column : allColumns()) {
|
||||
// filter out draftOnly columns from the base table
|
||||
if (draft || !column.isDraftOnly()) {
|
||||
createTable.getColumn().add(column.createColumn());
|
||||
}
|
||||
createTable.getColumn().add(column.createColumn());
|
||||
}
|
||||
for (MCompoundForeignKey compoundKey : compoundKeys) {
|
||||
createTable.getForeignKey().add(compoundKey.createForeignKey());
|
||||
@@ -282,10 +255,7 @@ public class MTable {
|
||||
for (MColumn newColumn : newColumnMap.values()) {
|
||||
MColumn localColumn = getColumn(newColumn.getName());
|
||||
if (localColumn == null) {
|
||||
// can ignore if draftOnly column and non-draft table
|
||||
if (!newColumn.isDraftOnly() || draft) {
|
||||
diffNewColumn(newColumn, newTable);
|
||||
}
|
||||
diffNewColumn(newColumn, newTable);
|
||||
} else {
|
||||
localColumn.compare(modelDiff, this, newColumn);
|
||||
}
|
||||
@@ -296,10 +266,6 @@ public class MTable {
|
||||
MColumn newColumn = newColumnMap.get(existingColumn.getName());
|
||||
if (newColumn == null) {
|
||||
diffDropColumn(modelDiff, existingColumn);
|
||||
} else if (newColumn.isDraftOnly() && !draft) {
|
||||
// effectively a drop column (draft only column on a non-draft table)
|
||||
logger.log(TRACE, "... drop column {0} from table {1} as now draftOnly", newColumn.getName(), name);
|
||||
diffDropColumn(modelDiff, existingColumn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,13 +391,6 @@ public class MTable {
|
||||
return pos == -1 ? null : name.substring(0, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this table is a 'Draft' table.
|
||||
*/
|
||||
public boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this table is partitioned.
|
||||
*/
|
||||
@@ -685,42 +644,6 @@ public class MTable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the references (FK) if it should relate to a draft table.
|
||||
*/
|
||||
public void adjustReferences(ModelContainer modelContainer) {
|
||||
Collection<MColumn> cols = allColumns();
|
||||
for (MColumn col : cols) {
|
||||
String references = col.getReferences();
|
||||
if (references != null) {
|
||||
String baseTable = extractBaseTable(references);
|
||||
MTable refBaseTable = modelContainer.getTable(baseTable);
|
||||
if (refBaseTable.draftTable != null) {
|
||||
// change references to another associated 'draft' table
|
||||
String newReferences = deriveReferences(references, refBaseTable.draftTable.getName());
|
||||
col.setReferences(newReferences);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table name from references (table.column).
|
||||
*/
|
||||
private String extractBaseTable(String references) {
|
||||
int lastDot = references.lastIndexOf('.');
|
||||
return references.substring(0, lastDot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the new references using the given draftTableName.
|
||||
* (The referenced column is the same as before).
|
||||
*/
|
||||
private String deriveReferences(String references, String draftTableName) {
|
||||
int lastDot = references.lastIndexOf('.');
|
||||
return draftTableName + "." + references.substring(lastDot + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds information which columns are nullable or not to the compound indices.
|
||||
*/
|
||||
|
||||
-11
@@ -58,17 +58,6 @@ public class ModelContainer {
|
||||
return partitionedTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the FK references on all the draft tables.
|
||||
*/
|
||||
public void adjustDraftReferences() {
|
||||
for (MTable table : this.tables.values()) {
|
||||
if (table.isDraft()) {
|
||||
table.adjustReferences(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the map of all the tables.
|
||||
*/
|
||||
|
||||
-53
@@ -59,14 +59,6 @@ public class ModelBuildContext {
|
||||
return new DefaultConstraintMaxLength(databasePlatform.maxConstraintNameLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the foreign key references on any draft tables (that reference other draft tables).
|
||||
* This is called as a 'second pass' after all the draft tables have been identified.
|
||||
*/
|
||||
public void adjustDraftReferences() {
|
||||
model.adjustDraftReferences();
|
||||
}
|
||||
|
||||
public String normaliseTable(String baseTable) {
|
||||
return constraintNaming.normaliseTable(baseTable);
|
||||
}
|
||||
@@ -170,51 +162,6 @@ public class ModelBuildContext {
|
||||
return dbTypeMap.get(dbType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the draft table for a given table.
|
||||
*/
|
||||
public void createDraft(MTable table, boolean draftable) {
|
||||
|
||||
MTable draftTable = table.createDraftTable();
|
||||
draftTable.setPkName(primaryKeyName(draftTable.getName()));
|
||||
|
||||
if (draftable) {
|
||||
// Add a FK from @Draftable live table back to it's draft table)
|
||||
List<MColumn> pkCols = table.primaryKeyColumns();
|
||||
if (pkCols.size() == 1) {
|
||||
// only doing this for single column PK at this stage
|
||||
MColumn pk = pkCols.get(0);
|
||||
pk.setReferences(draftTable.getName() + "." + pk.getName());
|
||||
pk.setForeignKeyName(foreignKeyConstraintName(table.getName(), pk.getName(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
int fkCount = 0;
|
||||
int ixCount = 0;
|
||||
int uqCount = 0;
|
||||
Collection<MColumn> cols = draftTable.allColumns();
|
||||
for (MColumn col : cols) {
|
||||
if (col.getForeignKeyName() != null) {
|
||||
// Note that we adjust the 'references' table later in a second pass
|
||||
// after we know all the tables that are 'draftable'
|
||||
//col.setReferences(refTable + "." + refColumn);
|
||||
col.setForeignKeyName(foreignKeyConstraintName(draftTable.getName(), col.getName(), ++fkCount));
|
||||
|
||||
String[] indexCols = {col.getName()};
|
||||
col.setForeignKeyIndex(foreignKeyIndexName(draftTable.getName(), indexCols, ++ixCount));
|
||||
}
|
||||
// adjust the unique constraint names
|
||||
if (col.getUnique() != null) {
|
||||
col.setUnique(uniqueConstraintName(draftTable.getName(), col.getName(), ++uqCount));
|
||||
}
|
||||
if (col.getUniqueOneToOne() != null) {
|
||||
col.setUniqueOneToOne(uniqueConstraintName(draftTable.getName(), col.getName(), ++uqCount));
|
||||
}
|
||||
}
|
||||
|
||||
addTable(draftTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a builder to add foreign keys.
|
||||
*/
|
||||
|
||||
-5
@@ -38,11 +38,6 @@ class ModelBuildIntersectionTable {
|
||||
}
|
||||
|
||||
buildFkConstraints();
|
||||
|
||||
if (manyProp.targetDescriptor().isDraftable()) {
|
||||
ctx.createDraft(intersectionTable, false);
|
||||
}
|
||||
|
||||
return intersectionTable;
|
||||
}
|
||||
|
||||
|
||||
-14
@@ -114,22 +114,9 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
addDraftTable();
|
||||
table.updateCompoundIndices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a 'draft' table that is mostly the same as the base table.
|
||||
* It has @DraftOnly columns and adjusted primary and foreign keys.
|
||||
*/
|
||||
private void addDraftTable() {
|
||||
if (beanDescriptor.isDraftable() || beanDescriptor.isDraftableElement()) {
|
||||
// create a 'Draft' table which looks very similar (change PK, FK etc)
|
||||
ctx.createDraft(table, !beanDescriptor.isDraftableElement());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitMany(BeanPropertyAssocMany<?> p) {
|
||||
if (p.createJoinTable()) {
|
||||
@@ -251,7 +238,6 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
MColumn col = table.addColumnScalar(p.dbColumn(), ctx.getColumnDefn(p, false));
|
||||
//MColumn col = new MColumn(p.dbColumn(), ctx.getColumnDefn(p, false));
|
||||
col.setComment(p.dbComment());
|
||||
col.setDraftOnly(p.isDraftOnly());
|
||||
col.setHistoryExclude(p.isExcludedFromHistory());
|
||||
if (p.isId() || p.isImportedPrimaryKey()) {
|
||||
col.setPrimaryKey(true);
|
||||
|
||||
@@ -523,14 +523,6 @@ public abstract class TQRootBean<T, R> {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query against the draft set of tables.
|
||||
*/
|
||||
public R asDraft() {
|
||||
query.asDraft();
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query including soft deleted rows.
|
||||
*/
|
||||
|
||||
@@ -78,7 +78,7 @@ public class PlatformNoGeneratedKeysTest {
|
||||
|
||||
assertThat(d0.getId()).isNotNull();
|
||||
|
||||
server.publish(BasicDraftableBean.class, d0.getId());
|
||||
//server.publish(BasicDraftableBean.class, d0.getId());
|
||||
|
||||
BasicDraftableBean one = server.find(BasicDraftableBean.class, d0.getId());
|
||||
|
||||
|
||||
@@ -476,46 +476,6 @@ public class TDSpiEbeanServer extends TDSpiServer implements SpiEbeanServer {
|
||||
public void register(TransactionCallback transactionCallback) throws PersistenceException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T publish(Class<T> beanType, Object id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T publish(Class<T> beanType, Object id, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T draftRestore(Class<T> beanType, Object id, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T draftRestore(Class<T> beanType, Object id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction createTransaction() {
|
||||
return null;
|
||||
|
||||
@@ -508,46 +508,6 @@ public class TDSpiServer implements SpiServer {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T publish(Class<T> beanType, Object id, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T publish(Class<T> beanType, Object id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> publish(Query<T> query) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T draftRestore(Class<T> beanType, Object id, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T draftRestore(Class<T> beanType, Object id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query, Transaction transaction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> draftRestore(Query<T> query) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Set<String> validateQuery(Query<T> query) {
|
||||
return null;
|
||||
|
||||
@@ -14,19 +14,11 @@ public class FlagsTest {
|
||||
|
||||
int state = 0;
|
||||
|
||||
state = Flags.setPublish(state);
|
||||
assertThat(Flags.isSet(state, Flags.PUBLISH)).isTrue();
|
||||
|
||||
state = Flags.setMerge(state);
|
||||
state = Flags.setInsert(state);
|
||||
assertThat(Flags.isSet(state, Flags.PUBLISH)).isTrue();
|
||||
assertThat(Flags.isSet(state, Flags.MERGE)).isTrue();
|
||||
assertThat(Flags.isSet(state, Flags.INSERT)).isTrue();
|
||||
|
||||
state = Flags.unsetPublish(state);
|
||||
assertThat(Flags.isSet(state, Flags.PUBLISH)).isFalse();
|
||||
assertThat(Flags.isSet(state, Flags.MERGE)).isTrue();
|
||||
assertThat(Flags.isSet(state, Flags.INSERT)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -72,15 +64,11 @@ public class FlagsTest {
|
||||
@Test
|
||||
public void isPublishOrMerge() {
|
||||
|
||||
assertThat(Flags.isPublishMergeOrNormal(0)).isFalse();
|
||||
assertThat(Flags.isPublishMergeOrNormal(Flags.INSERT)).isFalse();
|
||||
assertThat(Flags.isPublishMergeOrNormal(Flags.RECURSE)).isFalse();
|
||||
assertThat(Flags.isMergeOrNormal(0)).isFalse();
|
||||
assertThat(Flags.isMergeOrNormal(Flags.INSERT)).isFalse();
|
||||
assertThat(Flags.isMergeOrNormal(Flags.RECURSE)).isFalse();
|
||||
|
||||
assertThat(Flags.isPublishMergeOrNormal(Flags.PUBLISH)).isTrue();
|
||||
assertThat(Flags.isPublishMergeOrNormal(Flags.MERGE)).isTrue();
|
||||
assertThat(Flags.isPublishMergeOrNormal(Flags.NORMAL)).isTrue();
|
||||
|
||||
int mergePublish = Flags.setMerge(Flags.setPublish(0));
|
||||
assertThat(Flags.isPublishMergeOrNormal(mergePublish)).isTrue();
|
||||
assertThat(Flags.isMergeOrNormal(Flags.MERGE)).isTrue();
|
||||
assertThat(Flags.isMergeOrNormal(Flags.NORMAL)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,11 @@ import jakarta.persistence.OneToMany;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Draftable
|
||||
public class DefaultsModel {
|
||||
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
@Draft
|
||||
boolean draft;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
List<ReferencedDefaultsModel> relatedModels;
|
||||
@@ -37,12 +34,4 @@ public class DefaultsModel {
|
||||
public void setRelatedModels(final List<ReferencedDefaultsModel> relatedModels) {
|
||||
this.relatedModels = relatedModels;
|
||||
}
|
||||
|
||||
public boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
public void setDraft(final boolean draft) {
|
||||
this.draft = draft;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,13 @@ public class TestDefaults extends BaseTestCase {
|
||||
|
||||
assertThat(current).isNotEmpty();
|
||||
if (isMySql() || isMariaDB() || isOracle()) {
|
||||
assertThat(current.get(0)).contains("insert into defaults_model_draft values (default);");
|
||||
assertThat(current.get(0)).contains("insert into defaults_model values (default);");
|
||||
} else if (isDb2()) {
|
||||
assertThat(current.get(0)).contains("insert into defaults_model_draft (id) values (default)");
|
||||
assertThat(current.get(0)).contains("insert into defaults_model (id) values (default)");
|
||||
} else if (isSqlServer()) {
|
||||
assertThat(current.get(0)).contains("insert into defaults_model_draft (id) values (?)");
|
||||
assertThat(current.get(0)).contains("insert into defaults_model (id) values (?)");
|
||||
} else {
|
||||
assertThat(current.get(0)).contains("insert into defaults_model_draft default values;");
|
||||
assertThat(current.get(0)).contains("insert into defaults_model default values;");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public class DocLinkTest extends BaseTestCase {
|
||||
Link link1 = new Link("something");
|
||||
link1.save();
|
||||
|
||||
DB.getDefault().publish(Link.class, link1.getId());
|
||||
//DB.getDefault().publish(Link.class, link1.getId());
|
||||
|
||||
Link link = DB.find(Link.class)
|
||||
.setId(link1.getId())
|
||||
@@ -50,7 +50,7 @@ public class DocLinkTest extends BaseTestCase {
|
||||
assertThat(link1.isDraft()).isFalse();
|
||||
|
||||
link1.save();
|
||||
assertThat(link1.isDraft()).isTrue();
|
||||
//assertThat(link1.isDraft()).isTrue();
|
||||
|
||||
// perform stateless update
|
||||
Link linkUpdate = new Link();
|
||||
@@ -73,7 +73,7 @@ public class DocLinkTest extends BaseTestCase {
|
||||
assertThat(link1.isDraft()).isFalse();
|
||||
|
||||
link1.save();
|
||||
assertThat(link1.isDraft()).isTrue();
|
||||
//assertThat(link1.isDraft()).isTrue();
|
||||
|
||||
link1.setComment("some change");
|
||||
link1.save();
|
||||
@@ -86,74 +86,36 @@ public class DocLinkTest extends BaseTestCase {
|
||||
|
||||
Link link1 = new Link("Ld2");
|
||||
link1.save();
|
||||
DB.getDefault().publish(Link.class, link1.getId());
|
||||
//DB.getDefault().publish(Link.class, link1.getId());
|
||||
|
||||
Link link = DB.find(Link.class).setId(link1.getId()).asDraft().findOne();
|
||||
Link link = DB.find(Link.class).setId(link1.getId()).findOne(); //.asDraft()
|
||||
DB.deletePermanent(link);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteLivePermanent_throwsException() {
|
||||
|
||||
Link link1 = new Link("Ld2");
|
||||
link1.save();
|
||||
|
||||
Link live = DB.getDefault().publish(Link.class, link1.getId());
|
||||
|
||||
try {
|
||||
DB.deletePermanent(live);
|
||||
fail("never get here");
|
||||
|
||||
} catch (PersistenceException e) {
|
||||
// assert nice message when trying to delete live bean
|
||||
assertThat(e.getMessage()).contains("Explicit Delete is not allowed on a 'live' bean - only draft beans");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete_whenPublished() {
|
||||
|
||||
Link link1 = new Link("Ld2");
|
||||
link1.save();
|
||||
Database server = DB.getDefault();
|
||||
server.publish(Link.class, link1.getId());
|
||||
//server.publish(Link.class, link1.getId());
|
||||
|
||||
link1 = DB.find(Link.class).setId(link1.getId()).asDraft().findOne();
|
||||
assertThat(link1.isDraft()).isTrue();
|
||||
link1 = DB.find(Link.class).setId(link1.getId()).findOne(); //.asDraft()
|
||||
// assertThat(link1.isDraft()).isTrue();
|
||||
|
||||
// this is a soft delete (no automatic publish here, only updates draft)
|
||||
link1.delete();
|
||||
|
||||
Link live = DB.find(Link.class).setId(link1.getId()).findOne();
|
||||
assertThat(live).isNotNull();
|
||||
assertThat(live.isDraft()).isFalse();
|
||||
assertThat(live.isDeleted()).isFalse(); // soft delete state not published yet
|
||||
|
||||
// this is a permanent delete (effectively has automatic publish)
|
||||
server.deletePermanent(link1);
|
||||
|
||||
live = DB.find(Link.class).setId(link1.getId()).findOne();
|
||||
assertThat(live).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLive_throwsException() {
|
||||
|
||||
Link link1 = new Link("forUpdateLive");
|
||||
link1.save();
|
||||
|
||||
Link live = DB.getDefault().publish(Link.class, link1.getId());
|
||||
|
||||
live.setComment("foo");
|
||||
// Expect a nice
|
||||
try {
|
||||
live.save();
|
||||
fail("Never get here");
|
||||
|
||||
} catch (PersistenceException e) {
|
||||
// we want to assert the message is nice and meaningful (and not a optimistic locking exception etc)
|
||||
assertThat(e.getMessage()).contains("Save or update is not allowed on a 'live' bean - only draft beans");
|
||||
}
|
||||
// //assertThat(live.isDraft()).isFalse();
|
||||
// assertThat(live.isDeleted()).isFalse(); // soft delete state not published yet
|
||||
//
|
||||
// // this is a permanent delete (effectively has automatic publish)
|
||||
// server.deletePermanent(link1);
|
||||
//
|
||||
// live = DB.find(Link.class).setId(link1.getId()).findOne();
|
||||
// assertThat(live).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,19 +128,19 @@ public class DocLinkTest extends BaseTestCase {
|
||||
link1.setWhenPublish(when);
|
||||
link1.save();
|
||||
|
||||
Link draft1 = DB.find(Link.class).setId(link1.getId()).asDraft().findOne();
|
||||
assertThat(draft1.isDirty()).isTrue();
|
||||
Link draft1 = DB.find(Link.class).setId(link1.getId()).findOne(); // .asDraft()
|
||||
//assertThat(draft1.isDirty()).isTrue();
|
||||
|
||||
Database server = DB.getDefault();
|
||||
|
||||
Link linkLive = server.publish(Link.class, link1.getId(), null);
|
||||
Link linkLive = draft1;//server.publish(Link.class, link1.getId(), null);
|
||||
assertThat(linkLive.getComment()).isEqualTo(comment);
|
||||
assertThat(linkLive.getWhenPublish()).isEqualToIgnoringMillis(when);
|
||||
|
||||
Link draft1b = DB.find(Link.class).setId(link1.getId()).asDraft().findOne();
|
||||
assertThat(draft1b.isDirty()).isFalse();
|
||||
assertThat(draft1b.getComment()).isNull();
|
||||
assertThat(draft1b.getWhenPublish()).isNull();
|
||||
// Link draft1b = DB.find(Link.class).setId(link1.getId()).findOne(); // .asDraft()
|
||||
// assertThat(draft1b.isDirty()).isFalse();
|
||||
// assertThat(draft1b.getComment()).isNull();
|
||||
// assertThat(draft1b.getWhenPublish()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,9 +156,9 @@ public class DocLinkTest extends BaseTestCase {
|
||||
link3.save();
|
||||
|
||||
Database server = DB.getDefault();
|
||||
server.publish(Link.class, link1.getId(), null);
|
||||
server.publish(Link.class, link2.getId(), null);
|
||||
server.publish(Link.class, link3.getId(), null);
|
||||
// server.publish(Link.class, link1.getId(), null);
|
||||
// server.publish(Link.class, link2.getId(), null);
|
||||
// server.publish(Link.class, link3.getId(), null);
|
||||
|
||||
Doc doc1 = new Doc("DocOne");
|
||||
doc1.getLinks().add(link1);
|
||||
@@ -205,12 +167,12 @@ public class DocLinkTest extends BaseTestCase {
|
||||
|
||||
Doc draftDoc1 = server.find(Doc.class)
|
||||
.setId(doc1.getId())
|
||||
.asDraft()
|
||||
//.asDraft()
|
||||
.findOne();
|
||||
|
||||
assertThat(draftDoc1.getLinks()).hasSize(2);
|
||||
|
||||
Doc liveDoc1 = server.publish(Doc.class, doc1.getId(), null);
|
||||
Doc liveDoc1 = doc1; // server.publish(Doc.class, doc1.getId(), null);
|
||||
|
||||
assertThat(liveDoc1.getLinks()).hasSize(2);
|
||||
assertThat(liveDoc1.getLinks()).extracting("id").contains(link1.getId(), link2.getId());
|
||||
@@ -223,7 +185,7 @@ public class DocLinkTest extends BaseTestCase {
|
||||
draftDoc1.save();
|
||||
|
||||
// publish with insert and delete of Links M2M relationship
|
||||
Doc liveDoc2 = server.publish(Doc.class, doc1.getId(), null);
|
||||
Doc liveDoc2 = draftDoc1;// server.publish(Doc.class, doc1.getId(), null);
|
||||
assertThat(liveDoc2.getLinks()).hasSize(2);
|
||||
assertThat(liveDoc2.getLinks()).extracting("id").contains(remaining.getId(), link3.getId());
|
||||
|
||||
@@ -241,25 +203,25 @@ public class DocLinkTest extends BaseTestCase {
|
||||
|
||||
Database server = DB.getDefault();
|
||||
|
||||
Link live = server.publish(Link.class, link1.getId(), null);
|
||||
Link live = link1;//server.publish(Link.class, link1.getId(), null);
|
||||
assertThat(live.isDraft()).isFalse();
|
||||
|
||||
Link draftLink = DB.find(Link.class)
|
||||
.setId(link1.getId())
|
||||
.asDraft()
|
||||
//.asDraft()
|
||||
.findOne();
|
||||
|
||||
draftLink.setLocation("secondLocation");
|
||||
draftLink.save();
|
||||
|
||||
server.draftRestore(Link.class, link1.getId(), null);
|
||||
// server.draftRestore(Link.class, link1.getId(), null);
|
||||
|
||||
draftLink = DB.find(Link.class)
|
||||
.setId(link1.getId())
|
||||
.asDraft()
|
||||
//.asDraft()
|
||||
.findOne();
|
||||
|
||||
assertThat(draftLink.getLocation()).isEqualTo("firstLocation");
|
||||
assertThat(draftLink.getLocation()).isEqualTo("secondLocation");//"firstLocation");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -272,11 +234,11 @@ public class DocLinkTest extends BaseTestCase {
|
||||
|
||||
Database server = DB.getDefault();
|
||||
|
||||
server.publish(Link.class, link1.getId(), null);
|
||||
//server.publish(Link.class, link1.getId(), null);
|
||||
|
||||
Link draftLink = DB.find(Link.class)
|
||||
.setId(link1.getId())
|
||||
.asDraft()
|
||||
//.asDraft()
|
||||
.findOne();
|
||||
|
||||
draftLink.setLocation("secondLocation");
|
||||
@@ -284,11 +246,11 @@ public class DocLinkTest extends BaseTestCase {
|
||||
draftLink.save();
|
||||
|
||||
Query<Link> query = server.find(Link.class).where().eq("id", link1.getId()).query();
|
||||
List<Link> links = server.draftRestore(query);
|
||||
List<Link> links = query.findList();//server.draftRestore(query);
|
||||
|
||||
assertThat(links).hasSize(1);
|
||||
assertThat(links.get(0).getLocation()).isEqualTo("firstLocation");
|
||||
assertThat(links.get(0).isDirty()).isEqualTo(false);
|
||||
assertThat(links.get(0).getComment()).isNull();
|
||||
assertThat(links.get(0).getLocation()).isEqualTo("secondLocation");//"firstLocation");
|
||||
//assertThat(links.get(0).isDirty()).isEqualTo(false);
|
||||
// assertThat(links.get(0).getComment()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class LinkQueryPublishTest {
|
||||
ids.add(link3.getId());
|
||||
|
||||
PagedList<Link> pagedList =
|
||||
server.find(Link.class).asDraft()
|
||||
server.find(Link.class)//.asDraft()
|
||||
.where().idIn(ids)
|
||||
.setMaxRows(10)
|
||||
.findPagedList();
|
||||
@@ -48,7 +48,7 @@ public class LinkQueryPublishTest {
|
||||
.order().asc("id");
|
||||
|
||||
|
||||
List<Link> pubList = server.publish(pubQuery);
|
||||
List<Link> pubList = pubQuery.findList(); // server.publish(pubQuery);
|
||||
|
||||
assertThat(pubList).hasSize(3);
|
||||
assertThat(pubList).extracting("id").contains(link1.getId(), link2.getId(), link3.getId());
|
||||
|
||||
@@ -37,25 +37,18 @@ public class OrganisationTest {
|
||||
Database server = DB.getDefault();
|
||||
|
||||
Document draftDoc = server.find(Document.class)
|
||||
.asDraft()
|
||||
//.asDraft()
|
||||
.setId(doc.getId())
|
||||
.findOne();
|
||||
|
||||
assertNotNull(draftDoc);
|
||||
|
||||
Document liveDoc = server.find(Document.class)
|
||||
.setId(doc.getId())
|
||||
.findOne();
|
||||
assertNull(liveDoc);
|
||||
|
||||
|
||||
server.publish(Document.class, doc.getId(), null);
|
||||
//server.publish(Document.class, doc.getId(), null);
|
||||
|
||||
doc.setTitle("Mod1");
|
||||
doc.save();
|
||||
|
||||
server.publish(Document.class, doc.getId(), null);
|
||||
|
||||
//server.publish(Document.class, doc.getId(), null);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,9 +70,9 @@ public class OrganisationTest {
|
||||
Database server = DB.getDefault();
|
||||
|
||||
|
||||
server.publish(Document.class, doc.getId(), null);
|
||||
//server.publish(Document.class, doc.getId(), null);
|
||||
|
||||
Document fetchDoc = DB.find(Document.class).setId(doc.getId()).asDraft().findOne();
|
||||
Document fetchDoc = DB.find(Document.class).setId(doc.getId()).findOne(); //.asDraft()
|
||||
List<DocumentMedia> media = fetchDoc.getMedia();
|
||||
|
||||
assertThat(media.size()).isEqualTo(2);
|
||||
@@ -97,7 +90,7 @@ public class OrganisationTest {
|
||||
|
||||
// publish will perform an insert, update and delete on child DocumentMedia
|
||||
// during the publish below with media1 being deleted
|
||||
Document liveBean = server.publish(Document.class, doc.getId(), null);
|
||||
Document liveBean = doc;//server.publish(Document.class, doc.getId(), null);
|
||||
assertThat(liveBean.getBody()).isEqualTo("Body2");
|
||||
assertThat(liveBean.getMedia().size()).isEqualTo(2);
|
||||
assertThat(liveBean.getMedia()).extracting("name").contains("media2", "media3");
|
||||
|
||||
@@ -16,8 +16,10 @@ public class TestInsertCheckUnique extends BaseTestCase {
|
||||
|
||||
@BeforeEach
|
||||
public void clearDb() {
|
||||
DB.find(Document.class).asDraft().where().contains("title", "UniqueKey").delete();
|
||||
DB.find(Document.class).asDraft().where().isNull("title").delete();
|
||||
DB.find(Document.class)//.asDraft()
|
||||
.where().contains("title", "UniqueKey").delete();
|
||||
DB.find(Document.class)//.asDraft()
|
||||
.where().isNull("title").delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -35,10 +37,6 @@ public class TestInsertCheckUnique extends BaseTestCase {
|
||||
doc2.setTitle("AUniqueKey_duplicateCheck");
|
||||
doc2.setBody("clashes with doc1");
|
||||
|
||||
assertThat(DB.checkUniqueness(doc2)).isEmpty();
|
||||
|
||||
DB.getDefault().publish(doc1.getClass(), doc1.getId());
|
||||
|
||||
assertThat(DB.checkUniqueness(doc2).toString()).contains("title");
|
||||
}
|
||||
}
|
||||
@@ -59,12 +57,11 @@ public class TestInsertCheckUnique extends BaseTestCase {
|
||||
|
||||
assertThat(DB.checkUniqueness(doc2)).isEmpty();
|
||||
|
||||
DB.getDefault().publish(doc1.getClass(), doc1.getId());
|
||||
|
||||
assertThat(DB.checkUniqueness(doc2)).isEmpty();
|
||||
//DB.getDefault().publish(doc1.getClass(), doc1.getId());
|
||||
//assertThat(DB.checkUniqueness(doc2)).isEmpty();
|
||||
|
||||
doc2.save();
|
||||
DB.getDefault().publish(doc2.getClass(), doc2.getId());
|
||||
//DB.getDefault().publish(doc2.getClass(), doc2.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +74,7 @@ public class TestInsertCheckUnique extends BaseTestCase {
|
||||
doc1.setBody("one");
|
||||
doc1.save();
|
||||
|
||||
DB.getDefault().publish(doc1.getClass(), doc1.getId());
|
||||
//DB.getDefault().publish(doc1.getClass(), doc1.getId());
|
||||
|
||||
Document doc2 = new Document();
|
||||
doc2.setTitle("One flew over the cuckoo's nest");
|
||||
|
||||
@@ -21,7 +21,9 @@ public class TestInsertDuplicateKey extends BaseTestCase {
|
||||
|
||||
@BeforeEach
|
||||
public void clearDb() {
|
||||
server().find(Document.class).asDraft().where().contains("title", "UniqueKey").delete();
|
||||
server().find(Document.class)
|
||||
//.asDraft()
|
||||
.where().contains("title", "UniqueKey").delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -64,7 +66,7 @@ public class TestInsertDuplicateKey extends BaseTestCase {
|
||||
|
||||
List<Document> found = DB.getDefault()
|
||||
.find(Document.class)
|
||||
.asDraft()
|
||||
//.asDraft()
|
||||
.where().startsWith("body", "insertTheBatch_duplicateKey_catchAndContinue")
|
||||
.findList();
|
||||
|
||||
|
||||
@@ -35,12 +35,8 @@ public class Document extends BaseDomain {
|
||||
@ManyToOne
|
||||
Organisation organisation;
|
||||
|
||||
/**
|
||||
* Relationship to draftable elements.
|
||||
*/
|
||||
//@PrivateOwned
|
||||
@OneToMany(mappedBy = "document")//, cascade = CascadeType.ALL)
|
||||
List<DocumentMedia> media;
|
||||
@OneToMany(mappedBy = "document", cascade = CascadeType.ALL)
|
||||
List<DocumentMedia> media;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
@@ -96,7 +92,7 @@ public class Document extends BaseDomain {
|
||||
}
|
||||
|
||||
public Document asDraft(Long id) {
|
||||
return query().asDraft().setId(id).findOne();
|
||||
return query().setId(id).findOne(); //.asDraft()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ public class TestTransactionTryResources extends BaseTestCase {
|
||||
|
||||
Document document = Document.find.asDraft(doc.getId());
|
||||
assertThat(document).isNotNull();
|
||||
assertThat(document.isDraft()).isTrue();
|
||||
|
||||
// cleanup
|
||||
DB.delete(document);
|
||||
@@ -69,7 +68,6 @@ public class TestTransactionTryResources extends BaseTestCase {
|
||||
|
||||
List<Document> docs = Document.find.query()
|
||||
.where().startsWith("body", "tryWithResources_catch")
|
||||
.asDraft()
|
||||
.findList();
|
||||
|
||||
assertThat(docs).hasSize(1);
|
||||
|
||||
Reference in New Issue
Block a user