mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge remote-tracking branch 'upstream/master'
# Conflicts: # ebean-bom/pom.xml # tests/test-kotlin/pom.xml
This commit is contained in:
@@ -55,9 +55,38 @@ Post questions or issues to the Ebean google group - https://groups.google.com/f
|
||||
## Documentation
|
||||
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
|
||||
|
||||
|
||||
## Maven central
|
||||
[Maven central - io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
|
||||
|
||||
## Building Ebean from source
|
||||
|
||||
- JDK 11 or higher installed
|
||||
- Maven installed
|
||||
- `git clone git@github.com:ebean-orm/ebean.git`
|
||||
- `mvn clean install`
|
||||
|
||||
Ebean 13 uses Java modules with module-info. This means that there are stricter compilation
|
||||
rules in place now than when building with classpath pre version 13.
|
||||
|
||||
For Maven Surefire testing we use `<surefire.useModulePath>false</surefire.useModulePath>` such
|
||||
that tests run using classpath and not module-path. We are doing this until all the tooling
|
||||
(Maven, IDE) improves in the area of testing with module-info.
|
||||
|
||||
#### Eclipse IDE
|
||||
|
||||
Right now we can't use Eclipse IDE to build Ebean and run its tests due to its poor support
|
||||
for java modules. See [ebean/issues/2653](https://github.com/ebean-orm/ebean/issues/2653)
|
||||
|
||||
The current recommendation is to use IntelliJ IDEA as the IDE to build and hack Ebean.
|
||||
|
||||
|
||||
#### IntelliJ IDEA
|
||||
|
||||
We want to get IntelliJ to run tests using classpath similar to Maven Surefire. To do this set:
|
||||
`JUnit -> modify options -> Do not use module-path option`
|
||||
|
||||
To set this option as the global default for IntelliJ use:
|
||||
|
||||
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
||||
package io.ebean;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to <code>io.ebean.Database</code>.
|
||||
* Provides the API for fetching and saving beans to a particular Database.
|
||||
* <p>
|
||||
* Effectively this is an alias for {@link Database} which is now the new
|
||||
* and improved name for EbeanServer.
|
||||
* <p>
|
||||
* The preference is to use DB and Database rather than Ebean and EbeanServer.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface EbeanServer extends Database {
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to DatabaseFactory.
|
||||
* <p>
|
||||
* Creates EbeanServer instances.
|
||||
* <p>
|
||||
* This uses either a ServerConfig or properties in the ebean.properties file to
|
||||
* configure and create a EbeanServer instance.
|
||||
* </p>
|
||||
* <p>
|
||||
* The EbeanServer instance can either be registered with the Ebean singleton or
|
||||
* not. The Ebean singleton effectively holds a map of EbeanServers by a name.
|
||||
* If the EbeanServer is registered with the Ebean singleton you can retrieve it
|
||||
* later via {@link Ebean#getServer(String)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* One EbeanServer can be nominated as the 'default/primary' EbeanServer. Many
|
||||
* methods on the Ebean singleton such as {@link Ebean#find(Class)} are just a
|
||||
* convenient way of using the 'default/primary' EbeanServer.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public class EbeanServerFactory {
|
||||
|
||||
/**
|
||||
* Initialise the container with clustering configuration.
|
||||
* <p>
|
||||
* Call this prior to creating any EbeanServer instances or alternatively set the
|
||||
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
|
||||
*/
|
||||
public static void initialiseContainer(ContainerConfig containerConfig) {
|
||||
DatabaseFactory.initialiseContainer(containerConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using ebean.properties to configure the database.
|
||||
*/
|
||||
public static EbeanServer create(String name) {
|
||||
return (EbeanServer)DatabaseFactory.create(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig object to configure the database.
|
||||
*/
|
||||
public static EbeanServer create(ServerConfig config) {
|
||||
return (EbeanServer)DatabaseFactory.create(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
|
||||
*/
|
||||
public static EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
|
||||
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown gracefully all EbeanServers cleaning up any resources as required.
|
||||
* <p>
|
||||
* This is typically invoked via JVM shutdown hook and not explicitly called.
|
||||
* </p>
|
||||
*/
|
||||
public static void shutdown() {
|
||||
DatabaseFactory.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import io.ebean.DatabaseFactory;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to <code>io.ebean.DatabaseConfig</code>.
|
||||
*
|
||||
* The configuration used for creating a Database.
|
||||
* <p>
|
||||
* Used to programmatically construct a Database and optionally register it
|
||||
* with the DB singleton.
|
||||
* </p>
|
||||
* <p>
|
||||
* If you just use DB without this programmatic configuration DB will read
|
||||
* the application.properties file and take the configuration from there. This usually
|
||||
* includes searching the class path and automatically registering any entity
|
||||
* classes and listeners etc.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* ServerConfig config = new ServerConfig();
|
||||
*
|
||||
* // read the ebean.properties and load
|
||||
* // those settings into this serverConfig object
|
||||
* config.loadFromProperties();
|
||||
*
|
||||
* // explicitly register the entity beans to avoid classpath scanning
|
||||
* config.addClass(Customer.class);
|
||||
* config.addClass(User.class);
|
||||
*
|
||||
* Database database = DatabaseFactory.create(config);
|
||||
*
|
||||
* }</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 DatabaseFactory
|
||||
*/
|
||||
@Deprecated
|
||||
public class ServerConfig extends DatabaseConfig {
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package io.ebean.config;
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to DatabaseConfigProvider.
|
||||
* <p>
|
||||
* 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>
|
||||
* 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>
|
||||
*/
|
||||
@Deprecated
|
||||
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);
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import java.util.stream.Stream;
|
||||
/**
|
||||
* Service Provider extension to EbeanServer.
|
||||
*/
|
||||
public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer, BeanCollectionLoader {
|
||||
public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectionLoader {
|
||||
|
||||
/**
|
||||
* Return true if the L2 cache has been disabled.
|
||||
@@ -55,7 +55,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
|
||||
* <p>
|
||||
* Typically used to identify the origin of queries for AutoTune and object
|
||||
* graph costing.
|
||||
* </p>
|
||||
*/
|
||||
CallOrigin createCallOrigin();
|
||||
|
||||
|
||||
+87
-59
@@ -13,6 +13,8 @@ import java.io.Serializable;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* The default cache implementation.
|
||||
@@ -43,10 +45,13 @@ public class DefaultServerCache implements ServerCache {
|
||||
|
||||
protected final String name;
|
||||
protected final String shortName;
|
||||
private final int maxSize;
|
||||
private final int trimFrequency;
|
||||
private final int maxIdleSecs;
|
||||
private final int maxSecsToLive;
|
||||
protected final int maxSize;
|
||||
protected final int trimFrequency;
|
||||
protected final int maxIdleSecs;
|
||||
protected final int maxSecsToLive;
|
||||
protected final long trimOnPut;
|
||||
protected final ReentrantLock lock = new ReentrantLock();
|
||||
protected final AtomicLong mutationCounter = new AtomicLong();
|
||||
|
||||
public DefaultServerCache(DefaultServerCacheConfig config) {
|
||||
this.name = config.getName();
|
||||
@@ -56,6 +61,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
this.maxIdleSecs = config.getMaxIdleSecs();
|
||||
this.maxSecsToLive = config.getMaxSecsToLive();
|
||||
this.trimFrequency = config.determineTrimFrequency();
|
||||
this.trimOnPut = config.determineTrimOnPut();
|
||||
|
||||
MetricFactory factory = MetricFactory.get();
|
||||
String prefix = "l2n.";
|
||||
@@ -187,6 +193,9 @@ public class DefaultServerCache implements ServerCache {
|
||||
public void put(Object key, Object value) {
|
||||
map.put(key, new SoftReference<>(new CacheEntry(key, value)));
|
||||
putCount.increment();
|
||||
if (mutationCounter.incrementAndGet() > trimOnPut) {
|
||||
runEviction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,62 +231,72 @@ public class DefaultServerCache implements ServerCache {
|
||||
* Run the eviction based on Idle time, Time to live and LRU last access.
|
||||
*/
|
||||
public void runEviction() {
|
||||
long trimForMaxSize;
|
||||
if (maxSize == 0) {
|
||||
trimForMaxSize = 0;
|
||||
} else {
|
||||
trimForMaxSize = size() - maxSize;
|
||||
}
|
||||
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
|
||||
// nothing to trim on this cache
|
||||
return;
|
||||
}
|
||||
long startNanos = System.nanoTime();
|
||||
long trimmedByIdle = 0;
|
||||
long trimmedByGC = 0;
|
||||
long trimmedByTTL = 0;
|
||||
long trimmedByLRU = 0;
|
||||
|
||||
List<CacheEntry> activeList = new ArrayList<>(map.size());
|
||||
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
|
||||
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
|
||||
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
SoftReference<CacheEntry> ref = it.next();
|
||||
final CacheEntry cacheEntry = ref.get();
|
||||
if (cacheEntry == null) {
|
||||
it.remove();
|
||||
trimmedByGC++;
|
||||
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
|
||||
it.remove();
|
||||
trimmedByIdle++;
|
||||
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
|
||||
it.remove();
|
||||
trimmedByTTL++;
|
||||
} else if (trimForMaxSize > 0) {
|
||||
activeList.add(cacheEntry);
|
||||
lock.lock();
|
||||
try {
|
||||
long trimForMaxSize;
|
||||
if (maxSize == 0) {
|
||||
trimForMaxSize = 0;
|
||||
} else {
|
||||
trimForMaxSize = size() - maxSize;
|
||||
}
|
||||
}
|
||||
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
|
||||
// sort into last access time ascending
|
||||
activeList.sort(BY_LAST_ACCESS);
|
||||
int trimSize = getTrimSize();
|
||||
for (int i = trimSize; i < activeList.size(); i++) {
|
||||
// remove if still in the cache
|
||||
if (map.remove(activeList.get(i).getKey()) != null) {
|
||||
trimmedByLRU++;
|
||||
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
|
||||
// nothing to trim on this cache
|
||||
mutationCounter.set(0);
|
||||
return;
|
||||
}
|
||||
long startNanos = System.nanoTime();
|
||||
long trimmedByIdle = 0;
|
||||
long trimmedByGC = 0;
|
||||
long trimmedByTTL = 0;
|
||||
long trimmedByLRU = 0;
|
||||
|
||||
try {
|
||||
List<CacheEntry> activeList = new ArrayList<>(map.size());
|
||||
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
|
||||
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
|
||||
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
SoftReference<CacheEntry> ref = it.next();
|
||||
final CacheEntry cacheEntry = ref.get();
|
||||
if (cacheEntry == null) {
|
||||
it.remove();
|
||||
trimmedByGC++;
|
||||
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
|
||||
it.remove();
|
||||
trimmedByIdle++;
|
||||
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
|
||||
it.remove();
|
||||
trimmedByTTL++;
|
||||
} else if (trimForMaxSize > 0) {
|
||||
activeList.add(cacheEntry.forSort());
|
||||
}
|
||||
}
|
||||
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
|
||||
// sort into last access time ascending
|
||||
activeList.sort(BY_LAST_ACCESS);
|
||||
int trimSize = getTrimSize();
|
||||
for (int i = trimSize; i < activeList.size(); i++) {
|
||||
// remove if still in the cache
|
||||
if (map.remove(activeList.get(i).getKey()) != null) {
|
||||
trimmedByLRU++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mutationCounter.set(0);
|
||||
evictCount.add(trimmedByIdle);
|
||||
evictCount.add(trimmedByGC);
|
||||
evictCount.add(trimmedByTTL);
|
||||
evictCount.add(trimmedByLRU);
|
||||
if (logger.isTraceEnabled()) {
|
||||
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
|
||||
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
|
||||
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn("Error during trim of DefaultServerCache [" + name + "]. Cache might be bigger than desired.", e);
|
||||
}
|
||||
}
|
||||
|
||||
evictCount.add(trimmedByIdle);
|
||||
evictCount.add(trimmedByGC);
|
||||
evictCount.add(trimmedByTTL);
|
||||
evictCount.add(trimmedByLRU);
|
||||
if (logger.isTraceEnabled()) {
|
||||
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
|
||||
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
|
||||
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +312,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator for sorting by last access time.
|
||||
* Comparator for sorting by last access sort, a copy of last access time that should not mutate during trim processing.
|
||||
*/
|
||||
public static final class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
|
||||
|
||||
@@ -301,7 +320,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
|
||||
@Override
|
||||
public int compare(CacheEntry e1, CacheEntry e2) {
|
||||
return Long.compare(e1.getLastAccessTime(), e2.getLastAccessTime());
|
||||
return Long.compare(e1.lastAccessSort, e2.lastAccessSort);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +333,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
private final Object value;
|
||||
private final long createTime;
|
||||
private long lastAccessTime;
|
||||
private long lastAccessSort;
|
||||
|
||||
public CacheEntry(Object key, Object value) {
|
||||
this.key = key;
|
||||
@@ -322,6 +342,14 @@ public class DefaultServerCache implements ServerCache {
|
||||
this.lastAccessTime = createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a copy of lastAccessTime used for sorting. This value should not change during trim processing.
|
||||
*/
|
||||
public CacheEntry forSort() {
|
||||
this.lastAccessSort = lastAccessTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry key.
|
||||
*/
|
||||
|
||||
+10
@@ -76,4 +76,14 @@ public final class DefaultServerCacheConfig {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the number of mutations/puts required to trigger a runEviction() in the foreground.
|
||||
*/
|
||||
public long determineTrimOnPut() {
|
||||
if (maxSize > 0) {
|
||||
return maxSize / 10;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.ebeaninternal.server.cluster;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
||||
import org.slf4j.Logger;
|
||||
@@ -20,7 +20,7 @@ public class ClusterManager implements ServerLookup {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private final ConcurrentHashMap<String, EbeanServer> serverMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Database> serverMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final Object monitor = new Object();
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ClusterManager implements ServerLookup {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public void registerServer(EbeanServer server) {
|
||||
public void registerServer(Database server) {
|
||||
lock.lock();
|
||||
try {
|
||||
serverMap.put(server.name(), server);
|
||||
@@ -66,7 +66,7 @@ public class ClusterManager implements ServerLookup {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EbeanServer getServer(String name) {
|
||||
public Database getServer(String name) {
|
||||
lock.lock();
|
||||
try {
|
||||
return serverMap.get(name);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package io.ebeaninternal.server.cluster;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Database;
|
||||
|
||||
/**
|
||||
* Returns EbeanServer instances for remote message reading.
|
||||
* Returns Database instances for remote message reading.
|
||||
*/
|
||||
public interface ServerLookup {
|
||||
|
||||
/**
|
||||
* Return the EbeanServer instance by name.
|
||||
*/
|
||||
EbeanServer getServer(String name);
|
||||
Database getServer(String name);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DatabaseConfigProvider;
|
||||
import io.ebean.config.ModuleInfoLoader;
|
||||
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;
|
||||
@@ -128,15 +126,8 @@ public final class DefaultContainer implements SpiContainer {
|
||||
|
||||
private void applyConfigServices(DatabaseConfig config) {
|
||||
if (config.isDefaultServer()) {
|
||||
boolean appliedConfig = false;
|
||||
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
|
||||
configProvider.apply(config);
|
||||
appliedConfig = true;
|
||||
}
|
||||
if (!appliedConfig && config instanceof ServerConfig) {
|
||||
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
|
||||
configProvider.apply((ServerConfig)config);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.isAutoLoadModuleInfo()) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
package io.ebeaninternal.server.querydefn;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.Update;
|
||||
import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.SpiUpdate;
|
||||
@@ -14,7 +14,7 @@ public final class DefaultOrmUpdate<T> implements SpiUpdate<T>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8791423602246515438L;
|
||||
|
||||
private transient final EbeanServer server;
|
||||
private transient final Database server;
|
||||
private final Class<?> beanType;
|
||||
private final String name;
|
||||
private String label;
|
||||
@@ -35,7 +35,7 @@ public final class DefaultOrmUpdate<T> implements SpiUpdate<T>, Serializable {
|
||||
* Create with a specific server. This means you can use the
|
||||
* UpdateSql.execute() method.
|
||||
*/
|
||||
public DefaultOrmUpdate(Class<?> beanType, EbeanServer server, String baseTable, String updateStatement) {
|
||||
public DefaultOrmUpdate(Class<?> beanType, Database server, String baseTable, String updateStatement) {
|
||||
this.beanType = beanType;
|
||||
this.server = server;
|
||||
this.baseTable = baseTable;
|
||||
|
||||
@@ -4,7 +4,6 @@ module io.ebean.core {
|
||||
uses io.ebean.cache.ServerCachePlugin;
|
||||
uses io.ebean.cache.ServerCacheNotifyPlugin;
|
||||
uses io.ebean.config.DatabaseConfigProvider;
|
||||
uses io.ebean.config.ServerConfigProvider;
|
||||
uses io.ebean.config.ModuleInfoLoader;
|
||||
uses io.ebean.config.dbplatform.DatabasePlatformProvider;
|
||||
uses io.ebean.datasource.DataSourceAlertFactory;
|
||||
|
||||
+24
-13
@@ -6,8 +6,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class DefaultServerCacheConfigTest {
|
||||
|
||||
class DefaultServerCacheConfigTest {
|
||||
|
||||
private DefaultServerCacheConfig create(int maxSize, int maxIdleSecs, int maxSecsToLive, int trimFreq) {
|
||||
ServerCacheOptions options = new ServerCacheOptions();
|
||||
@@ -20,33 +19,45 @@ public class DefaultServerCacheConfigTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void trimFreq_halfIdle() {
|
||||
|
||||
void trimFreq_halfIdle() {
|
||||
assertEquals(create(10000,10,20, 0).determineTrimFrequency(), 4);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void trimFreq_halfIdle_withRounding() {
|
||||
|
||||
void trimFreq_halfIdle_withRounding() {
|
||||
assertEquals(create(10000,11,20, 0).determineTrimFrequency(), 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void trimFreq_halfTTL() {
|
||||
|
||||
void trimFreq_halfTTL() {
|
||||
assertEquals(create(10000,0,20, 0).determineTrimFrequency(), 9);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void trimFreq_halfTTL_withRounding() {
|
||||
|
||||
void trimFreq_halfTTL_withRounding() {
|
||||
assertEquals(create(10000,0,21, 0).determineTrimFrequency(), 9);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void trimFreq_explicit() {
|
||||
|
||||
void trimFreq_explicit() {
|
||||
assertEquals(create(10000,10,20, 42).determineTrimFrequency(), 42);
|
||||
}
|
||||
|
||||
@Test
|
||||
void trimOnPut_default() {
|
||||
assertEquals(create(0,0,0, 0).determineTrimOnPut(), 1_000);
|
||||
}
|
||||
|
||||
@Test
|
||||
void trimOnPut_tenPercent() {
|
||||
assertEquals(create(10_000,0,0, 0).determineTrimOnPut(), 1_000);
|
||||
assertEquals(create(9_000,0,0, 0).determineTrimOnPut(), 900);
|
||||
assertEquals(create(100,0,0, 0).determineTrimOnPut(), 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void trimOnPut_roundDown() {
|
||||
assertEquals(create(9010,0,0, 0).determineTrimOnPut(), 901);
|
||||
assertEquals(create(9009,0,0, 0).determineTrimOnPut(), 900);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+6
-11
@@ -10,16 +10,14 @@ import org.junit.jupiter.api.Test;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class DefaultServerCache_RunEvictionTest {
|
||||
|
||||
class DefaultServerCache_RunEvictionTest {
|
||||
|
||||
private DefaultServerCache createCache() {
|
||||
|
||||
ServerCacheOptions cacheOptions = new ServerCacheOptions();
|
||||
cacheOptions.setMaxSize(10000);
|
||||
cacheOptions.setMaxSize(300);
|
||||
cacheOptions.setMaxIdleSecs(1);
|
||||
cacheOptions.setMaxSecsToLive(2);
|
||||
cacheOptions.setTrimFrequency(1);
|
||||
cacheOptions.setTrimFrequency(5);
|
||||
|
||||
ServerCacheConfig con = new ServerCacheConfig(ServerCacheType.BEAN, "foo", "foo", cacheOptions, null, null);
|
||||
return new DefaultServerCache(new DefaultServerCacheConfig(con));
|
||||
@@ -35,8 +33,7 @@ public class DefaultServerCache_RunEvictionTest {
|
||||
|
||||
@Disabled("test takes long time")
|
||||
@Test
|
||||
public void runEvict() throws InterruptedException {
|
||||
|
||||
void runEvict() throws InterruptedException {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
doStuff();
|
||||
cache.runEviction();
|
||||
@@ -47,12 +44,10 @@ public class DefaultServerCache_RunEvictionTest {
|
||||
}
|
||||
|
||||
private void doStuff() {
|
||||
|
||||
for (int i = 0; i < 500; i++) {
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
String key = "" + random.nextInt(20000);
|
||||
|
||||
int mode = random.nextInt(10);
|
||||
if (mode < 8) {
|
||||
if (mode < 7) {
|
||||
cache.get(key);
|
||||
} else {
|
||||
cache.put(key, key + "-" + System.currentTimeMillis());
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.docker.commands.ElasticConfig;
|
||||
import io.ebean.docker.commands.ElasticContainer;
|
||||
|
||||
import java.util.Properties;
|
||||
@@ -19,27 +18,18 @@ class ElasticSearchSetup {
|
||||
}
|
||||
|
||||
void run() {
|
||||
ElasticConfig elasticConfig = readConfig();
|
||||
if (elasticConfig != null) {
|
||||
new ElasticContainer(elasticConfig).start();
|
||||
}
|
||||
}
|
||||
|
||||
ElasticConfig readConfig() {
|
||||
|
||||
String version = read("version", null);
|
||||
if (version == null) {
|
||||
// we need an explicit version to run
|
||||
return null;
|
||||
if (version != null) {
|
||||
Properties properties = populateDockerProperties(version);
|
||||
ElasticContainer.newBuilder(version)
|
||||
.properties(properties)
|
||||
.build()
|
||||
.start();
|
||||
}
|
||||
|
||||
return new ElasticConfig(version, populateDockerProperties(version));
|
||||
}
|
||||
|
||||
private Properties populateDockerProperties(String version) {
|
||||
|
||||
PropertiesBuilder properties = new PropertiesBuilder();
|
||||
|
||||
String mode = config.getProperty("ebean.test.shutdown");
|
||||
if (mode != null) {
|
||||
properties.set("shutdown", mode);
|
||||
@@ -63,7 +53,7 @@ class ElasticSearchSetup {
|
||||
|
||||
private static class PropertiesBuilder {
|
||||
|
||||
private Properties dockerProperties = new Properties();
|
||||
private final Properties dockerProperties = new Properties();
|
||||
|
||||
private void set(String key, String val) {
|
||||
dockerProperties.setProperty("elastic." + key, val);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.docker.commands.RedisConfig;
|
||||
import io.ebean.docker.commands.RedisContainer;
|
||||
|
||||
import java.util.Properties;
|
||||
@@ -16,9 +15,10 @@ class RedisSetup {
|
||||
String host = dockerHost.dockerHost(properties.getProperty("ebean.test.dockerHost"));
|
||||
properties.setProperty("redis.host", host);
|
||||
}
|
||||
RedisConfig redisConfig = new RedisConfig(version, properties);
|
||||
RedisContainer container = new RedisContainer(redisConfig);
|
||||
container.start();
|
||||
RedisContainer.newBuilder(version)
|
||||
.properties(properties)
|
||||
.build()
|
||||
.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package io.ebean.xtest.internal.server.cluster.binarymessage;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.xtest.internal.api.TDSpiEbeanServer;
|
||||
import io.ebeaninternal.api.TransactionEventTable;
|
||||
import io.ebeaninternal.server.cache.RemoteCacheEvent;
|
||||
@@ -94,7 +94,7 @@ public class BinaryTransactionEventReadWriteTest extends BaseTestCase {
|
||||
|
||||
class TDServerLookup implements ServerLookup {
|
||||
@Override
|
||||
public EbeanServer getServer(String name) {
|
||||
public Database getServer(String name) {
|
||||
return mockEbeanServer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.CockroachConfig;
|
||||
import io.ebean.docker.commands.CockroachContainer;
|
||||
|
||||
public class StartCockroach {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
CockroachConfig config = new CockroachConfig("v21.2.4");
|
||||
config.setDbName("unit");
|
||||
|
||||
CockroachContainer container = new CockroachContainer(config);
|
||||
container.start();
|
||||
CockroachContainer.newBuilder("v21.2.4")
|
||||
.dbName("unit")
|
||||
.build()
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.Db2Config;
|
||||
import io.ebean.docker.commands.Db2Container;
|
||||
|
||||
public class StartDb2 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Db2Config config = new Db2Config("11.5.6.0a");
|
||||
config.setDbName("unit");
|
||||
config.setUser("unit");
|
||||
config.setPassword("unit");
|
||||
|
||||
// to change collation, charset and other parameters like pagesize:
|
||||
config.setCreateOptions("USING CODESET UTF-8 TERRITORY DE COLLATE USING IDENTITY PAGESIZE 32768");
|
||||
config.setConfigOptions("USING STRING_UNITS CODEUNITS32");
|
||||
|
||||
Db2Container container = new Db2Container(config);
|
||||
container.startWithDropCreate();
|
||||
Db2Container.newBuilder("11.5.6.0a")
|
||||
.dbName("unit")
|
||||
.user("unit")
|
||||
.password("unit")
|
||||
// to change collation, charset and other parameters like pagesize:
|
||||
.configOptions("USING CODESET UTF-8 TERRITORY DE COLLATE USING IDENTITY PAGESIZE 32768")
|
||||
.configOptions("USING STRING_UNITS CODEUNITS32")
|
||||
.build()
|
||||
.startWithDropCreate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.MariaDBConfig;
|
||||
import io.ebean.docker.commands.MariaDBContainer;
|
||||
|
||||
public class StartMariaDb {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
MariaDBConfig config = new MariaDBConfig("10.5");
|
||||
config.setDbName("unit");
|
||||
config.setUser("unit");
|
||||
config.setPassword("unit");
|
||||
|
||||
MariaDBContainer container = new MariaDBContainer(config);
|
||||
container.startWithDropCreate();
|
||||
MariaDBContainer.newBuilder("10.5")
|
||||
.dbName("unit")
|
||||
.user("unit")
|
||||
.password("unit")
|
||||
.build()
|
||||
.startWithDropCreate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.MySqlConfig;
|
||||
import io.ebean.docker.commands.MySqlContainer;
|
||||
|
||||
public class StartMySql {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
MySqlConfig config = new MySqlConfig("8.0");
|
||||
config.setDbName("unit");
|
||||
config.setUser("unit");
|
||||
config.setPassword("unit");
|
||||
MySqlContainer.newBuilder("8.0")
|
||||
.dbName("unit")
|
||||
.user("unit")
|
||||
.password("unit")
|
||||
.build()
|
||||
.startWithDropCreate();
|
||||
|
||||
// by default this mysql docker collation is case sensitive
|
||||
// using utf8mb4_bin
|
||||
@@ -22,7 +23,5 @@ public class StartMySql {
|
||||
// config.setCollation("utf8mb4_unicode_ci");
|
||||
// config.setCharacterSet("utf8mb4");
|
||||
|
||||
MySqlContainer container = new MySqlContainer(config);
|
||||
container.startWithDropCreate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.NuoDBConfig;
|
||||
import io.ebean.docker.commands.NuoDBContainer;
|
||||
|
||||
public class StartNuoDB {
|
||||
|
||||
public static void main(String[] args) {
|
||||
NuoDBContainer container = NuoDBContainer.newBuilder("4.0")
|
||||
.schema("test_user")
|
||||
.build();
|
||||
|
||||
NuoDBConfig config = new NuoDBConfig();
|
||||
config.setSchema("test_user");
|
||||
|
||||
NuoDBContainer container = new NuoDBContainer(config);
|
||||
container.stopRemove();
|
||||
container.startWithDropCreate();
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.OracleConfig;
|
||||
import io.ebean.docker.commands.OracleContainer;
|
||||
|
||||
public class StartOracle {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
OracleConfig config = new OracleConfig();
|
||||
config.setUser("test_ebean");
|
||||
|
||||
OracleContainer container = new OracleContainer(config);
|
||||
container.startWithDropCreate();
|
||||
OracleContainer.newBuilder("latest")
|
||||
.user("test_ebean")
|
||||
.build()
|
||||
.startWithDropCreate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.PostgresConfig;
|
||||
import io.ebean.docker.commands.PostgresContainer;
|
||||
|
||||
public class StartPostgres {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
PostgresConfig config = new PostgresConfig("13");
|
||||
config.setPort(5432);
|
||||
config.setDbName("unit");
|
||||
config.setUser("unit");
|
||||
config.setPassword("unit");
|
||||
config.setContainerName("pg13x");
|
||||
config.setExtensions("hstore,pgcrypto");
|
||||
|
||||
PostgresContainer container = new PostgresContainer(config);
|
||||
container.startWithDropCreate();
|
||||
PostgresContainer.newBuilder("13")
|
||||
.port(5432)
|
||||
.dbName("unit")
|
||||
.user("unit")
|
||||
.password("unit")
|
||||
.containerName("pg13x")
|
||||
.extensions("hstore,pgcrypto")
|
||||
.build()
|
||||
.startWithDropCreate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.SqlServerConfig;
|
||||
import io.ebean.docker.commands.SqlServerContainer;
|
||||
|
||||
public class StartSqlServer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SqlServerConfig config = new SqlServerConfig("2019-GA-ubuntu-16.04");
|
||||
config.setDbName("test_ebean");
|
||||
config.setUser("test_ebean");
|
||||
SqlServerContainer.newBuilder("2019-GA-ubuntu-16.04")
|
||||
.dbName("test_ebean")
|
||||
.user("test_ebean")
|
||||
.build()
|
||||
.start();
|
||||
|
||||
// by default this sqlserver docker collation is case sensitive
|
||||
// using MSSQL_COLLATION=Latin1_General_100_BIN2
|
||||
@@ -20,8 +20,5 @@ public class StartSqlServer {
|
||||
|
||||
//config.setCollation("default");
|
||||
//config.setCollation("Latin1_General_100_CI");
|
||||
|
||||
SqlServerContainer container = new SqlServerContainer(config);
|
||||
container.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.YugabyteConfig;
|
||||
import io.ebean.docker.commands.YugabyteContainer;
|
||||
|
||||
public class StartYugabyte {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Check add extensions ?
|
||||
YugabyteConfig config = new YugabyteConfig("2.11.2.0-b89");
|
||||
config.setDbName("unit");
|
||||
config.setUser("unit");
|
||||
config.setExtensions("pgcrypto");
|
||||
|
||||
YugabyteContainer container = new YugabyteContainer(config);
|
||||
container.startWithDropCreate();
|
||||
YugabyteContainer.newBuilder("2.11.2.0-b89")
|
||||
.dbName("unit")
|
||||
.user("unit")
|
||||
.extensions("pgcrypto")
|
||||
.build()
|
||||
.startWithDropCreate();
|
||||
|
||||
// Run container ut_yugabyte with host:localhost port:6433 db:unit user:unit/test shutdown:None
|
||||
// docker run -d --name ut_yugabyte -p 6433:5433 -p 7000:7000 -p 9000:9000 -p 9042:9042 yugabytedb/yugabyte:2.11.2.0-b89 bin/yugabyted start --daemon=false
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<ebean-ddl-runner.version>1.3</ebean-ddl-runner.version>
|
||||
<ebean-migration-auto.version>1.2</ebean-migration-auto.version>
|
||||
<ebean-migration.version>13.0.0</ebean-migration.version>
|
||||
<ebean-test-docker.version>4.9</ebean-test-docker.version>
|
||||
<ebean-test-docker.version>5.0</ebean-test-docker.version>
|
||||
<ebean-datasource.version>7.5</ebean-datasource.version>
|
||||
<ebean-agent.version>13.5.0</ebean-agent.version>
|
||||
<ebean-maven-plugin.version>13.5.0</ebean-maven-plugin.version>
|
||||
|
||||
Reference in New Issue
Block a user