mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 23:56:36 +00:00
Merge pull request #202 from ebean-orm/java8
Add support for java.time types, tidy up ScalarTypes
This commit is contained in:
@@ -182,7 +182,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<version>3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
|
||||
@@ -457,6 +457,30 @@ public interface EbeanServer {
|
||||
* Execute the query visiting the results. This is similar to findIterate in
|
||||
* that not all the result beans need to be held in memory at the same time
|
||||
* and as such is go for processing large queries.
|
||||
*
|
||||
* @see Query#findEach(QueryEachConsumer)
|
||||
*/
|
||||
public <T> void findEach(Query<T> query, QueryEachConsumer<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query visiting the results. This is similar to findIterate in
|
||||
* that not all the result beans need to be held in memory at the same time
|
||||
* and as such is go for processing large queries.
|
||||
*
|
||||
* @see Query#findEachWhile(QueryEachWhileConsumer)
|
||||
*/
|
||||
public <T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated in favor of #findEachWhile which is functionally exactly the same
|
||||
* but has a much better name.
|
||||
* <p>
|
||||
* Execute the query visiting the results. This is similar to findIterate in
|
||||
* that not all the result beans need to be held in memory at the same time
|
||||
* and as such is go for processing large queries.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public <T> void findVisit(Query<T> query, QueryResultVisitor<T> visitor, Transaction transaction);
|
||||
|
||||
|
||||
@@ -102,9 +102,25 @@ public interface ExpressionList<T> extends Serializable {
|
||||
public QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
* Execute the query visiting the results.
|
||||
*
|
||||
* @see Query#findVisit(QueryResultVisitor)
|
||||
* Execute the query process the beans one at a time.
|
||||
*
|
||||
* @see Query#findEach(QueryEachConsumer)
|
||||
*/
|
||||
public void findEach(QueryEachConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Execute the query processing the beans one at a time with the ability to
|
||||
* stop processing before reading all the beans.
|
||||
*
|
||||
* @see Query#findEachWhile(QueryEachWhileConsumer)
|
||||
*/
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated in favor of #findEachWhile which is functionally exactly the same
|
||||
* but has a much better name.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public void findVisit(QueryResultVisitor<T> visitor);
|
||||
|
||||
|
||||
@@ -328,6 +328,37 @@ public abstract class Model {
|
||||
return query().findIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query consuming each bean one at a time.
|
||||
* <p>
|
||||
* This is generally used to process large queries where unlike findList
|
||||
* you do not want to hold all the results in memory at once but instead
|
||||
* process them one at a time (requiring far less memory).
|
||||
* </p>
|
||||
* Equivalent to {@link Query#findEach(QueryEachConsumer)}
|
||||
*/
|
||||
public void findEach(QueryEachConsumer<T> consumer) {
|
||||
query().findEach(consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query consuming each bean one at a time.
|
||||
* <p>
|
||||
* This is similar to #findEach except that you return boolean
|
||||
* true to continue processing beans and return false to stop
|
||||
* processing early.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is generally used to process large queries where unlike findList
|
||||
* you do not want to hold all the results in memory at once but instead
|
||||
* process them one at a time (requiring far less memory).
|
||||
* </p>
|
||||
* Equivalent to {@link Query#findEachWhile(QueryEachWhileConsumer)}
|
||||
*/
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer) {
|
||||
query().findEachWhile(consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all entities of the given type.
|
||||
* <p>
|
||||
|
||||
@@ -446,37 +446,89 @@ public interface Query<T> extends Serializable {
|
||||
*/
|
||||
public QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
* This is deprecated in favor of #findEachWhile.
|
||||
* <p>
|
||||
* This is functionally exactly the same as #findEachWhile. It is
|
||||
* replaced by findEachWhile because the method name is much better.
|
||||
* </p>
|
||||
*
|
||||
* @param visitor
|
||||
* the visitor used to process the queried beans.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public void findVisit(QueryResultVisitor<T> visitor);
|
||||
|
||||
/**
|
||||
* Execute the query processing the beans one at a time.
|
||||
* <p>
|
||||
* This method is appropriate to process very large query results as the
|
||||
* beans are consumed one at a time and do not need to be held in memory
|
||||
* (unlike #findList #findSet etc)
|
||||
* </p>
|
||||
* <p>
|
||||
* Compared with #findEachWhile this will always process all the beans where as
|
||||
* #findEachWhile provides a way to stop processing the query result early before
|
||||
* all the beans have been read.
|
||||
* </p>
|
||||
* <p>
|
||||
* This method is functionally equivalent to findIterate() but instead of using an
|
||||
* iterator uses the QueryEachConsumer (SAM) interface which is better suited to use
|
||||
* with Java8 closures.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* query.findVisit((Customer customer) -> {
|
||||
*
|
||||
* // do something with customer
|
||||
* System.out.println("-- visit " + customer);
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param consumer
|
||||
* the consumer used to process the queried beans.
|
||||
*/
|
||||
public void findEach(QueryEachConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Execute the query using callbacks to a visitor to process the resulting
|
||||
* beans one at a time.
|
||||
* <p>
|
||||
* Similar to findIterate() this query method does not require all the result
|
||||
* beans to be all held in memory at once and as such is useful for processing
|
||||
* large queries.
|
||||
* This method is functionally equivalent to findIterate() but instead of using an
|
||||
* iterator uses the QueryEachWhileConsumer (SAM) interface which is better suited to use
|
||||
* with Java8 closures.
|
||||
* </p>
|
||||
*
|
||||
|
||||
*
|
||||
* <pre class="code">
|
||||
*
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* .fetch("contacts", new FetchConfig().query(2))
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* query.findVisit(new QueryResultVisitor<Customer>() {
|
||||
*
|
||||
* public boolean accept(Customer customer) {
|
||||
*
|
||||
* query.findEachWhile((Customer customer) -> {
|
||||
*
|
||||
* // do something with customer
|
||||
* System.out.println("-- visit " + customer);
|
||||
* return true;
|
||||
* }
|
||||
*
|
||||
* // return true to continue processing or false to stop
|
||||
* return (customer.getId() < 40);
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param visitor
|
||||
* the visitor used to process the queried beans.
|
||||
*
|
||||
* @param consumer
|
||||
* the consumer used to process the queried beans.
|
||||
*/
|
||||
public void findVisit(QueryResultVisitor<T> visitor);
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Execute the query returning the list of objects.
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
/**
|
||||
* Used to process a query result one bean at a time via a callback to this
|
||||
* visitor.
|
||||
* <p>
|
||||
* If you wish to stop further processing return false from the accept method.
|
||||
* </p>
|
||||
* <p>
|
||||
* Unlike findList() and findSet() using a QueryResultVisitor does not require
|
||||
* all the beans in the query result to be held in memory at once. This makes
|
||||
* QueryResultVisitor useful for processing large queries.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* query.findVisit((Customer customer) -> {
|
||||
*
|
||||
* // do something with customer
|
||||
* System.out.println("-- visit " + customer);
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param <T>
|
||||
* the type of entity bean being queried.
|
||||
*/
|
||||
public interface QueryEachConsumer<T> {
|
||||
|
||||
/**
|
||||
* Process the bean.
|
||||
*
|
||||
* @param bean
|
||||
* the entity bean to process
|
||||
*/
|
||||
public void accept(T bean);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
/**
|
||||
* Used to process a query result one bean at a time via a callback to this
|
||||
* visitor.
|
||||
* <p>
|
||||
* If you wish to stop further processing return false from the accept method.
|
||||
* </p>
|
||||
* <p>
|
||||
* Unlike findList() and findSet() using a QueryResultVisitor does not require
|
||||
* all the beans in the query result to be held in memory at once. This makes
|
||||
* QueryResultVisitor useful for processing large queries.
|
||||
* </p>
|
||||
* <p/>
|
||||
* <pre class="code">
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* .fetch("contacts", new FetchConfig().query(2))
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* query.findEachWhile((Customer customer) -> {
|
||||
*
|
||||
* // do something with customer
|
||||
* System.out.println("-- visit " + customer);
|
||||
*
|
||||
* // return true to continue processing or false to stop
|
||||
* return (customer.getId() < 40);
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> the type of entity bean being queried.
|
||||
*/
|
||||
public interface QueryEachWhileConsumer<T> {
|
||||
|
||||
/**
|
||||
* Process the bean and return true if you want to continue processing more
|
||||
* beans. Return false if you want to stop processing further.
|
||||
*
|
||||
* @param bean the entity bean to process
|
||||
* @return true to continue processing more beans or false to stop.
|
||||
*/
|
||||
public boolean accept(T bean);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
/**
|
||||
* Configuration for JSON features.
|
||||
*/
|
||||
public abstract class JsonConfig {
|
||||
|
||||
/**
|
||||
* Defined the format used for DateTime types.
|
||||
*/
|
||||
public enum DateTime {
|
||||
|
||||
/**
|
||||
* Format as epoch millis.
|
||||
*/
|
||||
MILLIS,
|
||||
|
||||
/**
|
||||
* Format as epoch with nanos.
|
||||
*/
|
||||
NANOS,
|
||||
|
||||
/**
|
||||
* Format as ISO-8601 date format.
|
||||
*/
|
||||
ISO8601
|
||||
}
|
||||
|
||||
}
|
||||
@@ -121,6 +121,11 @@ public class ServerConfig {
|
||||
*/
|
||||
private AutofetchConfig autofetchConfig = new AutofetchConfig();
|
||||
|
||||
/**
|
||||
* The JSON format used for DateTime types. Default to millis.
|
||||
*/
|
||||
private JsonConfig.DateTime jsonDateTime = JsonConfig.DateTime.MILLIS;
|
||||
|
||||
/**
|
||||
* The database platform name. Used to imply a DatabasePlatform to use.
|
||||
*/
|
||||
@@ -217,7 +222,7 @@ public class ServerConfig {
|
||||
* Setting to indicate if UUID should be stored as binary(16) or varchar(40).
|
||||
*/
|
||||
private boolean uuidStoreAsBinary;
|
||||
|
||||
|
||||
|
||||
private List<BeanPersistController> persistControllers = new ArrayList<BeanPersistController>();
|
||||
private List<BeanPersistListener<?>> persistListeners = new ArrayList<BeanPersistListener<?>>();
|
||||
@@ -241,9 +246,13 @@ public class ServerConfig {
|
||||
private boolean collectQueryStatsByNode;
|
||||
|
||||
private boolean collectQueryOrigins;
|
||||
|
||||
|
||||
private JsonFactory jsonFactory;
|
||||
|
||||
private boolean localTimeWithNanos;
|
||||
|
||||
private boolean durationWithNanos;
|
||||
|
||||
/**
|
||||
* Construct a Server Configuration for programmatically creating an
|
||||
* EbeanServer.
|
||||
@@ -270,6 +279,20 @@ public class ServerConfig {
|
||||
this.jsonFactory = jsonFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JSON format used for DateTime types.
|
||||
*/
|
||||
public JsonConfig.DateTime getJsonDateTime() {
|
||||
return jsonDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JSON format to use for DateTime types.
|
||||
*/
|
||||
public void setJsonDateTime(JsonConfig.DateTime jsonDateTime) {
|
||||
this.jsonDateTime = jsonDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the EbeanServer.
|
||||
*/
|
||||
@@ -859,6 +882,43 @@ public class ServerConfig {
|
||||
this.uuidStoreAsBinary = uuidStoreAsBinary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if LocalTime should be persisted with nanos precision.
|
||||
*/
|
||||
public boolean isLocalTimeWithNanos() {
|
||||
return localTimeWithNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if LocalTime should be persisted with nanos precision.
|
||||
* <p>
|
||||
* Otherwise it is persisted using java.sql.Time which is seconds precision.
|
||||
* </p>
|
||||
*/
|
||||
public void setLocalTimeWithNanos(boolean localTimeWithNanos) {
|
||||
this.localTimeWithNanos = localTimeWithNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Duration should be persisted with nanos precision (SQL DECIMAL).
|
||||
* <p>
|
||||
* Otherwise it is persisted with second precision (SQL INTEGER).
|
||||
* </p>
|
||||
*/
|
||||
public boolean isDurationWithNanos() {
|
||||
return durationWithNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if Duration should be persisted with nanos precision (SQL DECIMAL).
|
||||
* <p>
|
||||
* Otherwise it is persisted with second precision (SQL INTEGER).
|
||||
* </p>
|
||||
*/
|
||||
public void setDurationWithNanos(boolean durationWithNanos) {
|
||||
this.durationWithNanos = durationWithNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to run the DDL generation on startup.
|
||||
*/
|
||||
@@ -1364,10 +1424,18 @@ public class ServerConfig {
|
||||
databaseBooleanFalse = p.get("databaseBooleanFalse", null);
|
||||
databasePlatformName = p.get("databasePlatformName", null);
|
||||
uuidStoreAsBinary = p.getBoolean("uuidStoreAsBinary", false);
|
||||
localTimeWithNanos = p.getBoolean("localTimeWithNanos", false);
|
||||
|
||||
lazyLoadBatchSize = p.getInt("lazyLoadBatchSize", 1);
|
||||
queryBatchSize = p.getInt("queryBatchSize", DEFAULT_QUERY_BATCH_SIZE);
|
||||
|
||||
String jsonDateTimeFormat = p.get("jsonDateTime", null);
|
||||
if (jsonDateTimeFormat != null) {
|
||||
jsonDateTime = JsonConfig.DateTime.valueOf(jsonDateTimeFormat);
|
||||
} else {
|
||||
jsonDateTime = JsonConfig.DateTime.MILLIS;
|
||||
}
|
||||
|
||||
ddlGenerate = p.getBoolean("ddl.generate", false);
|
||||
ddlRun = p.getBoolean("ddl.run", false);
|
||||
|
||||
|
||||
@@ -17,36 +17,10 @@ import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.AdminAutofetch;
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.BeanState;
|
||||
import com.avaje.ebean.CallableSql;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.ExpressionFactory;
|
||||
import com.avaje.ebean.Filter;
|
||||
import com.avaje.ebean.FutureIds;
|
||||
import com.avaje.ebean.FutureList;
|
||||
import com.avaje.ebean.FutureRowCount;
|
||||
import com.avaje.ebean.PagedList;
|
||||
import com.avaje.ebean.PagingList;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.QueryIterator;
|
||||
import com.avaje.ebean.QueryResultVisitor;
|
||||
import com.avaje.ebean.SqlFutureList;
|
||||
import com.avaje.ebean.SqlQuery;
|
||||
import com.avaje.ebean.SqlRow;
|
||||
import com.avaje.ebean.SqlUpdate;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.TxCallable;
|
||||
import com.avaje.ebean.TxIsolation;
|
||||
import com.avaje.ebean.TxRunnable;
|
||||
import com.avaje.ebean.TxScope;
|
||||
import com.avaje.ebean.TxType;
|
||||
import com.avaje.ebean.Update;
|
||||
import com.avaje.ebean.ValuePair;
|
||||
import com.avaje.ebean.bean.BeanCollection;
|
||||
import com.avaje.ebean.bean.CallStack;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
@@ -273,17 +247,14 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
|
||||
List<SpiEbeanPlugin> spiPlugins = new ArrayList<SpiEbeanPlugin>();
|
||||
|
||||
final Iterator<SpiEbeanPlugin> plugins = ServiceLoader.load(SpiEbeanPlugin.class).iterator();
|
||||
|
||||
while (plugins.hasNext()) {
|
||||
SpiEbeanPlugin plugin = plugins.next();
|
||||
for (SpiEbeanPlugin plugin : ServiceLoader.load(SpiEbeanPlugin.class)) {
|
||||
spiPlugins.add(plugin);
|
||||
plugin.setup(this, this.getDatabasePlatform(), config.getServerConfig());
|
||||
|
||||
if (plugin instanceof DdlGenerator) {
|
||||
// backwards compatible
|
||||
ddlGenerator = (DdlGenerator)plugin;
|
||||
}
|
||||
ddlGenerator = (DdlGenerator) plugin;
|
||||
}
|
||||
}
|
||||
|
||||
if (ddlGenerator == null) {
|
||||
@@ -1413,12 +1384,27 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query, t);
|
||||
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
request.findVisit(visitor);
|
||||
} finally {
|
||||
// do nothing - findVisit garuntee's cleanup of the transaction if required
|
||||
}
|
||||
request.initTransIfRequired();
|
||||
request.findVisit(visitor);
|
||||
// no try finally - findVisit guarantee's cleanup of the transaction if required
|
||||
}
|
||||
|
||||
public <T> void findEach(Query<T> query, QueryEachConsumer<T> consumer, Transaction t) {
|
||||
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query, t);
|
||||
|
||||
request.initTransIfRequired();
|
||||
request.findEach(consumer);
|
||||
// no try finally - findVisit guarantee's cleanup of the transaction if required
|
||||
}
|
||||
|
||||
public <T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction t) {
|
||||
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query, t);
|
||||
|
||||
request.initTransIfRequired();
|
||||
request.findEachWhile(consumer);
|
||||
// no try finally - findVisit guarantee's cleanup of the transaction if required
|
||||
}
|
||||
|
||||
public <T> QueryIterator<T> findIterate(Query<T> query, Transaction t) {
|
||||
@@ -1542,7 +1528,7 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
public void markAsDirty(Object bean) {
|
||||
if (bean instanceof EntityBean == false) {
|
||||
if (!(bean instanceof EntityBean)) {
|
||||
throw new IllegalArgumentException("This bean is not an EntityBean?");
|
||||
}
|
||||
// mark the bean as dirty (so that an update will not get skipped)
|
||||
@@ -1650,7 +1636,7 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
if (bean == null) {
|
||||
throw new IllegalArgumentException(Message.msg("bean.isnull"));
|
||||
}
|
||||
if (bean instanceof EntityBean == false) {
|
||||
if (!(bean instanceof EntityBean)) {
|
||||
throw new IllegalArgumentException("Was expecting an EntityBean but got a "+bean.getClass());
|
||||
}
|
||||
return (EntityBean)bean;
|
||||
@@ -1959,10 +1945,7 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
public boolean isSupportedType(java.lang.reflect.Type genericType) {
|
||||
|
||||
TypeInfo typeInfo = ParamTypeHelper.getTypeInfo(genericType);
|
||||
if (typeInfo == null) {
|
||||
return false;
|
||||
}
|
||||
return getBeanDescriptor(typeInfo.getBeanType()) != null;
|
||||
return typeInfo != null && getBeanDescriptor(typeInfo.getBeanType()) != null;
|
||||
}
|
||||
|
||||
public Object getBeanId(Object bean) {
|
||||
|
||||
@@ -6,9 +6,7 @@ import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.QueryIterator;
|
||||
import com.avaje.ebean.QueryResultVisitor;
|
||||
import com.avaje.ebean.RawSql;
|
||||
import com.avaje.ebean.*;
|
||||
import com.avaje.ebean.bean.BeanCollection;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebean.event.BeanFinder;
|
||||
@@ -234,6 +232,30 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
return idList.getIdList();
|
||||
}
|
||||
|
||||
public void findEach(QueryEachConsumer<T> consumer) {
|
||||
QueryIterator<T> it = queryEngine.findIterate(this);
|
||||
try {
|
||||
while (it.hasNext()) {
|
||||
consumer.accept(it.next());
|
||||
}
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer) {
|
||||
QueryIterator<T> it = queryEngine.findIterate(this);
|
||||
try {
|
||||
while (it.hasNext()) {
|
||||
if (!consumer.accept(it.next())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void findVisit(QueryResultVisitor<T> visitor) {
|
||||
QueryIterator<T> it = queryEngine.findIterate(this);
|
||||
try {
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.avaje.ebean.QueryEachConsumer;
|
||||
import com.avaje.ebean.QueryEachWhileConsumer;
|
||||
import com.avaje.ebean.QueryIterator;
|
||||
import com.avaje.ebean.QueryResultVisitor;
|
||||
import com.avaje.ebean.bean.BeanCollection;
|
||||
@@ -65,7 +67,17 @@ public interface SpiOrmQueryRequest<T> {
|
||||
*/
|
||||
public void findVisit(QueryResultVisitor<T> visitor);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Execute the find returning a QueryIterator and visitor pattern.
|
||||
*/
|
||||
public void findEach(QueryEachConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Execute the find returning a QueryIterator and visitor pattern.
|
||||
*/
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Execute the find returning a QueryIterator.
|
||||
*/
|
||||
public QueryIterator<T> findIterate();
|
||||
|
||||
@@ -62,10 +62,10 @@ import com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations;
|
||||
import com.avaje.ebeaninternal.server.deploy.parse.TransientProperties;
|
||||
import com.avaje.ebeaninternal.server.idgen.UuidIdGenerator;
|
||||
import com.avaje.ebeaninternal.server.lib.util.Dnode;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflect;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectFactory;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectProperties;
|
||||
import com.avaje.ebeaninternal.server.reflect.EnhanceBeanReflectFactory;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertyInfo;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertyInfoFactory;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertiesReader;
|
||||
import com.avaje.ebeaninternal.server.properties.EnhanceBeanPropertyInfoFactory;
|
||||
import com.avaje.ebeaninternal.server.type.TypeManager;
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
*/
|
||||
private final DeployInherit deplyInherit;
|
||||
|
||||
private final BeanReflectFactory reflectFactory;
|
||||
private final BeanPropertyInfoFactory reflectFactory;
|
||||
|
||||
private final DeployUtil deployUtil;
|
||||
|
||||
@@ -1274,9 +1274,9 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
}
|
||||
}
|
||||
|
||||
private BeanReflectFactory createReflectionFactory() {
|
||||
private BeanPropertyInfoFactory createReflectionFactory() {
|
||||
|
||||
return new EnhanceBeanReflectFactory();
|
||||
return new EnhanceBeanPropertyInfoFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1295,9 +1295,9 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
|
||||
Class<?> beanType = desc.getBeanType();
|
||||
|
||||
BeanReflectProperties reflectProps = new BeanReflectProperties(beanType);
|
||||
BeanPropertiesReader reflectProps = new BeanPropertiesReader(beanType);
|
||||
|
||||
BeanReflect beanReflect = reflectFactory.create(beanType);
|
||||
BeanPropertyInfo beanReflect = reflectFactory.create(beanType);
|
||||
desc.setBeanReflect(beanReflect);
|
||||
desc.setProperties(reflectProps.getProperties());
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.ebeaninternal.server.lib.util.StringHelper;
|
||||
import com.avaje.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import com.avaje.ebeaninternal.server.query.SqlJoinType;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertyGetter;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJson;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
@@ -41,29 +41,6 @@ import com.fasterxml.jackson.core.JsonToken;
|
||||
*/
|
||||
public class BeanProperty implements ElPropertyValue {
|
||||
|
||||
/**
|
||||
* Advanced bean deployment. To exclude this property from update where
|
||||
* clause.
|
||||
*/
|
||||
public static final String EXCLUDE_FROM_UPDATE_WHERE = "EXCLUDE_FROM_UPDATE_WHERE";
|
||||
|
||||
/**
|
||||
* Advanced bean deployment. To exclude this property from delete where
|
||||
* clause.
|
||||
*/
|
||||
public static final String EXCLUDE_FROM_DELETE_WHERE = "EXCLUDE_FROM_DELETE_WHERE";
|
||||
|
||||
/**
|
||||
* Advanced bean deployment. To exclude this property from insert.
|
||||
*/
|
||||
public static final String EXCLUDE_FROM_INSERT = "EXCLUDE_FROM_INSERT";
|
||||
|
||||
/**
|
||||
* Advanced bean deployment. To exclude this property from update set
|
||||
* clause.
|
||||
*/
|
||||
public static final String EXCLUDE_FROM_UPDATE = "EXCLUDE_FROM_UPDATE";
|
||||
|
||||
/**
|
||||
* Flag to mark this at part of the unique id.
|
||||
*/
|
||||
@@ -219,9 +196,9 @@ public class BeanProperty implements ElPropertyValue {
|
||||
*/
|
||||
final GeneratedProperty generatedProperty;
|
||||
|
||||
final BeanReflectGetter getter;
|
||||
final BeanPropertyGetter getter;
|
||||
|
||||
final BeanReflectSetter setter;
|
||||
final BeanPropertySetter setter;
|
||||
|
||||
final BeanDescriptor<?> descriptor;
|
||||
|
||||
@@ -488,15 +465,7 @@ public class BeanProperty implements ElPropertyValue {
|
||||
* Return true if the underlying type is mutable.
|
||||
*/
|
||||
public boolean isMutableScalarType() {
|
||||
if (scalarType == null) {
|
||||
return false;
|
||||
}
|
||||
return scalarType.isMutable();
|
||||
}
|
||||
|
||||
public void copyProperty(EntityBean sourceBean, EntityBean destBean) {
|
||||
Object value = getValue(sourceBean);
|
||||
setValue(destBean, value);
|
||||
return scalarType != null && scalarType.isMutable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,10 +475,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return descriptor.getEncryptKey(this);
|
||||
}
|
||||
|
||||
public String getDecryptProperty() {
|
||||
return dbEncryptFunction.getDecryptSql(this.getName());
|
||||
}
|
||||
|
||||
public String getDecryptProperty(String propertyName) {
|
||||
return dbEncryptFunction.getDecryptSql(propertyName);
|
||||
}
|
||||
@@ -575,24 +540,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return owningType.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
public Object readSetOwning(DbReadContext ctx, EntityBean bean, Class<?> type) throws SQLException {
|
||||
|
||||
try {
|
||||
Object value = scalarType.read(ctx.getDataReader());
|
||||
if (value == null || bean == null) {
|
||||
// not setting the value...
|
||||
} else {
|
||||
if (owningType.equals(type)) {
|
||||
setValue(bean, value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
String msg = "Error readSet on " + descriptor + "." + name;
|
||||
throw new PersistenceException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadIgnore(DbReadContext ctx) {
|
||||
scalarType.loadIgnore(ctx.getDataReader());
|
||||
}
|
||||
@@ -616,16 +563,13 @@ public class BeanProperty implements ElPropertyValue {
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean, Class<?> type) throws SQLException {
|
||||
|
||||
try {
|
||||
Object value = scalarType.read(ctx.getDataReader());
|
||||
if (bean == null || (type != null && !owningType.isAssignableFrom(type))) {
|
||||
// not setting the value...
|
||||
} else {
|
||||
setValue(bean, value);
|
||||
}
|
||||
return value;
|
||||
Object value = scalarType.read(ctx.getDataReader());
|
||||
if (bean != null && ((type == null || owningType.isAssignableFrom(type)))) {
|
||||
setValue(bean, value);
|
||||
}
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
String msg = "Error readSet on " + descriptor + "." + name;
|
||||
throw new PersistenceException(msg, e);
|
||||
throw new PersistenceException("Error readSet on " + descriptor + "." + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,21 +597,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return scalarType.readData(dataInput);
|
||||
}
|
||||
|
||||
public boolean isCascadeValidate() {
|
||||
return cascadeValidate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a bean is a reference (will be lazy loaded) or a
|
||||
* BeanCollection that has not yet been populated.
|
||||
* <p>
|
||||
* For base types this returns true.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isValueLoaded(Object value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public BeanProperty getBeanProperty() {
|
||||
return this;
|
||||
}
|
||||
@@ -737,16 +666,21 @@ public class BeanProperty implements ElPropertyValue {
|
||||
}
|
||||
}
|
||||
|
||||
private static Object[] NO_ARGS = new Object[0];
|
||||
|
||||
public Object getCacheDataValue(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData) {
|
||||
setValue(bean, cacheData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the property value from a compound value type.
|
||||
*/
|
||||
public Object getValueObject(Object bean) {
|
||||
throw new RuntimeException("Expected to be called only on BeanPropertyCompoundScalar");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the property method.
|
||||
*/
|
||||
@@ -759,19 +693,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
throw new RuntimeException(msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly use reflection to get value.
|
||||
*/
|
||||
public Object getValueViaReflection(Object bean) {
|
||||
try {
|
||||
return readMethod.invoke(bean, NO_ARGS);
|
||||
} catch (Exception ex) {
|
||||
String beanType = bean == null ? "null" : bean.getClass().getName();
|
||||
String msg = "get " + name + " on [" + descriptor + "] type[" + beanType + "] threw error.";
|
||||
throw new RuntimeException(msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getValueIntercept(EntityBean bean) {
|
||||
try {
|
||||
@@ -826,13 +747,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a full ElGetValue.
|
||||
*/
|
||||
public boolean isDeployOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsFormulaWithJoin() {
|
||||
return formula && sqlFormulaJoin != null;
|
||||
@@ -902,7 +816,7 @@ public class BeanProperty implements ElPropertyValue {
|
||||
/**
|
||||
* Return the scalarType.
|
||||
*/
|
||||
public ScalarType<?> getScalarType() {
|
||||
public ScalarType<Object> getScalarType() {
|
||||
return scalarType;
|
||||
}
|
||||
|
||||
@@ -923,7 +837,7 @@ public class BeanProperty implements ElPropertyValue {
|
||||
}
|
||||
|
||||
public Object parseDateTime(long systemTimeMillis) {
|
||||
return scalarType.parseDateTime(systemTimeMillis);
|
||||
return scalarType.convertFromMillis(systemTimeMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1031,10 +945,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getDeployProperty() {
|
||||
return dbColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* The database column name this is mapped to.
|
||||
*/
|
||||
@@ -1168,13 +1078,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return embedded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an extra attribute set on this property.
|
||||
*/
|
||||
public String getExtraAttribute(String key) {
|
||||
return extraAttributeMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default value.
|
||||
*/
|
||||
|
||||
@@ -385,12 +385,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isValueLoaded(Object value) {
|
||||
return !(value instanceof BeanCollection<?>) || ((BeanCollection<?>) value).isPopulated();
|
||||
}
|
||||
|
||||
public void add(BeanCollection<?> collection, EntityBean bean) {
|
||||
help.add(collection, bean);
|
||||
}
|
||||
|
||||
@@ -265,14 +265,6 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValueLoaded(Object value) {
|
||||
if (value instanceof EntityBean) {
|
||||
return ((EntityBean) value)._ebean_getIntercept().isLoaded();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return meta data for the deployment of the embedded bean specific to this
|
||||
* property.
|
||||
|
||||
@@ -89,19 +89,6 @@ public class BeanPropertyCompound extends BeanProperty {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying compound type.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object getValueUnderlying(EntityBean bean) {
|
||||
|
||||
Object value = getValue(bean);
|
||||
if (typeConverter != null){
|
||||
value = typeConverter.unwrapValue(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public ElPropertyValue buildElPropertyValue(String propName, String remainder, ElPropertyChainBuilder chain, boolean propertyDeploy) {
|
||||
|
||||
if (chain == null) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import com.avaje.ebeaninternal.server.type.CtCompoundProperty;
|
||||
|
||||
/**
|
||||
@@ -22,7 +22,7 @@ import com.avaje.ebeaninternal.server.type.CtCompoundProperty;
|
||||
*/
|
||||
public class BeanPropertyCompoundRoot {
|
||||
|
||||
private final BeanReflectSetter setter;
|
||||
private final BeanPropertySetter setter;
|
||||
|
||||
/**
|
||||
* The method used to write the property.
|
||||
|
||||
+81
-74
@@ -6,93 +6,100 @@ import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import com.avaje.ebeaninternal.server.type.CtCompoundProperty;
|
||||
|
||||
/**
|
||||
* A BeanProperty owned by a Compound value object that maps to
|
||||
* A BeanProperty owned by a Compound value object that maps to
|
||||
* a real scalar type.
|
||||
*
|
||||
* @author rbygrave
|
||||
*/
|
||||
public class BeanPropertyCompoundScalar extends BeanProperty {
|
||||
|
||||
private final BeanPropertyCompoundRoot rootProperty;
|
||||
|
||||
private final CtCompoundProperty ctProperty;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final ScalarTypeConverter typeConverter;
|
||||
|
||||
public BeanPropertyCompoundScalar(BeanPropertyCompoundRoot rootProperty, DeployBeanProperty scalarDeploy,
|
||||
CtCompoundProperty ctProperty, ScalarTypeConverter<?, ?> typeConverter) {
|
||||
|
||||
super(scalarDeploy);
|
||||
this.rootProperty = rootProperty;
|
||||
this.ctProperty = ctProperty;
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
private final BeanPropertyCompoundRoot rootProperty;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object getValue(EntityBean valueObject) {
|
||||
Object val = valueObject;
|
||||
if (typeConverter != null){
|
||||
val = typeConverter.unwrapValue(val);
|
||||
}
|
||||
return ctProperty.getValue(val);
|
||||
}
|
||||
private final CtCompoundProperty ctProperty;
|
||||
|
||||
@Override
|
||||
public void setValue(EntityBean bean, Object value) {
|
||||
setValueInCompound(bean, value, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setValueInCompound(EntityBean bean, Object value, boolean intercept) {
|
||||
|
||||
Object compoundValue = ctProperty.setValue(bean, value);
|
||||
|
||||
if (compoundValue != null){
|
||||
if (typeConverter != null){
|
||||
compoundValue = typeConverter.wrapValue(compoundValue);
|
||||
}
|
||||
// we are at the top level and we have a compound value
|
||||
// that we can set using the root property
|
||||
if (intercept){
|
||||
rootProperty.setRootValueIntercept(bean, compoundValue);
|
||||
} else {
|
||||
rootProperty.setRootValue(bean, compoundValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final ScalarTypeConverter typeConverter;
|
||||
|
||||
/**
|
||||
* No interception on embedded scalar values inside a CVO.
|
||||
*/
|
||||
@Override
|
||||
public void setValueIntercept(EntityBean bean, Object value) {
|
||||
setValueInCompound(bean, value, true);
|
||||
}
|
||||
public BeanPropertyCompoundScalar(BeanPropertyCompoundRoot rootProperty, DeployBeanProperty scalarDeploy,
|
||||
CtCompoundProperty ctProperty, ScalarTypeConverter<?, ?> typeConverter) {
|
||||
|
||||
/**
|
||||
* No interception on embedded scalar values inside a CVO.
|
||||
*/
|
||||
@Override
|
||||
public Object getValueIntercept(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
}
|
||||
super(scalarDeploy);
|
||||
this.rootProperty = rootProperty;
|
||||
this.ctProperty = ctProperty;
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object elGetReference(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
/**
|
||||
* Return one of the scalar values from a compound type.
|
||||
*/
|
||||
public Object getValueObject(Object compoundValue) {
|
||||
if (typeConverter != null) {
|
||||
compoundValue = typeConverter.unwrapValue(compoundValue);
|
||||
}
|
||||
return ctProperty.getValue(compoundValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object getValue(EntityBean valueObject) {
|
||||
Object val = valueObject;
|
||||
if (typeConverter != null) {
|
||||
val = typeConverter.unwrapValue(val);
|
||||
}
|
||||
return ctProperty.getValue(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate) {//, boolean reference) {
|
||||
super.elSetValue(bean, value, populate);
|
||||
@Override
|
||||
public void setValue(EntityBean bean, Object value) {
|
||||
setValueInCompound(bean, value, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setValueInCompound(EntityBean bean, Object value, boolean intercept) {
|
||||
|
||||
Object compoundValue = ctProperty.setValue(bean, value);
|
||||
|
||||
if (compoundValue != null) {
|
||||
if (typeConverter != null) {
|
||||
compoundValue = typeConverter.wrapValue(compoundValue);
|
||||
}
|
||||
// we are at the top level and we have a compound value
|
||||
// that we can set using the root property
|
||||
if (intercept) {
|
||||
rootProperty.setRootValueIntercept(bean, compoundValue);
|
||||
} else {
|
||||
rootProperty.setRootValue(bean, compoundValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No interception on embedded scalar values inside a CVO.
|
||||
*/
|
||||
@Override
|
||||
public void setValueIntercept(EntityBean bean, Object value) {
|
||||
setValueInCompound(bean, value, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* No interception on embedded scalar values inside a CVO.
|
||||
*/
|
||||
@Override
|
||||
public Object getValueIntercept(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object elGetReference(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate) {//, boolean reference) {
|
||||
super.elSetValue(bean, value, populate);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.avaje.ebeaninternal.server.deploy.DRawSqlMeta;
|
||||
import com.avaje.ebeaninternal.server.deploy.DeployNamedQuery;
|
||||
import com.avaje.ebeaninternal.server.deploy.DeployNamedUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflect;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertyInfo;
|
||||
|
||||
/**
|
||||
* Describes Beans including their deployment information.
|
||||
@@ -127,7 +127,7 @@ public class DeployBeanDescriptor<T> {
|
||||
* Used to provide mechanism to new EntityBean instances. Generated code
|
||||
* faster than reflection at this stage.
|
||||
*/
|
||||
private BeanReflect beanReflect;
|
||||
private BeanPropertyInfo beanReflect;
|
||||
private String[] properties;
|
||||
|
||||
/**
|
||||
@@ -302,7 +302,7 @@ public class DeployBeanDescriptor<T> {
|
||||
this.properties = props;
|
||||
}
|
||||
|
||||
public BeanReflect getBeanReflect() {
|
||||
public BeanPropertyInfo getBeanReflect() {
|
||||
return beanReflect;
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ public class DeployBeanDescriptor<T> {
|
||||
* Set the BeanReflect used to create new instances of an EntityBean. This
|
||||
* could use reflection or code generation to do this.
|
||||
*/
|
||||
public void setBeanReflect(BeanReflect beanReflect) {
|
||||
public void setBeanReflect(BeanPropertyInfo beanReflect) {
|
||||
this.beanReflect = beanReflect;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertyGetter;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarTypeEnum;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarTypeWrapper;
|
||||
@@ -202,9 +202,9 @@ public class DeployBeanProperty {
|
||||
|
||||
private int propertyIndex;
|
||||
|
||||
private BeanReflectGetter getter;
|
||||
private BeanPropertyGetter getter;
|
||||
|
||||
private BeanReflectSetter setter;
|
||||
private BeanPropertySetter setter;
|
||||
|
||||
/**
|
||||
* Generator for insert or update timestamp etc.
|
||||
@@ -414,7 +414,7 @@ public class DeployBeanProperty {
|
||||
ScalarTypeEnum etype = (ScalarTypeEnum) scalarType;
|
||||
|
||||
// check dbColName IN ('A', 'I', 'D')
|
||||
return "check (" + dbColumn + " in " + etype.getContraintInValues() + ")";
|
||||
return "check (" + dbColumn + " in " + etype.getConstraintInValues() + ")";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -439,11 +439,11 @@ public class DeployBeanProperty {
|
||||
this.propertyIndex = propertyIndex;
|
||||
}
|
||||
|
||||
public BeanReflectGetter getGetter() {
|
||||
public BeanPropertyGetter getGetter() {
|
||||
return getter;
|
||||
}
|
||||
|
||||
public BeanReflectSetter getSetter() {
|
||||
public BeanPropertySetter getSetter() {
|
||||
return setter;
|
||||
}
|
||||
|
||||
@@ -482,14 +482,14 @@ public class DeployBeanProperty {
|
||||
/**
|
||||
* Set the getter used to read the property value from a bean.
|
||||
*/
|
||||
public void setGetter(BeanReflectGetter getter) {
|
||||
public void setGetter(BeanPropertyGetter getter) {
|
||||
this.getter = getter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the setter used to set the property value to a bean.
|
||||
*/
|
||||
public void setSetter(BeanReflectSetter setter) {
|
||||
public void setSetter(BeanPropertySetter setter) {
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
|
||||
+86
-86
@@ -21,99 +21,99 @@ import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
*/
|
||||
public class DeployBeanPropertyCompound extends DeployBeanProperty {
|
||||
|
||||
final CtCompoundType<?> compoundType;
|
||||
final CtCompoundType<?> compoundType;
|
||||
|
||||
final ScalarTypeConverter<?, ?> typeConverter;
|
||||
final ScalarTypeConverter<?, ?> typeConverter;
|
||||
|
||||
DeployBeanEmbedded deployEmbedded;
|
||||
|
||||
/**
|
||||
* Create the property.
|
||||
*/
|
||||
public DeployBeanPropertyCompound(DeployBeanDescriptor<?> desc, Class<?> targetType,
|
||||
CtCompoundType<?> compoundType, ScalarTypeConverter<?, ?> typeConverter) {
|
||||
|
||||
super(desc, targetType, null, null);
|
||||
this.compoundType = compoundType;
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
DeployBeanEmbedded deployEmbedded;
|
||||
|
||||
public BeanPropertyCompoundRoot getFlatProperties(BeanDescriptorMap owner, BeanDescriptor<?> descriptor) {
|
||||
|
||||
// get a 'flat' list of all the scalar types, their relative property names
|
||||
// and also set their matching dbColumn
|
||||
|
||||
// represents the root property
|
||||
BeanPropertyCompoundRoot rootProperty = new BeanPropertyCompoundRoot(this);
|
||||
|
||||
// Walk the tree of a compound type collecting the
|
||||
// scalar types and non-scalar properties
|
||||
CtCompoundTypeScalarList ctMeta = new CtCompoundTypeScalarList();
|
||||
|
||||
compoundType.accumulateScalarTypes(null, ctMeta);
|
||||
|
||||
List<BeanProperty> beanPropertyList = new ArrayList<BeanProperty>();
|
||||
|
||||
|
||||
// for each of the scalar types inside a compound value object
|
||||
// build a BeanPropertyCompoundScalar with appropriate deployment
|
||||
// information.
|
||||
|
||||
for (Entry<String, ScalarType<?>> entry : ctMeta.entries()) {
|
||||
/**
|
||||
* Create the property.
|
||||
*/
|
||||
public DeployBeanPropertyCompound(DeployBeanDescriptor<?> desc, Class<?> targetType,
|
||||
CtCompoundType<?> compoundType, ScalarTypeConverter<?, ?> typeConverter) {
|
||||
|
||||
String relativePropertyName = entry.getKey();
|
||||
ScalarType<?> scalarType = entry.getValue();
|
||||
|
||||
CtCompoundProperty ctProp = ctMeta.getCompoundType(relativePropertyName);
|
||||
|
||||
|
||||
String dbColumn = relativePropertyName.replace(".", "_");
|
||||
dbColumn = getDbColumn(relativePropertyName, dbColumn);
|
||||
|
||||
DeployBeanProperty deploy = new DeployBeanProperty(null, scalarType.getType(), scalarType, null);
|
||||
deploy.setScalarType(scalarType);
|
||||
deploy.setDbColumn(dbColumn);
|
||||
deploy.setName(relativePropertyName);
|
||||
deploy.setDbInsertable(true);
|
||||
deploy.setDbUpdateable(true);
|
||||
deploy.setDbRead(true);
|
||||
|
||||
BeanPropertyCompoundScalar bp = new BeanPropertyCompoundScalar(rootProperty, deploy, ctProp, typeConverter);
|
||||
beanPropertyList.add(bp);
|
||||
|
||||
rootProperty.register(bp);
|
||||
}
|
||||
|
||||
rootProperty.setNonScalarProperties(ctMeta.getNonScalarProperties());
|
||||
return rootProperty;
|
||||
}
|
||||
|
||||
private String getDbColumn(String propName, String defaultDbColumn){
|
||||
if (deployEmbedded == null){
|
||||
return defaultDbColumn;
|
||||
}
|
||||
String dbColumn = deployEmbedded.getPropertyColumnMap().get(propName);
|
||||
return dbColumn == null ? defaultDbColumn : dbColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the deploy information specifically for the deployment
|
||||
* of Embedded beans.
|
||||
*/
|
||||
public DeployBeanEmbedded getDeployEmbedded() {
|
||||
// deployment should be single threaded
|
||||
if (deployEmbedded == null){
|
||||
deployEmbedded = new DeployBeanEmbedded();
|
||||
}
|
||||
return deployEmbedded;
|
||||
}
|
||||
super(desc, targetType, null, null);
|
||||
this.compoundType = compoundType;
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
public ScalarTypeConverter<?, ?> getTypeConverter() {
|
||||
return typeConverter;
|
||||
public BeanPropertyCompoundRoot getFlatProperties(BeanDescriptorMap owner, BeanDescriptor<?> descriptor) {
|
||||
|
||||
// get a 'flat' list of all the scalar types, their relative property names
|
||||
// and also set their matching dbColumn
|
||||
|
||||
// represents the root property
|
||||
BeanPropertyCompoundRoot rootProperty = new BeanPropertyCompoundRoot(this);
|
||||
|
||||
// Walk the tree of a compound type collecting the
|
||||
// scalar types and non-scalar properties
|
||||
CtCompoundTypeScalarList ctMeta = new CtCompoundTypeScalarList();
|
||||
|
||||
compoundType.accumulateScalarTypes(null, ctMeta);
|
||||
|
||||
List<BeanProperty> beanPropertyList = new ArrayList<BeanProperty>();
|
||||
|
||||
|
||||
// for each of the scalar types inside a compound value object
|
||||
// build a BeanPropertyCompoundScalar with appropriate deployment
|
||||
// information.
|
||||
|
||||
for (Entry<String, ScalarType<?>> entry : ctMeta.entries()) {
|
||||
|
||||
String relativePropertyName = entry.getKey();
|
||||
ScalarType<?> scalarType = entry.getValue();
|
||||
|
||||
CtCompoundProperty ctProp = ctMeta.getCompoundType(relativePropertyName);
|
||||
|
||||
|
||||
String dbColumn = (getName() + "." + relativePropertyName).replace(".", "_");
|
||||
dbColumn = getDbColumn(relativePropertyName, dbColumn);
|
||||
|
||||
DeployBeanProperty deploy = new DeployBeanProperty(null, scalarType.getType(), scalarType, null);
|
||||
deploy.setScalarType(scalarType);
|
||||
deploy.setDbColumn(dbColumn);
|
||||
deploy.setName(relativePropertyName);
|
||||
deploy.setDbInsertable(true);
|
||||
deploy.setDbUpdateable(true);
|
||||
deploy.setDbRead(true);
|
||||
|
||||
BeanPropertyCompoundScalar bp = new BeanPropertyCompoundScalar(rootProperty, deploy, ctProp, typeConverter);
|
||||
beanPropertyList.add(bp);
|
||||
|
||||
rootProperty.register(bp);
|
||||
}
|
||||
|
||||
public CtCompoundType<?> getCompoundType() {
|
||||
return compoundType;
|
||||
rootProperty.setNonScalarProperties(ctMeta.getNonScalarProperties());
|
||||
return rootProperty;
|
||||
}
|
||||
|
||||
private String getDbColumn(String propName, String defaultDbColumn) {
|
||||
if (deployEmbedded == null) {
|
||||
return defaultDbColumn;
|
||||
}
|
||||
String dbColumn = deployEmbedded.getPropertyColumnMap().get(propName);
|
||||
return dbColumn == null ? defaultDbColumn : dbColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the deploy information specifically for the deployment
|
||||
* of Embedded beans.
|
||||
*/
|
||||
public DeployBeanEmbedded getDeployEmbedded() {
|
||||
// deployment should be single threaded
|
||||
if (deployEmbedded == null) {
|
||||
deployEmbedded = new DeployBeanEmbedded();
|
||||
}
|
||||
return deployEmbedded;
|
||||
}
|
||||
|
||||
public ScalarTypeConverter<?, ?> getTypeConverter() {
|
||||
return typeConverter;
|
||||
}
|
||||
|
||||
public CtCompoundType<?> getCompoundType() {
|
||||
return compoundType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-5
@@ -93,7 +93,7 @@ public class DeployCreateProperties {
|
||||
}
|
||||
|
||||
/**
|
||||
* reflect the bean properties from Class. Some of these properties may not map to database
|
||||
* properties the bean properties from Class. Some of these properties may not map to database
|
||||
* columns.
|
||||
*/
|
||||
private void createProperties(DeployBeanDescriptor<?> desc, Class<?> beanType, int level) {
|
||||
@@ -125,7 +125,7 @@ public class DeployCreateProperties {
|
||||
Method getter = findGetter(field, initFieldName, declaredMethods, scalaObject);
|
||||
Method setter = findSetter(field, initFieldName, declaredMethods, scalaObject);
|
||||
|
||||
DeployBeanProperty prop = createProp(level, desc, field, beanType, getter, setter);
|
||||
DeployBeanProperty prop = createProp(desc, field, beanType, getter, setter);
|
||||
if (prop == null) {
|
||||
// transient annotation on unsupported type
|
||||
|
||||
@@ -152,7 +152,7 @@ public class DeployCreateProperties {
|
||||
Class<?> superClass = beanType.getSuperclass();
|
||||
|
||||
if (!superClass.equals(Object.class)) {
|
||||
// recursively add any properties in the inheritance heirarchy
|
||||
// recursively add any properties in the inheritance hierarchy
|
||||
// up to the Object.class level...
|
||||
createProperties(desc, superClass, level + 1);
|
||||
}
|
||||
@@ -361,7 +361,7 @@ public class DeployCreateProperties {
|
||||
|
||||
if (field.getAnnotation(ColumnHstore.class) != null) {
|
||||
return ScalarTypePostgresHstore.KEY;
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -372,7 +372,7 @@ public class DeployCreateProperties {
|
||||
return (t != null);
|
||||
}
|
||||
|
||||
private DeployBeanProperty createProp(int level, DeployBeanDescriptor<?> desc, Field field, Class<?> beanType,
|
||||
private DeployBeanProperty createProp(DeployBeanDescriptor<?> desc, Field field, Class<?> beanType,
|
||||
Method getter, Method setter) {
|
||||
|
||||
DeployBeanProperty prop = createProp(desc, field);
|
||||
|
||||
@@ -215,7 +215,7 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
}
|
||||
|
||||
public Object parseDateTime(long systemTimeMillis) {
|
||||
return scalarType.parseDateTime(systemTimeMillis);
|
||||
return scalarType.convertFromMillis(systemTimeMillis);
|
||||
}
|
||||
|
||||
public StringParser getStringParser() {
|
||||
|
||||
@@ -218,6 +218,16 @@ abstract class JunctionExpression<T> implements Junction<T>, SpiExpression, Expr
|
||||
return exprList.findIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEach(QueryEachConsumer<T> consumer) {
|
||||
exprList.findEach(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer) {
|
||||
exprList.findEachWhile(consumer);
|
||||
}
|
||||
|
||||
public void findVisit(QueryResultVisitor<T> visitor) {
|
||||
exprList.findVisit(visitor);
|
||||
}
|
||||
|
||||
+27
-26
@@ -14,40 +14,41 @@ import com.avaje.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
*/
|
||||
public class BindableCompound implements Bindable {
|
||||
|
||||
private final Bindable[] items;
|
||||
private final BindableProperty[] items;
|
||||
|
||||
private final BeanPropertyCompound compound;
|
||||
private final BeanPropertyCompound compound;
|
||||
|
||||
public BindableCompound(BeanPropertyCompound embProp, List<Bindable> list) {
|
||||
this.compound = embProp;
|
||||
this.items = list.toArray(new Bindable[list.size()]);
|
||||
public BindableCompound(BeanPropertyCompound embProp, List<BindableProperty> list) {
|
||||
this.compound = embProp;
|
||||
this.items = list.toArray(new BindableProperty[list.size()]);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BindableCompound " + compound + " items:" + Arrays.toString(items);
|
||||
}
|
||||
|
||||
public void dmlAppend(GenerateDmlRequest request) {
|
||||
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i].dmlAppend(request);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BindableCompound " + compound + " items:" + Arrays.toString(items);
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(compound)) {
|
||||
list.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void dmlAppend(GenerateDmlRequest request) {
|
||||
public void dmlBind(BindableRequest bindRequest, EntityBean bean) throws SQLException {
|
||||
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i].dmlAppend(request);
|
||||
}
|
||||
}
|
||||
// get the compound type value
|
||||
Object valueObject = compound.getValue(bean);
|
||||
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(compound)) {
|
||||
list.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void dmlBind(BindableRequest bindRequest, EntityBean bean) throws SQLException {
|
||||
|
||||
throw new RuntimeException("This is broken, need to break out the scalar values!!");
|
||||
|
||||
//Object valueObject = compound.getValue(bean);
|
||||
//for (int i = 0; i < items.length; i++) {
|
||||
// items[i].dmlBind(bindRequest, valueObject);
|
||||
//}
|
||||
// bind each of the underlying scalar values for this compound type
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i].dmlBindObject(bindRequest, valueObject);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+36
-22
@@ -13,33 +13,47 @@ import com.avaje.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
*/
|
||||
public class BindableProperty implements Bindable {
|
||||
|
||||
protected final BeanProperty prop;
|
||||
protected final BeanProperty prop;
|
||||
|
||||
public BindableProperty(BeanProperty prop) {
|
||||
this.prop = prop;
|
||||
public BindableProperty(BeanProperty prop) {
|
||||
this.prop = prop;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return prop.toString();
|
||||
}
|
||||
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(prop)) {
|
||||
list.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return prop.toString();
|
||||
public void dmlAppend(GenerateDmlRequest request) {
|
||||
request.appendColumn(prop.getDbColumn());
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal binding of a property value from the bean.
|
||||
*/
|
||||
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
|
||||
|
||||
Object value = null;
|
||||
if (bean != null) {
|
||||
value = prop.getValue(bean);
|
||||
}
|
||||
request.bind(value, prop, prop.getName());
|
||||
}
|
||||
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(prop)) {
|
||||
list.add(this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* For compound types bind one of the underlying scalar values for a compound type.
|
||||
*/
|
||||
public void dmlBindObject(BindableRequest request, Object bean) throws SQLException {
|
||||
|
||||
public void dmlAppend(GenerateDmlRequest request) {
|
||||
request.appendColumn(prop.getDbColumn());
|
||||
}
|
||||
|
||||
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
|
||||
|
||||
Object value = null;
|
||||
if (bean != null) {
|
||||
value = prop.getValue(bean);
|
||||
}
|
||||
// value = prop.getDefaultValue();
|
||||
request.bind(value, prop, prop.getName());
|
||||
Object value = null;
|
||||
if (bean != null) {
|
||||
value = prop.getValueObject(bean);
|
||||
}
|
||||
request.bind(value, prop, prop.getName());
|
||||
}
|
||||
}
|
||||
|
||||
+37
-34
@@ -16,49 +16,52 @@ import com.avaje.ebeaninternal.server.persist.dml.DmlMode;
|
||||
*/
|
||||
public class FactoryBaseProperties {
|
||||
|
||||
private final FactoryProperty factoryProperty;
|
||||
|
||||
|
||||
public FactoryBaseProperties(boolean bindEncryptDataFirst) {
|
||||
factoryProperty = new FactoryProperty(bindEncryptDataFirst);
|
||||
}
|
||||
private final FactoryProperty factoryProperty;
|
||||
|
||||
/**
|
||||
* Add Bindable for the base properties to the list.
|
||||
*/
|
||||
public void create(List<Bindable> list, BeanDescriptor<?> desc, DmlMode mode, boolean withLobs) {
|
||||
|
||||
add(desc.propertiesBaseScalar(), list, desc, mode, withLobs);
|
||||
public FactoryBaseProperties(boolean bindEncryptDataFirst) {
|
||||
factoryProperty = new FactoryProperty(bindEncryptDataFirst);
|
||||
}
|
||||
|
||||
BeanPropertyCompound[] compoundProps = desc.propertiesBaseCompound();
|
||||
for (int i = 0; i < compoundProps.length; i++) {
|
||||
BeanProperty[] props = compoundProps[i].getScalarProperties();
|
||||
/**
|
||||
* Add Bindable for the base properties to the list.
|
||||
*/
|
||||
public void create(List<Bindable> list, BeanDescriptor<?> desc, DmlMode mode, boolean withLobs) {
|
||||
|
||||
ArrayList<Bindable> newList = new ArrayList<Bindable>(props.length);
|
||||
add(props, newList, desc, mode, withLobs);
|
||||
|
||||
BindableCompound compoundBindable = new BindableCompound(compoundProps[i], newList);
|
||||
add(desc.propertiesBaseScalar(), list, desc, mode, withLobs);
|
||||
|
||||
list.add(compoundBindable);
|
||||
}
|
||||
}
|
||||
BeanPropertyCompound[] compoundProps = desc.propertiesBaseCompound();
|
||||
for (int i = 0; i < compoundProps.length; i++) {
|
||||
BeanProperty[] props = compoundProps[i].getScalarProperties();
|
||||
|
||||
private void add(BeanProperty[] props, List<Bindable> list, BeanDescriptor<?> desc, DmlMode mode, boolean withLobs) {
|
||||
List<BindableProperty> newList = new ArrayList<BindableProperty>(props.length);
|
||||
addCompound(props, newList, desc, mode, withLobs);
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
BindableCompound compoundBindable = new BindableCompound(compoundProps[i], newList);
|
||||
|
||||
// if(DmlMode.WHERE.equals(mode) && !withLobs && !props[i].isDbUpdatable()) {
|
||||
// // skip non-updatable column from where clause
|
||||
// } else {
|
||||
Bindable item = factoryProperty.create(props[i], mode, withLobs);
|
||||
if (item != null) {
|
||||
list.add(item);
|
||||
} else {
|
||||
// null where readOnly (Secondary tables) or Lob exclusion
|
||||
}
|
||||
// }
|
||||
}
|
||||
list.add(compoundBindable);
|
||||
}
|
||||
}
|
||||
|
||||
private void add(BeanProperty[] props, List<Bindable> list, BeanDescriptor<?> desc, DmlMode mode, boolean withLobs) {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Bindable item = factoryProperty.create(props[i], mode, withLobs);
|
||||
if (item != null) {
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addCompound(BeanProperty[] props, List<BindableProperty> list, BeanDescriptor<?> desc, DmlMode mode, boolean withLobs) {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
BindableProperty item = (BindableProperty) factoryProperty.create(props[i], mode, withLobs);
|
||||
if (item != null) {
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-3
@@ -1,17 +1,20 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BeanReflectProperties {
|
||||
/**
|
||||
* Determines the properties on a given bean.
|
||||
*/
|
||||
public class BeanPropertiesReader {
|
||||
|
||||
private final Map<String,Integer> propertyIndexMap = new HashMap<String,Integer>();
|
||||
|
||||
private final String[] props;
|
||||
|
||||
public BeanReflectProperties(Class<?> clazz) {
|
||||
public BeanPropertiesReader(Class<?> clazz) {
|
||||
this.props = getProperties(clazz);
|
||||
for (int i=0; i<props.length; i++) {
|
||||
propertyIndexMap.put(props[i], Integer.valueOf(i));
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
|
||||
/**
|
||||
* The getter implementation for a given bean property.
|
||||
*/
|
||||
public interface BeanReflectGetter {
|
||||
public interface BeanPropertyGetter {
|
||||
|
||||
/**
|
||||
* Return the value of a given bean property.
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
/**
|
||||
* Provides getter setter and construction methods for beans.
|
||||
@@ -7,7 +7,7 @@ package com.avaje.ebeaninternal.server.reflect;
|
||||
* code generation.
|
||||
* </p>
|
||||
*/
|
||||
public interface BeanReflect {
|
||||
public interface BeanPropertyInfo {
|
||||
|
||||
/**
|
||||
* Create an EntityBean for this type.
|
||||
@@ -17,10 +17,10 @@ public interface BeanReflect {
|
||||
/**
|
||||
* Return the getter for a given bean property.
|
||||
*/
|
||||
public BeanReflectGetter getGetter(String name, int position);
|
||||
public BeanPropertyGetter getGetter(String name, int position);
|
||||
|
||||
/**
|
||||
* Return the setter for a given bean property.
|
||||
*/
|
||||
public BeanReflectSetter getSetter(String name, int position);
|
||||
public BeanPropertySetter getSetter(String name, int position);
|
||||
}
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
|
||||
/**
|
||||
* Creates BeanReflect object used to provide getter setter and construction
|
||||
* for the beans.
|
||||
*/
|
||||
public interface BeanReflectFactory {
|
||||
public interface BeanPropertyInfoFactory {
|
||||
|
||||
/**
|
||||
* Create the BeanReflect for the given plain bean and its EntityBean equivalent.
|
||||
*/
|
||||
public BeanReflect create(Class<?> entityBeanType);
|
||||
public BeanPropertyInfo create(Class<?> entityBeanType);
|
||||
}
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
|
||||
/**
|
||||
* The setter for a given bean property.
|
||||
*/
|
||||
public interface BeanReflectSetter {
|
||||
public interface BeanPropertySetter {
|
||||
|
||||
/**
|
||||
* Set the property value of a bean.
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -11,13 +11,13 @@ import com.avaje.ebean.bean.EntityBean;
|
||||
* A BeanReflect implementation based on the enhancement that creates EntityBean
|
||||
* implementations.
|
||||
*/
|
||||
public final class EnhanceBeanReflect implements BeanReflect {
|
||||
public final class EnhanceBeanPropertyInfo implements BeanPropertyInfo {
|
||||
|
||||
private static final Object[] constuctorArgs = new Object[0];
|
||||
|
||||
private final Constructor<?> constructor;
|
||||
|
||||
public EnhanceBeanReflect(Class<?> clazz) {
|
||||
public EnhanceBeanPropertyInfo(Class<?> clazz) {
|
||||
try {
|
||||
if (Modifier.isAbstract(clazz.getModifiers())) {
|
||||
this.constructor = null;
|
||||
@@ -47,15 +47,15 @@ public final class EnhanceBeanReflect implements BeanReflect {
|
||||
}
|
||||
}
|
||||
|
||||
public BeanReflectGetter getGetter(String name, int position) {
|
||||
public BeanPropertyGetter getGetter(String name, int position) {
|
||||
return new Getter(position);
|
||||
}
|
||||
|
||||
public BeanReflectSetter getSetter(String name, int position) {
|
||||
public BeanPropertySetter getSetter(String name, int position) {
|
||||
return new Setter(position);
|
||||
}
|
||||
|
||||
static final class Getter implements BeanReflectGetter {
|
||||
static final class Getter implements BeanPropertyGetter {
|
||||
|
||||
private final int fieldIndex;
|
||||
|
||||
@@ -72,7 +72,7 @@ public final class EnhanceBeanReflect implements BeanReflect {
|
||||
}
|
||||
}
|
||||
|
||||
static final class Setter implements BeanReflectSetter {
|
||||
static final class Setter implements BeanPropertySetter {
|
||||
|
||||
private final int fieldIndex;
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.avaje.ebeaninternal.server.properties;
|
||||
|
||||
/**
|
||||
* Creates a BeanReflectFactory based on the enhancement that
|
||||
* creates EntityBean implementations.
|
||||
*/
|
||||
public final class EnhanceBeanPropertyInfoFactory implements BeanPropertyInfoFactory {
|
||||
|
||||
public BeanPropertyInfo create(Class<?> entityBeanType) {
|
||||
return new EnhanceBeanPropertyInfo(entityBeanType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,22 +8,8 @@ import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.Expression;
|
||||
import com.avaje.ebean.ExpressionFactory;
|
||||
import com.avaje.ebean.ExpressionList;
|
||||
import com.avaje.ebean.FetchConfig;
|
||||
import com.avaje.ebean.FutureIds;
|
||||
import com.avaje.ebean.FutureList;
|
||||
import com.avaje.ebean.FutureRowCount;
|
||||
import com.avaje.ebean.OrderBy;
|
||||
import com.avaje.ebean.*;
|
||||
import com.avaje.ebean.OrderBy.Property;
|
||||
import com.avaje.ebean.PagedList;
|
||||
import com.avaje.ebean.PagingList;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.QueryIterator;
|
||||
import com.avaje.ebean.QueryResultVisitor;
|
||||
import com.avaje.ebean.RawSql;
|
||||
import com.avaje.ebean.bean.BeanCollectionTouched;
|
||||
import com.avaje.ebean.bean.CallStack;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
@@ -911,6 +897,16 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
server.findVisit(this, visitor, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer) {
|
||||
server.findEachWhile(this, consumer, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEach(QueryEachConsumer<T> consumer) {
|
||||
server.findEach(this, consumer, null);
|
||||
}
|
||||
|
||||
public QueryIterator<T> findIterate() {
|
||||
return server.findIterate(this, null);
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.avaje.ebeaninternal.server.reflect;
|
||||
|
||||
/**
|
||||
* Creates a BeanReflectFactory based on the enhancement that
|
||||
* creates EntityBean implementations.
|
||||
*/
|
||||
public final class EnhanceBeanReflectFactory implements BeanReflectFactory {
|
||||
|
||||
public BeanReflect create(Class<?> entityBeanType) {
|
||||
return new EnhanceBeanReflect(entityBeanType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.CompoundType;
|
||||
import com.avaje.ebean.config.CompoundTypeProperty;
|
||||
|
||||
import java.time.Period;
|
||||
|
||||
/**
|
||||
* Compound type for Period value type.
|
||||
* <p>
|
||||
* Persists the Period into 3 separate integer columns for years, months and days.
|
||||
* </p>
|
||||
*/
|
||||
public class CompoundTypePeriod implements CompoundType<Period> {
|
||||
|
||||
CompoundTypeProperty[] properties = new CompoundTypeProperty[3];
|
||||
|
||||
public CompoundTypePeriod() {
|
||||
properties[0] = new CTPeriodYear();
|
||||
properties[1] = new CTPeriodMonth();
|
||||
properties[2] = new CTPeriodDay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Period create(Object[] propertyValues) {
|
||||
return Period.of((Integer)propertyValues[0], (Integer)propertyValues[1], (Integer)propertyValues[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTypeProperty<Period, ?>[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
static class CTPeriodYear implements CompoundTypeProperty<Period, Integer> {
|
||||
|
||||
public String getName() {
|
||||
return "years";
|
||||
}
|
||||
|
||||
public Integer getValue(Period valueObject) {
|
||||
return valueObject.getYears();
|
||||
}
|
||||
|
||||
public int getDbType() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class CTPeriodMonth implements CompoundTypeProperty<Period, Integer> {
|
||||
|
||||
public String getName() {
|
||||
return "months";
|
||||
}
|
||||
|
||||
public Integer getValue(Period valueObject) {
|
||||
return valueObject.getMonths();
|
||||
}
|
||||
|
||||
public int getDbType() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class CTPeriodDay implements CompoundTypeProperty<Period, Integer> {
|
||||
|
||||
public String getName() {
|
||||
return "days";
|
||||
}
|
||||
|
||||
public Integer getValue(Period valueObject) {
|
||||
return valueObject.getDays();
|
||||
}
|
||||
|
||||
public int getDbType() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class DateTimeJsonParser {
|
||||
@@ -31,4 +32,7 @@ public class DateTimeJsonParser {
|
||||
}
|
||||
}
|
||||
|
||||
public String format(Date value) {
|
||||
return dtFormat().format(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
/*
|
||||
* Copyright 2013 FasterXML.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the license for the specific language governing permissions and
|
||||
* limitations under the license.
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Utilities to aid in the translation of decimal types to/from multiple parts.
|
||||
*
|
||||
* @author Nick Williams
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public final class DecimalUtils {
|
||||
|
||||
private static final char[] ZEROES = new char[]{'0', '0', '0', '0', '0', '0', '0', '0', '0'};
|
||||
|
||||
private static final BigDecimal ONE_BILLION = new BigDecimal(1000000000L);
|
||||
|
||||
private DecimalUtils() {
|
||||
throw new RuntimeException("DecimalUtils cannot be instantiated.");
|
||||
}
|
||||
|
||||
public static Duration toDuration(BigDecimal value) {
|
||||
|
||||
long seconds = value.longValue();
|
||||
int nanoseconds = extractNanosecondDecimal(value, seconds);
|
||||
|
||||
return Duration.ofSeconds(seconds, nanoseconds);
|
||||
}
|
||||
|
||||
public static BigDecimal toDecimal(Duration instant) {
|
||||
return new BigDecimal(toDecimal(instant.getSeconds(), instant.getNano()));
|
||||
}
|
||||
|
||||
public static Timestamp toTimestamp(BigDecimal value) {
|
||||
|
||||
long seconds = value.longValue();
|
||||
int nanoseconds = extractNanosecondDecimal(value, seconds);
|
||||
|
||||
Timestamp ts = new Timestamp(seconds * 1000);
|
||||
ts.setNanos(nanoseconds);
|
||||
return ts;
|
||||
}
|
||||
|
||||
public static BigDecimal toDecimal(Timestamp instant) {
|
||||
long millis = instant.getTime();
|
||||
long secs = millis/1000;
|
||||
return new BigDecimal(toDecimal(secs, instant.getNanos()));
|
||||
}
|
||||
|
||||
public static Instant toInstant(BigDecimal value) {
|
||||
|
||||
long seconds = value.longValue();
|
||||
int nanoseconds = extractNanosecondDecimal(value, seconds);
|
||||
return Instant.ofEpochSecond(seconds, nanoseconds);
|
||||
}
|
||||
|
||||
public static BigDecimal toDecimal(Instant instant) {
|
||||
return new BigDecimal(toDecimal(instant.getEpochSecond(), instant.getNano()));
|
||||
}
|
||||
|
||||
public static String toDecimal(long seconds, int nanoseconds) {
|
||||
StringBuilder string = new StringBuilder(Integer.toString(nanoseconds));
|
||||
if (string.length() < 9)
|
||||
string.insert(0, ZEROES, 0, 9 - string.length());
|
||||
return seconds + "." + string;
|
||||
}
|
||||
|
||||
public static int extractNanosecondDecimal(BigDecimal value, long integer) {
|
||||
return value.subtract(new BigDecimal(integer)).multiply(ONE_BILLION).intValue();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.math.BigInteger;
|
||||
import java.sql.Types;
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -80,27 +81,27 @@ public class DefaultTypeFactory {
|
||||
/**
|
||||
* Create the default ScalarType for java.util.Date.
|
||||
*/
|
||||
public ScalarType<java.util.Date> createUtilDate() {
|
||||
public ScalarType<java.util.Date> createUtilDate(JsonConfig.DateTime mode) {
|
||||
// by default map anonymous java.util.Date to java.sql.Timestamp.
|
||||
// String mapType =
|
||||
// properties.getProperty("type.mapping.java.util.Date","timestamp");
|
||||
int utilDateType = getTemporalMapType("timestamp");
|
||||
|
||||
return createUtilDate(utilDateType);
|
||||
return createUtilDate(mode, utilDateType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ScalarType for java.util.Date explicitly specifying the type to
|
||||
* map to.
|
||||
*/
|
||||
public ScalarType<java.util.Date> createUtilDate(int utilDateType) {
|
||||
public ScalarType<java.util.Date> createUtilDate(JsonConfig.DateTime mode, int utilDateType) {
|
||||
|
||||
switch (utilDateType) {
|
||||
case Types.DATE:
|
||||
return new ScalarTypeUtilDate.DateType();
|
||||
|
||||
case Types.TIMESTAMP:
|
||||
return new ScalarTypeUtilDate.TimestampType();
|
||||
return new ScalarTypeUtilDate.TimestampType(mode);
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Invalid type " + utilDateType);
|
||||
@@ -110,23 +111,19 @@ public class DefaultTypeFactory {
|
||||
/**
|
||||
* Create the default ScalarType for java.util.Calendar.
|
||||
*/
|
||||
public ScalarType<Calendar> createCalendar() {
|
||||
// by default map anonymous java.util.Calendar to java.sql.Timestamp.
|
||||
// String mapType =
|
||||
// properties.getProperty("type.mapping.java.util.Calendar",
|
||||
// "timestamp");
|
||||
int jdbcType = getTemporalMapType("timestamp");
|
||||
public ScalarType<Calendar> createCalendar(JsonConfig.DateTime mode) {
|
||||
|
||||
return createCalendar(jdbcType);
|
||||
int jdbcType = getTemporalMapType("timestamp");
|
||||
return createCalendar(mode, jdbcType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ScalarType for java.util.Calendar explicitly specifying the type
|
||||
* to map to.
|
||||
*/
|
||||
public ScalarType<Calendar> createCalendar(int jdbcType) {
|
||||
public ScalarType<Calendar> createCalendar(JsonConfig.DateTime mode, int jdbcType) {
|
||||
|
||||
return new ScalarTypeCalendar(jdbcType);
|
||||
return new ScalarTypeCalendar(mode, jdbcType);
|
||||
}
|
||||
|
||||
private int getTemporalMapType(String mapType) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.sql.Date;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
@@ -22,6 +23,7 @@ import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.avaje.ebean.config.*;
|
||||
import org.joda.time.DateMidnight;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
@@ -32,10 +34,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.annotation.EnumMapping;
|
||||
import com.avaje.ebean.annotation.EnumValue;
|
||||
import com.avaje.ebean.config.CompoundType;
|
||||
import com.avaje.ebean.config.CompoundTypeProperty;
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebeaninternal.api.ClassUtil;
|
||||
import com.avaje.ebeaninternal.server.core.BootupClasses;
|
||||
import com.avaje.ebeaninternal.server.lib.util.StringHelper;
|
||||
@@ -102,8 +100,6 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
private final ScalarType<?> dateType = new ScalarTypeDate();
|
||||
|
||||
private final ScalarType<?> timestampType = new ScalarTypeTimestamp();
|
||||
|
||||
private final ScalarType<?> inetAddressType = new ScalarTypeInetAddress();
|
||||
private final ScalarType<?> urlType = new ScalarTypeURL();
|
||||
private final ScalarType<?> uriType = new ScalarTypeURI();
|
||||
@@ -115,7 +111,6 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
private final ScalarType<?> classType = new ScalarTypeClass();
|
||||
|
||||
private final ScalarTypeLongToTimestamp longToTimestamp = new ScalarTypeLongToTimestamp();
|
||||
|
||||
private final List<ScalarType<?>> customScalarTypes = new ArrayList<ScalarType<?>>();
|
||||
|
||||
@@ -125,6 +120,8 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
private final ReflectionBasedTypeBuilder reflectScalarBuilder;
|
||||
|
||||
private final JsonConfig.DateTime jsonDateTime;
|
||||
|
||||
/**
|
||||
* Create the DefaultTypeManager.
|
||||
*/
|
||||
@@ -133,6 +130,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
int clobType = config == null ? Types.CLOB : config.getDatabasePlatform().getClobDbType();
|
||||
int blobType = config == null ? Types.BLOB : config.getDatabasePlatform().getBlobDbType();
|
||||
|
||||
this.jsonDateTime = config.getJsonDateTime();
|
||||
this.checkImmutable = new CheckImmutable(this);
|
||||
this.reflectScalarBuilder = new ReflectionBasedTypeBuilder(this);
|
||||
|
||||
@@ -145,11 +143,12 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
|
||||
this.extraTypeFactory = new DefaultTypeFactory(config);
|
||||
|
||||
initialiseStandard(clobType, blobType, config.isUuidStoreAsBinary());
|
||||
initialiseJodaTypes();
|
||||
initialiseStandard(jsonDateTime, clobType, blobType, config.isUuidStoreAsBinary());
|
||||
initialiseJavaTimeTypes(jsonDateTime, config);
|
||||
initialiseJodaTypes(jsonDateTime);
|
||||
|
||||
if (bootupClasses != null) {
|
||||
initialiseCustomScalarTypes(bootupClasses);
|
||||
initialiseCustomScalarTypes(jsonDateTime, bootupClasses);
|
||||
initialiseScalarConverters(bootupClasses);
|
||||
initialiseCompoundTypes(bootupClasses);
|
||||
}
|
||||
@@ -311,19 +310,15 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
if (jdbcType == 0 || scalarType.getJdbcType() == jdbcType) {
|
||||
// matching type
|
||||
return (ScalarType<T>) scalarType;
|
||||
} else {
|
||||
// sometime like java.util.Date or java.util.Calendar
|
||||
// that that does not map to the same jdbc type as the
|
||||
// server wide settings.
|
||||
}
|
||||
}
|
||||
// a util Date with jdbcType not matching server wide settings
|
||||
if (type.equals(java.util.Date.class)) {
|
||||
return (ScalarType<T>) extraTypeFactory.createUtilDate(jdbcType);
|
||||
return (ScalarType<T>) extraTypeFactory.createUtilDate(jsonDateTime, jdbcType);
|
||||
}
|
||||
// a Calendar with jdbcType not matching server wide settings
|
||||
if (type.equals(java.util.Calendar.class)) {
|
||||
return (ScalarType<T>) extraTypeFactory.createCalendar(jdbcType);
|
||||
return (ScalarType<T>) extraTypeFactory.createCalendar(jsonDateTime, jdbcType);
|
||||
}
|
||||
|
||||
String msg = "Unmatched ScalarType for " + type + " jdbcType:" + jdbcType;
|
||||
@@ -415,7 +410,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
public ScalarType<?> createEnumScalarType(Class<?> enumType) {
|
||||
|
||||
// get the mapping information from EnumMapping
|
||||
EnumMapping enumMapping = (EnumMapping) enumType.getAnnotation(EnumMapping.class);
|
||||
EnumMapping enumMapping = enumType.getAnnotation(EnumMapping.class);
|
||||
if (enumMapping == null) {
|
||||
// look for EnumValue annotations instead
|
||||
return createEnumScalarType2(enumType);
|
||||
@@ -466,7 +461,9 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
* interface and register it with this TypeManager.
|
||||
* </p>
|
||||
*/
|
||||
protected void initialiseCustomScalarTypes(BootupClasses bootupClasses) {
|
||||
protected void initialiseCustomScalarTypes(JsonConfig.DateTime mode, BootupClasses bootupClasses) {
|
||||
|
||||
ScalarTypeLongToTimestamp longToTimestamp = new ScalarTypeLongToTimestamp(mode);
|
||||
|
||||
customScalarTypes.add(longToTimestamp);
|
||||
|
||||
@@ -602,20 +599,48 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
return propParamTypes[1];
|
||||
}
|
||||
|
||||
protected void initialiseJavaTimeTypes(JsonConfig.DateTime mode, ServerConfig config) {
|
||||
if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
|
||||
logger.debug("Registering java.time data types");
|
||||
typeMap.put(java.time.LocalDate.class, new ScalarTypeLocalDate());
|
||||
typeMap.put(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(mode));
|
||||
typeMap.put(OffsetDateTime.class, new ScalarTypeOffsetDateTime(mode));
|
||||
typeMap.put(ZonedDateTime.class, new ScalarTypeZonedDateTime(mode));
|
||||
typeMap.put(Instant.class, new ScalarTypeInstant(mode));
|
||||
|
||||
typeMap.put(DayOfWeek.class, new ScalarTypeDayOfWeek());
|
||||
typeMap.put(Month.class, new ScalarTypeMonth());
|
||||
typeMap.put(Year.class, new ScalarTypeYear());
|
||||
typeMap.put(YearMonth.class, new ScalarTypeYearMonthDate());
|
||||
typeMap.put(MonthDay.class, new ScalarTypeMonthDay());
|
||||
typeMap.put(OffsetTime.class, new ScalarTypeOffsetTime());
|
||||
typeMap.put(ZoneId.class, new ScalarTypeZoneId());
|
||||
typeMap.put(ZoneOffset.class, new ScalarTypeZoneOffset());
|
||||
|
||||
createCompoundScalarDataReader(Period.class, new CompoundTypePeriod(), "");
|
||||
|
||||
boolean localTimeNanos = config.isLocalTimeWithNanos();
|
||||
typeMap.put(java.time.LocalTime.class, (localTimeNanos)? new ScalarTypeLocalTimeWithNanos() : new ScalarTypeLocalTime());
|
||||
|
||||
boolean durationNanos = config.isDurationWithNanos();
|
||||
typeMap.put(Duration.class, (durationNanos)? new ScalarTypeDurationWithNanos() : new ScalarTypeDuration());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if Joda classes are in the classpath and if so register the Joda
|
||||
* data types.
|
||||
*/
|
||||
protected void initialiseJodaTypes() {
|
||||
protected void initialiseJodaTypes(JsonConfig.DateTime mode) {
|
||||
|
||||
// detect if Joda classes are in the classpath
|
||||
if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
|
||||
// Joda classes are in the classpath so register the types
|
||||
logger.debug("Registering Joda data types");
|
||||
typeMap.put(LocalDateTime.class, new ScalarTypeJodaLocalDateTime());
|
||||
typeMap.put(LocalDateTime.class, new ScalarTypeJodaLocalDateTime(mode));
|
||||
typeMap.put(DateTime.class, new ScalarTypeJodaDateTime(mode));
|
||||
typeMap.put(LocalDate.class, new ScalarTypeJodaLocalDate());
|
||||
typeMap.put(LocalTime.class, new ScalarTypeJodaLocalTime());
|
||||
typeMap.put(DateTime.class, new ScalarTypeJodaDateTime());
|
||||
typeMap.put(DateMidnight.class, new ScalarTypeJodaDateMidnight());
|
||||
}
|
||||
}
|
||||
@@ -624,12 +649,12 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
* Register all the standard types supported. This is the standard JDBC types
|
||||
* plus some other common types such as java.util.Date and java.util.Calendar.
|
||||
*/
|
||||
protected void initialiseStandard(int platformClobType, int platformBlobType, boolean binaryUUID) {
|
||||
protected void initialiseStandard(JsonConfig.DateTime mode, int platformClobType, int platformBlobType, boolean binaryUUID) {
|
||||
|
||||
ScalarType<?> utilDateType = extraTypeFactory.createUtilDate();
|
||||
ScalarType<?> utilDateType = extraTypeFactory.createUtilDate(mode);
|
||||
typeMap.put(java.util.Date.class, utilDateType);
|
||||
|
||||
ScalarType<?> calType = extraTypeFactory.createCalendar();
|
||||
ScalarType<?> calType = extraTypeFactory.createCalendar(mode);
|
||||
typeMap.put(Calendar.class, calType);
|
||||
|
||||
ScalarType<?> mathBigIntType = extraTypeFactory.createMathBigInteger();
|
||||
@@ -644,8 +669,6 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
if (booleanType.getJdbcType() == Types.BIT) {
|
||||
// for MapBeans ... BIT types are assumed to be booleans
|
||||
nativeMap.put(Types.BIT, booleanType);
|
||||
} else {
|
||||
// boolean mapping to Types.Integer, Types.VARCHAR or Types.Boolean
|
||||
}
|
||||
|
||||
// Store UUID as binary(16) or varchar(40)
|
||||
@@ -733,6 +756,9 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
nativeMap.put(Types.TIME, timeType);
|
||||
typeMap.put(Date.class, dateType);
|
||||
nativeMap.put(Types.DATE, dateType);
|
||||
|
||||
ScalarType<?> timestampType = new ScalarTypeTimestamp(mode);
|
||||
|
||||
typeMap.put(Timestamp.class, timestampType);
|
||||
nativeMap.put(Types.TIMESTAMP, timestampType);
|
||||
|
||||
|
||||
@@ -15,7 +15,12 @@ public class EnumToDbIntegerMap extends EnumToDbValueMap<Integer> {
|
||||
return Types.INTEGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumToDbIntegerMap add(Object beanValue, Integer dbValue) {
|
||||
addInternal(beanValue, dbValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumToDbIntegerMap add(Object beanValue, String stringDbValue) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -162,19 +162,11 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
*/
|
||||
public T parse(String value);
|
||||
|
||||
/**
|
||||
* Convert the systemTimeMillis into the appropriate java object.
|
||||
* <p>
|
||||
* For non dateTime types this will throw an exception.
|
||||
* </p>
|
||||
*/
|
||||
public T parseDateTime(long dateTime);
|
||||
|
||||
/**
|
||||
* Return true if the type can accept long systemTimeMillis input.
|
||||
* <p>
|
||||
* This is used to determine if is is sensible to use the
|
||||
* {@link #parseDateTime(long)} method.
|
||||
* {@link #convertFromMillis(long)} method.
|
||||
* </p>
|
||||
* <p>
|
||||
* This includes the Date, Calendar, sql Date, Time, Timestamp, JODA types
|
||||
@@ -184,24 +176,32 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
*/
|
||||
public boolean isDateTimeCapable();
|
||||
|
||||
/**
|
||||
/**
|
||||
* Convert the systemTimeMillis into the appropriate java object.
|
||||
* <p>
|
||||
* For non dateTime types this will throw an exception.
|
||||
* </p>
|
||||
*/
|
||||
public T convertFromMillis(long dateTime);
|
||||
|
||||
/**
|
||||
* Read the value from binary input.
|
||||
*/
|
||||
public Object readData(DataInput dataInput) throws IOException;
|
||||
public T readData(DataInput dataInput) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the value to binary output.
|
||||
*/
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException;
|
||||
public void writeData(DataOutput dataOutput, T v) throws IOException;
|
||||
|
||||
/**
|
||||
* Read the value from JsonParser.
|
||||
*/
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException;
|
||||
public T jsonRead(JsonParser ctx, JsonToken event) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the value to the JsonGenerator.
|
||||
*/
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException;
|
||||
public void jsonWrite(JsonGenerator ctx, String name, T value) throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -57,20 +57,6 @@ public abstract class ScalarTypeBase<T> implements ScalarType<T> {
|
||||
return formatValue((T) v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the value is null.
|
||||
*/
|
||||
public boolean isDbNull(Object value) {
|
||||
return value == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value that was passed in.
|
||||
*/
|
||||
public Object getDbNullValue(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void loadIgnore(DataReader dataReader) {
|
||||
dataReader.incrementPos(1);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
/**
|
||||
* Convert the target value to millis.
|
||||
*/
|
||||
public abstract long convertToMillis(Object value);
|
||||
public abstract long convertToMillis(T value);
|
||||
|
||||
/**
|
||||
* Convert to java.sql.Date from the target Date type.
|
||||
@@ -39,19 +39,14 @@ public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
if (value == null) {
|
||||
b.setNull(Types.DATE);
|
||||
} else {
|
||||
Date date = convertToDate(value);
|
||||
b.setDate(date);
|
||||
b.setDate(convertToDate(value));
|
||||
}
|
||||
}
|
||||
|
||||
public T read(DataReader dataReader) throws SQLException {
|
||||
|
||||
Date ts = dataReader.getDate();
|
||||
if (ts == null) {
|
||||
return null;
|
||||
} else {
|
||||
return convertFromDate(ts);
|
||||
}
|
||||
return ts == null ? null : convertFromDate(ts);
|
||||
}
|
||||
|
||||
public String formatValue(T t) {
|
||||
@@ -64,7 +59,7 @@ public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
return convertFromDate(date);
|
||||
}
|
||||
|
||||
public T parseDateTime(long systemTimeMillis) {
|
||||
public T convertFromMillis(long systemTimeMillis) {
|
||||
Date ts = new Date(systemTimeMillis);
|
||||
return convertFromDate(ts);
|
||||
}
|
||||
@@ -74,20 +69,20 @@ public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public T jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
if (JsonToken.VALUE_NUMBER_INT == event) {
|
||||
return parseDateTime(ctx.getLongValue());
|
||||
return convertFromMillis(ctx.getLongValue());
|
||||
} else {
|
||||
return convertFromDate(Date.valueOf(ctx.getText()));
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, T value) throws IOException {
|
||||
long millis = convertToMillis(value);
|
||||
ctx.writeNumberField(name, millis);
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public T readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -98,9 +93,8 @@ public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, T value) throws IOException {
|
||||
|
||||
T value = (T) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
|
||||
@@ -1,39 +1,69 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Base type for DateTime types.
|
||||
*/
|
||||
public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
|
||||
protected DateTimeJsonParser dateTimeParser = new DateTimeJsonParser();
|
||||
|
||||
public ScalarTypeBaseDateTime(Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
|
||||
protected final DateTimeJsonParser dateTimeParser = new DateTimeJsonParser();
|
||||
|
||||
protected final JsonConfig.DateTime mode;
|
||||
|
||||
public ScalarTypeBaseDateTime(JsonConfig.DateTime mode, Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
super(type, jdbcNative, jdbcType);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public abstract long convertToMillis(Object value);
|
||||
|
||||
/**
|
||||
* Convert the value to a Timestamp.
|
||||
*/
|
||||
public abstract Timestamp convertToTimestamp(T t);
|
||||
|
||||
/**
|
||||
* Convert to the value from a Timestamp.
|
||||
*/
|
||||
public abstract T convertFromTimestamp(Timestamp ts);
|
||||
|
||||
/**
|
||||
* Convert from epoch millis to the value.
|
||||
*/
|
||||
public abstract T convertFromMillis(long systemTimeMillis);
|
||||
|
||||
/**
|
||||
* Convert from the value to epoch millis.
|
||||
*/
|
||||
public abstract long convertToMillis(T value);
|
||||
|
||||
/**
|
||||
* Convert the value to time with nanos format.
|
||||
*/
|
||||
protected abstract String toJsonNanos(T value);
|
||||
|
||||
/**
|
||||
* Convert the value to ISO8601 format.
|
||||
*/
|
||||
protected abstract String toJsonISO8601(T value);
|
||||
|
||||
public void bind(DataBind b, T value) throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.TIMESTAMP);
|
||||
} else {
|
||||
Timestamp ts = convertToTimestamp(value);
|
||||
b.setTimestamp(ts);
|
||||
b.setTimestamp(convertToTimestamp(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,23 +77,50 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that given epoch seconds and nanos return a JSON nanos formatted string.
|
||||
*/
|
||||
protected String toJsonNanos(long epochSecs, int nanos) {
|
||||
return DecimalUtils.toDecimal(epochSecs, nanos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public T jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
|
||||
if (JsonToken.VALUE_NUMBER_INT == event) {
|
||||
long millis = ctx.getLongValue();
|
||||
return parseDateTime(millis);
|
||||
|
||||
} else {
|
||||
String jsonDateTime = ctx.getText();
|
||||
return convertFromTimestamp(dateTimeParser.parse(jsonDateTime));
|
||||
switch (event) {
|
||||
case VALUE_NUMBER_INT: {
|
||||
return convertFromMillis(ctx.getLongValue());
|
||||
}
|
||||
case VALUE_NUMBER_FLOAT: {
|
||||
BigDecimal value = ctx.getDecimalValue();
|
||||
Timestamp timestamp = DecimalUtils.toTimestamp(value);
|
||||
return convertFromTimestamp(timestamp);
|
||||
}
|
||||
default: {
|
||||
String jsonDateTime = ctx.getText();
|
||||
return convertFromTimestamp(dateTimeParser.parse(jsonDateTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
long millis = convertToMillis(value);
|
||||
ctx.writeNumberField(name, millis);
|
||||
public void jsonWrite(JsonGenerator generator, String name, T value) throws IOException {
|
||||
|
||||
switch (mode) {
|
||||
case ISO8601: {
|
||||
generator.writeFieldName(name);
|
||||
generator.writeString(toJsonISO8601(value));
|
||||
break;
|
||||
}
|
||||
case NANOS: {
|
||||
generator.writeFieldName(name);
|
||||
generator.writeNumber(toJsonNanos(value));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
generator.writeNumberField(name, convertToMillis(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String formatValue(T t) {
|
||||
@@ -76,16 +133,12 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
return convertFromTimestamp(ts);
|
||||
}
|
||||
|
||||
public T parseDateTime(long systemTimeMillis) {
|
||||
Timestamp ts = new Timestamp(systemTimeMillis);
|
||||
return convertFromTimestamp(ts);
|
||||
}
|
||||
|
||||
public boolean isDateTimeCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public T readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -95,10 +148,8 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, T value) throws IOException {
|
||||
|
||||
T value = (T) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
|
||||
@@ -86,7 +86,7 @@ public abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parseDateTime(long systemTimeMillis) {
|
||||
public T convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ public abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public T readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -111,10 +111,8 @@ public abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, T value) throws IOException {
|
||||
|
||||
T value = (T) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
@@ -125,12 +123,12 @@ public abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public T jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return parse(ctx.getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, T value) throws IOException {
|
||||
ctx.writeStringField(name, format(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,75 +17,73 @@ import com.fasterxml.jackson.core.JsonToken;
|
||||
*/
|
||||
public class ScalarTypeBigDecimal extends ScalarTypeBase<BigDecimal> {
|
||||
|
||||
public ScalarTypeBigDecimal() {
|
||||
super(BigDecimal.class, true, Types.DECIMAL);
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
double val = dataInput.readDouble();
|
||||
return new BigDecimal(val);
|
||||
}
|
||||
public ScalarTypeBigDecimal() {
|
||||
super(BigDecimal.class, true, Types.DECIMAL);
|
||||
}
|
||||
|
||||
public BigDecimal readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
double val = dataInput.readDouble();
|
||||
return new BigDecimal(val);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
|
||||
BigDecimal b = (BigDecimal)v;
|
||||
if (b == null){
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeDouble(b.doubleValue());
|
||||
}
|
||||
public void writeData(DataOutput dataOutput, BigDecimal b) throws IOException {
|
||||
|
||||
if (b == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeDouble(b.doubleValue());
|
||||
}
|
||||
|
||||
public void bind(DataBind b, BigDecimal value) throws SQLException {
|
||||
if (value == null){
|
||||
b.setNull(Types.DECIMAL);
|
||||
} else {
|
||||
b.setBigDecimal(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BigDecimal read(DataReader dataReader) throws SQLException {
|
||||
|
||||
return dataReader.getBigDecimal();
|
||||
}
|
||||
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.toBigDecimal(value);
|
||||
}
|
||||
|
||||
public BigDecimal toBeanType(Object value) {
|
||||
return BasicTypeConverter.toBigDecimal(value);
|
||||
}
|
||||
|
||||
public String formatValue(BigDecimal t) {
|
||||
return t.toPlainString();
|
||||
public void bind(DataBind b, BigDecimal value) throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.DECIMAL);
|
||||
} else {
|
||||
b.setBigDecimal(value);
|
||||
}
|
||||
}
|
||||
|
||||
public BigDecimal parse(String value) {
|
||||
return new BigDecimal(value);
|
||||
}
|
||||
public BigDecimal read(DataReader dataReader) throws SQLException {
|
||||
|
||||
public BigDecimal parseDateTime(long systemTimeMillis) {
|
||||
return BigDecimal.valueOf(systemTimeMillis);
|
||||
}
|
||||
return dataReader.getBigDecimal();
|
||||
}
|
||||
|
||||
public boolean isDateTimeCapable() {
|
||||
return true;
|
||||
}
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.toBigDecimal(value);
|
||||
}
|
||||
|
||||
public BigDecimal toBeanType(Object value) {
|
||||
return BasicTypeConverter.toBigDecimal(value);
|
||||
}
|
||||
|
||||
public String formatValue(BigDecimal t) {
|
||||
return t.toPlainString();
|
||||
}
|
||||
|
||||
public BigDecimal parse(String value) {
|
||||
return new BigDecimal(value);
|
||||
}
|
||||
|
||||
public BigDecimal convertFromMillis(long systemTimeMillis) {
|
||||
return BigDecimal.valueOf(systemTimeMillis);
|
||||
}
|
||||
|
||||
public boolean isDateTimeCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public BigDecimal jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getDecimalValue();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
ctx.writeNumberField(name, (BigDecimal)value);
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, BigDecimal value) throws IOException {
|
||||
ctx.writeNumberField(name, (BigDecimal) value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ public class ScalarTypeBoolean {
|
||||
return Boolean.valueOf(value);
|
||||
}
|
||||
|
||||
public Boolean parseDateTime(long systemTimeMillis) {
|
||||
public Boolean convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@@ -269,32 +269,30 @@ public class ScalarTypeBoolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Boolean readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
boolean val = dataInput.readBoolean();
|
||||
return Boolean.valueOf(val);
|
||||
return dataInput.readBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Boolean val) throws IOException {
|
||||
|
||||
Boolean val = (Boolean) v;
|
||||
if (val == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeBoolean(val.booleanValue());
|
||||
dataOutput.writeBoolean(val);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) {
|
||||
public Boolean jsonRead(JsonParser ctx, JsonToken event) {
|
||||
return JsonToken.VALUE_TRUE == event ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Boolean value) throws IOException {
|
||||
ctx.writeBooleanField(name, (Boolean) value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ public class ScalarTypeByte extends ScalarTypeBase<Byte> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Byte value) throws IOException {
|
||||
throw new IOException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Byte jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
throw new IOException("Not supported");
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class ScalarTypeByte extends ScalarTypeBase<Byte> {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
public Byte parseDateTime(long systemTimeMillis) {
|
||||
public Byte convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@@ -67,18 +67,16 @@ public class ScalarTypeByte extends ScalarTypeBase<Byte> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Byte readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
byte val = dataInput.readByte();
|
||||
return Byte.valueOf(val);
|
||||
return dataInput.readByte();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Byte val) throws IOException {
|
||||
|
||||
Byte val = (Byte) v;
|
||||
if (val == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
|
||||
@@ -45,12 +45,12 @@ public abstract class ScalarTypeBytesBase extends ScalarTypeBase<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, byte[] value) throws IOException {
|
||||
ctx.writeBinaryField(name, (byte[]) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public byte[] jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(500);
|
||||
ctx.readBinaryValue(out);
|
||||
return out.toByteArray();
|
||||
@@ -64,7 +64,7 @@ public abstract class ScalarTypeBytesBase extends ScalarTypeBase<byte[]> {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
public byte[] parseDateTime(long systemTimeMillis) {
|
||||
public byte[] convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public abstract class ScalarTypeBytesBase extends ScalarTypeBase<byte[]> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public byte[] readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -83,10 +83,11 @@ public abstract class ScalarTypeBytesBase extends ScalarTypeBase<byte[]> {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, byte[] v) throws IOException {
|
||||
if (v == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
byte[] bytes = convertToBytes(v);
|
||||
dataOutput.writeInt(bytes.length);
|
||||
dataOutput.write(bytes);
|
||||
|
||||
@@ -67,12 +67,12 @@ public class ScalarTypeBytesEncrypted implements ScalarType<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, byte[] value) throws IOException {
|
||||
ctx.writeBinaryField(name, (byte[]) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public byte[] jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(500);
|
||||
ctx.readBinaryValue(out);
|
||||
return out.toByteArray();
|
||||
@@ -90,8 +90,8 @@ public class ScalarTypeBytesEncrypted implements ScalarType<byte[]> {
|
||||
return baseType.parse(value);
|
||||
}
|
||||
|
||||
public byte[] parseDateTime(long systemTimeMillis) {
|
||||
return baseType.parseDateTime(systemTimeMillis);
|
||||
public byte[] convertFromMillis(long systemTimeMillis) {
|
||||
return baseType.convertFromMillis(systemTimeMillis);
|
||||
}
|
||||
|
||||
public byte[] read(DataReader dataReader) throws SQLException {
|
||||
@@ -113,17 +113,26 @@ public class ScalarTypeBytesEncrypted implements ScalarType<byte[]> {
|
||||
baseType.accumulateScalarTypes(propName, list);
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
int len = dataInput.readInt();
|
||||
byte[] value = new byte[len];
|
||||
dataInput.readFully(value);
|
||||
return value;
|
||||
public byte[] readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
int len = dataInput.readInt();
|
||||
byte[] value = new byte[len];
|
||||
dataInput.readFully(value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
byte[] value = (byte[]) v;
|
||||
dataOutput.writeInt(value.length);
|
||||
dataOutput.write(value);
|
||||
public void writeData(DataOutput dataOutput, byte[] value) throws IOException {
|
||||
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeInt(value.length);
|
||||
dataOutput.write(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -13,25 +14,32 @@ import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
*/
|
||||
public class ScalarTypeCalendar extends ScalarTypeBaseDateTime<Calendar> {
|
||||
|
||||
public ScalarTypeCalendar(int jdbcType) {
|
||||
super(Calendar.class, false, jdbcType);
|
||||
public ScalarTypeCalendar(JsonConfig.DateTime mode, int jdbcType) {
|
||||
super(mode, Calendar.class, false, jdbcType);
|
||||
}
|
||||
|
||||
public void bind(DataBind b, Calendar value) throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.TIMESTAMP);
|
||||
} else {
|
||||
Calendar date = (Calendar) value;
|
||||
|
||||
if (jdbcType == Types.TIMESTAMP) {
|
||||
Timestamp timestamp = new Timestamp(date.getTimeInMillis());
|
||||
Timestamp timestamp = new Timestamp(value.getTimeInMillis());
|
||||
b.setTimestamp(timestamp);
|
||||
} else {
|
||||
Date d = new Date(date.getTimeInMillis());
|
||||
Date d = new Date(value.getTimeInMillis());
|
||||
b.setDate(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar convertFromMillis(long systemTimeMillis) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(systemTimeMillis);
|
||||
return calendar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar convertFromTimestamp(Timestamp ts) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
@@ -40,8 +48,18 @@ public class ScalarTypeCalendar extends ScalarTypeBaseDateTime<Calendar> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((Calendar) value).getTimeInMillis();
|
||||
protected String toJsonNanos(Calendar value) {
|
||||
return String.valueOf(value.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(Calendar value) {
|
||||
return dateTimeParser.format(value.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Calendar value) {
|
||||
return value.getTimeInMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,10 +67,12 @@ public class ScalarTypeCalendar extends ScalarTypeBaseDateTime<Calendar> {
|
||||
return new Timestamp(t.getTimeInMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.convert(value, jdbcType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar toBeanType(Object value) {
|
||||
return BasicTypeConverter.toCalendar(value);
|
||||
}
|
||||
|
||||
@@ -64,11 +64,11 @@ public class ScalarTypeCharArray extends ScalarTypeBaseVarchar<char[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public char[] jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getValueAsString().toCharArray();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, char[] value) throws IOException {
|
||||
ctx.writeStringField(name, String.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ public class ScalarTypeDate extends ScalarTypeBaseDate<java.sql.Date> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((Date) value).getTime();
|
||||
public long convertToMillis(Date value) {
|
||||
return value.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.DayOfWeek;
|
||||
|
||||
/**
|
||||
* ScalarType mapping for Month enum.
|
||||
*/
|
||||
public class ScalarTypeDayOfWeek extends ScalarTypeEnumWithMapping {
|
||||
|
||||
static final EnumToDbIntegerMap beanDbMap = new EnumToDbIntegerMap();
|
||||
|
||||
static {
|
||||
DayOfWeek[] values = DayOfWeek.values();
|
||||
for (DayOfWeek value : values) {
|
||||
beanDbMap.add(value, value.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public ScalarTypeDayOfWeek() {
|
||||
super(beanDbMap, DayOfWeek.class, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind DayOfWeek enum using getValue().
|
||||
*/
|
||||
@Override
|
||||
public void bind(DataBind b, Object value) throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.INTEGER);
|
||||
} else {
|
||||
// avoiding the map lookup
|
||||
b.setInt(((DayOfWeek)value).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read DayOfWeek using int value.
|
||||
*/
|
||||
@Override
|
||||
public Object read(DataReader dataReader) throws SQLException {
|
||||
Integer i = dataReader.getInt();
|
||||
if (i == null) {
|
||||
return null;
|
||||
} else {
|
||||
// avoiding the map lookup
|
||||
return DayOfWeek.of(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class ScalarTypeDouble extends ScalarTypeBase<Double> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double parseDateTime(long systemTimeMillis) {
|
||||
public Double convertFromMillis(long systemTimeMillis) {
|
||||
return Double.valueOf(systemTimeMillis);
|
||||
}
|
||||
|
||||
@@ -65,34 +65,32 @@ public class ScalarTypeDouble extends ScalarTypeBase<Double> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Double readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
double val = dataInput.readDouble();
|
||||
return Double.valueOf(val);
|
||||
return dataInput.readDouble();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Double value) throws IOException {
|
||||
|
||||
Double value = (Double) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeDouble(value.doubleValue());
|
||||
dataOutput.writeDouble(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Double jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getDoubleValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
ctx.writeNumberField(name, (Double) value);
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Double value) throws IOException {
|
||||
ctx.writeNumberField(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.Duration (with seconds precision).
|
||||
*/
|
||||
public class ScalarTypeDuration extends ScalarTypeBase<Duration> {
|
||||
|
||||
public ScalarTypeDuration() {
|
||||
super(Duration.class, false, Types.BIGINT);
|
||||
}
|
||||
|
||||
protected ScalarTypeDuration(int jdbcType) {
|
||||
super(Duration.class, false, jdbcType);
|
||||
}
|
||||
|
||||
public BigDecimal convertToBigDecimal(Duration value) {
|
||||
return (value == null) ? null : DecimalUtils.toDecimal(value);
|
||||
}
|
||||
|
||||
public Duration convertFromBigDecimal(BigDecimal value) {
|
||||
return (value == null) ? null : DecimalUtils.toDuration(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBind bind, Duration value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.BIGINT);
|
||||
} else {
|
||||
bind.setLong(value.getSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration read(DataReader dataReader) throws SQLException {
|
||||
Long value = dataReader.getLong();
|
||||
return (value == null) ? null : Duration.ofSeconds(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Long) return value;
|
||||
return ((Duration)value).getSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration toBeanType(Object value) {
|
||||
if (value instanceof Duration) return (Duration) value;
|
||||
return Duration.ofSeconds(BasicTypeConverter.toLong(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
return convertFromBigDecimal(new BigDecimal(dataInput.readUTF()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Duration value) throws IOException {
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeUTF(convertToBigDecimal(value).toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(Duration v) {
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration parse(String value) {
|
||||
return Duration.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTimeCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return Duration.parse(ctx.getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Duration value) throws IOException {
|
||||
ctx.writeStringField(name, value.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.Duration (with Nanos precision).
|
||||
* <p>
|
||||
* Stored in the DB as DECIMAL value.
|
||||
* </p>
|
||||
*/
|
||||
public class ScalarTypeDurationWithNanos extends ScalarTypeDuration {
|
||||
|
||||
public ScalarTypeDurationWithNanos() {
|
||||
super(Types.DECIMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBind bind, Duration value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.DECIMAL);
|
||||
} else {
|
||||
bind.setBigDecimal(convertToBigDecimal(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration read(DataReader dataReader) throws SQLException {
|
||||
return convertFromBigDecimal(dataReader.getBigDecimal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof BigDecimal) return value;
|
||||
return convertToBigDecimal((Duration)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration toBeanType(Object value) {
|
||||
if (value instanceof Duration) return (Duration) value;
|
||||
return convertFromBigDecimal(BasicTypeConverter.toBigDecimal(value));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,12 +34,12 @@ public class ScalarTypeEncryptedWrapper<T> implements ScalarType<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public T readData(DataInput dataInput) throws IOException {
|
||||
return wrapped.readData(dataInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, T v) throws IOException {
|
||||
wrapped.writeData(dataOutput, v);
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ public class ScalarTypeEncryptedWrapper<T> implements ScalarType<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parseDateTime(long systemTimeMillis) {
|
||||
return wrapped.parseDateTime(systemTimeMillis);
|
||||
public T convertFromMillis(long systemTimeMillis) {
|
||||
return wrapped.convertFromMillis(systemTimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,12 +133,12 @@ public class ScalarTypeEncryptedWrapper<T> implements ScalarType<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public T jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return wrapped.jsonRead(ctx, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, T value) throws IOException {
|
||||
wrapped.jsonWrite(ctx, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ public interface ScalarTypeEnum {
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getContraintInValues();
|
||||
public String getConstraintInValues();
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ScalarTypeEnumStandard {
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getContraintInValues() {
|
||||
public String getConstraintInValues() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
@@ -101,7 +101,7 @@ public class ScalarTypeEnumStandard {
|
||||
if (beanValue == null) {
|
||||
return null;
|
||||
}
|
||||
return ((Enum<?>) beanValue).toString();
|
||||
return beanValue.toString();
|
||||
}
|
||||
|
||||
public Object toBeanType(Object dbValue) {
|
||||
@@ -129,7 +129,7 @@ public class ScalarTypeEnumStandard {
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getContraintInValues() {
|
||||
public String getConstraintInValues() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
@@ -186,7 +186,7 @@ public class ScalarTypeEnumStandard {
|
||||
return dbValue;
|
||||
}
|
||||
|
||||
int ordinal = ((Integer) dbValue).intValue();
|
||||
int ordinal = (Integer) dbValue;
|
||||
if (ordinal < 0 || ordinal >= enumArray.length) {
|
||||
String m = "Unexpected ordinal [" + ordinal + "] out of range [" + enumArray.length + "]";
|
||||
throw new IllegalStateException(m);
|
||||
@@ -222,7 +222,7 @@ public class ScalarTypeEnumStandard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseDateTime(long systemTimeMillis) {
|
||||
public Object convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public class ScalarTypeEnumWithMapping extends ScalarTypeEnumStandard.EnumBase i
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getContraintInValues() {
|
||||
public String getConstraintInValues() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ScalarTypeFloat extends ScalarTypeBase<Float> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float parseDateTime(long systemTimeMillis) {
|
||||
public Float convertFromMillis(long systemTimeMillis) {
|
||||
return Float.valueOf(systemTimeMillis);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ScalarTypeFloat extends ScalarTypeBase<Float> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Float readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -75,24 +75,23 @@ public class ScalarTypeFloat extends ScalarTypeBase<Float> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Float value) throws IOException {
|
||||
|
||||
Float value = (Float) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeFloat(value.floatValue());
|
||||
dataOutput.writeFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Float jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getFloatValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Float value) throws IOException {
|
||||
ctx.writeNumberField(name, (Float) value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* ScalarType for java.sql.Timestamp.
|
||||
*/
|
||||
public class ScalarTypeInstant extends ScalarTypeBaseDateTime<Instant> {
|
||||
|
||||
public ScalarTypeInstant(JsonConfig.DateTime mode) {
|
||||
super(mode, Instant.class, true, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonNanos(Instant value) {
|
||||
return toJsonNanos(value.getEpochSecond(), value.getNano());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(Instant value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Instant value) {
|
||||
return value.toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant convertFromMillis(long systemTimeMillis) {
|
||||
return Instant.ofEpochMilli(systemTimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant convertFromTimestamp(Timestamp ts) {
|
||||
return ts.toInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(Instant t) {
|
||||
return Timestamp.from(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Timestamp) return value;
|
||||
return convertToTimestamp((Instant) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant toBeanType(Object value) {
|
||||
if (value instanceof Instant) return (Instant) value;
|
||||
return convertFromTimestamp((Timestamp) value);
|
||||
}
|
||||
}
|
||||
@@ -36,13 +36,22 @@ public class ScalarTypeInteger extends ScalarTypeBase<Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
return Integer.valueOf(dataInput.readInt());
|
||||
public Integer readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
return Integer.valueOf(dataInput.readInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
dataOutput.writeInt((Integer) v);
|
||||
public void writeData(DataOutput dataOutput, Integer value) throws IOException {
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeInt(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +75,7 @@ public class ScalarTypeInteger extends ScalarTypeBase<Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer parseDateTime(long systemTimeMillis) {
|
||||
public Integer convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@@ -76,12 +85,12 @@ public class ScalarTypeInteger extends ScalarTypeBase<Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Integer jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getIntValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
ctx.writeNumberField(name, (Integer) value);
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Integer value) throws IOException {
|
||||
ctx.writeNumberField(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ public class ScalarTypeJodaDateMidnight extends ScalarTypeBaseDate<DateMidnight>
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((DateMidnight) value).getMillis();
|
||||
public long convertToMillis(DateMidnight value) {
|
||||
return value.getMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,22 +3,39 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* ScalarType for Joda DateTime. This maps to a JDBC Timestamp.
|
||||
*/
|
||||
public class ScalarTypeJodaDateTime extends ScalarTypeBaseDateTime<DateTime> {
|
||||
|
||||
public ScalarTypeJodaDateTime() {
|
||||
super(DateTime.class, false, Types.TIMESTAMP);
|
||||
public ScalarTypeJodaDateTime(JsonConfig.DateTime mode) {
|
||||
super(mode, DateTime.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((DateTime) value).getMillis();
|
||||
public long convertToMillis(DateTime value) {
|
||||
return value.getMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonNanos(DateTime value) {
|
||||
return String.valueOf(value.toDateTime().getMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(DateTime value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTime convertFromMillis(long systemTimeMillis) {
|
||||
return new DateTime(systemTimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,8 +17,8 @@ public class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate<LocalDate> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((LocalDate) value).toDateMidnight().getMillis();
|
||||
public long convertToMillis(LocalDate value) {
|
||||
return value.toDateMidnight().getMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +48,7 @@ public class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate<LocalDate> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate parseDateTime(long systemTimeMillis) {
|
||||
public LocalDate convertFromMillis(long systemTimeMillis) {
|
||||
return new LocalDate(systemTimeMillis);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.util.Date;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
@@ -12,13 +14,29 @@ import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
*/
|
||||
public class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDateTime> {
|
||||
|
||||
public ScalarTypeJodaLocalDateTime() {
|
||||
super(LocalDateTime.class, false, Types.TIMESTAMP);
|
||||
public ScalarTypeJodaLocalDateTime(JsonConfig.DateTime mode) {
|
||||
super(mode, LocalDateTime.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((LocalDateTime) value).toDateTime().getMillis();
|
||||
protected String toJsonNanos(LocalDateTime value) {
|
||||
return String.valueOf(value.toDateTime().getMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(LocalDateTime value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(LocalDateTime value) {
|
||||
return value.toDateTime().getMillis();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LocalDateTime convertFromMillis(long systemTimeMillis) {
|
||||
return new LocalDateTime(systemTimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,9 +65,4 @@ public class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDat
|
||||
return (LocalDateTime) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime parseDateTime(long systemTimeMillis) {
|
||||
return new LocalDateTime(systemTimeMillis);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,15 +72,15 @@ public class ScalarTypeJodaLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, LocalTime value) throws IOException {
|
||||
ctx.writeStringField(name, value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public LocalTime jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
if (JsonToken.VALUE_NUMBER_INT == event) {
|
||||
long millis = ctx.getLongValue();
|
||||
return parseDateTime(millis);
|
||||
return convertFromMillis(millis);
|
||||
} else {
|
||||
String string = ctx.getValueAsString();
|
||||
throw new RuntimeException("convert " + string);
|
||||
@@ -88,7 +88,7 @@ public class ScalarTypeJodaLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime parseDateTime(long systemTimeMillis) {
|
||||
public LocalTime convertFromMillis(long systemTimeMillis) {
|
||||
return new LocalTime(systemTimeMillis);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ScalarTypeJodaLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public LocalTime readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -108,9 +108,8 @@ public class ScalarTypeJodaLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, LocalTime value) throws IOException {
|
||||
|
||||
Time value = (Time) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.LocalDate. This maps to a JDBC Date.
|
||||
*/
|
||||
public class ScalarTypeLocalDate extends ScalarTypeBaseDate<LocalDate> {
|
||||
|
||||
public ScalarTypeLocalDate() {
|
||||
super(LocalDate.class, false, Types.DATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(LocalDate value) {
|
||||
ZonedDateTime zonedDateTime = value.atStartOfDay(ZoneId.systemDefault());
|
||||
return zonedDateTime.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate convertFromDate(Date ts) {
|
||||
return ts.toLocalDate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date convertToDate(LocalDate t) {
|
||||
return Date.valueOf(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof LocalDate) {
|
||||
return Date.valueOf((LocalDate) value);
|
||||
}
|
||||
return BasicTypeConverter.toDate(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate toBeanType(Object value) {
|
||||
if (value instanceof java.sql.Date) {
|
||||
return ((java.sql.Date) value).toLocalDate();
|
||||
}
|
||||
return (LocalDate) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate convertFromMillis(long systemTimeMillis) {
|
||||
return new Timestamp(systemTimeMillis).toLocalDateTime().toLocalDate();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* ScalarType for java.sql.Timestamp.
|
||||
*/
|
||||
public class ScalarTypeLocalDateTime extends ScalarTypeBaseDateTime<LocalDateTime> {
|
||||
|
||||
public ScalarTypeLocalDateTime(JsonConfig.DateTime mode) {
|
||||
super(mode, LocalDateTime.class, true, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime convertFromMillis(long systemTimeMillis) {
|
||||
return new Timestamp(systemTimeMillis).toLocalDateTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(LocalDateTime value) {
|
||||
return value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonNanos(LocalDateTime value) {
|
||||
return String.valueOf(convertToMillis(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(LocalDateTime value) {
|
||||
return value.atZone(ZoneId.systemDefault()).toInstant().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime convertFromTimestamp(Timestamp ts) {
|
||||
return ts.toLocalDateTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(LocalDateTime t) {
|
||||
|
||||
ZonedDateTime zonedDateTime = t.atZone(ZoneId.systemDefault());
|
||||
return Timestamp.from(zonedDateTime.toInstant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Timestamp) return value;
|
||||
return convertToTimestamp((LocalDateTime)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime toBeanType(Object value) {
|
||||
if (value instanceof LocalDateTime) return (LocalDateTime)value;
|
||||
return convertFromTimestamp((Timestamp)value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.LocalTime stored as JDBC Time.
|
||||
*/
|
||||
public class ScalarTypeLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
|
||||
public ScalarTypeLocalTime() {
|
||||
super(LocalTime.class, false, Types.TIME);
|
||||
}
|
||||
|
||||
protected ScalarTypeLocalTime(int jdbcTtype) {
|
||||
super(LocalTime.class, false, jdbcTtype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBind bind, LocalTime value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.TIME);
|
||||
} else {
|
||||
bind.setTime(Time.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime read(DataReader dataReader) throws SQLException {
|
||||
Time time = dataReader.getTime();
|
||||
return (time == null) ? null : time.toLocalTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Time) return value;
|
||||
return Time.valueOf((LocalTime)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime toBeanType(Object value) {
|
||||
if (value instanceof LocalTime) return (LocalTime) value;
|
||||
return BasicTypeConverter.toTime(value).toLocalTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
return LocalTime.ofNanoOfDay(dataInput.readLong());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, LocalTime value) throws IOException {
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeLong(value.toNanoOfDay());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(LocalTime v) {
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime parse(String value) {
|
||||
return LocalTime.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTimeCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return LocalTime.parse(ctx.getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, LocalTime value) throws IOException {
|
||||
ctx.writeStringField(name, value.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.LocalTime stored with Nanos as DB BIGINT type.
|
||||
*/
|
||||
public class ScalarTypeLocalTimeWithNanos extends ScalarTypeLocalTime {
|
||||
|
||||
public ScalarTypeLocalTimeWithNanos() {
|
||||
super(Types.BIGINT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBind bind, LocalTime value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.BIGINT);
|
||||
} else {
|
||||
bind.setLong(value.toNanoOfDay());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime read(DataReader dataReader) throws SQLException {
|
||||
Long value = dataReader.getLong();
|
||||
return (value == null) ? null : LocalTime.ofNanoOfDay(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Long) return value;
|
||||
return ((LocalTime)value).toNanoOfDay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime toBeanType(Object value) {
|
||||
if (value instanceof LocalTime) return (LocalTime) value;
|
||||
return LocalTime.ofNanoOfDay(BasicTypeConverter.toLong(value));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,8 +55,8 @@ public class ScalarTypeLong extends ScalarTypeBase<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long parseDateTime(long systemTimeMillis) {
|
||||
return Long.valueOf(systemTimeMillis);
|
||||
public Long convertFromMillis(long systemTimeMillis) {
|
||||
return systemTimeMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,34 +65,32 @@ public class ScalarTypeLong extends ScalarTypeBase<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Long readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
long val = dataInput.readLong();
|
||||
return Long.valueOf(val);
|
||||
return dataInput.readLong();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Long value) throws IOException {
|
||||
|
||||
Long value = (Long) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeLong(value.longValue());
|
||||
dataOutput.writeLong(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Long jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getLongValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Long value) throws IOException {
|
||||
ctx.writeNumberField(name, (Long) value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public class ScalarTypeLongToTimestamp extends ScalarTypeWrapper<Long, Timestamp> {
|
||||
|
||||
public ScalarTypeLongToTimestamp() {
|
||||
super(Long.class, new ScalarTypeTimestamp(), new LongToTimestampConverter());
|
||||
public ScalarTypeLongToTimestamp(JsonConfig.DateTime mode) {
|
||||
super(Long.class, new ScalarTypeTimestamp(mode), new LongToTimestampConverter());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
@@ -61,7 +63,7 @@ public class ScalarTypeMathBigInteger extends ScalarTypeBase<BigInteger> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger parseDateTime(long systemTimeMillis) {
|
||||
public BigInteger convertFromMillis(long systemTimeMillis) {
|
||||
return BigInteger.valueOf(systemTimeMillis);
|
||||
}
|
||||
|
||||
@@ -71,19 +73,18 @@ public class ScalarTypeMathBigInteger extends ScalarTypeBase<BigInteger> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public BigInteger readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
long val = dataInput.readLong();
|
||||
return Long.valueOf(val);
|
||||
return BigInteger.valueOf(val);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, BigInteger value) throws IOException {
|
||||
|
||||
Long value = (Long) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
@@ -93,12 +94,12 @@ public class ScalarTypeMathBigInteger extends ScalarTypeBase<BigInteger> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public BigInteger jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getDecimalValue().toBigInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, BigInteger value) throws IOException {
|
||||
ctx.writeNumberField(name, ((BigInteger) value).longValue());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.Month;
|
||||
|
||||
/**
|
||||
* ScalarType mapping for Month enum.
|
||||
*/
|
||||
public class ScalarTypeMonth extends ScalarTypeEnumWithMapping {
|
||||
|
||||
static final EnumToDbIntegerMap beanDbMap = new EnumToDbIntegerMap();
|
||||
|
||||
static {
|
||||
Month[] values = Month.values();
|
||||
for (Month value : values) {
|
||||
beanDbMap.add(value, value.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public ScalarTypeMonth() {
|
||||
super(beanDbMap, Month.class, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind Month enum value.
|
||||
*/
|
||||
@Override
|
||||
public void bind(DataBind b, Object value) throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.INTEGER);
|
||||
} else {
|
||||
// avoiding the map lookup
|
||||
b.setInt(((Month)value).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Month enum from integer.
|
||||
*/
|
||||
@Override
|
||||
public Object read(DataReader dataReader) throws SQLException {
|
||||
Integer i = dataReader.getInt();
|
||||
if (i == null) {
|
||||
return null;
|
||||
} else {
|
||||
// avoiding the map lookup
|
||||
return Month.of(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.Date;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.MonthDay;
|
||||
|
||||
/**
|
||||
* ScalarType for MonthDay stored as a SQL Date using a fixed year.
|
||||
* <p>
|
||||
* Note that the year used should be a leap year.
|
||||
* </p>
|
||||
*/
|
||||
public class ScalarTypeMonthDay extends ScalarTypeBase<MonthDay> {
|
||||
|
||||
protected int year;
|
||||
|
||||
/**
|
||||
* Construct with a year of 2000 (which is a leap year).
|
||||
*/
|
||||
public ScalarTypeMonthDay() {
|
||||
this(2000); // Year 2000 is a leap year
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a base year. The year should be a leap year to
|
||||
* allow the 29th Feb value.
|
||||
*/
|
||||
public ScalarTypeMonthDay(int year) {
|
||||
super(MonthDay.class, false, Types.DATE);
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
private MonthDay convertFromDate(Date ts) {
|
||||
LocalDate localDate = ts.toLocalDate();
|
||||
return MonthDay.of(localDate.getMonthValue(), localDate.getDayOfMonth());
|
||||
}
|
||||
|
||||
private Date convertToDate(MonthDay value) {
|
||||
return Date.valueOf(LocalDate.of(2000, value.getMonthValue(), value.getDayOfMonth()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonthDay read(DataReader dataReader) throws SQLException {
|
||||
Date ts = dataReader.getDate();
|
||||
return ts == null ? null : convertFromDate(ts);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void bind(DataBind b, MonthDay value) throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.DATE);
|
||||
} else {
|
||||
b.setDate(convertToDate(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Date) return value;
|
||||
return convertToDate((MonthDay) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonthDay toBeanType(Object value) {
|
||||
if (value instanceof MonthDay) return (MonthDay) value;
|
||||
return convertFromDate((Date) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(MonthDay value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonthDay parse(String value) {
|
||||
return MonthDay.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTimeCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonthDay convertFromMillis(long dateTime) {
|
||||
throw new RuntimeException("Not supported on this type");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonthDay readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
int month = dataInput.readInt();
|
||||
int day = dataInput.readInt();
|
||||
return MonthDay.of(month, day);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, MonthDay value) throws IOException {
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.write(value.getMonthValue());
|
||||
dataOutput.write(value.getDayOfMonth());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonthDay jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return parse(ctx.getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, MonthDay value) throws IOException {
|
||||
ctx.writeStringField(name, format(value));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* ScalarType for java.sql.Timestamp.
|
||||
*/
|
||||
public class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime<OffsetDateTime> {
|
||||
|
||||
public ScalarTypeOffsetDateTime(JsonConfig.DateTime mode) {
|
||||
super(mode, OffsetDateTime.class, true, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonNanos(OffsetDateTime value) {
|
||||
return toJsonNanos(value.toEpochSecond(), value.getNano());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(OffsetDateTime value) {
|
||||
return value.toInstant().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(OffsetDateTime value) {
|
||||
return value.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetDateTime convertFromMillis(long systemTimeMillis) {
|
||||
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(systemTimeMillis), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetDateTime convertFromTimestamp(Timestamp ts) {
|
||||
return OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(OffsetDateTime t) {
|
||||
return Timestamp.from(t.toInstant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Timestamp) return value;
|
||||
return convertToTimestamp((OffsetDateTime)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetDateTime toBeanType(Object value) {
|
||||
if (value instanceof OffsetDateTime) return (OffsetDateTime) value;
|
||||
return convertFromTimestamp((Timestamp)value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.time.OffsetTime;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.OffsetTime stored as DB VARCHAR
|
||||
*/
|
||||
public class ScalarTypeOffsetTime extends ScalarTypeBaseVarchar<OffsetTime> {
|
||||
|
||||
public ScalarTypeOffsetTime() {
|
||||
super(OffsetTime.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(OffsetTime v) {
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetTime parse(String value) {
|
||||
return OffsetTime.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetTime convertFromDbString(String dbValue) {
|
||||
return OffsetTime.parse(dbValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToDbString(OffsetTime beanValue) {
|
||||
return beanValue.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class ScalarTypePostgresHstore extends ScalarTypeBase<Map> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map parseDateTime(long dateTime) {
|
||||
public Map convertFromMillis(long dateTime) {
|
||||
throw new RuntimeException("Should never be called");
|
||||
}
|
||||
|
||||
@@ -98,19 +98,28 @@ public class ScalarTypePostgresHstore extends ScalarTypeBase<Map> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
String json = dataInput.readUTF();
|
||||
return parse(json);
|
||||
public Map readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
String json = dataInput.readUTF();
|
||||
return parse(json);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
String json = format(v);
|
||||
dataOutput.writeUTF(json);
|
||||
public void writeData(DataOutput dataOutput, Map v) throws IOException {
|
||||
if (v == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
String json = format(v);
|
||||
dataOutput.writeUTF(json);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Map value) throws IOException {
|
||||
// write the field name followed by the Map/JSON Object
|
||||
if (value == null) {
|
||||
ctx.writeNullField(name);
|
||||
@@ -121,7 +130,7 @@ public class ScalarTypePostgresHstore extends ScalarTypeBase<Map> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Map jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
// at this point the BeanProperty has read the START_OBJECT token
|
||||
// to check for a null value. Pass the START_OBJECT token through to
|
||||
// the EJson parsing so that it knows the first token has been read
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ScalarTypeShort extends ScalarTypeBase<Short> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short parseDateTime(long systemTimeMillis) {
|
||||
public Short convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@@ -66,34 +66,32 @@ public class ScalarTypeShort extends ScalarTypeBase<Short> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Short readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
short val = dataInput.readShort();
|
||||
return Short.valueOf(val);
|
||||
return dataInput.readShort();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Short value) throws IOException {
|
||||
|
||||
Short value = (Short) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeShort(value.shortValue());
|
||||
dataOutput.writeShort(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Short jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getShortValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Short value) throws IOException {
|
||||
ctx.writeNumberField(name, (Short) value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ScalarTypeString extends ScalarTypeBase<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseDateTime(long systemTimeMillis) {
|
||||
public String convertFromMillis(long systemTimeMillis) {
|
||||
return String.valueOf(systemTimeMillis);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ScalarTypeString extends ScalarTypeBase<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public String readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -74,9 +74,8 @@ public class ScalarTypeString extends ScalarTypeBase<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, String value) throws IOException {
|
||||
|
||||
String value = (String) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
@@ -86,12 +85,12 @@ public class ScalarTypeString extends ScalarTypeBase<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public String jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return ctx.getValueAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, String value) throws IOException {
|
||||
ctx.writeStringField(name, (String) value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ScalarTypeTime extends ScalarTypeBase<Time> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time parseDateTime(long systemTimeMillis) {
|
||||
public Time convertFromMillis(long systemTimeMillis) {
|
||||
return new Time(systemTimeMillis);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ScalarTypeTime extends ScalarTypeBase<Time> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public Time readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -76,9 +76,8 @@ public class ScalarTypeTime extends ScalarTypeBase<Time> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, Time value) throws IOException {
|
||||
|
||||
Time value = (Time) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
@@ -88,12 +87,12 @@ public class ScalarTypeTime extends ScalarTypeBase<Time> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public Time jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return parse(ctx.getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Time value) throws IOException {
|
||||
ctx.writeStringField(name, format(value));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -11,13 +13,28 @@ import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
*/
|
||||
public class ScalarTypeTimestamp extends ScalarTypeBaseDateTime<Timestamp> {
|
||||
|
||||
public ScalarTypeTimestamp() {
|
||||
super(Timestamp.class, true, Types.TIMESTAMP);
|
||||
public ScalarTypeTimestamp(JsonConfig.DateTime mode) {
|
||||
super(mode, Timestamp.class, true, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((Timestamp) value).getTime();
|
||||
protected String toJsonNanos(Timestamp value) {
|
||||
return String.valueOf(value.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(Timestamp value) {
|
||||
return dateTimeParser.format(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Timestamp value) {
|
||||
return value.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertFromMillis(long systemTimeMillis) {
|
||||
return new Timestamp(systemTimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,6 +47,8 @@ public class ScalarTypeTimestamp extends ScalarTypeBaseDateTime<Timestamp> {
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void bind(DataBind b, Timestamp value) throws SQLException {
|
||||
if (value == null) {
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ScalarTypeUUIDBinary extends ScalarTypeBase<UUID> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID parseDateTime(long dateTime) {
|
||||
public UUID convertFromMillis(long dateTime) {
|
||||
throw new IllegalStateException("Never called");
|
||||
}
|
||||
|
||||
@@ -124,33 +124,32 @@ public class ScalarTypeUUIDBinary extends ScalarTypeBase<UUID> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
public UUID readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
return dataInput.readUTF();
|
||||
return parse(dataInput.readUTF());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
public void writeData(DataOutput dataOutput, UUID value) throws IOException {
|
||||
|
||||
String value = (String) v;
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeUTF(format(v));
|
||||
dataOutput.writeUTF(format(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
public UUID jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return UUID.fromString(ctx.getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) throws IOException {
|
||||
public void jsonWrite(JsonGenerator ctx, String name, UUID value) throws IOException {
|
||||
ctx.writeStringField(name, value.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.util.Date;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -12,92 +13,106 @@ import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
*/
|
||||
public class ScalarTypeUtilDate {
|
||||
|
||||
public static class TimestampType extends ScalarTypeBaseDateTime<java.util.Date> {
|
||||
public static class TimestampType extends ScalarTypeBaseDateTime<java.util.Date> {
|
||||
|
||||
public TimestampType() {
|
||||
super(java.util.Date.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return BasicTypeConverter.toTimestamp(value).getTime();
|
||||
public TimestampType(JsonConfig.DateTime mode) {
|
||||
super(mode, java.util.Date.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
public java.util.Date read(DataReader dataReader) throws SQLException {
|
||||
Timestamp timestamp = dataReader.getTimestamp();
|
||||
if (timestamp == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new java.util.Date(timestamp.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(DataBind b, java.util.Date value)
|
||||
throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.TIMESTAMP);
|
||||
} else {
|
||||
@Override
|
||||
protected String toJsonNanos(Date value) {
|
||||
return String.valueOf(value.getTime());
|
||||
}
|
||||
|
||||
Timestamp timestamp = new Timestamp(value.getTime());
|
||||
b.setTimestamp(timestamp);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected String toJsonISO8601(Date value) {
|
||||
return dateTimeParser.format(value);
|
||||
}
|
||||
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.toTimestamp(value);
|
||||
}
|
||||
@Override
|
||||
public long convertToMillis(Date value) {
|
||||
return value.getTime();
|
||||
}
|
||||
|
||||
public java.util.Date toBeanType(Object value) {
|
||||
return BasicTypeConverter.toUtilDate(value);
|
||||
}
|
||||
@Override
|
||||
public java.util.Date read(DataReader dataReader) throws SQLException {
|
||||
Timestamp timestamp = dataReader.getTimestamp();
|
||||
if (timestamp == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new java.util.Date(timestamp.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Date convertFromTimestamp(Timestamp ts) {
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
@Override
|
||||
public void bind(DataBind b, java.util.Date value)
|
||||
throws SQLException {
|
||||
if (value == null) {
|
||||
b.setNull(Types.TIMESTAMP);
|
||||
} else {
|
||||
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(Date t) {
|
||||
return new Timestamp(t.getTime());
|
||||
}
|
||||
Timestamp timestamp = new Timestamp(value.getTime());
|
||||
b.setTimestamp(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
public java.util.Date parseDateTime(long systemTimeMillis) {
|
||||
return new java.util.Date(systemTimeMillis);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.toTimestamp(value);
|
||||
}
|
||||
|
||||
public static class DateType extends ScalarTypeBaseDate<java.util.Date> {
|
||||
|
||||
public DateType() {
|
||||
super(Date.class, false, Types.DATE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
java.sql.Date date = BasicTypeConverter.toDate(value);
|
||||
return date.getTime();
|
||||
@Override
|
||||
public java.util.Date toBeanType(Object value) {
|
||||
return BasicTypeConverter.toUtilDate(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date convertFromDate(java.sql.Date ts) {
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
public Date convertFromTimestamp(Timestamp ts) {
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.sql.Date convertToDate(Date t) {
|
||||
return new java.sql.Date(t.getTime());
|
||||
}
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(Date t) {
|
||||
return new Timestamp(t.getTime());
|
||||
}
|
||||
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.toDate(value);
|
||||
}
|
||||
@Override
|
||||
public java.util.Date convertFromMillis(long systemTimeMillis) {
|
||||
return new java.util.Date(systemTimeMillis);
|
||||
}
|
||||
}
|
||||
|
||||
public java.util.Date toBeanType(Object value) {
|
||||
return BasicTypeConverter.toUtilDate(value);
|
||||
}
|
||||
}
|
||||
public static class DateType extends ScalarTypeBaseDate<java.util.Date> {
|
||||
|
||||
public DateType() {
|
||||
super(Date.class, false, Types.DATE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long convertToMillis(java.util.Date value) {
|
||||
return value.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date convertFromDate(java.sql.Date ts) {
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.sql.Date convertToDate(Date t) {
|
||||
return new java.sql.Date(t.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
return BasicTypeConverter.toDate(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.Date toBeanType(Object value) {
|
||||
return BasicTypeConverter.toUtilDate(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,16 +57,16 @@ public class ScalarTypeWrapper<B, S> implements ScalarType<B> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
Object v = scalarType.readData(dataInput);
|
||||
return converter.wrapValue((S) v);
|
||||
public B readData(DataInput dataInput) throws IOException {
|
||||
S unwrapValue = scalarType.readData(dataInput);
|
||||
return converter.wrapValue(unwrapValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException {
|
||||
S sv = converter.unwrapValue((B) v);
|
||||
scalarType.writeData(dataOutput, sv);
|
||||
public void writeData(DataOutput dataOutput, B value) throws IOException {
|
||||
S unwrapValue = converter.unwrapValue(value);
|
||||
scalarType.writeData(dataOutput, unwrapValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,8 +126,8 @@ public class ScalarTypeWrapper<B, S> implements ScalarType<B> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public B parseDateTime(long systemTimeMillis) {
|
||||
S sv = scalarType.parseDateTime(systemTimeMillis);
|
||||
public B convertFromMillis(long systemTimeMillis) {
|
||||
S sv = scalarType.convertFromMillis(systemTimeMillis);
|
||||
if (sv == null) {
|
||||
return nullValue;
|
||||
}
|
||||
@@ -185,17 +185,15 @@ public class ScalarTypeWrapper<B, S> implements ScalarType<B> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
Object object = scalarType.jsonRead(ctx, event);
|
||||
return converter.wrapValue((S) object);
|
||||
public B jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
S object = scalarType.jsonRead(ctx, event);
|
||||
return converter.wrapValue(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object beanValue) throws IOException {
|
||||
@SuppressWarnings("unchecked")
|
||||
S unwrapValue = converter.unwrapValue((B) beanValue);
|
||||
public void jsonWrite(JsonGenerator ctx, String name, B beanValue) throws IOException {
|
||||
S unwrapValue = converter.unwrapValue(beanValue);
|
||||
scalarType.jsonWrite(ctx, name, unwrapValue);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.Year;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.Year
|
||||
*/
|
||||
public class ScalarTypeYear extends ScalarTypeBase<Year> {
|
||||
|
||||
public ScalarTypeYear() {
|
||||
super(Year.class, true, Types.INTEGER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBind bind, Year value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.INTEGER);
|
||||
} else {
|
||||
bind.setInt(value.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Year read(DataReader dataReader) throws SQLException {
|
||||
Integer value = dataReader.getInt();
|
||||
return (value == null) ? null : Year.of(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Year readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
return Year.of(dataInput.readInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Year value) throws IOException {
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeInt(value.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Year) return ((Year)value).getValue();
|
||||
return BasicTypeConverter.toInteger(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Year toBeanType(Object value) {
|
||||
if (value instanceof Year) return (Year) value;
|
||||
return Year.of(BasicTypeConverter.toInteger(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(Year v) {
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Year parse(String value) {
|
||||
return Year.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTimeCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Year convertFromMillis(long systemTimeMillis) {
|
||||
throw new TextException("Not Supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Year jsonRead(JsonParser ctx, JsonToken event) throws IOException {
|
||||
return Year.of(ctx.getIntValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Year value) throws IOException {
|
||||
ctx.writeNumberField(name, value.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.YearMonth;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.LocalDate. This maps to a JDBC Date.
|
||||
*/
|
||||
public class ScalarTypeYearMonthDate extends ScalarTypeBaseDate<YearMonth> {
|
||||
|
||||
public ScalarTypeYearMonthDate() {
|
||||
super(YearMonth.class, false, Types.DATE);
|
||||
}
|
||||
|
||||
protected LocalDate toLocalDate(YearMonth yearMonth) {
|
||||
return LocalDate.of(yearMonth.getYear(), yearMonth.getMonth(), 1);
|
||||
}
|
||||
|
||||
protected YearMonth fromLocalDate(LocalDate localDate) {
|
||||
return YearMonth.of(localDate.getYear(), localDate.getMonth());
|
||||
}
|
||||
|
||||
@Override
|
||||
public YearMonth convertFromMillis(long systemTimeMillis) {
|
||||
return fromLocalDate(new Timestamp(systemTimeMillis).toLocalDateTime().toLocalDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(YearMonth value) {
|
||||
LocalDate localDate = toLocalDate(value);
|
||||
ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
|
||||
return zonedDateTime.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public YearMonth convertFromDate(Date ts) {
|
||||
return fromLocalDate(ts.toLocalDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date convertToDate(YearMonth t) {
|
||||
return Date.valueOf(toLocalDate(t));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Date) return value;
|
||||
if (value instanceof YearMonth) return Date.valueOf(toLocalDate((YearMonth) value));
|
||||
if (value instanceof LocalDate) return Date.valueOf((LocalDate)value);
|
||||
return BasicTypeConverter.toDate(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YearMonth toBeanType(Object value) {
|
||||
if (value instanceof YearMonth) return (YearMonth) value;
|
||||
if (value instanceof LocalDate) return fromLocalDate((LocalDate) value);
|
||||
return fromLocalDate(BasicTypeConverter.toDate(value).toLocalDate());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.time.OffsetTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.OffsetTime stored as DB VARCHAR
|
||||
*/
|
||||
public class ScalarTypeZoneId extends ScalarTypeBaseVarchar<ZoneId> {
|
||||
|
||||
public ScalarTypeZoneId() {
|
||||
super(ZoneId.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(ZoneId v) {
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZoneId parse(String value) {
|
||||
return ZoneId.of(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZoneId convertFromDbString(String dbValue) {
|
||||
return ZoneId.of(dbValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToDbString(ZoneId beanValue) {
|
||||
return beanValue.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
/**
|
||||
* ScalarType for java.time.OffsetTime stored as DB VARCHAR
|
||||
*/
|
||||
public class ScalarTypeZoneOffset extends ScalarTypeBaseVarchar<ZoneOffset> {
|
||||
|
||||
public ScalarTypeZoneOffset() {
|
||||
super(ZoneOffset.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(ZoneOffset v) {
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZoneOffset parse(String value) {
|
||||
return ZoneOffset.of(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZoneOffset convertFromDbString(String dbValue) {
|
||||
return ZoneOffset.of(dbValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToDbString(ZoneOffset beanValue) {
|
||||
return beanValue.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* ScalarType for ZonedDateTime.
|
||||
*/
|
||||
public class ScalarTypeZonedDateTime extends ScalarTypeBaseDateTime<ZonedDateTime> {
|
||||
|
||||
public ScalarTypeZonedDateTime(JsonConfig.DateTime mode) {
|
||||
super(mode, ZonedDateTime.class, true, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonNanos(ZonedDateTime value) {
|
||||
return toJsonNanos(value.toEpochSecond(), value.getNano());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJsonISO8601(ZonedDateTime value) {
|
||||
return value.toInstant().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(ZonedDateTime value) {
|
||||
return value.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZonedDateTime convertFromMillis(long systemTimeMillis) {
|
||||
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(systemTimeMillis), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZonedDateTime convertFromTimestamp(Timestamp ts) {
|
||||
return ZonedDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(ZonedDateTime t) {
|
||||
return Timestamp.from(t.toInstant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toJdbcType(Object value) {
|
||||
if (value instanceof Timestamp) return value;
|
||||
return convertToTimestamp((ZonedDateTime)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZonedDateTime toBeanType(Object value) {
|
||||
if (value instanceof ZonedDateTime) return (ZonedDateTime) value;
|
||||
return convertFromTimestamp((Timestamp)value);
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.avaje.ebean.Expression;
|
||||
import com.avaje.ebean.ExpressionFactory;
|
||||
import com.avaje.ebean.ExpressionList;
|
||||
import com.avaje.ebean.FutureIds;
|
||||
import com.avaje.ebean.FutureList;
|
||||
import com.avaje.ebean.FutureRowCount;
|
||||
import com.avaje.ebean.Junction;
|
||||
import com.avaje.ebean.OrderBy;
|
||||
import com.avaje.ebean.PagedList;
|
||||
import com.avaje.ebean.PagingList;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.QueryIterator;
|
||||
import com.avaje.ebean.QueryResultVisitor;
|
||||
import com.avaje.ebean.*;
|
||||
import com.avaje.ebean.event.BeanQueryRequest;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
@@ -172,6 +160,16 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.findIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEach(QueryEachConsumer<T> consumer) {
|
||||
query.findEach(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEachWhile(QueryEachWhileConsumer<T> consumer) {
|
||||
query.findEachWhile(consumer);
|
||||
}
|
||||
|
||||
public void findVisit(QueryResultVisitor<T> visitor) {
|
||||
query.findVisit(visitor);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ Export-Package: com.avaje.ebean,
|
||||
com.avaje.ebeaninternal.server.persist.dmlbind,
|
||||
com.avaje.ebeaninternal.server.query,
|
||||
com.avaje.ebeaninternal.server.querydefn,
|
||||
com.avaje.ebeaninternal.server.reflect,
|
||||
com.avaje.ebeaninternal.server.properties,
|
||||
com.avaje.ebeaninternal.server.resource,
|
||||
com.avaje.ebeaninternal.server.text.csv,
|
||||
com.avaje.ebeaninternal.server.text.json,
|
||||
|
||||
@@ -19,11 +19,7 @@ public class ConvertInetAddressTest {
|
||||
String uriAddr6 = ConvertInetAddresses.toUriString(addr6);
|
||||
Assert.assertEquals("["+ip6addr+"]", uriAddr6);
|
||||
Assert.assertEquals(ip6addr, addr6.getHostAddress());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void toUriString() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user