Merge branch 'master' into i723

Conflicts:
	querydsl-root/pom.xml
This commit is contained in:
Timo Westkämper 2014-05-03 20:45:27 +03:00
commit 644dc47868
58 changed files with 1212 additions and 1294 deletions

View File

@ -1,6 +1,5 @@
language: java
jdk:
- oraclejdk8
- oraclejdk7
services:
- mongodb

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>
@ -225,4 +225,4 @@
</repository>
</repositories>
</project>
</project>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -14,6 +14,7 @@
package com.mysema.query.codegen;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;
import javax.annotation.Nullable;
@ -38,11 +39,14 @@ public abstract class TypeMappings {
private final Map<String, Type> queryTypes = new HashMap<String, Type>();
private final Map<TypeCategory, Type> exprTypes = new HashMap<TypeCategory, Type>();
private final Map<TypeCategory, Type> exprTypes
= new EnumMap<TypeCategory, Type>(TypeCategory.class);
private final Map<TypeCategory, Type> pathTypes = new HashMap<TypeCategory, Type>();
private final Map<TypeCategory, Type> pathTypes
= new EnumMap<TypeCategory, Type>(TypeCategory.class);
private final Map<TypeCategory, Type> templateTypes = new HashMap<TypeCategory, Type>();
private final Map<TypeCategory, Type> templateTypes
= new EnumMap<TypeCategory, Type>(TypeCategory.class);
public Type getTemplateType(Type type, EntityType model, boolean raw) {
return getTemplateType(type, model, raw, false, false);

View File

@ -13,19 +13,20 @@
*/
package com.mysema.query.codegen;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.StringWriter;
import java.sql.Time;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;
import com.mysema.codegen.JavaWriter;
import com.mysema.codegen.model.*;
import com.mysema.query.annotations.PropertyType;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class EmbeddableSerializerTest {
@ -57,7 +58,8 @@ public class EmbeddableSerializerTest {
@Test
public void OriginalCategory() throws IOException{
Map<TypeCategory, String> categoryToSuperClass = new HashMap<TypeCategory, String>();
Map<TypeCategory, String> categoryToSuperClass
= new EnumMap<TypeCategory, String>(TypeCategory.class);
categoryToSuperClass.put(TypeCategory.COMPARABLE, "ComparablePath<Entity>");
categoryToSuperClass.put(TypeCategory.ENUM, "EnumPath<Entity>");
categoryToSuperClass.put(TypeCategory.DATE, "DatePath<Entity>");

View File

@ -20,7 +20,7 @@ import java.io.StringWriter;
import java.sql.Time;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;
import org.junit.Test;
@ -69,7 +69,6 @@ public class EntitySerializerTest {
"extends EntityPathBase<EntitySerializerTest.Entity>"));
}
@Test
public void No_Package() throws IOException {
SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false);
@ -82,7 +81,8 @@ public class EntitySerializerTest {
@Test
public void OriginalCategory() throws IOException{
Map<TypeCategory, String> categoryToSuperClass = new HashMap<TypeCategory, String>();
Map<TypeCategory, String> categoryToSuperClass
= new EnumMap<TypeCategory, String>(TypeCategory.class);
categoryToSuperClass.put(TypeCategory.COMPARABLE, "ComparablePath<Entity>");
categoryToSuperClass.put(TypeCategory.ENUM, "EnumPath<Entity>");
categoryToSuperClass.put(TypeCategory.DATE, "DatePath<Entity>");

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -259,6 +259,11 @@ public final class CaseBuilder {
return thenDate(ConstantImpl.create(date));
}
@Deprecated
public Cases<java.sql.Date, DateExpression<java.sql.Date>> thenDate(java.sql.Date date) {
return then(date);
}
// DateTime
public <T extends Comparable> Cases<T, DateTimeExpression<T>> then(DateTimeExpression<T> expr) {
@ -279,10 +284,20 @@ public final class CaseBuilder {
return thenDateTime(ConstantImpl.create(ts));
}
@Deprecated
public Cases<Timestamp, DateTimeExpression<Timestamp>> thenDateTime(Timestamp ts) {
return then(ts);
}
public Cases<java.util.Date, DateTimeExpression<java.util.Date>> then(java.util.Date date) {
return thenDateTime(ConstantImpl.create(date));
}
@Deprecated
public Cases<java.util.Date, DateTimeExpression<java.util.Date>> thenDateTime(java.util.Date date) {
return then(date);
}
// Enum
public <T extends Enum<T>> Cases<T,EnumExpression<T>> then(EnumExpression<T> expr) {

View File

@ -13,24 +13,28 @@
*/
package com.mysema.testutil;
import com.google.common.base.Stopwatch;
public final class Runner {
private static final int WARMUP = 50000;
private static final int BENCHMARK = 1000000;
public static void run(String label, Benchmark benchmark) throws Exception {
// warmup
benchmark.run(50000);
benchmark.run(WARMUP);
System.err.print("- ");
// run garbage collection
System.gc();
System.err.print("- ");
// perform timing
long start = System.nanoTime();
benchmark.run(1000000);
long end = System.nanoTime();
System.err.println(label + " " + ((end-start) / 1000000));
Stopwatch stopwatch = new Stopwatch().start();
benchmark.run(BENCHMARK);
System.err.println(label + " " + stopwatch.stop().toString());
}
private Runner() {}
}

View File

@ -1,6 +1,6 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY versionNumber "3.3.2">
<!ENTITY versionNumber "3.3.3">
<!ENTITY copyrightYear "2007-2014">
<!ENTITY copyrightHolder "Mysema Ltd.">
]>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>
@ -282,4 +282,4 @@
</pluginRepository>
</pluginRepositories>
</project>
</project>

View File

@ -14,36 +14,27 @@
package com.mysema.query.jdo.sql;
import javax.annotation.Nullable;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.mysema.query.JoinFlag;
import com.mysema.query.QueryFlag;
import com.mysema.query.QueryFlag.Position;
import com.mysema.query.QueryMetadata;
import com.google.common.collect.Lists;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.commons.lang.IteratorAdapter;
import com.mysema.query.*;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.ForeignKey;
import com.mysema.query.sql.RelationalFunctionCall;
import com.mysema.query.sql.RelationalPath;
import com.mysema.query.sql.SQLCommonQuery;
import com.mysema.query.sql.SQLOps;
import com.mysema.query.sql.SQLTemplates;
import com.mysema.query.sql.Union;
import com.mysema.query.sql.UnionImpl;
import com.mysema.query.sql.UnionUtils;
import com.mysema.query.sql.WithBuilder;
import com.mysema.query.support.Expressions;
import com.mysema.query.support.ProjectableQuery;
import com.mysema.query.sql.ProjectableSQLQuery;
import com.mysema.query.sql.SQLSerializer;
import com.mysema.query.support.QueryMixin;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Expression;
import com.mysema.query.types.ExpressionUtils;
import com.mysema.query.types.OperationImpl;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.SubQueryExpression;
import com.mysema.query.types.expr.Wildcard;
import com.mysema.query.types.query.ListSubQuery;
import com.mysema.query.types.template.NumberTemplate;
import com.mysema.query.types.template.SimpleTemplate;
import com.mysema.query.types.FactoryExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for JDO based SQLQuery implementations
@ -53,7 +44,29 @@ import com.mysema.query.types.template.SimpleTemplate;
* @param <T>
*/
@SuppressWarnings("rawtypes")
public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T> & com.mysema.query.Query<T>> extends ProjectableQuery<T> implements SQLCommonQuery<T> {
public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T>> extends ProjectableSQLQuery<T> {
private static final Logger logger = LoggerFactory.getLogger(JDOSQLQuery.class);
private final Closeable closeable = new Closeable() {
@Override
public void close() throws IOException {
AbstractSQLQuery.this.close();
}
};
protected final boolean detach;
private List<Object> orderedConstants = new ArrayList<Object>();
@Nullable
protected final PersistenceManager persistenceManager;
protected List<Query> queries = new ArrayList<Query>(2);
@Nullable
protected FactoryExpression<?> projection;
protected final QueryMixin<T> queryMixin;
@ -62,261 +75,213 @@ public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T> & com.mysem
protected boolean unionAll;
protected final Configuration configuration;
@SuppressWarnings("unchecked")
public AbstractSQLQuery(QueryMetadata metadata, Configuration conf) {
super(new QueryMixin<T>(metadata, false));
this.configuration = conf;
public AbstractSQLQuery(QueryMetadata metadata, Configuration conf, PersistenceManager persistenceManager,
boolean detach) {
super(new QueryMixin<T>(metadata, false), conf);
this.queryMixin = super.queryMixin;
this.queryMixin.setSelf((T)this);
this.persistenceManager = persistenceManager;
this.detach = detach;
}
public void close() {
for (Query query : queries) {
query.closeAll();
}
}
@Override
public long count() {
return uniqueResult(Wildcard.countAsInt);
Query query = createQuery(true);
query.setUnique(true);
reset();
Long rv = (Long) execute(query, true);
if (rv != null) {
return rv.longValue();
} else {
throw new QueryException("Query returned null");
}
}
@Override
public boolean exists() {
return limit(1).uniqueResult(NumberTemplate.ONE) != null;
private Query createQuery(boolean forCount) {
SQLSerializer serializer = new SQLSerializer(configuration);
if (union != null) {
serializer.serializeUnion(union, queryMixin.getMetadata(), unionAll);
} else {
serializer.serialize(queryMixin.getMetadata(), forCount);
}
// create Query
if (logger.isDebugEnabled()) {
logger.debug(serializer.toString());
}
Query query = persistenceManager.newQuery("javax.jdo.query.SQL",serializer.toString());
orderedConstants = serializer.getConstants();
queries.add(query);
if (!forCount) {
List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection();
if (projection.get(0) instanceof FactoryExpression) {
this.projection = (FactoryExpression<?>)projection.get(0);
}
} else {
query.setResultClass(Long.class);
}
return query;
}
public T from(Expression<?> arg) {
return queryMixin.from(arg);
}
@Override
public T from(Expression<?>... args) {
return queryMixin.from(args);
}
@Override
@SuppressWarnings("unchecked")
public T from(SubQueryExpression<?> subQuery, Path<?> alias) {
return queryMixin.from(ExpressionUtils.as((Expression) subQuery, alias));
private <T> T detach(T results) {
if (results instanceof Collection) {
return (T) persistenceManager.detachCopyAll(results);
} else {
return persistenceManager.detachCopy(results);
}
}
private Object project(FactoryExpression<?> expr, Object row) {
if (row == null) {
return null;
} else if (row.getClass().isArray()) {
return expr.newInstance((Object[])row);
} else {
return expr.newInstance(new Object[]{row});
}
}
private Object execute(Query query, boolean forCount) {
Object rv;
if (!orderedConstants.isEmpty()) {
rv = query.executeWithArray(orderedConstants.toArray());
} else {
rv = query.execute();
}
if (isDetach()) {
rv = detach(rv);
}
if (projection != null && !forCount) {
if (rv instanceof List) {
List<?> original = (List<?>)rv;
rv = Lists.newArrayList();
for (Object o : original) {
((List)rv).add(project(projection, o));
}
} else {
rv = project(projection, rv);
}
}
return rv;
}
@Override
public T fullJoin(EntityPath<?> o) {
return queryMixin.fullJoin(o);
}
@Override
public <E> T fullJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.fullJoin(target, alias);
}
@Override
public <E> T fullJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.fullJoin(entity).on(key.on(entity));
}
@Override
public T fullJoin(SubQueryExpression<?> o, Path<?> alias) {
return queryMixin.fullJoin(o, alias);
}
public QueryMetadata getMetadata() {
return queryMixin.getMetadata();
}
@Override
public T innerJoin(EntityPath<?> o) {
return queryMixin.innerJoin(o);
public boolean isDetach() {
return detach;
}
@Override
public <E> T innerJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.innerJoin(target, alias);
public CloseableIterator<Tuple> iterate(Expression<?>... args) {
return iterate(queryMixin.createProjection(args));
}
@Override
public <E> T innerJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.innerJoin(entity).on(key.on(entity));
public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) {
return new IteratorAdapter<RT>(list(projection).iterator(), closeable);
}
@Override
public T innerJoin(SubQueryExpression<?> o, Path<?> alias) {
return queryMixin.innerJoin(o, alias);
}
@Override
public T join(EntityPath<?> o) {
return queryMixin.join(o);
}
@Override
public <E> T join(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.join(target, alias);
}
@Override
public <E> T join(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.join(entity).on(key.on(entity));
}
@Override
public T join(SubQueryExpression<?> o, Path<?> alias) {
return queryMixin.join(o, alias);
}
@Override
public T leftJoin(EntityPath<?> o) {
return queryMixin.leftJoin(o);
}
@Override
public <E> T leftJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.leftJoin(target, alias);
}
@Override
public <E> T leftJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.leftJoin(entity).on(key.on(entity));
}
@Override
public T leftJoin(SubQueryExpression<?> o, Path<?> alias) {
return queryMixin.leftJoin(o, alias);
}
public T on(Predicate condition) {
return queryMixin.on(condition);
}
@Override
public T on(Predicate... conditions) {
return queryMixin.on(conditions);
}
@Override
public T rightJoin(EntityPath<?> o) {
return queryMixin.rightJoin(o);
}
@Override
public <E> T rightJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.rightJoin(target, alias);
}
@Override
public <E> T rightJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.rightJoin(entity).on(key.on(entity));
}
@Override
public T rightJoin(SubQueryExpression<?> o, Path<?> alias) {
return queryMixin.rightJoin(o, alias);
}
@Override
public T addJoinFlag(String flag) {
return addJoinFlag(flag, JoinFlag.Position.BEFORE_TARGET);
public List<Tuple> list(Expression<?>... args) {
return list(queryMixin.createProjection(args));
}
@Override
@SuppressWarnings("unchecked")
public T addJoinFlag(String flag, JoinFlag.Position position) {
queryMixin.addJoinFlag(new JoinFlag(flag, position));
return (T)this;
public <RT> List<RT> list(Expression<RT> expr) {
queryMixin.addProjection(expr);
Object rv = execute(createQuery(false), false);
reset();
return rv instanceof List ? (List<RT>)rv : Collections.singletonList((RT) rv);
}
@Override
public T addFlag(Position position, String prefix, Expression<?> expr) {
Expression<?> flag = SimpleTemplate.create(expr.getType(), prefix + "{0}", expr);
return queryMixin.addFlag(new QueryFlag(position, flag));
public SearchResults<Tuple> listResults(Expression<?>... args) {
return listResults(queryMixin.createProjection(args));
}
@Override
public T addFlag(Position position, String flag) {
return queryMixin.addFlag(new QueryFlag(position, flag));
}
@Override
public T addFlag(Position position, Expression<?> flag) {
return queryMixin.addFlag(new QueryFlag(position, flag));
}
public <RT> Union<RT> union(ListSubQuery<RT>... sq) {
return innerUnion(sq);
}
public <RT> Union<RT> union(SubQueryExpression<RT>... sq) {
return innerUnion(sq);
}
public <RT> Union<RT> unionAll(ListSubQuery<RT>... sq) {
unionAll = true;
return innerUnion(sq);
}
public <RT> Union<RT> unionAll(SubQueryExpression<RT>... sq) {
unionAll = true;
return innerUnion(sq);
}
public <RT> T union(Path<?> alias, ListSubQuery<RT>... sq) {
return from(UnionUtils.union(sq, alias, false));
}
public <RT> T union(Path<?> alias, SubQueryExpression<RT>... sq) {
return from(UnionUtils.union(sq, alias, false));
}
public <RT> T unionAll(Path<?> alias, ListSubQuery<RT>... sq) {
return from(UnionUtils.union(sq, alias, true));
}
public <RT> T unionAll(Path<?> alias, SubQueryExpression<RT>... sq) {
return from(UnionUtils.union(sq, alias, true));
}
@Override
public T withRecursive(Path<?> alias, SubQueryExpression<?> query) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, query);
}
@Override
public T withRecursive(Path<?> alias, Expression<?> query) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, query);
}
@Override
public WithBuilder<T> withRecursive(Path<?> alias, Path<?>... columns) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, columns);
}
@Override
public T with(Path<?> alias, SubQueryExpression<?> query) {
Expression<?> expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query);
return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr));
}
@Override
public T with(Path<?> alias, Expression<?> query) {
Expression<?> expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query);
return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr));
}
@Override
public WithBuilder<T> with(Path<?> alias, Path<?>... columns) {
Expression<?> columnsCombined = ExpressionUtils.list(Object.class, columns);
Expression<?> aliasCombined = Expressions.operation(alias.getType(), SQLOps.WITH_COLUMNS, alias, columnsCombined);
return new WithBuilder<T>(queryMixin, aliasCombined);
}
@SuppressWarnings("unchecked")
private <RT> Union<RT> innerUnion(SubQueryExpression<?>... sq) {
queryMixin.getMetadata().setValidate(false);
if (!queryMixin.getMetadata().getJoins().isEmpty()) {
throw new IllegalArgumentException("Don't mix union and from");
public <RT> SearchResults<RT> listResults(Expression<RT> expr) {
queryMixin.addProjection(expr);
Query countQuery = createQuery(true);
countQuery.setUnique(true);
long total = (Long) execute(countQuery, true);
if (total > 0) {
QueryModifiers modifiers = queryMixin.getMetadata().getModifiers();
Query query = createQuery(false);
reset();
return new SearchResults<RT>((List<RT>) execute(query, false), modifiers, total);
} else {
reset();
return SearchResults.emptyResults();
}
this.union = UnionUtils.union(sq, unionAll);
return new UnionImpl<T, RT>((T)this, sq[0].getMetadata().getProjection());
}
private void reset() {
queryMixin.getMetadata().reset();
}
@Override
public String toString() {
if (!queryMixin.getMetadata().getJoins().isEmpty()) {
SQLSerializer serializer = new SQLSerializer(configuration);
serializer.serialize(queryMixin.getMetadata(), false);
return serializer.toString().trim();
} else {
return super.toString();
}
}
@Override
@Nullable
public Tuple uniqueResult(Expression<?>... args) {
return uniqueResult(queryMixin.createProjection(args));
}
@Override
@SuppressWarnings("unchecked")
@Nullable
public <RT> RT uniqueResult(Expression<RT> expr) {
queryMixin.addProjection(expr);
return (RT)uniqueResult();
}
@Nullable
private Object uniqueResult() {
if (getMetadata().getModifiers().getLimit() == null) {
limit(2);
}
Query query = createQuery(false);
reset();
Object rv = execute(query, false);
if (rv instanceof List) {
List<?> list = (List<?>)rv;
if (!list.isEmpty()) {
if (list.size() > 1) {
throw new NonUniqueResultException();
}
return list.get(0);
} else {
return null;
}
} else {
return rv;
}
}
}

View File

@ -13,35 +13,14 @@
*/
package com.mysema.query.jdo.sql;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.commons.lang.IteratorAdapter;
import com.mysema.query.DefaultQueryMetadata;
import com.mysema.query.NonUniqueResultException;
import com.mysema.query.QueryException;
import com.mysema.query.QueryMetadata;
import com.mysema.query.QueryModifiers;
import com.mysema.query.SearchResults;
import com.mysema.query.Tuple;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.SQLSerializer;
import com.mysema.query.sql.SQLTemplates;
import com.mysema.query.types.Expression;
import com.mysema.query.types.FactoryExpression;
import javax.annotation.Nullable;
import javax.jdo.PersistenceManager;
/**
* JDOSQLQuery is an SQLQuery implementation that uses JDO's SQL query functionality
@ -52,28 +31,6 @@ import com.mysema.query.types.FactoryExpression;
*/
public final class JDOSQLQuery extends AbstractSQLQuery<JDOSQLQuery> {
private static final Logger logger = LoggerFactory.getLogger(JDOSQLQuery.class);
private final Closeable closeable = new Closeable() {
@Override
public void close() throws IOException {
JDOSQLQuery.this.close();
}
};
private final boolean detach;
private List<Object> orderedConstants = new ArrayList<Object>();
@Nullable
private final PersistenceManager persistenceManager;
private List<Query> queries = new ArrayList<Query>(2);
@Nullable
private FactoryExpression<?> projection;
public JDOSQLQuery(@Nullable PersistenceManager persistenceManager, SQLTemplates templates) {
this(persistenceManager, new Configuration(templates), new DefaultQueryMetadata().noValidate(), false);
}
@ -86,210 +43,18 @@ public final class JDOSQLQuery extends AbstractSQLQuery<JDOSQLQuery> {
@Nullable PersistenceManager persistenceManager,
Configuration configuration,
QueryMetadata metadata, boolean detach) {
super(metadata, configuration);
this.persistenceManager = persistenceManager;
this.detach = detach;
}
public void close() {
for (Query query : queries) {
query.closeAll();
}
super(metadata, configuration, persistenceManager, detach);
}
@Override
public long count() {
Query query = createQuery(true);
query.setUnique(true);
reset();
Long rv = (Long) execute(query, true);
if (rv != null) {
return rv.longValue();
} else {
throw new QueryException("Query returned null");
}
}
private Query createQuery(boolean forCount) {
SQLSerializer serializer = new SQLSerializer(configuration);
if (union != null) {
serializer.serializeUnion(union, queryMixin.getMetadata(), unionAll);
} else {
serializer.serialize(queryMixin.getMetadata(), forCount);
}
// create Query
if (logger.isDebugEnabled()) {
logger.debug(serializer.toString());
}
Query query = persistenceManager.newQuery("javax.jdo.query.SQL",serializer.toString());
orderedConstants = serializer.getConstants();
queries.add(query);
if (!forCount) {
List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection();
if (projection.get(0) instanceof FactoryExpression) {
this.projection = (FactoryExpression<?>)projection.get(0);
}
} else {
query.setResultClass(Long.class);
}
public JDOSQLQuery clone() {
JDOSQLQuery query = new JDOSQLQuery(persistenceManager, configuration, getMetadata().clone(), detach);
query.clone(this);
return query;
}
@SuppressWarnings("unchecked")
private <T> T detach(T results) {
if (results instanceof Collection) {
return (T) persistenceManager.detachCopyAll(results);
} else {
return persistenceManager.detachCopy(results);
}
}
private Object project(FactoryExpression<?> expr, Object row) {
if (row == null) {
return null;
} else if (row.getClass().isArray()) {
return expr.newInstance((Object[])row);
} else {
return expr.newInstance(new Object[]{row});
}
}
private Object execute(Query query, boolean forCount) {
Object rv;
if (!orderedConstants.isEmpty()) {
rv = query.executeWithArray(orderedConstants.toArray());
} else {
rv = query.execute();
}
if (isDetach()) {
rv = detach(rv);
}
if (projection != null && !forCount) {
if (rv instanceof List) {
List<?> original = (List<?>)rv;
rv = Lists.newArrayList();
for (Object o : original) {
((List)rv).add(project(projection, o));
}
} else {
rv = project(projection, rv);
}
}
return rv;
}
@Override
public QueryMetadata getMetadata() {
return queryMixin.getMetadata();
protected SQLSerializer createSerializer() {
return new SQLSerializer(configuration);
}
public boolean isDetach() {
return detach;
}
@Override
public CloseableIterator<Tuple> iterate(Expression<?>... args) {
return iterate(queryMixin.createProjection(args));
}
@Override
public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) {
return new IteratorAdapter<RT>(list(projection).iterator(), closeable);
}
@Override
public List<Tuple> list(Expression<?>... args) {
return list(queryMixin.createProjection(args));
}
@Override
@SuppressWarnings("unchecked")
public <RT> List<RT> list(Expression<RT> expr) {
queryMixin.addProjection(expr);
Object rv = execute(createQuery(false), false);
reset();
return rv instanceof List ? (List<RT>)rv : Collections.singletonList((RT)rv);
}
@Override
public SearchResults<Tuple> listResults(Expression<?>... args) {
return listResults(queryMixin.createProjection(args));
}
@Override
@SuppressWarnings("unchecked")
public <RT> SearchResults<RT> listResults(Expression<RT> expr) {
queryMixin.addProjection(expr);
Query countQuery = createQuery(true);
countQuery.setUnique(true);
long total = (Long) execute(countQuery, true);
if (total > 0) {
QueryModifiers modifiers = queryMixin.getMetadata().getModifiers();
Query query = createQuery(false);
reset();
return new SearchResults<RT>((List<RT>) execute(query, false), modifiers, total);
} else {
reset();
return SearchResults.emptyResults();
}
}
private void reset() {
queryMixin.getMetadata().reset();
}
@Override
public String toString() {
if (!queryMixin.getMetadata().getJoins().isEmpty()) {
SQLSerializer serializer = new SQLSerializer(configuration);
serializer.serialize(queryMixin.getMetadata(), false);
return serializer.toString().trim();
} else {
return super.toString();
}
}
@Override
@Nullable
public Tuple uniqueResult(Expression<?>... args) {
return uniqueResult(queryMixin.createProjection(args));
}
@Override
@SuppressWarnings("unchecked")
@Nullable
public <RT> RT uniqueResult(Expression<RT> expr) {
queryMixin.addProjection(expr);
return (RT)uniqueResult();
}
@Nullable
private Object uniqueResult() {
if (getMetadata().getModifiers().getLimit() == null) {
limit(2);
}
Query query = createQuery(false);
reset();
Object rv = execute(query, false);
if (rv instanceof List) {
List<?> list = (List<?>)rv;
if (!list.isEmpty()) {
if (list.size() > 1) {
throw new NonUniqueResultException();
}
return list.get(0);
} else {
return null;
}
} else {
return rv;
}
}
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>
@ -350,4 +350,4 @@
</profile>
</profiles>
</project>
</project>

View File

@ -50,11 +50,11 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends Pr
this.queryMixin.setSelf((Q) this);
}
protected static boolean isEntityExpression(Expression<?> expr) {
protected boolean isEntityExpression(Expression<?> expr) {
return expr instanceof EntityPath || expr.getType().isAnnotationPresent(Entity.class);
}
protected static Expression<?> extractEntityExpression(Expression<?> expr) {
protected Expression<?> extractEntityExpression(Expression<?> expr) {
if (expr instanceof Operation) {
return ((Operation<?>)expr).getArg(0);
} else if (expr instanceof TemplateExpression) {

View File

@ -15,7 +15,7 @@ package com.mysema.query.jpa;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -98,7 +98,7 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
private static final String ON = " on ";
private static final Map<JoinType, String> joinTypes = new HashMap<JoinType, String>();
private static final Map<JoinType, String> joinTypes = new EnumMap<JoinType, String>(JoinType.class);
private final JPQLTemplates templates;

View File

@ -13,6 +13,10 @@
*/
package com.mysema.query.jpa.hibernate.sql;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.query.*;
import com.mysema.query.NonUniqueResultException;
@ -33,10 +37,6 @@ import org.hibernate.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
/**
* AbstractHibernateSQLQuery is the base class for Hibernate Native SQL queries
*
@ -44,7 +44,7 @@ import java.util.Map;
*
* @param <Q>
*/
public abstract class AbstractHibernateSQLQuery<Q extends AbstractHibernateSQLQuery<Q> & com.mysema.query.Query<Q>> extends AbstractSQLQuery<Q> {
public abstract class AbstractHibernateSQLQuery<Q extends AbstractHibernateSQLQuery<Q>> extends AbstractSQLQuery<Q> {
private static final Logger logger = LoggerFactory.getLogger(AbstractHibernateSQLQuery.class);

View File

@ -13,14 +13,12 @@
*/
package com.mysema.query.jpa.hibernate.sql;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import com.mysema.query.QueryMetadata;
import com.mysema.query.jpa.hibernate.SessionHolder;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.SQLCommonQuery;
import com.mysema.query.sql.SQLTemplates;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
/**
* HibernateSQLQuery is an SQLQuery implementation that uses Hibernate's Native SQL functionality
@ -29,7 +27,7 @@ import com.mysema.query.sql.SQLTemplates;
* @author tiwe
*
*/
public final class HibernateSQLQuery extends AbstractHibernateSQLQuery<HibernateSQLQuery> implements SQLCommonQuery<HibernateSQLQuery> {
public final class HibernateSQLQuery extends AbstractHibernateSQLQuery<HibernateSQLQuery> {
public HibernateSQLQuery(Session session, SQLTemplates sqlTemplates) {
super(session, new Configuration(sqlTemplates));

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>
@ -148,4 +148,4 @@
</build>
</project>
</project>

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>3.3.3.BUILD-SNAPSHOT</version>
<version>3.3.4.BUILD-SNAPSHOT</version>
<relativePath>../querydsl-root/pom.xml</relativePath>
</parent>
@ -15,6 +15,10 @@
<description>SQL support for Querydsl</description>
<packaging>jar</packaging>
<properties>
<bridge-method.version>1.11</bridge-method.version>
</properties>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
@ -115,12 +119,63 @@
<artifactId>jdepend</artifactId>
<version>2.9.1</version>
<scope>test</scope>
</dependency>
</dependency>
<!-- backwards compatibility -->
<dependency>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
<version>${bridge-method.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci</groupId>
<artifactId>annotation-indexer</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>annotation-indexer</artifactId>
<version>1.2</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-injector</artifactId>
<version>${bridge-method.version}</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
<version>${bridge-method.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci</groupId>
<artifactId>annotation-indexer</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>annotation-indexer</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.springsource.bundlor</groupId>
<artifactId>com.springsource.bundlor.maven</artifactId>
@ -232,4 +287,4 @@
</repository>
</repositories>
</project>
</project>

View File

@ -165,7 +165,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends Pr
}
@Override
public final <RT> CloseableIterator<RT> iterate(Expression<RT> expr) {
public <RT> CloseableIterator<RT> iterate(Expression<RT> expr) {
expr = queryMixin.addProjection(expr);
return iterateSingle(queryMixin.getMetadata(), expr);
}

View File

@ -17,6 +17,7 @@ import java.sql.Connection;
import javax.inject.Provider;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import com.mysema.query.sql.dml.SQLDeleteClause;
import com.mysema.query.sql.dml.SQLInsertClause;
import com.mysema.query.sql.dml.SQLMergeClause;
@ -78,11 +79,13 @@ public abstract class AbstractSQLQueryFactory<Q extends SQLCommonQuery<Q>, SQ ex
@SuppressWarnings("unchecked")
@Override
@WithBridgeMethods(value=SQLSubQuery.class, castRequired=true)
public SQ subQuery() {
return (SQ) new SQLSubQuery();
}
@Override
@WithBridgeMethods(value=SQLSubQuery.class, castRequired=true)
public final SQ subQuery(Expression<?> from) {
return subQuery().from(from);
}

View File

@ -73,6 +73,21 @@ public final class Configuration {
}
}
/**
* Get the literal representation of the given constant
*
* @param o
* @return
*/
public String asLiteral(Object o) {
Type type = javaTypeMapping.getType(o.getClass());
if (type != null) {
return templates.serialize(type.getLiteral(o), type.getSQLTypes()[0]);
} else {
throw new IllegalArgumentException("Unsupported literal type " + o.getClass().getName());
}
}
public SQLTemplates getTemplates() {
return templates;
}

View File

@ -17,6 +17,8 @@ import com.mysema.query.QueryMetadata;
import com.mysema.query.QueryModifiers;
import com.mysema.query.types.Ops;
import java.sql.Types;
/**
* DerbyTemplates is an SQL dialect for Derby
*
@ -107,15 +109,16 @@ public class DerbyTemplates extends SQLTemplates {
}
@Override
public String asLiteral(DateTimeType type, String literal) {
// JDBC escape syntax
String keyword = "ts";
if (type == DateTimeType.DATE) {
keyword = "d";
} else if (type == DateTimeType.TIME) {
keyword = "t";
public String serialize(String literal, int jdbcType) {
if (jdbcType == Types.TIMESTAMP) {
return "{ts '" + literal + "'}";
} else if (jdbcType == Types.DATE) {
return "{d '" + literal + "'}";
} else if (jdbcType == Types.TIME) {
return "{t '" + literal + "'}";
} else {
return super.serialize(literal, jdbcType);
}
return "{" + keyword + " '" + literal + "'}";
}
@Override

View File

@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map;
import com.google.common.collect.ImmutableList;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import com.mysema.query.DefaultQueryMetadata;
import com.mysema.query.JoinFlag;
import com.mysema.query.QueryFlag;
@ -78,6 +79,7 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q addFlag(Position position, String prefix, Expression<?> expr) {
Expression<?> flag = TemplateExpressionImpl.create(expr.getType(), prefix + "{0}", expr);
return queryMixin.addFlag(new QueryFlag(position, flag));
@ -91,6 +93,7 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q addFlag(Position position, String flag) {
return queryMixin.addFlag(new QueryFlag(position, flag));
}
@ -103,6 +106,7 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q addFlag(Position position, Expression<?> flag) {
return queryMixin.addFlag(new QueryFlag(position, flag));
}
@ -115,6 +119,7 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q addJoinFlag(String flag) {
return addJoinFlag(flag, JoinFlag.Position.BEFORE_TARGET);
}
@ -127,6 +132,7 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
@SuppressWarnings("unchecked")
public Q addJoinFlag(String flag, JoinFlag.Position position) {
queryMixin.addJoinFlag(new JoinFlag(flag, position));
@ -143,131 +149,154 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
return exists().not();
}
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q from(Expression<?> arg) {
return queryMixin.from(arg);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q from(Expression<?>... args) {
return queryMixin.from(args);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
@SuppressWarnings({ "unchecked", "rawtypes" })
public Q from(SubQueryExpression<?> subQuery, Path<?> alias) {
return queryMixin.from(ExpressionUtils.as((Expression)subQuery, alias));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q fullJoin(EntityPath<?> target) {
return queryMixin.fullJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q fullJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.fullJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q fullJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.fullJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q fullJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.fullJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q innerJoin(EntityPath<?> target) {
return queryMixin.innerJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q innerJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.innerJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q innerJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.innerJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q innerJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.innerJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q join(EntityPath<?> target) {
return queryMixin.join(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q join(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.join(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q join(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.join(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q join(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.join(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q leftJoin(EntityPath<?> target) {
return queryMixin.leftJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q leftJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.leftJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q leftJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.leftJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q leftJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.leftJoin(target, alias);
}
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q on(Predicate condition) {
return queryMixin.on(condition);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q on(Predicate... conditions) {
return queryMixin.on(conditions);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q rightJoin(EntityPath<?> target) {
return queryMixin.rightJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q rightJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.fullJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public <E> Q rightJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.rightJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q rightJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.rightJoin(target, alias);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private <T> CollectionExpressionBase<?,T> union(Operator<Object> op, List<? extends SubQueryExpression<?>> sq) {
@ -311,30 +340,35 @@ public abstract class DetachableSQLQuery<Q extends DetachableSQLQuery<Q>> extend
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q withRecursive(Path<?> alias, SubQueryExpression<?> query) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, query);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q withRecursive(Path<?> alias, Expression<?> query) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, query);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public WithBuilder<Q> withRecursive(Path<?> alias, Path<?>... columns) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, columns);
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q with(Path<?> alias, SubQueryExpression<?> target) {
Expression<?> expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, target);
return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr));
}
@Override
@WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true)
public Q with(Path<?> alias, Expression<?> query) {
Expression<?> expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query);
return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr));

View File

@ -13,9 +13,6 @@
*/
package com.mysema.query.sql;
import java.math.BigInteger;
import java.util.List;
import com.mysema.commons.lang.Pair;
import com.mysema.query.QueryFlag.Position;
import com.mysema.query.QueryMetadata;
@ -24,6 +21,10 @@ import com.mysema.query.types.Expression;
import com.mysema.query.types.Ops;
import com.mysema.query.types.Path;
import java.math.BigInteger;
import java.sql.Types;
import java.util.List;
/**
* OracleTemplates is an SQL dialect for Oracle
*
@ -134,12 +135,11 @@ public class OracleTemplates extends SQLTemplates {
}
@Override
public String asLiteral(DateTimeType type, String literal) {
if (type == DateTimeType.TIME) {
// Oracle doesn't support the time type
return "(timestamp '1970-01-01 " + literal + "')";
public String serialize(String literal, int jdbcType) {
if (jdbcType == Types.TIME) {
return "(timestamp '1970-01-01 " + literal + "'}";
} else {
return super.asLiteral(type, literal);
return super.serialize(literal, jdbcType);
}
}

View File

@ -13,32 +13,19 @@
*/
package com.mysema.query.sql;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.query.JoinFlag;
import com.mysema.query.Query;
import com.mysema.query.QueryFlag;
import com.mysema.query.*;
import com.mysema.query.QueryFlag.Position;
import com.mysema.query.QueryMetadata;
import com.mysema.query.SearchResults;
import com.mysema.query.Tuple;
import com.mysema.query.support.Expressions;
import com.mysema.query.support.ProjectableQuery;
import com.mysema.query.support.QueryMixin;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Expression;
import com.mysema.query.types.ExpressionUtils;
import com.mysema.query.types.OperationImpl;
import com.mysema.query.types.ParamExpression;
import com.mysema.query.types.ParamNotSetException;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.SubQueryExpression;
import com.mysema.query.types.*;
import com.mysema.query.types.expr.Wildcard;
import com.mysema.query.types.query.ListSubQuery;
import com.mysema.query.types.template.NumberTemplate;
@ -73,6 +60,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q addJoinFlag(String flag) {
return addJoinFlag(flag, JoinFlag.Position.BEFORE_TARGET);
}
@ -85,6 +73,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
@SuppressWarnings("unchecked")
public Q addJoinFlag(String flag, JoinFlag.Position position) {
queryMixin.addJoinFlag(new JoinFlag(flag, position));
@ -100,6 +89,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q addFlag(Position position, String prefix, Expression<?> expr) {
Expression<?> flag = SimpleTemplate.create(expr.getType(), prefix + "{0}", expr);
return queryMixin.addFlag(new QueryFlag(position, flag));
@ -111,6 +101,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @param flag
* @return
*/
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q addFlag(QueryFlag flag) {
return queryMixin.addFlag(flag);
}
@ -123,6 +114,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q addFlag(Position position, String flag) {
return queryMixin.addFlag(new QueryFlag(position, flag));
}
@ -135,6 +127,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @return
*/
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q addFlag(Position position, Expression<?> flag) {
return queryMixin.addFlag(new QueryFlag(position, flag));
}
@ -150,117 +143,140 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
return limit(1).singleResult(NumberTemplate.ONE) != null;
}
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q from(Expression<?> arg) {
return queryMixin.from(arg);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q from(Expression<?>... args) {
return queryMixin.from(args);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
@SuppressWarnings({ "unchecked", "rawtypes" })
public Q from(SubQueryExpression<?> subQuery, Path<?> alias) {
return queryMixin.from(ExpressionUtils.as((Expression) subQuery, alias));
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q fullJoin(EntityPath<?> target) {
return queryMixin.fullJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q fullJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.fullJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q fullJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.fullJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q fullJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.fullJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q innerJoin(EntityPath<?> target) {
return queryMixin.innerJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q innerJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.innerJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q innerJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.innerJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q innerJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.innerJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q join(EntityPath<?> target) {
return queryMixin.join(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q join(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.join(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q join(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.join(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q join(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.join(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q leftJoin(EntityPath<?> target) {
return queryMixin.leftJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q leftJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.leftJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q leftJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.leftJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q leftJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.leftJoin(entity).on(key.on(entity));
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q rightJoin(EntityPath<?> target) {
return queryMixin.rightJoin(target);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q rightJoin(RelationalFunctionCall<E> target, Path<E> alias) {
return queryMixin.rightJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q rightJoin(SubQueryExpression<?> target, Path<?> alias) {
return queryMixin.rightJoin(target, alias);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <E> Q rightJoin(ForeignKey<E> key, RelationalPath<E> entity) {
return queryMixin.rightJoin(entity).on(key.on(entity));
}
@ -294,11 +310,13 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
return listResults(queryMixin.createProjection(args));
}
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q on(Predicate condition) {
return queryMixin.on(condition);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q on(Predicate... conditions) {
return queryMixin.on(conditions);
}
@ -321,6 +339,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @param sq
* @return
*/
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <RT> Q union(Path<?> alias, ListSubQuery<RT>... sq) {
return from(UnionUtils.union(sq, alias, false));
}
@ -343,6 +362,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @param sq
* @return
*/
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <RT> Q union(Path<?> alias, SubQueryExpression<RT>... sq) {
return from(UnionUtils.union(sq, alias, false));
}
@ -366,6 +386,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @param sq
* @return
*/
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <RT> Q unionAll(Path<?> alias, ListSubQuery<RT>... sq) {
return from(UnionUtils.union(sq, alias, true));
}
@ -389,6 +410,7 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
* @param sq
* @return
*/
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public <RT> Q unionAll(Path<?> alias, SubQueryExpression<RT>... sq) {
return from(UnionUtils.union(sq, alias, true));
}
@ -409,12 +431,14 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q withRecursive(Path<?> alias, SubQueryExpression<?> query) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, query);
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q withRecursive(Path<?> alias, Expression<?> query) {
queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE));
return with(alias, query);
@ -427,12 +451,14 @@ public abstract class ProjectableSQLQuery<Q extends ProjectableSQLQuery<Q> & Que
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q with(Path<?> alias, SubQueryExpression<?> query) {
Expression<?> expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query);
return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr));
}
@Override
@WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true)
public Q with(Path<?> alias, Expression<?> query) {
Expression<?> expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query);
return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr));

View File

@ -13,7 +13,7 @@
*/
package com.mysema.query.sql;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;
import com.mysema.query.types.ConstantImpl;
@ -43,11 +43,14 @@ import com.mysema.query.types.expr.Wildcard;
@SuppressWarnings("rawtypes")
public final class SQLExpressions {
private static final Map<DatePart, Operator> DATE_ADD_OPS = new HashMap<DatePart, Operator>();
private static final Map<DatePart, Operator> DATE_ADD_OPS
= new EnumMap<DatePart, Operator>(DatePart.class);
private static final Map<DatePart, Operator> DATE_DIFF_OPS = new HashMap<DatePart, Operator>();
private static final Map<DatePart, Operator> DATE_DIFF_OPS
= new EnumMap<DatePart, Operator>(DatePart.class);
private static final Map<DatePart, Operator> DATE_TRUNC_OPS = new HashMap<DatePart, Operator>();
private static final Map<DatePart, Operator> DATE_TRUNC_OPS
= new EnumMap<DatePart, Operator>(DatePart.class);
static {
DATE_ADD_OPS.put(DatePart.year, Ops.DateTimeOps.ADD_YEARS);

View File

@ -13,15 +13,6 @@
*/
package com.mysema.query.sql;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@ -32,24 +23,11 @@ import com.mysema.query.QueryFlag;
import com.mysema.query.QueryFlag.Position;
import com.mysema.query.QueryMetadata;
import com.mysema.query.support.SerializerBase;
import com.mysema.query.types.Constant;
import com.mysema.query.types.ConstantImpl;
import com.mysema.query.types.Expression;
import com.mysema.query.types.ExpressionUtils;
import com.mysema.query.types.FactoryExpression;
import com.mysema.query.types.Operator;
import com.mysema.query.types.Ops;
import com.mysema.query.types.Order;
import com.mysema.query.types.OrderSpecifier;
import com.mysema.query.types.ParamExpression;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.SubQueryExpression;
import com.mysema.query.types.Template;
import com.mysema.query.types.*;
import com.mysema.query.types.Template.Element;
import com.mysema.query.types.TemplateExpression;
import com.mysema.query.types.TemplateFactory;
import javax.annotation.Nullable;
import java.util.*;
/**
* SqlSerializer serializes Querydsl queries into SQL
@ -705,12 +683,12 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
if (!first) {
append(COMMA);
}
append(templates.asLiteral(o));
append(configuration.asLiteral(o));
first = false;
}
append(")");
} else {
append(templates.asLiteral(constant));
append(configuration.asLiteral(constant));
}
} else if (constant instanceof Collection) {
append("(");

View File

@ -20,6 +20,8 @@ import com.mysema.query.QueryModifiers;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.Ops;
import java.sql.Types;
/**
* SQLServerTemplates is an SQL dialect for Microsoft SQL Server
*
@ -115,15 +117,16 @@ public class SQLServerTemplates extends SQLTemplates {
}
@Override
public String asLiteral(DateTimeType type, String literal) {
// JDBC escape syntax
String keyword = "ts";
if (type == DateTimeType.DATE) {
keyword = "d";
} else if (type == DateTimeType.TIME) {
keyword = "t";
public String serialize(String literal, int jdbcType) {
if (jdbcType == Types.TIMESTAMP) {
return "{ts '" + literal + "'}";
} else if (jdbcType == Types.DATE) {
return "{d '" + literal + "'}";
} else if (jdbcType == Types.TIME) {
return "{t '" + literal + "'}";
} else {
return super.serialize(literal, jdbcType);
}
return "{" + keyword + " '" + literal + "'}";
}
@Override

View File

@ -13,20 +13,6 @@
*/
package com.mysema.query.sql;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.ReadableInstant;
import org.joda.time.ReadablePartial;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import com.google.common.primitives.Primitives;
import com.mysema.commons.lang.Pair;
import com.mysema.query.JoinType;
@ -34,12 +20,11 @@ import com.mysema.query.QueryException;
import com.mysema.query.QueryFlag.Position;
import com.mysema.query.QueryMetadata;
import com.mysema.query.QueryModifiers;
import com.mysema.query.types.Expression;
import com.mysema.query.types.Ops;
import com.mysema.query.types.Path;
import com.mysema.query.types.SubQueryExpression;
import com.mysema.query.types.TemplateExpressionImpl;
import com.mysema.query.types.Templates;
import com.mysema.query.types.*;
import java.lang.reflect.Field;
import java.sql.Types;
import java.util.*;
/**
* SQLTemplates extends Templates to provides SQL specific extensions
@ -49,8 +34,6 @@ import com.mysema.query.types.Templates;
*/
public class SQLTemplates extends Templates {
enum DateTimeType {DATE, TIME, DATETIME};
public static final Expression<?> RECURSIVE = TemplateExpressionImpl.create(Object.class, "");
public static final SQLTemplates DEFAULT = new SQLTemplates("\"",'\\',false);
@ -94,12 +77,6 @@ public class SQLTemplates extends Templates {
}
private static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm:ss");
private final Map<Class<?>, String> class2type = new HashMap<Class<?>, String>();
private final String quoteStr;
@ -365,35 +342,25 @@ public class SQLTemplates extends Templates {
class2type.put(java.sql.Timestamp.class, "timestamp");
}
public String asLiteral(Object o) {
if (o instanceof Character) {
return "'" + escapeLiteral(o.toString()) + "'";
} else if (o instanceof String) {
return "'" + escapeLiteral(o.toString()) + "'";
// java.util.Date
} else if (o instanceof java.util.Date) {
java.util.Date date = (java.util.Date)o;
if (o instanceof java.sql.Date) {
return asLiteral(DateTimeType.DATE, dateFormatter.print(date.getTime()));
} else if (o instanceof java.sql.Time) {
return asLiteral(DateTimeType.TIME, timeFormatter.print(date.getTime()));
} else {
return asLiteral(DateTimeType.DATETIME, dateTimeFormatter.print(date.getTime()));
}
// Joda time
} else if (o instanceof ReadablePartial) {
ReadablePartial partial = (ReadablePartial)o;
if (o instanceof LocalDate) {
return asLiteral(DateTimeType.DATE, dateFormatter.print(partial));
} else if (o instanceof LocalTime) {
return asLiteral(DateTimeType.TIME, timeFormatter.print(partial));
} else {
return asLiteral(DateTimeType.DATETIME, dateTimeFormatter.print(partial));
}
} else if (o instanceof ReadableInstant) {
return asLiteral(DateTimeType.DATETIME, dateTimeFormatter.print((ReadableInstant)o));
} else {
return o.toString();
public String serialize(String literal, int jdbcType) {
switch (jdbcType) {
case Types.TIMESTAMP:
return "(timestamp '" + literal + "')";
case Types.DATE:
return "(date '" + literal + "')";
case Types.TIME:
return "(time '" + literal + "')";
case Types.CHAR:
case Types.CLOB:
case Types.LONGNVARCHAR:
case Types.LONGVARCHAR:
case Types.NCHAR:
case Types.NCLOB:
case Types.NVARCHAR:
case Types.VARCHAR:
return "'" + escapeLiteral(literal) + "'";
default:
return literal;
}
}
@ -417,17 +384,6 @@ public class SQLTemplates extends Templates {
return builder.toString();
}
public String asLiteral(DateTimeType type, String literal) {
// SQL 92 standard
String keyword = "timestamp";
if (type == DateTimeType.DATE) {
keyword = "date";
} else if (type == DateTimeType.TIME) {
keyword = "time";
}
return "(" + keyword + " '" + literal + "')";
}
protected void addClass2TypeMappings(String type, Class<?>... classes) {
for (Class<?> cl : classes) {
class2type.put(cl, type);

View File

@ -14,7 +14,10 @@
package com.mysema.query.sql;
import com.mysema.query.types.Ops;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.sql.Types;
/**
* SQLiteTemplates is a SQL dialect for SQLite
@ -24,6 +27,12 @@ import org.joda.time.*;
*/
public class SQLiteTemplates extends SQLTemplates {
private static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm:ss");
public static Builder builder() {
return new Builder() {
@Override
@ -87,19 +96,16 @@ public class SQLiteTemplates extends SQLTemplates {
}
@Override
public String asLiteral(Object o) {
if (o instanceof java.util.Date) {
return String.valueOf(((java.util.Date)o).getTime());
} else if (o instanceof ReadableInstant) {
return String.valueOf(((ReadableInstant) o).getMillis());
} else if (o instanceof LocalDate) {
return String.valueOf(((LocalDate) o).toDateTimeAtStartOfDay(DateTimeZone.UTC).getMillis());
} else if (o instanceof LocalDateTime) {
return String.valueOf(((LocalDateTime) o).toDateTime(DateTimeZone.UTC).getMillis());
} else if (o instanceof LocalTime) {
return String.valueOf(((LocalTime) o).getMillisOfDay());
public String serialize(String literal, int jdbcType) {
// XXX doesn't work with LocalDate, LocalDateTime and LocalTime
if (jdbcType == Types.TIMESTAMP) {
return String.valueOf(dateTimeFormatter.parseDateTime(literal).getMillis());
} else if (jdbcType == Types.DATE) {
return String.valueOf(dateFormatter.parseDateTime(literal).getMillis());
} else if (jdbcType == Types.TIME) {
return String.valueOf(timeFormatter.parseDateTime(literal).getMillis());
} else {
return super.asLiteral(o);
return super.serialize(literal, jdbcType);
}
}

View File

@ -13,12 +13,6 @@
*/
package com.mysema.query.sql.teradata;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.mysema.query.sql.Configuration;
@ -26,6 +20,12 @@ import com.mysema.query.sql.SQLBindings;
import com.mysema.query.sql.SQLTemplates;
import com.mysema.query.sql.dml.AbstractSQLClause;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
/**
* SetQueryBandClause provides support for Teradata specific set query_band executions.
*
@ -116,9 +116,9 @@ public class SetQueryBandClause extends AbstractSQLClause<SetQueryBandClause> {
builder.append(";");
}
if (configuration.getUseLiterals() || forSession) {
queryString = "set query_band="
+ configuration.getTemplates().asLiteral(builder.toString())
+ (forSession ? " for session" : " for transaction");
queryString = "set query_band='"
+ configuration.getTemplates().escapeLiteral(builder.toString())
+ (forSession ? "' for session" : "' for transaction");
parameter = null;
} else {
queryString = "set query_band=?" + (forSession ? " for session" : " for transaction");

View File

@ -0,0 +1,51 @@
/*
* Copyright 2014, Mysema Ltd
*
* 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.
*/
package com.mysema.query.sql.types;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Common abstract superclass for Type implementations
*
* @author tiwe
*
* @param <T>
*/
public abstract class AbstractDateTimeType<T> extends AbstractType<T> {
private static final Calendar UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
static {
UTC.setTimeInMillis(0);
}
protected static Calendar utc() {
return (Calendar) UTC.clone();
}
protected static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
protected static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
protected static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm:ss");
public AbstractDateTimeType(int type) {
super(type);
}
}

View File

@ -13,9 +13,6 @@
*/
package com.mysema.query.sql.types;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Common abstract superclass for Type implementations
*
@ -25,16 +22,6 @@ import java.util.TimeZone;
*/
public abstract class AbstractType<T> implements Type<T> {
private static final Calendar UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
static {
UTC.setTimeInMillis(0);
}
protected static Calendar utc() {
return (Calendar) UTC.clone();
}
private final int type;
public AbstractType(int type) {
@ -46,4 +33,8 @@ public abstract class AbstractType<T> implements Type<T> {
return new int[]{type};
}
public String getLiteral(T value) {
return value.toString();
}
}

View File

@ -26,7 +26,7 @@ import java.util.Calendar;
* @author tiwe
*
*/
public class CalendarType extends AbstractType<Calendar> {
public class CalendarType extends AbstractDateTimeType<Calendar> {
public CalendarType() {
super(Types.TIMESTAMP);
@ -36,6 +36,11 @@ public class CalendarType extends AbstractType<Calendar> {
super(type);
}
@Override
public String getLiteral(Calendar value) {
return dateTimeFormatter.print(value.getTimeInMillis());
}
@Override
public Calendar getValue(ResultSet rs, int startIndex) throws SQLException {
Timestamp ts = rs.getTimestamp(startIndex);

View File

@ -13,21 +13,17 @@
*/
package com.mysema.query.sql.types;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import org.joda.time.DateTime;
import java.sql.*;
/**
* DateTimeType maps DateTime to Timestamp on the JDBC level
*
* @author tiwe
*
*/
public class DateTimeType extends AbstractType<DateTime> {
public class DateTimeType extends AbstractDateTimeType<DateTime> {
public DateTimeType() {
super(Types.TIMESTAMP);
@ -37,6 +33,11 @@ public class DateTimeType extends AbstractType<DateTime> {
super(type);
}
@Override
public String getLiteral(DateTime value) {
return dateTimeFormatter.print(value);
}
@Override
public Class<DateTime> getReturnedClass() {
return DateTime.class;

View File

@ -13,11 +13,7 @@
*/
package com.mysema.query.sql.types;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.*;
/**
* DateType maps Date to Date on the JDBC level
@ -25,7 +21,7 @@ import java.sql.Types;
* @author tiwe
*
*/
public class DateType extends AbstractType<Date> {
public class DateType extends AbstractDateTimeType<Date> {
public DateType() {
super(Types.DATE);
@ -35,6 +31,11 @@ public class DateType extends AbstractType<Date> {
super(type);
}
@Override
public String getLiteral(Date value) {
return dateFormatter.print(value.getTime());
}
@Override
public Date getValue(ResultSet rs, int startIndex) throws SQLException {
return rs.getDate(startIndex);

View File

@ -13,23 +13,19 @@
*/
package com.mysema.query.sql.types;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import java.sql.*;
/**
* LocalDateTimeType maps LocalDateTime to Timestamp on the JDBC level
*
* @author tiwe
*
*/
public class LocalDateTimeType extends AbstractType<LocalDateTime> {
public class LocalDateTimeType extends AbstractDateTimeType<LocalDateTime> {
public LocalDateTimeType() {
super(Types.TIMESTAMP);
@ -39,6 +35,11 @@ public class LocalDateTimeType extends AbstractType<LocalDateTime> {
super(type);
}
@Override
public String getLiteral(LocalDateTime value) {
return dateTimeFormatter.print(value);
}
@Override
public Class<LocalDateTime> getReturnedClass() {
return LocalDateTime.class;

View File

@ -13,22 +13,18 @@
*/
package com.mysema.query.sql.types;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import java.sql.*;
/**
* LocalDateType maps LocalDate to Date on the JDBC level
*
* @author tiwe
*
*/
public class LocalDateType extends AbstractType<LocalDate> {
public class LocalDateType extends AbstractDateTimeType<LocalDate> {
public LocalDateType() {
super(Types.DATE);
@ -38,6 +34,11 @@ public class LocalDateType extends AbstractType<LocalDate> {
super(type);
}
@Override
public String getLiteral(LocalDate value) {
return dateFormatter.print(value);
}
@Override
public Class<LocalDate> getReturnedClass() {
return LocalDate.class;

View File

@ -13,22 +13,18 @@
*/
package com.mysema.query.sql.types;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Types;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalTime;
import java.sql.*;
/**
* LocalTimeType maps LocalTime to Time on the JDBC level
*
* @author tiwe
*
*/
public class LocalTimeType extends AbstractType<LocalTime> {
public class LocalTimeType extends AbstractDateTimeType<LocalTime> {
public LocalTimeType() {
super(Types.TIME);
@ -38,6 +34,11 @@ public class LocalTimeType extends AbstractType<LocalTime> {
super(type);
}
@Override
public String getLiteral(LocalTime value) {
return timeFormatter.print(value);
}
@Override
public Class<LocalTime> getReturnedClass() {
return LocalTime.class;

View File

@ -13,11 +13,7 @@
*/
package com.mysema.query.sql.types;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Types;
import java.sql.*;
/**
* TimeType maps Time to Time on the JDBC level
@ -25,7 +21,7 @@ import java.sql.Types;
* @author tiwe
*
*/
public class TimeType extends AbstractType<Time> {
public class TimeType extends AbstractDateTimeType<Time> {
public TimeType() {
super(Types.TIME);
@ -35,6 +31,11 @@ public class TimeType extends AbstractType<Time> {
super(type);
}
@Override
public String getLiteral(Time value) {
return timeFormatter.print(value.getTime());
}
@Override
public Time getValue(ResultSet rs, int startIndex) throws SQLException {
return rs.getTime(startIndex);

View File

@ -13,11 +13,7 @@
*/
package com.mysema.query.sql.types;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.sql.*;
/**
* TimestampType maps Timestamp to Timestamp on the JDBC level
@ -25,7 +21,7 @@ import java.sql.Types;
* @author tiwe
*
*/
public class TimestampType extends AbstractType<Timestamp> {
public class TimestampType extends AbstractDateTimeType<Timestamp> {
public TimestampType() {
super(Types.TIMESTAMP);
@ -35,6 +31,11 @@ public class TimestampType extends AbstractType<Timestamp> {
super(type);
}
@Override
public String getLiteral(Timestamp value) {
return dateTimeFormatter.print(value.getTime());
}
@Override
public Timestamp getValue(ResultSet rs, int startIndex) throws SQLException {
return rs.getTimestamp(startIndex);

View File

@ -13,12 +13,11 @@
*/
package com.mysema.query.sql.types;
import javax.annotation.Nullable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.annotation.Nullable;
/**
* Defines the de/serialization of a typed Java object from a ResultSet or to a PreparedStatement
*
@ -46,6 +45,14 @@ public interface Type<T> {
*/
Class<T> getReturnedClass();
/**
* Get the literal representation
*
* @param value
* @return
*/
String getLiteral(T value);
/**
* Get the object from the result set
*

View File

@ -25,7 +25,7 @@ import java.util.Date;
* @author tiwe
*
*/
public class UtilDateType extends AbstractType<Date> {
public class UtilDateType extends AbstractDateTimeType<Date> {
public UtilDateType() {
super(Types.TIMESTAMP);
@ -35,6 +35,11 @@ public class UtilDateType extends AbstractType<Date> {
super(type);
}
@Override
public String getLiteral(Date value) {
return dateTimeFormatter.print(value.getTime());
}
@Override
public Date getValue(ResultSet rs, int startIndex) throws SQLException {
return rs.getTimestamp(startIndex);

View File

@ -19,7 +19,6 @@ import java.util.List;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.query.sql.AbstractSQLQuery;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.SQLCommonQuery;
import com.mysema.query.sql.SQLTemplates;
import com.mysema.query.types.Expression;
import com.mysema.query.types.FactoryExpression;
@ -29,7 +28,7 @@ import com.mysema.query.types.QBean;
* @author tiwe
*
*/
public class ExtendedSQLQuery extends AbstractSQLQuery<ExtendedSQLQuery> implements SQLCommonQuery<ExtendedSQLQuery> {
public class ExtendedSQLQuery extends AbstractSQLQuery<ExtendedSQLQuery> {
public ExtendedSQLQuery(SQLTemplates templates) {
super(null, new Configuration(templates), new DefaultQueryMetadata());

View File

@ -320,7 +320,7 @@ public class SelectBase extends AbstractBaseTest {
}
@Test
@IncludeIn({H2, SQLSERVER, MYSQL, ORACLE, SQLITE, TERADATA}) // TODO fix postgres
@IncludeIn({H2, SQLSERVER, MYSQL, ORACLE, TERADATA}) // TODO fix postgres
public void Dates() {
long ts = ((long)Math.floor(System.currentTimeMillis() / 1000)) * 1000;
long tsDate = new org.joda.time.LocalDate(ts).toDateMidnight().getMillis();

View File

@ -13,27 +13,22 @@
*/
package com.mysema.query.sql;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.*;
import com.mysema.query.types.path.NumberPath;
import com.mysema.query.types.template.SimpleTemplate;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.junit.Test;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.regex.Pattern;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.path.NumberPath;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.junit.Test;
import com.mysema.query.types.ConstantImpl;
import com.mysema.query.types.Operation;
import com.mysema.query.types.OperationImpl;
import com.mysema.query.types.Template;
import com.mysema.query.types.TemplateFactory;
import com.mysema.query.types.template.SimpleTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SQLTemplatesTest {
@ -58,17 +53,19 @@ public class SQLTemplatesTest {
@Test
public void AsLiteral() {
SQLTemplates templates = SQLTemplates.DEFAULT;
assertMatches(DATE, templates.asLiteral(new Date(0)));
assertMatches(TIME, templates.asLiteral(new Time(0)));
assertMatches(DATETIME, templates.asLiteral(new Timestamp(0)));
Configuration conf = new Configuration(templates);
assertMatches(DATE, conf.asLiteral(new Date(0)));
assertMatches(TIME, conf.asLiteral(new Time(0)));
assertMatches(DATETIME, conf.asLiteral(new Timestamp(0)));
}
@Test
public void AsLiteral_JodaTime() {
SQLTemplates templates = SQLTemplates.DEFAULT;
assertMatches(DATE, templates.asLiteral(new LocalDate(0)));
assertMatches(TIME, templates.asLiteral(new LocalTime(0)));
assertMatches(DATETIME, templates.asLiteral(new DateTime(0)));
Configuration conf = new Configuration(templates);
assertMatches(DATE, conf.asLiteral(new LocalDate(0)));
assertMatches(TIME, conf.asLiteral(new LocalTime(0)));
assertMatches(DATETIME, conf.asLiteral(new DateTime(0)));
}
@Test

View File

@ -2,6 +2,7 @@ Bundle-SymbolicName: com.mysema.querydsl.sql
Bundle-Name: Querydsl SQL
Bundle-Vendor: Mysema
Bundle-ManifestVersion: 2
Excluded-Imports: com.infradna.tool.bridge_method_injector
Import-Template:
com.mysema.commons.lang.*;version="${mysema.lang.version}",
com.mysema.query.*;version="${project.version}",