mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
Merged issue679 branch because of foreseen conflicts.
- conflicting getRealParameters moved to ConstructorUtils. Merge branch 'master' of github.com:mysema/querydsl into issue679 Conflicts: querydsl-core/src/main/java/com/mysema/query/types/ConstructorExpression.java
This commit is contained in:
commit
ce2c062b44
@ -1,6 +1,6 @@
|
||||
## Querydsl
|
||||
|
||||
Querydsl is a framework which enables the construction of type-safe SQL-like queries for multiple backends including JPA, JDO and SQL in Java.
|
||||
Querydsl is a framework which enables the construction of type-safe SQL-like queries for multiple backends including JPA, MongoDB and SQL in Java.
|
||||
|
||||
Instead of writing queries as inline strings or externalizing them into XML files they are constructed via a fluent API.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.persistence.Access;
|
||||
@ -133,12 +134,22 @@ public class JPAConfiguration extends DefaultConfiguration {
|
||||
}
|
||||
|
||||
mirror = TypeUtils.getAnnotationMirrorOfType(element, OneToMany.class);
|
||||
if (mirror == null) {
|
||||
mirror = TypeUtils.getAnnotationMirrorOfType(element, ManyToMany.class);
|
||||
}
|
||||
if (mirror != null) {
|
||||
TypeMirror typeArg = TypeUtils.getAnnotationValueAsTypeMirror(mirror, "targetEntity");
|
||||
TypeMirror erasure = types.erasure(element.asType());
|
||||
TypeElement typeElement = (TypeElement) types.asElement(erasure);
|
||||
if (typeElement != null && typeArg != null) {
|
||||
return types.getDeclaredType(typeElement, typeArg);
|
||||
if (typeElement.getTypeParameters().size() == 1) {
|
||||
return types.getDeclaredType(typeElement, typeArg);
|
||||
} else if (typeElement.getTypeParameters().size() == 2) {
|
||||
if (element.asType() instanceof DeclaredType) {
|
||||
TypeMirror first = ((DeclaredType)element.asType()).getTypeArguments().get(0);
|
||||
return types.getDeclaredType(typeElement, first, typeArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -93,6 +93,9 @@ public class GenericExporterTest extends AbstractProcessorTest {
|
||||
expected.add("QGeneric4Test_HidaBezGruppe.java");
|
||||
expected.add("QInterfaceType2Test_UserImpl.java");
|
||||
expected.add("QOrderTest_Order.java");
|
||||
expected.add("QManagedEmailTest_ManagedEmails.java");
|
||||
expected.add("QGeneric12Test_ChannelRole.java");
|
||||
expected.add("QManyToManyTest_Person.java");
|
||||
|
||||
execute(expected, "GenericExporterTest2", "HibernateAnnotationProcessor");
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package com.mysema.query.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -15,7 +15,7 @@ import org.junit.Test;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class Generic12Test {
|
||||
|
||||
|
||||
@Entity
|
||||
@Inheritance
|
||||
@DiscriminatorColumn(name = "CONTEXT")
|
||||
@ -58,10 +58,10 @@ public class Generic12Test {
|
||||
public static class SubjectRole extends Role { // missing type param, should be Role<SubjectPermission>
|
||||
// some constructors
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertEquals(QGeneric12Test_ChannelPermission.class,
|
||||
assertEquals(QGeneric12Test_Permission.class,
|
||||
QGeneric12Test_ChannelRole.channelRole.permissions.get(0).getClass());
|
||||
assertEquals(QGeneric12Test_Permission.class,
|
||||
QGeneric12Test_SubjectRole.subjectRole.permissions.get(0).getClass());
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
package com.mysema.query.domain;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.MapKey;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ManagedEmailTest {
|
||||
|
||||
public interface ManagedEmail {
|
||||
|
||||
}
|
||||
|
||||
public enum EmailType { WORK, HOME }
|
||||
|
||||
@Entity
|
||||
public static class ManagedEmailImpl implements ManagedEmail {
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class ManagedEmails {
|
||||
|
||||
@OneToMany(targetEntity = ManagedEmailImpl.class)
|
||||
@MapKey(name = "emailType")
|
||||
private Map<EmailType, ManagedEmail> emails;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertEquals(EmailType.class, QManagedEmailTest_ManagedEmails.managedEmails.emails.getKeyType());
|
||||
assertEquals(ManagedEmailImpl.class, QManagedEmailTest_ManagedEmails.managedEmails.emails.getValueType());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.mysema.query.domain;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ManyToManyTest {
|
||||
|
||||
public interface PhoneNumber {
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class PhoneNumberImpl {
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Person {
|
||||
|
||||
@ManyToMany(targetEntity=PhoneNumberImpl.class)
|
||||
Set<PhoneNumber> phones;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertEquals(PhoneNumberImpl.class, QManyToManyTest_Person.person.phones.getElementType());
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -13,67 +13,25 @@
|
||||
*/
|
||||
package com.mysema.query.codegen;
|
||||
|
||||
import static com.mysema.codegen.Symbols.ASSIGN;
|
||||
import static com.mysema.codegen.Symbols.COMMA;
|
||||
import static com.mysema.codegen.Symbols.DOT;
|
||||
import static com.mysema.codegen.Symbols.EMPTY;
|
||||
import static com.mysema.codegen.Symbols.NEW;
|
||||
import static com.mysema.codegen.Symbols.QUOTE;
|
||||
import static com.mysema.codegen.Symbols.RETURN;
|
||||
import static com.mysema.codegen.Symbols.SEMICOLON;
|
||||
import static com.mysema.codegen.Symbols.STAR;
|
||||
import static com.mysema.codegen.Symbols.SUPER;
|
||||
import static com.mysema.codegen.Symbols.THIS;
|
||||
import static com.mysema.codegen.Symbols.UNCHECKED;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mysema.codegen.CodeWriter;
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Constructor;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
import com.mysema.codegen.model.SimpleType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.model.TypeExtends;
|
||||
import com.mysema.codegen.model.Types;
|
||||
import com.mysema.query.types.ConstructorExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.PathMetadata;
|
||||
import com.mysema.query.types.PathMetadataFactory;
|
||||
import com.mysema.codegen.model.*;
|
||||
import com.mysema.query.types.*;
|
||||
import com.mysema.query.types.expr.ComparableExpression;
|
||||
import com.mysema.query.types.expr.SimpleExpression;
|
||||
import com.mysema.query.types.path.ArrayPath;
|
||||
import com.mysema.query.types.path.BooleanPath;
|
||||
import com.mysema.query.types.path.CollectionPath;
|
||||
import com.mysema.query.types.path.ComparablePath;
|
||||
import com.mysema.query.types.path.DatePath;
|
||||
import com.mysema.query.types.path.DateTimePath;
|
||||
import com.mysema.query.types.path.EntityPathBase;
|
||||
import com.mysema.query.types.path.EnumPath;
|
||||
import com.mysema.query.types.path.ListPath;
|
||||
import com.mysema.query.types.path.MapPath;
|
||||
import com.mysema.query.types.path.NumberPath;
|
||||
import com.mysema.query.types.path.PathInits;
|
||||
import com.mysema.query.types.path.SetPath;
|
||||
import com.mysema.query.types.path.SimplePath;
|
||||
import com.mysema.query.types.path.StringPath;
|
||||
import com.mysema.query.types.path.TimePath;
|
||||
import com.mysema.query.types.path.*;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.*;
|
||||
|
||||
import static com.mysema.codegen.Symbols.*;
|
||||
|
||||
/**
|
||||
* EntitySerializer is a {@link Serializer} implementation for entity types
|
||||
@ -371,6 +329,7 @@ public class EntitySerializer implements Serializer {
|
||||
protected void introFactoryMethods(CodeWriter writer, final EntityType model) throws IOException {
|
||||
String localName = writer.getRawName(model);
|
||||
String genericName = writer.getGenericName(true, model);
|
||||
Set<Integer> sizes = Sets.newHashSet();
|
||||
|
||||
for (Constructor c : model.getConstructors()) {
|
||||
// begin
|
||||
@ -378,12 +337,21 @@ public class EntitySerializer implements Serializer {
|
||||
writer.suppressWarnings(UNCHECKED);
|
||||
}
|
||||
Type returnType = new ClassType(ConstructorExpression.class, model);
|
||||
final boolean asExpr = sizes.add(c.getParameters().size());
|
||||
writer.beginStaticMethod(returnType, "create", c.getParameters(),
|
||||
new Function<Parameter, Parameter>() {
|
||||
@Override
|
||||
public Parameter apply(Parameter p) {
|
||||
return new Parameter(p.getName(), typeMappings.getExprType(
|
||||
p.getType(), model, false, false, true));
|
||||
Type type;
|
||||
if (!asExpr) {
|
||||
type = typeMappings.getExprType(
|
||||
p.getType(), model, false, false, true);
|
||||
} else if (p.getType().isFinal()) {
|
||||
type = new ClassType(Expression.class, p.getType());
|
||||
} else {
|
||||
type = new ClassType(Expression.class, new TypeExtends(p.getType()));
|
||||
}
|
||||
return new Parameter(p.getName(), type);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -13,21 +13,18 @@
|
||||
*/
|
||||
package com.mysema.query.codegen;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mysema.codegen.CodeWriter;
|
||||
import com.mysema.codegen.model.*;
|
||||
import com.mysema.query.types.ConstructorExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.expr.NumberExpression;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.mysema.codegen.CodeWriter;
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Constructor;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.model.Types;
|
||||
import com.mysema.query.types.ConstructorExpression;
|
||||
import com.mysema.query.types.expr.NumberExpression;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* ProjectionSerializer is a {@link Serializer} implementation for projection types
|
||||
@ -60,7 +57,7 @@ public final class ProjectionSerializer implements Serializer{
|
||||
|
||||
// imports
|
||||
writer.imports(NumberExpression.class.getPackage());
|
||||
writer.imports(ConstructorExpression.class, Generated.class);
|
||||
writer.imports(Expression.class, ConstructorExpression.class, Generated.class);
|
||||
|
||||
// javadoc
|
||||
writer.javadoc(queryType + " is a Querydsl Projection type for " + simpleName);
|
||||
@ -85,14 +82,24 @@ public final class ProjectionSerializer implements Serializer{
|
||||
intro(model, writer);
|
||||
|
||||
String localName = writer.getRawName(model);
|
||||
Set<Integer> sizes = Sets.newHashSet();
|
||||
|
||||
for (Constructor c : model.getConstructors()) {
|
||||
final boolean asExpr = sizes.add(c.getParameters().size());
|
||||
// begin
|
||||
writer.beginConstructor(c.getParameters(), new Function<Parameter,Parameter>() {
|
||||
@Override
|
||||
public Parameter apply(Parameter p) {
|
||||
return new Parameter(p.getName(), typeMappings.getExprType(p.getType(),
|
||||
model, false, false, true));
|
||||
Type type;
|
||||
if (!asExpr) {
|
||||
type = typeMappings.getExprType(p.getType(),
|
||||
model, false, false, true);
|
||||
} else if (p.getType().isFinal()) {
|
||||
type = new ClassType(Expression.class, p.getType());
|
||||
} else {
|
||||
type = new ClassType(Expression.class, new TypeExtends(p.getType()));
|
||||
}
|
||||
return new Parameter(p.getName(), type);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -75,7 +75,12 @@ public final class Property implements Comparable<Property> {
|
||||
|
||||
@Override
|
||||
public int compareTo(Property o) {
|
||||
return name.compareToIgnoreCase(o.getName());
|
||||
int rv = name.compareToIgnoreCase(o.getName());
|
||||
if (rv == 0) {
|
||||
return name.compareTo(o.getName());
|
||||
} else {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
public Property createCopy(EntityType targetModel) {
|
||||
|
||||
@ -13,22 +13,16 @@
|
||||
*/
|
||||
package com.mysema.query.codegen;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import com.mysema.codegen.JavaWriter;
|
||||
import com.mysema.codegen.model.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mysema.codegen.JavaWriter;
|
||||
import com.mysema.codegen.model.Constructor;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
import com.mysema.codegen.model.SimpleType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.model.Types;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class ProjectionSerializerTest {
|
||||
@ -47,9 +41,9 @@ public class ProjectionSerializerTest {
|
||||
Writer writer = new StringWriter();
|
||||
ProjectionSerializer serializer = new ProjectionSerializer(new JavaTypeMappings());
|
||||
serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer));
|
||||
assertTrue(writer.toString().contains("StringExpression firstName"));
|
||||
assertTrue(writer.toString().contains("StringExpression lastName"));
|
||||
assertTrue(writer.toString().contains("NumberExpression<Integer> age"));
|
||||
assertTrue(writer.toString().contains("Expression<String> firstName"));
|
||||
assertTrue(writer.toString().contains("Expression<String> lastName"));
|
||||
assertTrue(writer.toString().contains("Expression<Integer> age"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Querydsl Collections #
|
||||
## Querydsl Collections
|
||||
|
||||
The Collections module provides integration with Java Collections and Beans.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.Operator;
|
||||
import com.mysema.query.types.Ops;
|
||||
@ -79,8 +80,22 @@ public final class CollQueryFunctions {
|
||||
|
||||
private static final List<Object> nullList = Arrays.<Object>asList((Object)null);
|
||||
|
||||
public static boolean equals(Object o1, Object o2) {
|
||||
return Objects.equal(o1, o2);
|
||||
}
|
||||
|
||||
public static <T extends Comparable<? super T>> int compareTo(T c1, T c2) {
|
||||
if (c1 == null) {
|
||||
return c2 == null ? 0 : -1;
|
||||
} else if (c2 == null) {
|
||||
return 1;
|
||||
} else {
|
||||
return c1.compareTo(c2);
|
||||
}
|
||||
}
|
||||
|
||||
public static <A extends Comparable<? super A>> boolean between(A a, A b, A c) {
|
||||
return a.compareTo(b) >= 0 && a.compareTo(c) <= 0;
|
||||
return compareTo(a, b) >= 0 && compareTo(a, c) <= 0;
|
||||
}
|
||||
|
||||
public static double cot(double x) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011, 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
|
||||
@ -24,13 +24,13 @@ import com.mysema.query.types.template.BooleanTemplate;
|
||||
|
||||
/**
|
||||
* CollQueryMixin extends {@link QueryMixin} to provide normalization logic specific to this module
|
||||
*
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class CollQueryMixin<T> extends QueryMixin<T> {
|
||||
|
||||
|
||||
private static final Predicate ANY = BooleanTemplate.create("any");
|
||||
|
||||
public CollQueryMixin() {}
|
||||
@ -42,22 +42,22 @@ public class CollQueryMixin<T> extends QueryMixin<T> {
|
||||
public CollQueryMixin(T self, QueryMetadata metadata) {
|
||||
super(self, metadata);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Predicate normalize(Predicate predicate, boolean where) {
|
||||
predicate = (Predicate)ExpressionUtils.extract(predicate);
|
||||
if (predicate != null) {
|
||||
if (predicate != null) {
|
||||
Context context = new Context();
|
||||
Predicate transformed = (Predicate) predicate.accept(CollectionAnyVisitor.DEFAULT, context);
|
||||
for (int i = 0; i < context.paths.size(); i++) {
|
||||
innerJoin(
|
||||
(Path)context.paths.get(i).getMetadata().getParent(),
|
||||
leftJoin(
|
||||
(Path)context.paths.get(i).getMetadata().getParent(),
|
||||
(Path)context.replacements.get(i));
|
||||
on(ANY);
|
||||
}
|
||||
return transformed;
|
||||
return transformed;
|
||||
} else {
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,16 +29,16 @@ public class CollQueryTemplates extends JavaTemplates {
|
||||
|
||||
protected CollQueryTemplates() {
|
||||
String functions = CollQueryFunctions.class.getName();
|
||||
add(Ops.EQ, "{0}.equals({1})");
|
||||
add(Ops.NE, "!{0}.equals({1})");
|
||||
add(Ops.EQ, functions + ".equals({0}, {1})");
|
||||
add(Ops.NE, "!" + functions + ".equals({0}, {1})");
|
||||
add(Ops.INSTANCE_OF, "{1}.isInstance({0})");
|
||||
|
||||
// Comparable
|
||||
add(Ops.GT, "{0}.compareTo({1}) > 0");
|
||||
add(Ops.LT, "{0}.compareTo({1}) < 0");
|
||||
add(Ops.GOE, "{0}.compareTo({1}) >= 0");
|
||||
add(Ops.LOE, "{0}.compareTo({1}) <= 0");
|
||||
add(Ops.BETWEEN, functions + ".between({0},{1},{2})");
|
||||
add(Ops.GT, functions + ".compareTo({0}, {1}) > 0");
|
||||
add(Ops.LT, functions + ".compareTo({0}, {1}) < 0");
|
||||
add(Ops.GOE, functions + ".compareTo({0}, {1}) >= 0");
|
||||
add(Ops.LOE, functions + ".compareTo({0}, {1}) <= 0");
|
||||
add(Ops.BETWEEN, functions + ".between({0}, {1}, {2})");
|
||||
add(Ops.STRING_CAST, "String.valueOf({0})");
|
||||
|
||||
// Number
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.mysema.query.collections;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mysema.query.annotations.QueryEntity;
|
||||
|
||||
@QueryEntity
|
||||
public class Document {
|
||||
|
||||
private Long id;
|
||||
|
||||
private List<String> meshThesaurusTerms = new ArrayList<String>();
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<String> getMeshThesaurusTerms() {
|
||||
return meshThesaurusTerms;
|
||||
}
|
||||
|
||||
public void setMeshThesaurusTerms(List<String> meshThesaurusTerms) {
|
||||
this.meshThesaurusTerms = meshThesaurusTerms;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.mysema.query.collections;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mysema.query.types.Predicate;
|
||||
|
||||
public class DocumentTest {
|
||||
|
||||
private Document doc1, doc2, doc3;
|
||||
|
||||
private QDocument qDoc = QDocument.document;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
doc1 = new Document();
|
||||
doc1.setId(1L);
|
||||
doc1.getMeshThesaurusTerms().add("x");
|
||||
|
||||
doc2 = new Document();
|
||||
doc2.setId(2L);
|
||||
|
||||
doc3 = new Document();
|
||||
doc3.setId(3L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
Predicate crit = qDoc.id.eq(3L);
|
||||
List<Document> expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc);
|
||||
assertTrue(expResult.contains(doc3)); //ok
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
Predicate crit = qDoc.meshThesaurusTerms.any().eq("x");
|
||||
List<Document> expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc);
|
||||
assertTrue(expResult.contains(doc1)); //ok
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
Predicate crit = qDoc.meshThesaurusTerms.any().eq("x").or(qDoc.id.eq(3L));
|
||||
List<Document> expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc);
|
||||
assertTrue(expResult.contains(doc1));
|
||||
assertTrue(expResult.contains(doc3)); //fails, expResult contains only doc1, but should contain doc1 and doc3!
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4() {
|
||||
Predicate crit = qDoc.id.eq(3L).or(qDoc.meshThesaurusTerms.any().eq("x"));
|
||||
List<Document> expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc);
|
||||
assertTrue(expResult.contains(doc1));
|
||||
assertTrue(expResult.contains(doc3)); //fails, expResult contains only doc1, but should contain doc1 and doc3!
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.support;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mysema.query.*;
|
||||
import com.mysema.query.types.*;
|
||||
import com.mysema.query.types.template.BooleanTemplate;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ReplaceVisitor is a deep visitor that can be customized to replace segments of
|
||||
* expression trees
|
||||
*/
|
||||
public class ReplaceVisitor implements Visitor<Expression<?>, Void> {
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(Constant<?> expr, @Nullable Void context) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(FactoryExpression<?> expr, @Nullable Void context) {
|
||||
List<Expression<?>> args = visit(expr.getArgs());
|
||||
if (args.equals(expr.getArgs())) {
|
||||
return expr;
|
||||
} else {
|
||||
return FactoryExpressionUtils.wrap(expr, args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(Operation<?> expr, @Nullable Void context) {
|
||||
ImmutableList<Expression<?>> args = visit(expr.getArgs());
|
||||
if (args.equals(expr.getArgs())) {
|
||||
return expr;
|
||||
} else if (expr instanceof Predicate) {
|
||||
return new PredicateOperation((Operator)expr.getOperator(), args);
|
||||
} else {
|
||||
return new OperationImpl(expr.getType(), expr.getOperator(), args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(ParamExpression<?> expr, @Nullable Void context) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(Path<?> expr, @Nullable Void context) {
|
||||
if (expr.getMetadata().isRoot()) {
|
||||
return expr;
|
||||
} else {
|
||||
PathMetadata metadata = expr.getMetadata();
|
||||
Path<?> parent = (Path)metadata.getParent().accept(this, null);
|
||||
if (parent.equals(metadata.getParent())) {
|
||||
return expr;
|
||||
} else {
|
||||
metadata = new PathMetadata(parent, metadata.getElement(),
|
||||
metadata.getPathType());
|
||||
return new PathImpl(expr.getType(), metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(SubQueryExpression<?> expr, @Nullable Void context) {
|
||||
QueryMetadata md = new DefaultQueryMetadata();
|
||||
md.setDistinct(expr.getMetadata().isDistinct());
|
||||
md.setModifiers(expr.getMetadata().getModifiers());
|
||||
md.setUnique(expr.getMetadata().isUnique());
|
||||
for (QueryFlag flag : expr.getMetadata().getFlags()) {
|
||||
md.addFlag(new QueryFlag(flag.getPosition(), flag.getFlag().accept(this, null)));
|
||||
}
|
||||
for (Expression<?> e : expr.getMetadata().getGroupBy()) {
|
||||
md.addGroupBy(e.accept(this, null));
|
||||
}
|
||||
Predicate having = expr.getMetadata().getHaving();
|
||||
if (having != null) {
|
||||
md.addHaving((Predicate)having.accept(this, null));
|
||||
}
|
||||
for (JoinExpression je : expr.getMetadata().getJoins()) {
|
||||
md.addJoin(je.getType(), je.getTarget().accept(this, null));
|
||||
if (je.getCondition() != null) {
|
||||
md.addJoinCondition((Predicate)je.getCondition().accept(this, null));
|
||||
}
|
||||
for (JoinFlag jf : je.getFlags()) {
|
||||
md.addJoinFlag(new JoinFlag(jf.getFlag().accept(this, null), jf.getPosition()));
|
||||
}
|
||||
}
|
||||
for (OrderSpecifier<?> os : expr.getMetadata().getOrderBy()) {
|
||||
OrderSpecifier<?> os2 = new OrderSpecifier(os.getOrder(), os.getTarget().accept(this,
|
||||
null));
|
||||
switch (os.getNullHandling()) {
|
||||
case NullsFirst: os2 = os2.nullsFirst(); break;
|
||||
case NullsLast: os2 = os2.nullsLast(); break;
|
||||
}
|
||||
md.addOrderBy(os2);
|
||||
}
|
||||
for (Map.Entry<ParamExpression<?>, Object> entry : expr.getMetadata().getParams()
|
||||
.entrySet()) {
|
||||
md.setParam((ParamExpression)entry.getKey().accept(this, null), entry.getValue());
|
||||
}
|
||||
for (Expression<?> e : expr.getMetadata().getProjection()) {
|
||||
md.addProjection(e.accept(this, null));
|
||||
}
|
||||
Predicate where = expr.getMetadata().getWhere();
|
||||
if (where != null) {
|
||||
md.addWhere((Predicate)where.accept(this, null));
|
||||
}
|
||||
if (expr.getMetadata().equals(md)) {
|
||||
return expr;
|
||||
} else {
|
||||
return new SubQueryExpressionImpl(expr.getType(), md);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(TemplateExpression<?> expr, @Nullable Void context) {
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (Object arg : expr.getArgs()) {
|
||||
if (arg instanceof Expression) {
|
||||
builder.add(((Expression)arg).accept(this, null));
|
||||
} else {
|
||||
builder.add(arg);
|
||||
}
|
||||
}
|
||||
ImmutableList args = builder.build();
|
||||
if (args.equals(expr.getArgs())) {
|
||||
return expr;
|
||||
} else {
|
||||
if (expr instanceof Predicate) {
|
||||
return BooleanTemplate.create(expr.getTemplate(), args);
|
||||
} else {
|
||||
return new TemplateExpressionImpl(expr.getType(), expr.getTemplate(), args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ImmutableList<Expression<?>> visit(List<Expression<?>> args) {
|
||||
ImmutableList.Builder<Expression<?>> builder = ImmutableList.builder();
|
||||
for (Expression<?> arg : args) {
|
||||
builder.add(arg.accept(this, null));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@ -13,18 +13,17 @@
|
||||
*/
|
||||
package com.mysema.query.types.expr;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mysema.query.types.ConstantImpl;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.NullExpression;
|
||||
import com.mysema.query.types.Ops;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CaseBuilder enables the construction of typesafe case-when-then-else
|
||||
* constructs :
|
||||
@ -164,8 +163,28 @@ public final class CaseBuilder {
|
||||
this.when = b;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A> Cases<A, SimpleExpression<A>> then(Expression<A> expr) {
|
||||
if (expr instanceof BooleanExpression) {
|
||||
return (Cases) then((BooleanExpression) expr);
|
||||
} else if (expr instanceof StringExpression) {
|
||||
return (Cases) then((StringExpression) expr);
|
||||
} else if (expr instanceof NumberExpression) {
|
||||
return then((NumberExpression) expr);
|
||||
} else if (expr instanceof DateExpression) {
|
||||
return then((DateExpression) expr);
|
||||
} else if (expr instanceof DateTimeExpression) {
|
||||
return then((DateTimeExpression) expr);
|
||||
} else if (expr instanceof TimeExpression) {
|
||||
return then((TimeExpression) expr);
|
||||
} else if (expr instanceof ComparableExpression) {
|
||||
return then((ComparableExpression) expr);
|
||||
} else {
|
||||
return thenSimple(expr);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <A> Cases<A, SimpleExpression<A>> thenSimple(Expression<A> expr) {
|
||||
return new Cases<A, SimpleExpression<A>>((Class)expr.getType()) {
|
||||
@Override
|
||||
protected SimpleExpression<A> createResult(Class<A> type, Expression<A> last) {
|
||||
@ -176,12 +195,12 @@ public final class CaseBuilder {
|
||||
}
|
||||
|
||||
public <A> Cases<A, SimpleExpression<A>> then(A constant) {
|
||||
return then(ConstantImpl.create(constant));
|
||||
return thenSimple(ConstantImpl.create(constant));
|
||||
}
|
||||
|
||||
// Boolean
|
||||
|
||||
public Cases<Boolean,BooleanExpression> then(BooleanExpression expr) {
|
||||
public Cases<Boolean, BooleanExpression> then(BooleanExpression expr) {
|
||||
return thenBoolean(expr);
|
||||
}
|
||||
|
||||
@ -200,6 +219,26 @@ public final class CaseBuilder {
|
||||
return thenBoolean(ConstantImpl.create(b));
|
||||
}
|
||||
|
||||
// Comparable
|
||||
|
||||
public <T extends Comparable> Cases<T, ComparableExpression<T>> then(ComparableExpression<T> expr) {
|
||||
return thenComparable(expr);
|
||||
}
|
||||
|
||||
private <T extends Comparable> Cases<T, ComparableExpression<T>> thenComparable(Expression<T> expr) {
|
||||
return new Cases<T, ComparableExpression<T>>((Class)expr.getType()) {
|
||||
@Override
|
||||
protected ComparableExpression<T> createResult(Class<T> type, Expression<T> last) {
|
||||
return ComparableOperation.create(type, Ops.CASE, last);
|
||||
}
|
||||
|
||||
}.addCase(when, expr);
|
||||
}
|
||||
|
||||
public <A extends Comparable> Cases<A, ComparableExpression<A>> then(A arg) {
|
||||
return thenComparable(ConstantImpl.create(arg));
|
||||
}
|
||||
|
||||
// Date
|
||||
|
||||
public <T extends Comparable> Cases<T, DateExpression<T>> then(DateExpression<T> expr) {
|
||||
@ -216,7 +255,7 @@ public final class CaseBuilder {
|
||||
}.addCase(when, expr);
|
||||
}
|
||||
|
||||
public Cases<java.sql.Date, DateExpression<java.sql.Date>> thenDate(java.sql.Date date) {
|
||||
public Cases<java.sql.Date, DateExpression<java.sql.Date>> then(java.sql.Date date) {
|
||||
return thenDate(ConstantImpl.create(date));
|
||||
}
|
||||
|
||||
@ -236,11 +275,11 @@ public final class CaseBuilder {
|
||||
}.addCase(when, expr);
|
||||
}
|
||||
|
||||
public Cases<Timestamp, DateTimeExpression<Timestamp>> thenDateTime(Timestamp ts) {
|
||||
public Cases<Timestamp, DateTimeExpression<Timestamp>> then(Timestamp ts) {
|
||||
return thenDateTime(ConstantImpl.create(ts));
|
||||
}
|
||||
|
||||
public Cases<java.util.Date, DateTimeExpression<java.util.Date>> thenDateTime(java.util.Date date) {
|
||||
public Cases<java.util.Date, DateTimeExpression<java.util.Date>> then(java.util.Date date) {
|
||||
return thenDateTime(ConstantImpl.create(date));
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
package com.mysema.query.support;
|
||||
|
||||
import com.mysema.query.types.*;
|
||||
import com.mysema.query.types.path.StringPath;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ReplaceVisitorTest {
|
||||
|
||||
private static final ReplaceVisitor visitor = new ReplaceVisitor() {
|
||||
public Expression<?> visit(Path<?> expr, @Nullable Void context) {
|
||||
if (expr.getMetadata().isRoot()) {
|
||||
return new PathImpl(expr.getType(), expr.getMetadata().getName() + "_");
|
||||
} else {
|
||||
return super.visit(expr, context);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void Operation() {
|
||||
Expression<String> str = new StringPath(new PathImpl(Object.class, "customer"), "name");
|
||||
Expression<String> str2 = new StringPath("str");
|
||||
Expression<String> concat = Expressions.stringOperation(Ops.CONCAT, str, str2);
|
||||
assertEquals("customer.name + str", concat.toString());
|
||||
assertEquals("customer_.name + str_", concat.accept(visitor, null).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TemplateExpression() {
|
||||
Expression<String> str = new StringPath(new PathImpl(Object.class, "customer"), "name");
|
||||
Expression<String> str2 = new StringPath("str");
|
||||
Expression<String> concat = Expressions.stringTemplate("{0} + {1}", str, str2);
|
||||
assertEquals("customer.name + str", concat.toString());
|
||||
assertEquals("customer_.name + str_", concat.accept(visitor, null).toString());
|
||||
}
|
||||
}
|
||||
@ -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.1">
|
||||
<!ENTITY versionNumber "3.3.2">
|
||||
<!ENTITY copyrightYear "2007-2014">
|
||||
<!ENTITY copyrightHolder "Mysema Ltd.">
|
||||
]>
|
||||
|
||||
@ -501,7 +501,7 @@ QCustomer customer = QCustomer.customer;
|
||||
// delete all customers
|
||||
new JPADeleteClause(entityManager, customer).execute();
|
||||
// delete all customers with a level less than 3
|
||||
new JPAeDeleteClause(entityManager, customer).where(customer.level.lt(3)).execute();
|
||||
new JPADeleteClause(entityManager, customer).where(customer.level.lt(3)).execute();
|
||||
]]></programlisting>
|
||||
|
||||
<para>The second parameter of the JPADeleteClause constructor is the entity to
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Querydsl JDO #
|
||||
## Querydsl JDO
|
||||
|
||||
The JDO module provides integration with the JDO API.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -14,12 +14,14 @@
|
||||
package com.mysema.query.jdo;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.jdo.PersistenceManager;
|
||||
import javax.jdo.Transaction;
|
||||
|
||||
import com.mysema.query.types.Projections;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
@ -98,6 +100,11 @@ public class BasicsTest extends AbstractJDOTest {
|
||||
query().from(product).singleResult(new Expression<?>[]{product});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FactoryExpression_In_GroupBy() {
|
||||
Expression<Product> productBean = Projections.bean(Product.class, product.name, product.description);
|
||||
assertFalse(query().from(product).groupBy(productBean).list(productBean).isEmpty());
|
||||
}
|
||||
|
||||
@Test(expected=NonUniqueResultException.class)
|
||||
public void Unique_Result_Throws_Exception_On_Multiple_Results() {
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Querydsl JPA #
|
||||
## Querydsl JPA
|
||||
|
||||
The JPA module provides integration with the JPA 2 persistence API.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -13,11 +13,6 @@
|
||||
*/
|
||||
package com.mysema.query.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mysema.query.JoinFlag;
|
||||
@ -25,19 +20,14 @@ import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.support.Context;
|
||||
import com.mysema.query.support.ListAccessVisitor;
|
||||
import com.mysema.query.support.QueryMixin;
|
||||
import com.mysema.query.types.CollectionExpression;
|
||||
import com.mysema.query.types.ConstantImpl;
|
||||
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.PathImpl;
|
||||
import com.mysema.query.types.PathMetadata;
|
||||
import com.mysema.query.types.PathType;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.support.ReplaceVisitor;
|
||||
import com.mysema.query.types.*;
|
||||
import com.mysema.query.types.path.CollectionPathBase;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* JPAQueryMixin extends {@link QueryMixin} to support JPQL join construction
|
||||
*
|
||||
@ -51,6 +41,8 @@ public class JPAQueryMixin<T> extends QueryMixin<T> {
|
||||
|
||||
private final Map<Expression<?>, Path<?>> aliases = Maps.newHashMap();
|
||||
|
||||
private ReplaceVisitor replaceVisitor;
|
||||
|
||||
public static final JoinFlag FETCH = new JoinFlag("fetch ");
|
||||
|
||||
public static final JoinFlag FETCH_ALL_PROPERTIES = new JoinFlag(" fetch all properties");
|
||||
@ -130,16 +122,32 @@ public class JPAQueryMixin<T> extends QueryMixin<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Path<T> convertPathForOrder(Path<T> path) {
|
||||
PathMetadata<?> metadata = path.getMetadata();
|
||||
// at least three levels
|
||||
if (metadata.getParent() != null && !metadata.getParent().getMetadata().isRoot()) {
|
||||
Path<?> shortened = shorten(metadata.getParent());
|
||||
return new PathImpl<T>(path.getType(),
|
||||
new PathMetadata(shortened, metadata.getElement(), metadata.getPathType()));
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <RT> Expression<RT> convert(Expression<RT> expr, boolean forOrder) {
|
||||
if (forOrder && expr instanceof Path) {
|
||||
Path<?> path = (Path<?>)expr;
|
||||
PathMetadata<?> metadata = path.getMetadata();
|
||||
// at least three levels
|
||||
if (metadata.getParent() != null && !metadata.getParent().getMetadata().isRoot()) {
|
||||
Path<?> shortened = shorten(metadata.getParent());
|
||||
expr = new PathImpl<RT>(expr.getType(),
|
||||
new PathMetadata(shortened, metadata.getElement(), metadata.getPathType()));
|
||||
if (forOrder) {
|
||||
if (expr instanceof Path) {
|
||||
expr = convertPathForOrder((Path)expr);
|
||||
} else {
|
||||
if (replaceVisitor == null) {
|
||||
replaceVisitor = new ReplaceVisitor() {
|
||||
public Expression<?> visit(Path<?> expr, Void context) {
|
||||
return convertPathForOrder(expr);
|
||||
}
|
||||
};
|
||||
}
|
||||
expr = (Expression<RT>)expr.accept(replaceVisitor, null);
|
||||
}
|
||||
}
|
||||
return Conversions.convert(super.convert(expr, forOrder));
|
||||
|
||||
@ -331,18 +331,6 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FactoryExpression<?> expr, Void context) {
|
||||
if (!inProjection) {
|
||||
append("(");
|
||||
super.visit(expr, context);
|
||||
append(")");
|
||||
} else {
|
||||
super.visit(expr, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void visitOperation(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) {
|
||||
|
||||
@ -1139,6 +1139,12 @@ public abstract class AbstractJPATest {
|
||||
assertEquals(2l, query().from(cat).where(where).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FactoryExpression_In_GroupBy() {
|
||||
Expression<Cat> catBean = Projections.bean(Cat.class, cat.id, cat.name);
|
||||
assertFalse(query().from(cat).groupBy(catBean).list(catBean).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void Size() {
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
package com.mysema.query.jpa;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mysema.query.JoinExpression;
|
||||
import com.mysema.query.JoinType;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
@ -15,6 +9,11 @@ import com.mysema.query.jpa.domain4.QBookVersion;
|
||||
import com.mysema.query.types.PathMetadataFactory;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.path.StringPath;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class JPAQueryMixinTest {
|
||||
|
||||
@ -41,6 +40,22 @@ public class JPAQueryMixinTest {
|
||||
md.getOrderBy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void OrderBy_Operation() {
|
||||
QCat cat = QCat.cat;
|
||||
QCat cat_mate = new QCat("cat_mate");
|
||||
mixin.from(cat);
|
||||
mixin.orderBy(cat.mate.name.lower().asc());
|
||||
|
||||
QueryMetadata md = mixin.getMetadata();
|
||||
assertEquals(Arrays.asList(
|
||||
new JoinExpression(JoinType.DEFAULT, cat),
|
||||
new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(cat_mate))),
|
||||
md.getJoins());
|
||||
assertEquals(Arrays.asList(cat_mate.name.lower().asc()),
|
||||
md.getOrderBy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void OrderBy_Long() {
|
||||
QCat cat = QCat.cat;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Querydsl Lucene #
|
||||
## Querydsl Lucene 3
|
||||
|
||||
The Lucene module provides integration with the Lucene indexing library.
|
||||
The Lucene module provides integration with the Lucene 3 indexing library.
|
||||
|
||||
**Maven integration**
|
||||
|
||||
@ -8,7 +8,7 @@ The Lucene module provides integration with the Lucene indexing library.
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-lucene</artifactId>
|
||||
<artifactId>querydsl-lucene3</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
|
||||
@ -16,7 +16,7 @@ The Lucene module provides integration with the Lucene indexing library.
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
</dependency>
|
||||
|
||||
|
||||
**Creating the query types**
|
||||
@ -55,4 +55,4 @@ which is transformed into the following Lucene query :
|
||||
|
||||
+year:[1800 TO 2000] +title:huckle*
|
||||
|
||||
For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s04.html
|
||||
For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s04.html
|
||||
|
||||
@ -5,13 +5,13 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-lucene3</artifactId>
|
||||
<name>Querydsl - Lucene support</name>
|
||||
<name>Querydsl - Lucene 3 support</name>
|
||||
<description>Lucene support for Querydsl</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Querydsl Lucene #
|
||||
## Querydsl Lucene 4
|
||||
|
||||
The Lucene module provides integration with the Lucene indexing library.
|
||||
The Lucene module provides integration with the Lucene 4 indexing library.
|
||||
|
||||
**Maven integration**
|
||||
|
||||
@ -8,7 +8,7 @@ The Lucene module provides integration with the Lucene indexing library.
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-lucene</artifactId>
|
||||
<artifactId>querydsl-lucene4</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@ -5,13 +5,13 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-lucene4</artifactId>
|
||||
<name>Querydsl - Lucene support</name>
|
||||
<name>Querydsl - Lucene 4 support</name>
|
||||
<description>Lucene support for Querydsl</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
@ -248,6 +249,13 @@ public class AbstractMetaDataExportMojo extends AbstractMojo{
|
||||
*/
|
||||
private boolean exportForeignKeys;
|
||||
|
||||
/**
|
||||
* override default column order (default: alphabetical)
|
||||
*
|
||||
* @parameter
|
||||
*/
|
||||
private String columnComparatorClass;
|
||||
|
||||
/**
|
||||
* java import added to generated query classes:
|
||||
* com.bar for package (without .* notation)
|
||||
@ -370,6 +378,14 @@ public class AbstractMetaDataExportMojo extends AbstractMojo{
|
||||
configuration.registerNumeric(mapping.size, mapping.digits, Class.forName(mapping.javaType));
|
||||
}
|
||||
}
|
||||
if (columnComparatorClass != null) {
|
||||
try {
|
||||
exporter.setColumnComparatorClass( (Class) Class.forName(this.columnComparatorClass).asSubclass(Comparator.class));
|
||||
} catch (ClassNotFoundException e) {
|
||||
getLog().error(e);
|
||||
throw new MojoExecutionException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
exporter.setConfiguration(configuration);
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Querydsl Mongodb #
|
||||
## Querydsl Mongodb
|
||||
|
||||
The Mongodb module provides integration with the Mongodb API.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.mysema.query.mongodb.domain.*;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -41,15 +42,10 @@ import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadPreference;
|
||||
import com.mysema.query.NonUniqueResultException;
|
||||
import com.mysema.query.SearchResults;
|
||||
import com.mysema.query.mongodb.domain.Address;
|
||||
import com.mysema.query.mongodb.domain.City;
|
||||
import com.mysema.query.mongodb.domain.Item;
|
||||
import com.mysema.query.mongodb.domain.MapEntity;
|
||||
import com.mysema.query.mongodb.domain.QAddress;
|
||||
import com.mysema.query.mongodb.domain.QItem;
|
||||
import com.mysema.query.mongodb.domain.QMapEntity;
|
||||
import com.mysema.query.mongodb.domain.QUser;
|
||||
import com.mysema.query.mongodb.domain.User;
|
||||
import com.mysema.query.mongodb.domain.User.Gender;
|
||||
import com.mysema.query.mongodb.morphia.MorphiaQuery;
|
||||
import com.mysema.query.types.EntityPath;
|
||||
@ -70,6 +66,7 @@ public class MongodbQueryTest {
|
||||
private final QItem item = QItem.item;
|
||||
private final QAddress address = QAddress.address;
|
||||
private final QMapEntity mapEntity = QMapEntity.mapEntity;
|
||||
private final QDates dates = QDates.dates;
|
||||
|
||||
List<User> users = Lists.newArrayList();
|
||||
User u1, u2, u3, u4;
|
||||
@ -77,7 +74,7 @@ public class MongodbQueryTest {
|
||||
|
||||
public MongodbQueryTest() throws UnknownHostException, MongoException {
|
||||
mongo = new Mongo();
|
||||
morphia = new Morphia().map(User.class).map(Item.class).map(MapEntity.class);
|
||||
morphia = new Morphia().map(User.class).map(Item.class).map(MapEntity.class).map(Dates.class);
|
||||
ds = morphia.createDatastore(mongo, dbname);
|
||||
}
|
||||
|
||||
@ -209,6 +206,19 @@ public class MongodbQueryTest {
|
||||
assertEquals(0, query().where(user.addresses.any().street.eq("akatu")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Dates() {
|
||||
Date start = new Date();
|
||||
ds.delete(ds.createQuery(Dates.class));
|
||||
Dates d = new Dates();
|
||||
d.setDate(new Date());
|
||||
ds.save(d);
|
||||
Date end = new Date();
|
||||
|
||||
assertEquals(d, query(dates).where(dates.date.between(start, end)).singleResult());
|
||||
assertEquals(0, query(dates).where(dates.date.between(new Date(0), start)).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ElemMatch() {
|
||||
// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1"}}}
|
||||
|
||||
@ -131,6 +131,12 @@ public class MongodbSerializerTest {
|
||||
assertQuery(title.ne("A"), dbo("title", dbo("$ne", "A")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Between() {
|
||||
System.err.println(dbo("year", dbo("$gte", 1).append("$lte", 10)));
|
||||
assertQuery(year.between(1, 10), dbo("year", dbo("$gte", 1).append("$lte", 10)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void LessAndGreaterAndBetween() {
|
||||
assertQuery(title.lt("A"), dbo("title", dbo("$lt", "A")));
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.mysema.query.mongodb.domain;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.mongodb.morphia.annotations.Entity;
|
||||
import org.mongodb.morphia.annotations.Id;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
public class Dates {
|
||||
|
||||
private @Id ObjectId id;
|
||||
|
||||
private Date date;
|
||||
|
||||
public ObjectId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(ObjectId id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Task;
|
||||
@ -182,6 +183,11 @@ public class AntMetaDataExporter extends Task {
|
||||
*
|
||||
*/
|
||||
private boolean beanPrintSupertype;
|
||||
|
||||
/**
|
||||
* override default column order (default: alphabetical)
|
||||
*/
|
||||
private String columnComparatorClass;
|
||||
|
||||
/**
|
||||
* java import added to generated query classes:
|
||||
@ -192,7 +198,8 @@ public class AntMetaDataExporter extends Task {
|
||||
private String[] imports;
|
||||
|
||||
|
||||
@Override
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void execute() {
|
||||
Connection dbConn = null;
|
||||
File targetPackagePath = new File(targetSourceFolder);
|
||||
@ -256,6 +263,9 @@ public class AntMetaDataExporter extends Task {
|
||||
if (sourceEncoding != null) {
|
||||
exporter.setSourceEncoding(sourceEncoding);
|
||||
}
|
||||
if (columnComparatorClass != null) {
|
||||
exporter.setColumnComparatorClass((Class) Class.forName(this.columnComparatorClass).asSubclass(Comparator.class));
|
||||
}
|
||||
|
||||
exporter.export(dbConn.getMetaData());
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011, 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
|
||||
@ -18,22 +18,22 @@ import com.mysema.util.JavaSyntaxUtils;
|
||||
|
||||
/**
|
||||
* AbstractNamingStrategy is an abstract base class for NamingStrategy implementations
|
||||
*
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractNamingStrategy implements NamingStrategy {
|
||||
|
||||
|
||||
protected String foreignKeysClassName = "ForeignKeys";
|
||||
|
||||
|
||||
protected String foreignKeysVariable = "fk";
|
||||
|
||||
|
||||
protected String primaryKeysClassName = "PrimaryKeys";
|
||||
|
||||
|
||||
protected String primaryKeysVariable = "pk";
|
||||
|
||||
|
||||
protected String reservedSuffix = "_col";
|
||||
|
||||
|
||||
@Override
|
||||
public String appendSchema(String packageName, String schemaName) {
|
||||
String suffix = schemaName.toLowerCase();
|
||||
@ -42,7 +42,7 @@ public abstract class AbstractNamingStrategy implements NamingStrategy {
|
||||
}
|
||||
return packageName + "." + suffix;
|
||||
}
|
||||
|
||||
|
||||
protected String escape(EntityType entityType, String name) {
|
||||
int suffix = 0;
|
||||
while (true) {
|
||||
@ -52,9 +52,9 @@ public abstract class AbstractNamingStrategy implements NamingStrategy {
|
||||
} else {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getForeignKeysClassName() {
|
||||
return foreignKeysClassName;
|
||||
@ -74,7 +74,34 @@ public abstract class AbstractNamingStrategy implements NamingStrategy {
|
||||
public String getPrimaryKeysVariable(EntityType entityType) {
|
||||
return primaryKeysVariable;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String normalizeColumnName(String columnName) {
|
||||
if (columnName != null) {
|
||||
return columnName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeTableName(String tableName) {
|
||||
if (tableName != null) {
|
||||
return tableName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeSchemaName(String schemaName) {
|
||||
if (schemaName != null) {
|
||||
return schemaName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setForeignKeysClassName(String foreignKeysClassName) {
|
||||
this.foreignKeysClassName = foreignKeysClassName;
|
||||
}
|
||||
|
||||
@ -93,21 +93,6 @@ public class DefaultNamingStrategy extends AbstractNamingStrategy {
|
||||
return getPropertyName(pkName, entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeColumnName(String columnName) {
|
||||
return columnName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeTableName(String tableName) {
|
||||
return tableName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeSchemaName(String schemaName) {
|
||||
return schemaName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
}
|
||||
|
||||
protected String normalizePropertyName(String name) {
|
||||
return Naming.normalize(name, reservedSuffix);
|
||||
}
|
||||
|
||||
@ -73,10 +73,10 @@ public class KeyDataFactory {
|
||||
try{
|
||||
while (foreignKeys.next()) {
|
||||
String name = foreignKeys.getString(FK_NAME);
|
||||
String parentColumnName = foreignKeys.getString(FK_PARENT_COLUMN_NAME);
|
||||
String foreignSchemaName = foreignKeys.getString(FK_FOREIGN_SCHEMA_NAME);
|
||||
String foreignTableName = foreignKeys.getString(FK_FOREIGN_TABLE_NAME);
|
||||
String foreignColumn = foreignKeys.getString(FK_FOREIGN_COLUMN_NAME);
|
||||
String parentColumnName = namingStrategy.normalizeColumnName(foreignKeys.getString(FK_PARENT_COLUMN_NAME));
|
||||
String foreignSchemaName = namingStrategy.normalizeSchemaName(foreignKeys.getString(FK_FOREIGN_SCHEMA_NAME));
|
||||
String foreignTableName = namingStrategy.normalizeTableName(foreignKeys.getString(FK_FOREIGN_TABLE_NAME));
|
||||
String foreignColumn = namingStrategy.normalizeColumnName(foreignKeys.getString(FK_FOREIGN_COLUMN_NAME));
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = tableName + "_" + foreignTableName + "_IFK";
|
||||
}
|
||||
@ -102,10 +102,10 @@ public class KeyDataFactory {
|
||||
try{
|
||||
while (foreignKeys.next()) {
|
||||
String name = foreignKeys.getString(FK_NAME);
|
||||
String parentSchemaName = foreignKeys.getString(FK_PARENT_SCHEMA_NAME);
|
||||
String parentTableName = foreignKeys.getString(FK_PARENT_TABLE_NAME);
|
||||
String parentColumnName = foreignKeys.getString(FK_PARENT_COLUMN_NAME);
|
||||
String foreignColumn = foreignKeys.getString(FK_FOREIGN_COLUMN_NAME);
|
||||
String parentSchemaName = namingStrategy.normalizeSchemaName(foreignKeys.getString(FK_PARENT_SCHEMA_NAME));
|
||||
String parentTableName = namingStrategy.normalizeTableName(foreignKeys.getString(FK_PARENT_TABLE_NAME));
|
||||
String parentColumnName = namingStrategy.normalizeColumnName(foreignKeys.getString(FK_PARENT_COLUMN_NAME));
|
||||
String foreignColumn = namingStrategy.normalizeColumnName(foreignKeys.getString(FK_FOREIGN_COLUMN_NAME));
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = tableName + "_" + parentTableName + "_FK";
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -251,6 +252,7 @@ public class MetaDataExporter {
|
||||
int columnType = columns.getInt("DATA_TYPE");
|
||||
Number columnSize = (Number) columns.getObject("COLUMN_SIZE");
|
||||
Number columnDigits = (Number) columns.getObject("DECIMAL_DIGITS");
|
||||
int columnIndex = columns.getInt("ORDINAL_POSITION");
|
||||
int nullable = columns.getInt("NULLABLE");
|
||||
|
||||
String propertyName = namingStrategy.getPropertyName(normalizedColumnName, classModel);
|
||||
@ -269,7 +271,7 @@ public class MetaDataExporter {
|
||||
}
|
||||
Type typeModel = new ClassType(fieldType, clazz);
|
||||
Property property = createProperty(classModel, normalizedColumnName, propertyName, typeModel);
|
||||
ColumnMetadata column = ColumnMetadata.named(normalizedColumnName).ofType(columnType);
|
||||
ColumnMetadata column = ColumnMetadata.named(normalizedColumnName).ofType(columnType).withIndex(columnIndex);
|
||||
if (nullable == DatabaseMetaData.columnNoNulls) {
|
||||
column = column.notNull();
|
||||
}
|
||||
@ -539,6 +541,13 @@ public class MetaDataExporter {
|
||||
module.bind(SQLCodegenModule.INNER_CLASSES_FOR_KEYS, innerClassesForKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param columnComparator
|
||||
*/
|
||||
public void setColumnComparatorClass(Class<? extends Comparator<Property>> columnComparatorClass) {
|
||||
module.bind(SQLCodegenModule.COLUMN_COMPARATOR, columnComparatorClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param serializerClass
|
||||
*/
|
||||
|
||||
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -28,6 +29,7 @@ import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mysema.codegen.CodeWriter;
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
@ -35,7 +37,6 @@ import com.mysema.codegen.model.SimpleType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.model.Types;
|
||||
import com.mysema.query.codegen.CodegenModule;
|
||||
import com.mysema.query.codegen.EntitySerializer;
|
||||
import com.mysema.query.codegen.EntityType;
|
||||
import com.mysema.query.codegen.Property;
|
||||
@ -64,6 +65,8 @@ public class MetaDataSerializer extends EntitySerializer {
|
||||
private final boolean innerClassesForKeys;
|
||||
|
||||
private final Set<String> imports;
|
||||
|
||||
private final Comparator<Property> columnComparator;
|
||||
|
||||
/**
|
||||
* Create a new MetaDataSerializer instance
|
||||
@ -77,11 +80,13 @@ public class MetaDataSerializer extends EntitySerializer {
|
||||
TypeMappings typeMappings,
|
||||
NamingStrategy namingStrategy,
|
||||
@Named(SQLCodegenModule.INNER_CLASSES_FOR_KEYS) boolean innerClassesForKeys,
|
||||
@Named(SQLCodegenModule.IMPORTS) Set<String> imports) {
|
||||
@Named(SQLCodegenModule.IMPORTS) Set<String> imports,
|
||||
@Named(SQLCodegenModule.COLUMN_COMPARATOR) Comparator<Property> columnComparator) {
|
||||
super(typeMappings,Collections.<String>emptyList());
|
||||
this.namingStrategy = namingStrategy;
|
||||
this.innerClassesForKeys = innerClassesForKeys;
|
||||
this.imports = new HashSet<String>(imports);
|
||||
this.columnComparator = columnComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -203,12 +208,17 @@ public class MetaDataSerializer extends EntitySerializer {
|
||||
@Override
|
||||
protected void outro(EntityType model, CodeWriter writer) throws IOException {
|
||||
writer.beginPublicMethod(Types.VOID,"addMetadata");
|
||||
for (Property property : model.getProperties()) {
|
||||
List<Property> properties = Lists.newArrayList(model.getProperties());
|
||||
if (columnComparator != null) {
|
||||
Collections.sort(properties, columnComparator);
|
||||
}
|
||||
for (Property property : properties) {
|
||||
String name = property.getEscapedName();
|
||||
ColumnMetadata metadata = (ColumnMetadata) property.getData().get("COLUMN");
|
||||
StringBuilder columnMeta = new StringBuilder();
|
||||
columnMeta.append("ColumnMetadata");
|
||||
columnMeta.append(".named(\"" + metadata.getName() + "\")");
|
||||
columnMeta.append(".withIndex(" + metadata.getIndex() + ")");
|
||||
columnMeta.append(".ofType(" + metadata.getJdbcType() + ")");
|
||||
if (metadata.hasSize()) {
|
||||
columnMeta.append(".withSize(" + metadata.getSize() + ")");
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package com.mysema.query.sql.codegen;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mysema.query.codegen.Property;
|
||||
import com.mysema.query.sql.ColumnMetadata;
|
||||
|
||||
public class OrdinalPositionComparator implements Comparator<Property> {
|
||||
|
||||
public OrdinalPositionComparator() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Property property1, Property property2) {
|
||||
Integer comparison = null;
|
||||
for (Property property : Arrays.asList(property1, property2)) {
|
||||
Map<Object, Object> data = property.getData();
|
||||
ColumnMetadata columnMetadata = (ColumnMetadata) data.get("COLUMN");
|
||||
int index = columnMetadata.getIndex();
|
||||
comparison = comparison == null ? index : comparison - index;
|
||||
}
|
||||
return comparison;
|
||||
}
|
||||
|
||||
}
|
||||
@ -58,21 +58,6 @@ public class OriginalNamingStrategy extends AbstractNamingStrategy {
|
||||
return getPropertyName(primaryKeyName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeColumnName(String columnName) {
|
||||
return columnName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeTableName(String tableName) {
|
||||
return tableName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeSchemaName(String schemaName) {
|
||||
return schemaName.replaceAll("\r", "").replaceAll("\n", " ");
|
||||
}
|
||||
|
||||
private String getPropertyName(String name) {
|
||||
return Naming.normalize(name, reservedSuffix);
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ public class SQLCodegenModule extends CodegenModule{
|
||||
|
||||
public static final String SCHEMA_TO_PACKAGE = "schemaToPackage";
|
||||
|
||||
public static final String COLUMN_COMPARATOR = "columnComparator";
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
@ -57,6 +59,7 @@ public class SQLCodegenModule extends CodegenModule{
|
||||
bind(PACKAGE_NAME, "com.example");
|
||||
bind(BEAN_SERIALIZER, (Class<?>)null);
|
||||
bind(SCHEMA_TO_PACKAGE, false);
|
||||
bind(COLUMN_COMPARATOR, null);
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
|
||||
@ -115,6 +115,12 @@ public class MetaDataExporterTest {
|
||||
// multi key
|
||||
stmt.execute("create table multikey(id INT, id2 VARCHAR, id3 INT, CONSTRAINT pk_multikey PRIMARY KEY (id, id2, id3) )");
|
||||
|
||||
// M_PRODUCT_BOM_ID
|
||||
stmt.execute("create table product(id int, "
|
||||
+ "m_product_bom_id int, "
|
||||
+ "m_productbom_id int, "
|
||||
+ "constraint product_bom foreign key (m_productbom_id) references product(id))");
|
||||
|
||||
}finally{
|
||||
stmt.close();
|
||||
}
|
||||
@ -146,14 +152,14 @@ public class MetaDataExporterTest {
|
||||
|
||||
@Test
|
||||
public void NormalSettings_Repetition() throws SQLException {
|
||||
test("Q", "", "", "", defaultNaming, "target/1", false, false);
|
||||
test("Q", "", "", "", defaultNaming, "target/1", false, false, false);
|
||||
|
||||
File file = new File("target/1/test/QEmployee.java");
|
||||
long lastModified = file.lastModified();
|
||||
assertTrue(file.exists());
|
||||
|
||||
clean = false;
|
||||
test("Q", "", "", "", defaultNaming, "target/1", false, false);
|
||||
test("Q", "", "", "", defaultNaming, "target/1", false, false, false);
|
||||
assertEquals(lastModified, file.lastModified());
|
||||
}
|
||||
|
||||
@ -173,14 +179,15 @@ public class MetaDataExporterTest {
|
||||
for (boolean exportColumns : trueAndFalse) {
|
||||
for (String beanPackage : Arrays.asList("test2", null)) {
|
||||
for (Serializer beanSerializer : BEAN_SERIALIZERS) {
|
||||
for (boolean withOriginalPositioning : trueAndFalse) {
|
||||
counter++;
|
||||
this.beanPackageName = beanPackage;
|
||||
this.schemaToPackage = schemaToPackage;
|
||||
this.exportColumns = exportColumns;
|
||||
this.beanSerializer = beanSerializer;
|
||||
test(namePrefix, nameSuffix, beanPrefix, beanSuffix,
|
||||
ns, "target/multiple_"+counter, withBeans, withInnerClasses);
|
||||
}}}}}}}}}}}
|
||||
ns, "target/multiple_"+counter, withBeans, withInnerClasses, withOriginalPositioning);
|
||||
}}}}}}}}}}}}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -284,7 +291,7 @@ public class MetaDataExporterTest {
|
||||
|
||||
private void test(String namePrefix, String nameSuffix, String beanPrefix, String beanSuffix,
|
||||
NamingStrategy namingStrategy, String target, boolean withBeans,
|
||||
boolean withInnerClasses) throws SQLException{
|
||||
boolean withInnerClasses, boolean withOrdinalPositioning) throws SQLException{
|
||||
File targetDir = new File(target);
|
||||
if (clean) {
|
||||
try {
|
||||
@ -312,6 +319,9 @@ public class MetaDataExporterTest {
|
||||
if (withBeans) {
|
||||
exporter.setBeanSerializer(beanSerializer);
|
||||
}
|
||||
if (withOrdinalPositioning) {
|
||||
exporter.setColumnComparatorClass(OrdinalPositionComparator.class);
|
||||
}
|
||||
exporter.export(connection.getMetaData());
|
||||
|
||||
JavaCompiler compiler = new SimpleCompiler();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Querydsl SQL #
|
||||
## Querydsl SQL
|
||||
|
||||
The SQL module provides integration with the JDBC API.
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>3.3.2.BUILD-SNAPSHOT</version>
|
||||
<version>3.3.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../querydsl-root/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<version>1.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
</dependency>
|
||||
|
||||
@ -52,6 +52,7 @@ public class CUBRIDTemplates extends SQLTemplates {
|
||||
setParameterMetadataAvailable(false);
|
||||
setNullsFirst(null);
|
||||
setNullsLast(null);
|
||||
setDefaultValues("\ndefault values");
|
||||
|
||||
add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})");
|
||||
add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})");
|
||||
|
||||
@ -61,12 +61,14 @@ public final class ColumnMetadata implements Serializable {
|
||||
* if the name is null
|
||||
*/
|
||||
public static ColumnMetadata named(String name) {
|
||||
return new ColumnMetadata(name, null, true, UNDEFINED, UNDEFINED);
|
||||
return new ColumnMetadata(null, name, null, true, UNDEFINED, UNDEFINED);
|
||||
}
|
||||
|
||||
private static final int UNDEFINED = -1;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Integer index;
|
||||
|
||||
private final Integer jdbcType;
|
||||
|
||||
@ -76,8 +78,9 @@ public final class ColumnMetadata implements Serializable {
|
||||
|
||||
private final int decimalDigits;
|
||||
|
||||
private ColumnMetadata(String name, Integer jdbcType, boolean nullable, int size,
|
||||
private ColumnMetadata(Integer index, String name, Integer jdbcType, boolean nullable, int size,
|
||||
int decimalDigits) {
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.jdbcType = jdbcType;
|
||||
this.nullable = nullable;
|
||||
@ -88,6 +91,14 @@ public final class ColumnMetadata implements Serializable {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public ColumnMetadata withIndex(int index) {
|
||||
return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits);
|
||||
}
|
||||
|
||||
public int getJdbcType() {
|
||||
return jdbcType;
|
||||
@ -98,7 +109,7 @@ public final class ColumnMetadata implements Serializable {
|
||||
}
|
||||
|
||||
public ColumnMetadata ofType(int jdbcType) {
|
||||
return new ColumnMetadata(name, jdbcType, nullable, size, decimalDigits);
|
||||
return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits);
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
@ -106,7 +117,7 @@ public final class ColumnMetadata implements Serializable {
|
||||
}
|
||||
|
||||
public ColumnMetadata notNull() {
|
||||
return new ColumnMetadata(name, jdbcType, false, size, decimalDigits);
|
||||
return new ColumnMetadata(index, name, jdbcType, false, size, decimalDigits);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +134,7 @@ public final class ColumnMetadata implements Serializable {
|
||||
}
|
||||
|
||||
public ColumnMetadata withSize(int size) {
|
||||
return new ColumnMetadata(name, jdbcType, nullable, size, decimalDigits);
|
||||
return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +151,7 @@ public final class ColumnMetadata implements Serializable {
|
||||
}
|
||||
|
||||
public ColumnMetadata withDigits(int decimalDigits) {
|
||||
return new ColumnMetadata(name, jdbcType, nullable, size, decimalDigits);
|
||||
return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -54,6 +54,7 @@ public class DerbyTemplates extends SQLTemplates {
|
||||
addClass2TypeMappings("smallint", Byte.class);
|
||||
setAutoIncrement(" generated always as identity");
|
||||
setFunctionJoinsWrapped(true);
|
||||
setDefaultValues("\nvalues (default)");
|
||||
|
||||
add(Ops.CONCAT, "varchar({0} || {1})");
|
||||
add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})");
|
||||
|
||||
@ -44,6 +44,7 @@ public class HSQLDBTemplates extends SQLTemplates {
|
||||
super("\"", escape, quote);
|
||||
setLimitRequired(true);
|
||||
setAutoIncrement(" identity");
|
||||
setDefaultValues("\ndefault values");
|
||||
add(Ops.TRIM, "trim(both from {0})");
|
||||
add(Ops.NEGATE, "{0} * -1", 7);
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ public class PostgresTemplates extends SQLTemplates {
|
||||
setDummyTable(null);
|
||||
setCountDistinctMultipleColumns(true);
|
||||
setCountViaAnalytics(true);
|
||||
setDefaultValues("\ndefault values");
|
||||
|
||||
// type mappings
|
||||
addClass2TypeMappings("numeric(3,0)", Byte.class);
|
||||
|
||||
@ -47,9 +47,7 @@ public class RelationalPathBase<T> extends BeanPath<T> implements RelationalPath
|
||||
@Nullable
|
||||
private PrimaryKey<T> primaryKey;
|
||||
|
||||
private final List<Path<?>> columns = Lists.newArrayList();
|
||||
|
||||
private final Map<Path<?>, ColumnMetadata> columnMetadata = Maps.newHashMap();
|
||||
private final Map<Path<?>, ColumnMetadata> columnMetadata = Maps.newLinkedHashMap();
|
||||
|
||||
private final List<ForeignKey<?>> foreignKeys = Lists.newArrayList();
|
||||
|
||||
@ -143,20 +141,19 @@ public class RelationalPathBase<T> extends BeanPath<T> implements RelationalPath
|
||||
}
|
||||
|
||||
public Path<?>[] all() {
|
||||
Path<?>[] all = new Path[columns.size()];
|
||||
columns.toArray(all);
|
||||
Path<?>[] all = new Path[columnMetadata.size()];
|
||||
columnMetadata.keySet().toArray(all);
|
||||
return all;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <P extends Path<?>> P add(P path) {
|
||||
columns.add(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path<?>> getColumns() {
|
||||
return columns;
|
||||
return Lists.newArrayList(this.columnMetadata.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -537,11 +537,15 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
|
||||
}
|
||||
}
|
||||
|
||||
// values
|
||||
append(templates.getValues());
|
||||
append("(");
|
||||
handle(COMMA, values);
|
||||
append(")");
|
||||
if (!values.isEmpty()) {
|
||||
// values
|
||||
append(templates.getValues());
|
||||
append("(");
|
||||
handle(COMMA, values);
|
||||
append(")");
|
||||
} else {
|
||||
append(templates.getDefaultValues());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ public class SQLServerTemplates extends SQLTemplates {
|
||||
setDummyTable("");
|
||||
setNullsFirst(null);
|
||||
setNullsLast(null);
|
||||
setDefaultValues("\ndefault values");
|
||||
|
||||
// String
|
||||
add(Ops.CONCAT, "{0} + {1}", 13);
|
||||
|
||||
@ -176,6 +176,8 @@ public class SQLTemplates extends Templates {
|
||||
|
||||
private String values = "\nvalues ";
|
||||
|
||||
private String defaultValues = "\nvalues ()";
|
||||
|
||||
private String where = "\nwhere ";
|
||||
|
||||
private String with = "with ";
|
||||
@ -584,6 +586,10 @@ public class SQLTemplates extends Templates {
|
||||
return values;
|
||||
}
|
||||
|
||||
public final String getDefaultValues() {
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
public final String getWhere() {
|
||||
return where;
|
||||
}
|
||||
@ -946,6 +952,10 @@ public class SQLTemplates extends Templates {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
protected void setDefaultValues(String defaultValues) {
|
||||
this.defaultValues = defaultValues;
|
||||
}
|
||||
|
||||
protected void setWhere(String where) {
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ public class SQLiteTemplates extends SQLTemplates {
|
||||
setLimitRequired(true);
|
||||
setNullsFirst(null);
|
||||
setNullsLast(null);
|
||||
setDefaultValues("\ndefault values");
|
||||
add(Ops.MOD, "{0} % {1}");
|
||||
|
||||
add(Ops.INDEX_OF, "charindex({1},{0},1)-1");
|
||||
|
||||
@ -57,6 +57,7 @@ public class TeradataTemplates extends SQLTemplates {
|
||||
setNullsLast(null);
|
||||
setDummyTable(null);
|
||||
setCountViaAnalytics(true);
|
||||
setDefaultValues("\ndefault values");
|
||||
|
||||
addClass2TypeMappings("byteint", Byte.class);
|
||||
addClass2TypeMappings("double precision", Double.class);
|
||||
|
||||
@ -28,6 +28,9 @@ import static org.junit.Assert.assertTrue;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.mysema.query.sql.domain.QDateTest;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
@ -53,6 +56,8 @@ public class InsertBase extends AbstractBaseTest {
|
||||
private void reset() throws SQLException{
|
||||
delete(survey).execute();
|
||||
insert(survey).values(1, "Hello World", "Hello").execute();
|
||||
|
||||
delete(QDateTest.qDateTest).execute();
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -65,6 +70,30 @@ public class InsertBase extends AbstractBaseTest {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Insert_Dates() {
|
||||
QDateTest dateTest = QDateTest.qDateTest;
|
||||
LocalDate localDate = new LocalDate(1978, 1, 2);
|
||||
|
||||
Path<LocalDate> localDateProperty = new PathImpl<LocalDate>(LocalDate.class, "DATE_TEST");
|
||||
Path<DateTime> dateTimeProperty = new PathImpl<DateTime>(DateTime.class, "DATE_TEST");
|
||||
SQLInsertClause insert = insert(dateTest);
|
||||
insert.set(localDateProperty, localDate);
|
||||
insert.execute();
|
||||
|
||||
Tuple result = query().from(dateTest).singleResult(
|
||||
dateTest.dateTest.year(),
|
||||
dateTest.dateTest.month(),
|
||||
dateTest.dateTest.dayOfMonth(),
|
||||
dateTimeProperty);
|
||||
assertEquals(Integer.valueOf(1978), result.get(0, Integer.class));
|
||||
assertEquals(Integer.valueOf(1), result.get(1, Integer.class));
|
||||
assertEquals(Integer.valueOf(2), result.get(2, Integer.class));
|
||||
|
||||
DateTime dateTime = result.get(dateTimeProperty);
|
||||
assertEquals(dateTime, localDate.toDateTimeAtStartOfDay());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Complex1() {
|
||||
// related to #584795
|
||||
@ -137,6 +166,12 @@ public class InsertBase extends AbstractBaseTest {
|
||||
.values(4, null, null).execute());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExcludeIn({HSQLDB, DERBY})
|
||||
public void Insert_Without_Values() {
|
||||
assertEquals(1, insert(survey).execute());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExcludeIn(ORACLE)
|
||||
public void Insert_Nulls_In_Batch() {
|
||||
|
||||
@ -50,6 +50,13 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mysema.query.types.*;
|
||||
import com.google.common.collect.Maps;
|
||||
import junit.framework.Assert;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.LocalTime;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -70,19 +77,6 @@ import com.mysema.query.sql.domain.QEmployee;
|
||||
import com.mysema.query.sql.domain.QEmployeeNoPK;
|
||||
import com.mysema.query.sql.domain.QIdName;
|
||||
import com.mysema.query.support.Expressions;
|
||||
import com.mysema.query.types.ArrayConstructorExpression;
|
||||
import com.mysema.query.types.Concatenation;
|
||||
import com.mysema.query.types.ConstantImpl;
|
||||
import com.mysema.query.types.ConstructorExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.MappingProjection;
|
||||
import com.mysema.query.types.ParamNotSetException;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.PathImpl;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.QBean;
|
||||
import com.mysema.query.types.QTuple;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.expr.BooleanExpression;
|
||||
import com.mysema.query.types.expr.Coalesce;
|
||||
import com.mysema.query.types.expr.DateExpression;
|
||||
@ -370,6 +364,56 @@ public class SelectBase extends AbstractBaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IncludeIn({H2, SQLSERVER, MYSQL, ORACLE, SQLITE, 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();
|
||||
long tsTime = new org.joda.time.LocalTime(ts).getMillisOfDay();
|
||||
|
||||
List<Object> data = Lists.newArrayList();
|
||||
data.add(new java.util.Date(ts));
|
||||
data.add(new java.util.Date(tsDate));
|
||||
data.add(new java.util.Date(tsTime));
|
||||
data.add(new java.sql.Timestamp(ts));
|
||||
data.add(new java.sql.Timestamp(tsDate));
|
||||
data.add(new java.sql.Date(110, 0, 1));
|
||||
data.add(new java.sql.Date(tsDate));
|
||||
data.add(new java.sql.Time(0, 0, 0));
|
||||
data.add(new java.sql.Time(12, 30, 0));
|
||||
data.add(new java.sql.Time(23, 59, 59));
|
||||
//data.add(new java.sql.Time(tsTime));
|
||||
data.add(new DateTime(ts));
|
||||
data.add(new DateTime(tsDate));
|
||||
data.add(new DateTime(tsTime));
|
||||
data.add(new LocalDateTime(ts));
|
||||
data.add(new LocalDateTime(tsDate));
|
||||
data.add(new LocalDateTime(2014, 3, 30, 2, 0));
|
||||
data.add(new LocalDate(2010, 1, 1));
|
||||
data.add(new LocalDate(ts));
|
||||
data.add(new LocalDate(tsDate));
|
||||
data.add(new LocalTime(0, 0, 0));
|
||||
data.add(new LocalTime(12, 30, 0));
|
||||
data.add(new LocalTime(23, 59, 59));
|
||||
data.add(new LocalTime(ts));
|
||||
data.add(new LocalTime(tsTime));
|
||||
|
||||
Map<Object, Object> failures = Maps.newIdentityHashMap();
|
||||
for (Object dt : data) {
|
||||
Object dt2 = query().singleResult(new ConstantImpl(dt));
|
||||
if (!dt.equals(dt2)) {
|
||||
failures.put(dt, dt2);
|
||||
}
|
||||
}
|
||||
if (!failures.isEmpty()) {
|
||||
for (Map.Entry<Object, Object> entry : failures.entrySet()) {
|
||||
System.out.println(entry.getKey().getClass().getName()
|
||||
+ ": " + entry.getKey() + " != " + entry.getValue());
|
||||
}
|
||||
Assert.fail("Failed with " + failures);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExcludeIn({SQLITE})
|
||||
public void Date_Add() {
|
||||
@ -508,6 +552,12 @@ public class SelectBase extends AbstractBaseTest {
|
||||
assertTrue(query().from(employee).where(employee.firstname.eq("Barbara")).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FactoryExpression_In_GroupBy() {
|
||||
Expression<Employee> empBean = Projections.bean(Employee.class, employee.id, employee.superiorId);
|
||||
assertFalse(query().from(employee).groupBy(empBean).list(empBean).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExcludeIn({H2, SQLITE, DERBY, CUBRID, MYSQL})
|
||||
public void Full_Join() throws SQLException {
|
||||
|
||||
@ -21,6 +21,8 @@ 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;
|
||||
@ -102,5 +104,13 @@ public class SQLTemplatesTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Numeric_Operations() {
|
||||
NumberPath<Integer> intPath = Expressions.numberPath(Integer.class, "intPath");
|
||||
NumberPath<Integer> intPath2 = Expressions.numberPath(Integer.class, "intPath2");
|
||||
SQLSerializer serializer = new SQLSerializer(new Configuration(SQLTemplates.DEFAULT));
|
||||
serializer.handle(intPath.subtract(intPath2.add(2)));
|
||||
assertEquals("intPath - (intPath2 + ?)", serializer.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package com.mysema.query.sql.domain;
|
||||
|
||||
import com.mysema.query.sql.ColumnMetadata;
|
||||
import com.mysema.query.sql.RelationalPathBase;
|
||||
import com.mysema.query.types.PathMetadata;
|
||||
import com.mysema.query.types.PathMetadataFactory;
|
||||
import com.mysema.query.types.path.DatePath;
|
||||
|
||||
import java.sql.Date;
|
||||
|
||||
public class QDateTest extends RelationalPathBase<QDateTest> {
|
||||
|
||||
private static final long serialVersionUID = 1394463749655231079L;
|
||||
|
||||
public static final QDateTest qDateTest = new QDateTest("DATE_TEST");
|
||||
|
||||
public final DatePath<Date> dateTest = createDate("dateTest", java.sql.Date.class);
|
||||
|
||||
public QDateTest(String path) {
|
||||
super(QDateTest.class, PathMetadataFactory.forVariable(path), "PUBLIC", "DATE_TEST");
|
||||
addMetadata();
|
||||
}
|
||||
|
||||
public QDateTest(PathMetadata<?> metadata) {
|
||||
super(QDateTest.class, metadata, "PUBLIC", "DATE_TEST");
|
||||
addMetadata();
|
||||
}
|
||||
|
||||
protected void addMetadata() {
|
||||
addMetadata(dateTest, ColumnMetadata.named("DATE_TEST"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.mysema.query.types;
|
||||
package com.mysema.query.sql.types;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.mysema.query.types;
|
||||
package com.mysema.query.sql.types;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mysema.query.types;
|
||||
package com.mysema.query.sql.types;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
Loading…
Reference in New Issue
Block a user