mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bddfa3bc5f | ||
|
|
9ad460ecd8 | ||
|
|
50593a7f9d | ||
|
|
c088cfa339 | ||
|
|
e683e25a95 | ||
|
|
c7052c5bfa | ||
|
|
698ee2198d | ||
|
|
91c4eca528 | ||
|
|
81897bd54d | ||
|
|
2427630c07 | ||
|
|
3238c0def4 |
@@ -9,7 +9,7 @@
|
||||
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>11.17.3</version>
|
||||
<version>11.17.4</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ebean</name>
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-11.17.3</tag>
|
||||
<tag>ebean-11.17.4</tag>
|
||||
</scm>
|
||||
|
||||
<profiles>
|
||||
|
||||
@@ -2,6 +2,8 @@ package io.ebean;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Provides finder functionality for use with "Dependency Injection style" use of Ebean.
|
||||
* <p>
|
||||
@@ -115,6 +117,13 @@ public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
|
||||
db().save(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the beans in the collection.
|
||||
*/
|
||||
public int saveAll(Collection<T> bean) {
|
||||
return db().saveAll(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this entity.
|
||||
*
|
||||
@@ -154,6 +163,13 @@ public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
|
||||
return db().delete(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the beans in the collection.
|
||||
*/
|
||||
public int deleteAll(Collection<T> beans) {
|
||||
return db().deleteAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a bean permanently without soft delete.
|
||||
* <p>
|
||||
|
||||
@@ -57,22 +57,24 @@ import java.util.ServiceLoader;
|
||||
* <pre>{@code
|
||||
*
|
||||
* ServerConfig c = new ServerConfig();
|
||||
* c.setName("db");
|
||||
*
|
||||
* // read the ebean.properties and load
|
||||
* // those settings into this serverConfig object
|
||||
* c.loadFromProperties();
|
||||
*
|
||||
* // add any classes found in the app.data package
|
||||
* c.addPackage("com.myapp.domain");
|
||||
*
|
||||
* // register as the 'Default' server
|
||||
* c.setDefaultServer(true);
|
||||
* // explicitly register the entity beans to avoid classpath scanning
|
||||
* c.addClass(Customer.class);
|
||||
* c.addClass(User.class);
|
||||
*
|
||||
* EbeanServer server = EbeanServerFactory.create(c);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* Note that ServerConfigProvider provides a standard Java ServiceLoader mechanism that can
|
||||
* be used to apply configuration to the ServerConfig.
|
||||
* </p>
|
||||
*
|
||||
* @author emcgreal
|
||||
* @author rbygrave
|
||||
* @see EbeanServerFactory
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.ebean.config;
|
||||
|
||||
/**
|
||||
* Provides a ServiceLoader based mechanism to configure a ServerConfig.
|
||||
* <p>
|
||||
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
|
||||
* via a file at <code>META-INF/services/io.ebean.config.ServerConfigProvider</code>.
|
||||
* </p>
|
||||
* <p>
|
||||
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
|
||||
* spring specific configuration. When we are not using a DI container we may use this mechanism to
|
||||
* explicitly register the entity beans and avoid classpath scanning.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* public class EbeanConfigProvider implements ServerConfigProvider {
|
||||
*
|
||||
* @Override
|
||||
* public void apply(ServerConfig config) {
|
||||
*
|
||||
* // register the entity bean classes explicitly
|
||||
* config.addClass(Customer.class);
|
||||
* config.addClass(User.class);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public interface ServerConfigProvider {
|
||||
|
||||
/**
|
||||
* Apply the configuration to the ServerConfig.
|
||||
* <p>
|
||||
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
|
||||
* </p>
|
||||
*/
|
||||
void apply(ServerConfig config);
|
||||
}
|
||||
@@ -53,6 +53,10 @@ public class ScopeTrans {
|
||||
*/
|
||||
private boolean rolledBack;
|
||||
|
||||
/**
|
||||
* Flag set when nested commit has occurred.
|
||||
*/
|
||||
private boolean nestedCommit;
|
||||
|
||||
public ScopeTrans(boolean rollbackOnChecked, boolean created, SpiTransaction transaction, TxScope txScope) {
|
||||
|
||||
@@ -113,7 +117,6 @@ public class ScopeTrans {
|
||||
complete();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Complete the transaction programmatically. Try to commit.
|
||||
*/
|
||||
@@ -124,7 +127,7 @@ public class ScopeTrans {
|
||||
}
|
||||
|
||||
public void end() {
|
||||
if (created) {
|
||||
if (created || !nestedCommit) {
|
||||
transaction.end();
|
||||
}
|
||||
}
|
||||
@@ -133,6 +136,7 @@ public class ScopeTrans {
|
||||
if (created) {
|
||||
transaction.commit();
|
||||
} else {
|
||||
nestedCommit = true;
|
||||
transaction.setBatchFlushOnQuery(restoreBatchFlushOnQuery);
|
||||
if (restoreBatch != null) {
|
||||
transaction.setBatch(restoreBatch);
|
||||
|
||||
+12
-4
@@ -79,13 +79,21 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
protected void createOrReplaceFunction(DdlBuffer apply, String procedureName, String historyTable, List<String> includedColumns) throws IOException {
|
||||
apply
|
||||
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine()
|
||||
.append("begin").newLine();
|
||||
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine();
|
||||
|
||||
apply.append("declare").newLine()
|
||||
.append(" lowerTs timestamptz;").newLine()
|
||||
.append(" upperTs timestamptz;").newLine();
|
||||
|
||||
apply.append("begin").newLine()
|
||||
.append(" lowerTs = lower(OLD.sys_period);").newLine()
|
||||
.append(" upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);").newLine();
|
||||
|
||||
apply
|
||||
.append(" if (TG_OP = 'UPDATE') then").newLine();
|
||||
appendInsertIntoHistory(apply, historyTable, includedColumns);
|
||||
apply
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(").append(currentTimestamp).append(",null);").newLine()
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(upperTs,null);").newLine()
|
||||
.append(" return new;").newLine();
|
||||
apply
|
||||
.append(" elsif (TG_OP = 'DELETE') then").newLine();
|
||||
@@ -124,7 +132,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriod).append(",");
|
||||
appendColumnNames(buffer, columns, "");
|
||||
buffer.append(") values (tstzrange(lower(OLD.").append(sysPeriod).append("), ").append(currentTimestamp).append("), ");
|
||||
buffer.append(") values (tstzrange(lowerTs,upperTs), ");
|
||||
appendColumnNames(buffer, columns, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.dbmigration.model;
|
||||
import io.ebeaninternal.dbmigration.migration.ChangeSet;
|
||||
import io.ebeaninternal.dbmigration.migration.ChangeSetType;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
import io.ebeaninternal.dbmigration.migration.Migration;
|
||||
|
||||
@@ -207,10 +208,26 @@ public class PendingDrops {
|
||||
|
||||
} else if (pendingDrop instanceof DropTable && dropTableIn((DropTable) pendingDrop, appliedDrops)) {
|
||||
iterator.remove();
|
||||
|
||||
} else if (pendingDrop instanceof DropHistoryTable && dropHistoryTableIn((DropHistoryTable) pendingDrop, appliedDrops)) {
|
||||
iterator.remove();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the pendingDrop is contained in the appliedDrops.
|
||||
*/
|
||||
private boolean dropHistoryTableIn(DropHistoryTable pendingDrop, ChangeSet appliedDrops) {
|
||||
for (Object o : appliedDrops.getChangeSetChildren()) {
|
||||
if (o instanceof DropHistoryTable && sameHistoryTable(pendingDrop, (DropHistoryTable) o)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the pendingDrop is contained in the appliedDrops.
|
||||
*/
|
||||
@@ -235,6 +252,13 @@ public class PendingDrops {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the DropHistoryTable match by base-table name.
|
||||
*/
|
||||
private boolean sameHistoryTable(DropHistoryTable pendingDrop, DropHistoryTable o) {
|
||||
return pendingDrop.getBaseTable().equals(o.getBaseTable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the DropTable match by table name.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.ebean.cache.ServerCacheOptions;
|
||||
import io.ebean.cache.ServerCachePlugin;
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.ServerConfigProvider;
|
||||
import io.ebean.config.TenantMode;
|
||||
import io.ebean.config.UnderscoreNamingConvention;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
@@ -62,9 +63,8 @@ public class DefaultContainer implements SpiContainer {
|
||||
}
|
||||
|
||||
private void invokeBootupPlugin() {
|
||||
Iterator<SpiContainerBootup> it = ServiceLoader.load(SpiContainerBootup.class).iterator();
|
||||
while (it.hasNext()) {
|
||||
it.next().bootup();
|
||||
for (SpiContainerBootup boot : ServiceLoader.load(SpiContainerBootup.class)) {
|
||||
boot.bootup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,8 +103,13 @@ public class DefaultContainer implements SpiContainer {
|
||||
public SpiEbeanServer createServer(ServerConfig serverConfig) {
|
||||
|
||||
synchronized (this) {
|
||||
setNamingConvention(serverConfig);
|
||||
if (serverConfig.isDefaultServer()) {
|
||||
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
|
||||
configProvider.apply(serverConfig);
|
||||
}
|
||||
}
|
||||
|
||||
setNamingConvention(serverConfig);
|
||||
BootupClasses bootupClasses = getBootupClasses(serverConfig);
|
||||
|
||||
boolean online = true;
|
||||
|
||||
@@ -1734,7 +1734,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
if (beans == null || beans.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
executeInTrans((txn) -> {
|
||||
for (Object bean : beans) {
|
||||
update(checkEntityBean(bean), txn);
|
||||
@@ -1776,7 +1775,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
if (beans == null || beans.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
executeInTrans((txn) -> {
|
||||
for (Object bean : beans) {
|
||||
persister.insert(checkEntityBean(bean), txn);
|
||||
@@ -1845,24 +1843,27 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
public int saveAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException {
|
||||
return saveAllInternal(beans.iterator(), transaction);
|
||||
return saveAllInternal(beans, transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int saveAll(Collection<?> beans) throws OptimisticLockException {
|
||||
return saveAllInternal(beans.iterator(), null);
|
||||
return saveAllInternal(beans, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all beans in the iterator with an explicit transaction.
|
||||
*/
|
||||
private int saveAllInternal(Iterator<?> it, Transaction transaction) {
|
||||
private int saveAllInternal(Collection<?> beans, Transaction transaction) {
|
||||
|
||||
if (beans == null || beans.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return executeInTrans((txn) -> {
|
||||
txn.checkBatchEscalationOnCollection();
|
||||
int saveCount = 0;
|
||||
while (it.hasNext()) {
|
||||
persister.save(checkEntityBean(it.next()), txn);
|
||||
for (Object bean : beans) {
|
||||
persister.save(checkEntityBean(bean), txn);
|
||||
saveCount++;
|
||||
}
|
||||
|
||||
@@ -1950,12 +1951,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
public int deleteAllPermanent(Collection<?> beans) {
|
||||
return deleteAllInternal(beans.iterator(), null, true);
|
||||
return deleteAllInternal(beans, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteAllPermanent(Collection<?> beans, Transaction t) {
|
||||
return deleteAllInternal(beans.iterator(), t, true);
|
||||
return deleteAllInternal(beans, t, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1963,7 +1964,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
*/
|
||||
@Override
|
||||
public int deleteAll(Collection<?> beans) {
|
||||
return deleteAllInternal(beans.iterator(), null, false);
|
||||
return deleteAllInternal(beans, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1971,21 +1972,23 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
*/
|
||||
@Override
|
||||
public int deleteAll(Collection<?> beans, Transaction t) {
|
||||
return deleteAllInternal(beans.iterator(), t, false);
|
||||
return deleteAllInternal(beans, t, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the beans in the iterator with an explicit transaction.
|
||||
*/
|
||||
private int deleteAllInternal(Iterator<?> it, Transaction transaction, boolean permanent) {
|
||||
private int deleteAllInternal(Collection<?> beans, Transaction transaction, boolean permanent) {
|
||||
|
||||
if (beans == null || beans.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return executeInTrans((txn) -> {
|
||||
|
||||
txn.checkBatchEscalationOnCollection();
|
||||
int deleteCount = 0;
|
||||
while (it.hasNext()) {
|
||||
EntityBean bean = checkEntityBean(it.next());
|
||||
persister.delete(bean, txn, permanent);
|
||||
for (Object bean : beans) {
|
||||
persister.delete(checkEntityBean(bean), txn, permanent);
|
||||
deleteCount++;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,16 @@ package io.ebeaninternal.server.persist;
|
||||
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.SpiProfileTransactionEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A batched statement that is held in BatchedPstmtHolder. It has a list of
|
||||
@@ -17,6 +22,8 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BatchedPstmt.class);
|
||||
|
||||
/**
|
||||
* The underlying statement.
|
||||
*/
|
||||
@@ -40,6 +47,8 @@ public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
|
||||
private int[] results;
|
||||
|
||||
private List<InputStream> inputStreams;
|
||||
|
||||
/**
|
||||
* Create with a given statement.
|
||||
*/
|
||||
@@ -117,16 +126,19 @@ public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
}
|
||||
|
||||
private void executeAndCheckRowCounts() throws SQLException {
|
||||
try {
|
||||
results = pstmt.executeBatch();
|
||||
if (results.length != list.size()) {
|
||||
String s = "results array error " + results.length + " " + list.size();
|
||||
throw new SQLException(s);
|
||||
}
|
||||
|
||||
results = pstmt.executeBatch();
|
||||
if (results.length != list.size()) {
|
||||
String s = "results array error " + results.length + " " + list.size();
|
||||
throw new SQLException(s);
|
||||
}
|
||||
|
||||
// check for concurrency exceptions...
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
list.get(i).checkRowCount(results[i]);
|
||||
// check for concurrency exceptions...
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
list.get(i).checkRowCount(results[i]);
|
||||
}
|
||||
} finally {
|
||||
closeInputStreams();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,4 +160,23 @@ public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
public int[] getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any inputStreams that should be closed after execution.
|
||||
*/
|
||||
public void registerInputStreams(List<InputStream> inputStreams) {
|
||||
this.inputStreams = inputStreams;
|
||||
}
|
||||
|
||||
private void closeInputStreams() {
|
||||
if (inputStreams != null) {
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.warn("Error closing inputStream ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,15 @@ public class BatchedPstmtHolder {
|
||||
* This will return null if no matching PreparedStatement is found.
|
||||
*/
|
||||
public PreparedStatement getStmt(String stmtKey, BatchPostExecute postExecute) {
|
||||
BatchedPstmt batchedPstmt = getBatchedPstmt(stmtKey, postExecute);
|
||||
return (batchedPstmt == null) ? null : batchedPstmt.getStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BatchedPstmt that holds the batched statement.
|
||||
*/
|
||||
public BatchedPstmt getBatchedPstmt(String stmtKey, BatchPostExecute postExecute) {
|
||||
|
||||
BatchedPstmt bs = stmtMap.get(stmtKey);
|
||||
if (bs == null) {
|
||||
// the PreparedStatement has need been created
|
||||
@@ -53,7 +62,7 @@ public class BatchedPstmtHolder {
|
||||
if (bsSize > maxSize) {
|
||||
maxSize = bsSize;
|
||||
}
|
||||
return bs.getStatement();
|
||||
return bs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,6 +46,8 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
*/
|
||||
protected DataBind dataBind;
|
||||
|
||||
protected BatchedPstmt batchedPstmt;
|
||||
|
||||
protected String sql;
|
||||
|
||||
/**
|
||||
@@ -273,20 +275,18 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
/**
|
||||
* Return a prepared statement taking into account batch requirements.
|
||||
*/
|
||||
protected PreparedStatement getPstmt(SpiTransaction t, String sql, PersistRequestBean<?> request,
|
||||
boolean genKeys) throws SQLException {
|
||||
protected PreparedStatement getPstmt(SpiTransaction t, String sql, PersistRequestBean<?> request, boolean genKeys) throws SQLException {
|
||||
|
||||
BatchedPstmtHolder batch = t.getBatchControl().getPstmtHolder();
|
||||
PreparedStatement stmt = batch.getStmt(sql, request);
|
||||
|
||||
if (stmt != null) {
|
||||
return stmt;
|
||||
batchedPstmt = batch.getBatchedPstmt(sql, request);
|
||||
if (batchedPstmt != null) {
|
||||
return batchedPstmt.getStatement();
|
||||
}
|
||||
|
||||
stmt = getPstmt(t, sql, genKeys);
|
||||
PreparedStatement stmt = getPstmt(t, sql, genKeys);
|
||||
|
||||
BatchedPstmt bs = new BatchedPstmt(stmt, genKeys, sql, t);
|
||||
batch.addStmt(bs, request);
|
||||
batchedPstmt = new BatchedPstmt(stmt, genKeys, sql, t);
|
||||
batch.addStmt(batchedPstmt, request);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,9 @@ public class InsertHandler extends DmlHandler {
|
||||
}
|
||||
dataBind = bind(pstmt);
|
||||
meta.bind(this, bean, withId, persistRequest.isPublish());
|
||||
|
||||
if (persistRequest.isBatched()) {
|
||||
batchedPstmt.registerInputStreams(dataBind.getInputStreams());
|
||||
}
|
||||
logSql(sql);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ public class UpdateHandler extends DmlHandler {
|
||||
}
|
||||
dataBind = bind(pstmt);
|
||||
meta.bind(persistRequest, this, updatePlan);
|
||||
|
||||
if (persistRequest.isBatched()) {
|
||||
batchedPstmt.registerInputStreams(dataBind.getInputStreams());
|
||||
}
|
||||
setUpdateGenValues();
|
||||
|
||||
logSql(sql);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
@@ -13,10 +16,14 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
public class DataBind {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DataBind.class);
|
||||
|
||||
private final DataTimeZone dataTimeZone;
|
||||
|
||||
private final PreparedStatement pstmt;
|
||||
@@ -25,6 +32,8 @@ public class DataBind {
|
||||
|
||||
private final StringBuilder bindLog = new StringBuilder();
|
||||
|
||||
private List<InputStream> inputStreams;
|
||||
|
||||
private int pos;
|
||||
|
||||
public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
|
||||
@@ -79,7 +88,24 @@ public class DataBind {
|
||||
}
|
||||
|
||||
public int executeUpdate() throws SQLException {
|
||||
return pstmt.executeUpdate();
|
||||
try {
|
||||
return pstmt.executeUpdate();
|
||||
} finally {
|
||||
closeInputStreams();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeInputStreams() {
|
||||
if (inputStreams != null) {
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.warn("Error closing InputStream that was bound to PreparedStatement", e);
|
||||
}
|
||||
}
|
||||
inputStreams = null;
|
||||
}
|
||||
}
|
||||
|
||||
public PreparedStatement getPstmt() {
|
||||
@@ -147,7 +173,19 @@ public class DataBind {
|
||||
pstmt.setString(++pos, String.valueOf(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return any inputStreams that have been bound (and should be closed).
|
||||
* This is used for batched statement execution only.
|
||||
*/
|
||||
public List<InputStream> getInputStreams() {
|
||||
return inputStreams;
|
||||
}
|
||||
|
||||
public void setBinaryStream(InputStream inputStream, long length) throws SQLException {
|
||||
if (inputStreams == null) {
|
||||
inputStreams = new ArrayList<>();
|
||||
}
|
||||
inputStreams.add(inputStream);
|
||||
pstmt.setBinaryStream(++pos, inputStream, length);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,26 @@ public class EbeanServer_saveAllTest extends BaseTestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteAll_withNull() {
|
||||
Ebean.deleteAll(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteAll_withEmpty() {
|
||||
Ebean.saveAll(beans(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveAll_withNull() {
|
||||
Ebean.saveAll(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveAll_withEmpty() {
|
||||
Ebean.saveAll(beans(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveAll_withTransaction() {
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package io.ebeaninternal.dbmigration;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.EbeanServerFactory;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.StrictAssertions.assertThatThrownBy;
|
||||
|
||||
|
||||
/**
|
||||
* This is the Migrationscript generator. It generates 3 migrationscript for the models
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
public class DbMigrationDropHistoryTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DbMigrationDropHistoryTest.class);
|
||||
|
||||
@Test
|
||||
public void invokeTest() throws IOException {
|
||||
main(null);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
logger.info("start");
|
||||
|
||||
DefaultDbMigration migration = new DefaultDbMigration();
|
||||
|
||||
// We use src/test/resources as output directory (so we see in GIT if files will change)
|
||||
|
||||
migration.setPathToResources("src/test/resources");
|
||||
|
||||
ServerConfig config = new ServerConfig();
|
||||
config.setName("migrationtest-history");
|
||||
config.loadFromProperties();
|
||||
config.setRegister(false);
|
||||
config.setDefaultServer(false);
|
||||
|
||||
|
||||
config.setPackages(Arrays.asList("misc.migration.history.v1_0"));
|
||||
EbeanServer server = EbeanServerFactory.create(config);
|
||||
migration.setServer(server);
|
||||
|
||||
// First, we clean up the output-directory
|
||||
assertThat(migration.getMigrationDirectory().getAbsolutePath()).contains("migrationtest-history");
|
||||
Files.walk(migration.getMigrationDirectory().toPath())
|
||||
.filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete);
|
||||
|
||||
// then we generate migration scripts for v1_0
|
||||
assertThat(migration.generateMigration()).isEqualTo("1.0__initial");
|
||||
// and we check repeatative calls
|
||||
assertThat(migration.generateMigration()).isNull();
|
||||
|
||||
// and now for v1_1
|
||||
config.setPackages(Arrays.asList("misc.migration.history.v1_1"));
|
||||
server = EbeanServerFactory.create(config);
|
||||
migration.setServer(server);
|
||||
assertThat(migration.generateMigration()).isEqualTo("1.1");
|
||||
assertThat(migration.generateMigration()).isNull(); // subsequent call
|
||||
|
||||
|
||||
|
||||
System.setProperty("ddl.migration.pendingDropsFor", "1.1");
|
||||
assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1");
|
||||
assertThatThrownBy(()->migration.generateMigration())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("No 'pendingDrops'"); // subsequent call
|
||||
System.clearProperty("ddl.migration.pendingDropsFor");
|
||||
|
||||
logger.info("end");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,11 @@ public class DbMigrationGenerateTest {
|
||||
|
||||
System.setProperty("ddl.migration.pendingDropsFor", "1.1");
|
||||
assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1");
|
||||
|
||||
assertThatThrownBy(()->migration.generateMigration())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("No 'pendingDrops'"); // subsequent call
|
||||
|
||||
System.clearProperty("ddl.migration.pendingDropsFor");
|
||||
assertThat(migration.generateMigration()).isNull(); // subsequent call
|
||||
|
||||
@@ -98,6 +104,10 @@ public class DbMigrationGenerateTest {
|
||||
|
||||
System.setProperty("ddl.migration.pendingDropsFor", "1.3");
|
||||
assertThat(migration.generateMigration()).isEqualTo("1.4__dropsFor_1.3");
|
||||
assertThatThrownBy(()->migration.generateMigration())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("No 'pendingDrops'"); // subsequent call
|
||||
|
||||
System.clearProperty("ddl.migration.pendingDropsFor");
|
||||
assertThat(migration.generateMigration()).isNull(); // subsequent call
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package misc.migration.history.v1_0;
|
||||
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import io.ebean.annotation.History;
|
||||
|
||||
/**
|
||||
* detects a bug where dropHistoryTable is not applied correctly
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "migtest_e_history7")
|
||||
@History
|
||||
public class EHistory7 {
|
||||
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package misc.migration.history.v1_1;
|
||||
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* detects a bug where dropHistoryTable is not applied correctly
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "migtest_e_history7")
|
||||
public class EHistory7 {
|
||||
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.SqlQuery;
|
||||
import io.ebean.SqlRow;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.Version;
|
||||
import io.ebean.annotation.ForPlatform;
|
||||
import io.ebean.annotation.Platform;
|
||||
@@ -93,6 +94,52 @@ public class TestHistoryInsert extends BaseTestCase {
|
||||
assertThat(versions).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ForPlatform({Platform.POSTGRES})
|
||||
public void test_singleTransaction_multipleHistory() {
|
||||
|
||||
User user = new User();
|
||||
user.setName("First");
|
||||
user.setEmail("first@email.com");
|
||||
user.setPasswordHash("someHash");
|
||||
|
||||
try (Transaction transaction = Ebean.beginTransaction()) {
|
||||
// insert and many updates inside transaction
|
||||
Ebean.save(user);
|
||||
user.setEmail("first2@email.com");
|
||||
Ebean.save(user);
|
||||
user.setEmail("first3@email.com");
|
||||
Ebean.save(user);
|
||||
user.setEmail("first4@email.com");
|
||||
Ebean.save(user);
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
// a couple more updates outside of the first transaction
|
||||
user.setEmail("first5@email.com");
|
||||
Ebean.save(user);
|
||||
|
||||
user.setEmail("first6@email.com");
|
||||
Ebean.save(user);
|
||||
|
||||
List<SqlRow> sqlRows =
|
||||
Ebean.createSqlQuery("select lower(sys_period) lowerBound, upper(sys_period) upperBound from c_user_history where id = :id order by when_modified")
|
||||
.setParameter("id", user.getId())
|
||||
.findList();
|
||||
|
||||
Timestamp previousUpper = null;
|
||||
|
||||
for (SqlRow sqlRow : sqlRows) {
|
||||
Timestamp nextLower = sqlRow.getTimestamp("lowerBound");
|
||||
Timestamp nextUpper = sqlRow.getTimestamp("upperBound");
|
||||
if (previousUpper != null) {
|
||||
assertThat(previousUpper).isEqualTo(nextLower);
|
||||
}
|
||||
previousUpper = nextUpper;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use SqlQuery to query the history table directly.
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import io.ebean.BaseTestCase;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -26,6 +27,22 @@ public class TestBeanRepository extends BaseTestCase {
|
||||
|
||||
repository.update(fetchCustomer);
|
||||
repository.delete(fetchCustomer);
|
||||
|
||||
List<Customer> custs = new ArrayList<>();
|
||||
custs.add(newCustomer("c0"));
|
||||
custs.add(newCustomer("c1"));
|
||||
|
||||
int count = repository.saveAll(custs);
|
||||
assertThat(count).isEqualTo(2);
|
||||
|
||||
count = repository.deleteAll(custs);
|
||||
assertThat(count).isEqualTo(2);
|
||||
}
|
||||
|
||||
private Customer newCustomer(String name) {
|
||||
Customer customer = new Customer();
|
||||
customer.setName(name);
|
||||
return customer;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
package org.tests.transaction;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.Transaction;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tests.model.basic.EBasic;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestNestedTransaction extends BaseTestCase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TestNestedTransaction.class);
|
||||
|
||||
private EBasic bean;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
bean = new EBasic("new");
|
||||
Ebean.save(bean);
|
||||
}
|
||||
|
||||
private void assertClean() {
|
||||
EBasic myBean = Ebean.find(EBasic.class, bean.getId());
|
||||
assertThat(myBean.getName()).isEqualTo("new");
|
||||
}
|
||||
|
||||
private void assertModified() {
|
||||
EBasic myBean = Ebean.find(EBasic.class, bean.getId());
|
||||
assertThat(myBean.getName()).isEqualTo("modified");
|
||||
}
|
||||
|
||||
private void modify() {
|
||||
bean.setName("modified");
|
||||
Ebean.save(bean);
|
||||
}
|
||||
|
||||
// ===== level 0 =======
|
||||
@Test
|
||||
public void testNested_0() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_1() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn0.commit();
|
||||
}
|
||||
assertModified();
|
||||
}
|
||||
|
||||
// ===== level 1 =======
|
||||
@Test
|
||||
public void testNested_00() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_01() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
attemptCommit(txn0);
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
private void attemptCommit(Transaction txn) {
|
||||
try {
|
||||
txn.commit();
|
||||
} catch (IllegalStateException e) {
|
||||
// expected
|
||||
log.info("Expected IllegalStateException as transaction already rolled back " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_10() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn1.commit();
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_11() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn1.commit();
|
||||
}
|
||||
txn0.commit();
|
||||
}
|
||||
assertModified();
|
||||
}
|
||||
|
||||
// ===== level 2 =======
|
||||
@Test
|
||||
public void testNested_000() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_001() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
attemptCommit(txn0);
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_010() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
txn1.commit();
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_011() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
// no commit
|
||||
}
|
||||
txn1.commit();
|
||||
}
|
||||
attemptCommit(txn0);
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_100() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn2.commit();
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_101() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn2.commit();
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
attemptCommit(txn0);
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_110() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn2.commit();
|
||||
}
|
||||
txn1.commit();
|
||||
}
|
||||
// no commit
|
||||
}
|
||||
assertClean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNested_111() {
|
||||
try (Transaction txn0 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn1 = Ebean.beginTransaction()) {
|
||||
try (Transaction txn2 = Ebean.beginTransaction()) {
|
||||
modify();
|
||||
txn2.commit();
|
||||
}
|
||||
txn1.commit();
|
||||
}
|
||||
txn0.commit();
|
||||
}
|
||||
assertModified();
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,107 @@ package org.tests.types;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import org.tests.model.types.SomeFileBean;
|
||||
import io.ebean.Transaction;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.types.SomeFileBean;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URL;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestFileType extends BaseTestCase {
|
||||
|
||||
File file = getFile("/profile-image.jpg");
|
||||
File file2 = getFile("/java-64.png");
|
||||
private File file = getFile("/profile-image.jpg");
|
||||
private File file2 = getFile("/java-64.png");
|
||||
|
||||
private File newTempFile() throws IOException {
|
||||
File tempFile = File.createTempFile("testfile", "txt");
|
||||
try (PrintStream ps = new PrintStream(tempFile)) {
|
||||
ps.println("Hello World!");
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_closeFileStreamUnbatched() throws IOException {
|
||||
|
||||
File tempFile = newTempFile();
|
||||
|
||||
SomeFileBean bean0 = new SomeFileBean();
|
||||
bean0.setName("tempBeanUnbatched");
|
||||
bean0.setContent(tempFile);
|
||||
Ebean.save(bean0);
|
||||
|
||||
assertTrue(tempFile.delete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_closeFileStreamUnbatched_onUpdate() throws IOException {
|
||||
|
||||
SomeFileBean bean0 = new SomeFileBean();
|
||||
bean0.setName("tempBeanUnbatched");
|
||||
bean0.setContent(newTempFile());
|
||||
Ebean.save(bean0);
|
||||
|
||||
|
||||
File updateFile = newTempFile();
|
||||
bean0.setName("tempBeanModified");
|
||||
bean0.setContent(updateFile);
|
||||
Ebean.save(bean0);
|
||||
|
||||
assertTrue(updateFile.delete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_closeFileStreamBatched() throws IOException {
|
||||
|
||||
SomeFileBean bean0 = new SomeFileBean();
|
||||
bean0.setName("tempBeanUnbatched");
|
||||
bean0.setContent(newTempFile());
|
||||
Ebean.save(bean0);
|
||||
|
||||
|
||||
File tempFile = newTempFile();
|
||||
|
||||
try (Transaction txn = Ebean.beginTransaction()) {
|
||||
txn.setBatchSize(30);
|
||||
txn.setBatchMode(true);
|
||||
|
||||
bean0.setName("tempBeanBatchedModified");
|
||||
bean0.setContent(tempFile);
|
||||
Ebean.save(bean0);
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
assertTrue(tempFile.delete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_closeFileStreamBatched_update() throws IOException {
|
||||
|
||||
File tempFile = newTempFile();
|
||||
|
||||
try (Transaction txn = Ebean.beginTransaction()) {
|
||||
txn.setBatchSize(30);
|
||||
txn.setBatchMode(true);
|
||||
|
||||
SomeFileBean bean0 = new SomeFileBean();
|
||||
bean0.setName("tempBeanBatched");
|
||||
bean0.setContent(tempFile);
|
||||
Ebean.save(bean0);
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
assertTrue(tempFile.delete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_insertNullFile() {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
-- Migrationscripts for ebean unittest DbMigrationDropHistoryTest
|
||||
-- apply changes
|
||||
create table migtest_e_history7 (
|
||||
id integer auto_increment not null,
|
||||
constraint pk_migtest_e_history7 primary key (id)
|
||||
);
|
||||
|
||||
alter table migtest_e_history7 add column sys_period_start datetime(6) default now(6);
|
||||
alter table migtest_e_history7 add column sys_period_end datetime(6);
|
||||
create table migtest_e_history7_history(
|
||||
id integer,
|
||||
sys_period_start datetime(6),
|
||||
sys_period_end datetime(6)
|
||||
);
|
||||
create view migtest_e_history7_with_history as select * from migtest_e_history7 union all select * from migtest_e_history7_history;
|
||||
|
||||
create trigger migtest_e_history7_history_upd before update,delete on migtest_e_history7 for each row call "io.ebean.config.dbplatform.h2.H2HistoryTrigger";
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Migrationscripts for ebean unittest DbMigrationDropHistoryTest
|
||||
-- drop dependencies
|
||||
drop trigger migtest_e_history7_history_upd;
|
||||
drop view migtest_e_history7_with_history;
|
||||
alter table migtest_e_history7 drop column sys_period_start;
|
||||
alter table migtest_e_history7 drop column sys_period_end;
|
||||
drop table migtest_e_history7_history;
|
||||
|
||||
|
||||
-- apply changes
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
-- h2 and postgres script
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
create or replace view order_agg_vw as
|
||||
select d.order_id, sum(d.order_qty * d.unit_price) as order_total,
|
||||
sum(d.ship_qty * d.unit_price) as ship_total
|
||||
from o_order_detail d
|
||||
group by d.order_id
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
|
||||
<changeSet type="apply">
|
||||
<createTable name="migtest_e_history7" withHistory="true" pkName="pk_migtest_e_history7">
|
||||
<column name="id" type="integer" primaryKey="true"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
</migration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
|
||||
<changeSet type="pendingDrops">
|
||||
<dropHistoryTable baseTable="migtest_e_history7"/>
|
||||
</changeSet>
|
||||
</migration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
|
||||
<changeSet type="apply" dropsFor="1.1">
|
||||
<dropHistoryTable baseTable="migtest_e_history7"/>
|
||||
</changeSet>
|
||||
</migration>
|
||||
@@ -184,13 +184,18 @@ create table migtest_e_history6_history(like migtest_e_history6);
|
||||
create view migtest_e_history6_with_history as select * from migtest_e_history6 union all select * from migtest_e_history6_history;
|
||||
|
||||
create or replace function migtest_e_history2_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -201,13 +206,18 @@ create trigger migtest_e_history2_history_upd
|
||||
for each row execute procedure migtest_e_history2_history_version();
|
||||
|
||||
create or replace function migtest_e_history3_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -218,13 +228,18 @@ create trigger migtest_e_history3_history_upd
|
||||
for each row execute procedure migtest_e_history3_history_version();
|
||||
|
||||
create or replace function migtest_e_history4_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -235,13 +250,18 @@ create trigger migtest_e_history4_history_upd
|
||||
for each row execute procedure migtest_e_history4_history_version();
|
||||
|
||||
create or replace function migtest_e_history5_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -252,13 +272,18 @@ create trigger migtest_e_history5_history_upd
|
||||
for each row execute procedure migtest_e_history5_history_version();
|
||||
|
||||
create or replace function migtest_e_history6_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history6_history (sys_period,id, test_number1, test_number2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number1, OLD.test_number2);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history6_history (sys_period,id, test_number1, test_number2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number1, OLD.test_number2);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history6_history (sys_period,id, test_number1, test_number2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number1, OLD.test_number2);
|
||||
insert into migtest_e_history6_history (sys_period,id, test_number1, test_number2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number1, OLD.test_number2);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
|
||||
@@ -131,13 +131,18 @@ create view migtest_e_history4_with_history as select * from migtest_e_history4
|
||||
create view migtest_e_history5_with_history as select * from migtest_e_history5 union all select * from migtest_e_history5_history;
|
||||
|
||||
create or replace function migtest_e_history_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history_history (sys_period,id, test_string) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
|
||||
insert into migtest_e_history_history (sys_period,id, test_string) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -149,13 +154,18 @@ create trigger migtest_e_history_history_upd
|
||||
|
||||
-- changes: [add test_string2, add test_string3]
|
||||
create or replace function migtest_e_history2_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3, obsolete_string1, obsolete_string2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.test_string3, OLD.obsolete_string1, OLD.obsolete_string2);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3, obsolete_string1, obsolete_string2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.test_string3, OLD.obsolete_string1, OLD.obsolete_string2);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3, obsolete_string1, obsolete_string2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.test_string3, OLD.obsolete_string1, OLD.obsolete_string2);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3, obsolete_string1, obsolete_string2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.test_string3, OLD.obsolete_string1, OLD.obsolete_string2);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -163,13 +173,18 @@ $$ LANGUAGE plpgsql;
|
||||
|
||||
-- changes: [exclude test_string]
|
||||
create or replace function migtest_e_history3_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history3_history (sys_period,id) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history3_history (sys_period,id) values (tstzrange(lowerTs,upperTs), OLD.id);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history3_history (sys_period,id) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id);
|
||||
insert into migtest_e_history3_history (sys_period,id) values (tstzrange(lowerTs,upperTs), OLD.id);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -177,13 +192,18 @@ $$ LANGUAGE plpgsql;
|
||||
|
||||
-- changes: [alter test_number]
|
||||
create or replace function migtest_e_history4_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -191,13 +211,18 @@ $$ LANGUAGE plpgsql;
|
||||
|
||||
-- changes: [add test_boolean]
|
||||
create or replace function migtest_e_history5_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number, test_boolean) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number, OLD.test_boolean);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number, test_boolean) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number, OLD.test_boolean);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number, test_boolean) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number, OLD.test_boolean);
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number, test_boolean) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number, OLD.test_boolean);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
|
||||
@@ -21,13 +21,18 @@ create view migtest_e_history2_with_history as select * from migtest_e_history2
|
||||
|
||||
-- changes: [drop obsolete_string1, drop obsolete_string2]
|
||||
create or replace function migtest_e_history2_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.test_string3);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.test_string3);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.test_string3);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, test_string3) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.test_string3);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
|
||||
@@ -74,13 +74,18 @@ create view migtest_e_history4_with_history as select * from migtest_e_history4
|
||||
|
||||
-- changes: [add obsolete_string1, add obsolete_string2]
|
||||
create or replace function migtest_e_history2_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2, test_string2, test_string3) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.obsolete_string2, OLD.test_string2, OLD.test_string3);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2, test_string2, test_string3) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.obsolete_string2, OLD.test_string2, OLD.test_string3);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2, test_string2, test_string3) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.obsolete_string2, OLD.test_string2, OLD.test_string3);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2, test_string2, test_string3) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.obsolete_string2, OLD.test_string2, OLD.test_string3);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -88,13 +93,18 @@ $$ LANGUAGE plpgsql;
|
||||
|
||||
-- changes: [include test_string]
|
||||
create or replace function migtest_e_history3_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string);
|
||||
insert into migtest_e_history3_history (sys_period,id, test_string) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -102,13 +112,18 @@ $$ LANGUAGE plpgsql;
|
||||
|
||||
-- changes: [alter test_number]
|
||||
create or replace function migtest_e_history4_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
insert into migtest_e_history4_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
|
||||
@@ -50,13 +50,18 @@ create view migtest_e_history5_with_history as select * from migtest_e_history5
|
||||
|
||||
-- changes: [drop test_string2, drop test_string3]
|
||||
create or replace function migtest_e_history2_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
insert into migtest_e_history2_history (sys_period,id, test_string, obsolete_string2) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_string, OLD.obsolete_string2);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
@@ -64,13 +69,18 @@ $$ LANGUAGE plpgsql;
|
||||
|
||||
-- changes: [drop test_boolean]
|
||||
create or replace function migtest_e_history5_history_version() returns trigger as $$
|
||||
declare
|
||||
lowerTs timestamptz;
|
||||
upperTs timestamptz;
|
||||
begin
|
||||
lowerTs = lower(OLD.sys_period);
|
||||
upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);
|
||||
if (TG_OP = 'UPDATE') then
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(current_timestamp,null);
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
NEW.sys_period = tstzrange(upperTs,null);
|
||||
return new;
|
||||
elsif (TG_OP = 'DELETE') then
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.id, OLD.test_number);
|
||||
insert into migtest_e_history5_history (sys_period,id, test_number) values (tstzrange(lowerTs,upperTs), OLD.id, OLD.test_number);
|
||||
return old;
|
||||
end if;
|
||||
end;
|
||||
|
||||
@@ -171,3 +171,15 @@ ebean.migrationtest.migration.appName=migrationtest
|
||||
ebean.migrationtest.migration.migrationPath=dbmigration/migrationtest
|
||||
ebean.migrationtest.migration.strict=true
|
||||
|
||||
# parameters for migration test
|
||||
datasource.migrationtest-history.username=SA
|
||||
datasource.migrationtest-history.password=SA
|
||||
datasource.migrationtest-history.databaseUrl=jdbc:h2:mem:migration
|
||||
datasource.migrationtest-history.databaseDriver=org.h2.Driver
|
||||
ebean.migrationtest-history.applyPrefix=V
|
||||
ebean.migrationtest-history.ddl.generate=false
|
||||
ebean.migrationtest-history.ddl.run=false
|
||||
ebean.migrationtest-history.ddl.header=-- Migrationscripts for ebean unittest DbMigrationDropHistoryTest
|
||||
ebean.migrationtest-history.migration.appName=migrationtest-history
|
||||
ebean.migrationtest-history.migration.migrationPath=dbmigration/migrationtest-history
|
||||
ebean.migrationtest-history.migration.strict=true
|
||||
|
||||
Reference in New Issue
Block a user