diff --git a/querydsl-scala/readme.txt b/querydsl-scala/readme.txt new file mode 100644 index 000000000..6e19483ed --- /dev/null +++ b/querydsl-scala/readme.txt @@ -0,0 +1,11 @@ +Naming options : + +_ : (domainType.firstName _like "An%") _and (domainType.firstName _like "Be%") + +_ : (domainType.firstName like_ "An%") and_ (domainType.firstName like_ "Be%") + +$ : (domainType.firstName $like "An%") $and (domainType.firstName $like "Be%") + +Caps start : (domainType.firstName Like "An%") And (domainType.firstName Like "Be%") + +Full caps : (domainType.firstName LIKE "An%") AND (domainType.firstName LIKE "Be%") diff --git a/querydsl-scala/src/main/scala/com/mysema/query/scala/Conversions.scala b/querydsl-scala/src/main/scala/com/mysema/query/scala/Conversions.scala index c5ce1c34f..d3089a129 100644 --- a/querydsl-scala/src/main/scala/com/mysema/query/scala/Conversions.scala +++ b/querydsl-scala/src/main/scala/com/mysema/query/scala/Conversions.scala @@ -8,8 +8,6 @@ package com.mysema.query.scala; import com.mysema.query.alias._; import com.mysema.query.types._ -import com.mysema.query.types.expr._ -import com.mysema.query.types.path._ import org.apache.commons.lang.StringUtils; @@ -43,10 +41,39 @@ object Conversions { implicit def comparablePath(c: Comparable[_]): ComparablePath[_] = aliasFactory.getCurrentAndReset(); - implicit def simplePath(s: Object): SimplePath[_] = aliasFactory.getCurrentAndReset(); + //implicit def simplePath(s: Object): SimplePath[_] = aliasFactory.getCurrentAndReset(); + + implicit def entityPath(arg: Object): EntityPathImpl[_] = { + var rv : EntityPathImpl[_] = aliasFactory.getCurrentAndReset(); + if (rv != null) { + rv; + }else { + arg match { + case x:EntityPathImpl[_] => x; + case x:ManagedObject => x.__mappedPath.asInstanceOf[EntityPathImpl[_]]; + case _ => null; + } + } + } implicit def numberPath[N <: Number with Comparable[N]](n: N): NumberPath[N] = aliasFactory.getCurrentAndReset(); + implicit def scalaCollectionPath[T](c: scala.Collection[T]): CollectionPath[T] = aliasFactory.getCurrentAndReset(); + + implicit def scalaListPath[T](l: scala.List[T]): ListPath[T] = aliasFactory.getCurrentAndReset(); + + implicit def scalaSetPath[T](c: scala.collection.Set[T]): SetPath[T] = aliasFactory.getCurrentAndReset(); + + implicit def scalaMapPath[K,V](l: scala.collection.Map[K,V]): MapPath[K,V] = aliasFactory.getCurrentAndReset(); + + implicit def javaCollectionPath[T](c: java.util.Collection[T]): CollectionPath[T] = aliasFactory.getCurrentAndReset(); + + implicit def javaListPath[T](l: java.util.List[T]): ListPath[T] = aliasFactory.getCurrentAndReset(); + + implicit def javaSetPath[T](c: java.util.Set[T]): SetPath[T] = aliasFactory.getCurrentAndReset(); + + implicit def javaMapPath[K,V](l: java.util.Map[K,V]): MapPath[K,V] = aliasFactory.getCurrentAndReset(); + } class PathFactoryImpl extends PathFactory { @@ -81,4 +108,12 @@ class PathFactoryImpl extends PathFactory { def createMapPath[K,V](k: Class[K], v: Class[V], md: PathMetadata[_]) = Paths.map(k, v, md); + def isCollectionType(cl: Class[_]) = classOf[java.util.Collection[_]].isAssignableFrom(cl) || classOf[scala.Collection[_]].isAssignableFrom(cl); + + def isSetType(cl: Class[_]) = classOf[java.util.Set[_]].isAssignableFrom(cl) || classOf[scala.collection.Set[_]].isAssignableFrom(cl); + + def isListType(cl: Class[_]) = classOf[java.util.List[_]].isAssignableFrom(cl) || classOf[scala.List[_]].isAssignableFrom(cl); + + def isMapType(cl: Class[_]) = classOf[java.util.Map[_,_]].isAssignableFrom(cl) || classOf[scala.collection.Map[_,_]].isAssignableFrom(cl); + } diff --git a/querydsl-scala/src/main/scala/com/mysema/query/scala/Expressions.scala b/querydsl-scala/src/main/scala/com/mysema/query/scala/Expressions.scala index 933a34a7f..00fa7470c 100644 --- a/querydsl-scala/src/main/scala/com/mysema/query/scala/Expressions.scala +++ b/querydsl-scala/src/main/scala/com/mysema/query/scala/Expressions.scala @@ -4,11 +4,14 @@ * */ package com.mysema.query.scala; + import com.mysema.query.scala.Constants._ import com.mysema.query.scala.Operations._ import com.mysema.query.types._ +import com.mysema.query.types.PathMetadataFactory._ import com.mysema.query.types.Ops._ + import java.util.Collection import java.util.Arrays._; @@ -61,31 +64,52 @@ trait SimpleExpression[T] extends Expression[T] { trait ArrayExpression[T <: Array[_]] extends SimpleExpression[T] { - // TODO + def _size() = number[Integer](classOf[Integer], Ops.ARRAY_SIZE, this); + +// def _get(index: Integer) = Paths.simple(getType.getComponentType, forArrayAccess(this, index.intValue)); } -trait CollectionExpression[T] extends SimpleExpression[java.util.Collection[T]] { +trait CollectionExpressionBase[T <: Collection[_]] extends SimpleExpression[T] with ParametrizedExpression[T] { - // TODO + def _size() = number[Integer](classOf[Integer], COL_SIZE, this); + + def _isEmpty() = boolean(COL_IS_EMPTY, this); + + def _isNotEmpty() = _isEmpty().not; + + def _contains(child: T) = boolean(IN, constant(child), this); + + def _contains(child: Expression[T]) = boolean(IN, child, this); +} + +trait CollectionExpression[T] extends CollectionExpressionBase[java.util.Collection[T]] { } + +trait SetExpression[T] extends CollectionExpressionBase[java.util.Set[T]] { } + +trait ListExpression[T] extends CollectionExpressionBase[java.util.List[T]] { + + // TODO : get(Expression[Integer]) / get(Integer) } -trait SetExpression[T] extends SimpleExpression[java.util.Set[T]] { +trait MapExpression[K,V] extends SimpleExpression[java.util.Map[K,V]] with ParametrizedExpression[java.util.Map[K,V]]{ - // TODO + def _size() = number[Integer](classOf[Integer], MAP_SIZE, this); -} - -trait ListExpression[T] extends SimpleExpression[java.util.List[T]] { + def _isEmpty() = boolean(MAP_IS_EMPTY, this); - // TODO + def _isNotEmpty() = _isEmpty().not; -} - -trait MapExpression[K,V] extends SimpleExpression[java.util.Map[K,V]] { + def _containsKey(k: K) = boolean(CONTAINS_KEY, this, constant(k)); - // TODO + def _containsKey(k: Expression[K]) = boolean(CONTAINS_KEY, this, k); + + def _containsValue(v: V) = boolean(CONTAINS_KEY, this, constant(v)); + + def _containsValue(v: Expression[V]) = boolean(CONTAINS_KEY, this, v); + + // TODO : get } diff --git a/querydsl-scala/src/main/scala/com/mysema/query/scala/Paths.scala b/querydsl-scala/src/main/scala/com/mysema/query/scala/Paths.scala index 7a5f89146..f119f904a 100644 --- a/querydsl-scala/src/main/scala/com/mysema/query/scala/Paths.scala +++ b/querydsl-scala/src/main/scala/com/mysema/query/scala/Paths.scala @@ -66,6 +66,8 @@ class CollectionPath[T](t: Class[_ <: T], md: PathMetadata[_] ) def this(t: Class[_ <: T], variable: String) = this(t, forVariable(variable)); + def getParameter(i: Int) = t; + } class SetPath[T](t: Class[_ <: T], md: PathMetadata[_] ) @@ -73,6 +75,8 @@ class SetPath[T](t: Class[_ <: T], md: PathMetadata[_] ) def this(t: Class[_ <: T], variable: String) = this(t, forVariable(variable)); + def getParameter(i: Int) = t; + } class ListPath[T](t: Class[_ <: T], md: PathMetadata[_] ) @@ -80,6 +84,8 @@ class ListPath[T](t: Class[_ <: T], md: PathMetadata[_] ) def this(t: Class[_ <: T], variable: String) = this(t, forVariable(variable)); + def getParameter(i: Int) = t; + } class MapPath[K,V](k: Class[_ <: K], v: Class[_ <: V], md: PathMetadata[_] ) @@ -87,6 +93,8 @@ class MapPath[K,V](k: Class[_ <: K], v: Class[_ <: V], md: PathMetadata[_] ) def this(k: Class[_ <: K], v: Class[_ <: V], variable: String) = this(k, v, forVariable(variable)); + def getParameter(i: Int): Class[_] = { if (i == 0) k else v } + } class ComparablePath[T <: Comparable[_]](t: Class[_ <: T], md: PathMetadata[_] ) diff --git a/querydsl-scala/src/test/scala/com/mysema/query/scala/AliasTest.scala b/querydsl-scala/src/test/scala/com/mysema/query/scala/AliasTest.scala index dd7d2376c..21242bac3 100644 --- a/querydsl-scala/src/test/scala/com/mysema/query/scala/AliasTest.scala +++ b/querydsl-scala/src/test/scala/com/mysema/query/scala/AliasTest.scala @@ -1,10 +1,9 @@ -package com.mysema.query.scala - -import com.mysema.query.types.path._ -import com.mysema.query.sql.SQLSubQuery +package com.mysema.query.scala; import com.mysema.query.scala.Conversions._ +import com.mysema.query.sql.SQLSubQuery +import com.mysema.query.types.path._ import org.junit.Test import org.junit.Assert._ @@ -12,25 +11,15 @@ import org.junit.Assert._ class AliasTest { var domainType = alias(classOf[DomainType]) - -// @Test -// def Explicit_Cast(){ -// assertEquals("domainType.firstName", $(domainType.firstName).toString); -// } - + @Test - def Implicit_Cast1(){ - var path: StringPath = domainType.firstName; - assertEquals("domainType.firstName like Hello", (path _like "Hello").toString()); - assertEquals("domainType.firstName ASC", (path _asc).toString()); - assertEquals("domainType.firstName = Hello", (path _eq "Hello").toString()); - assertEquals("domainType.firstName != Hello", (path _ne "Hello").toString()); - } - - @Test - def Implicit_Cast2(){ + def String_Usage(){ + // eq, ne + assertEquals("domainType.firstName = Hello", (domainType.firstName _eq "Hello").toString()); + assertEquals("domainType.firstName != Hello", (domainType.firstName _ne "Hello").toString()); + assertEquals("domainType.firstName like Hello", (domainType.firstName _like "Hello").toString()); - assertEquals("domainType.firstName ASC", (domainType.firstName _asc).toString()); + assertEquals("domainType.firstName ASC", (domainType.firstName _asc).toString()); // and var andClause = (domainType.firstName _like "An%") _and (domainType.firstName _like "Be%"); @@ -45,11 +34,48 @@ class AliasTest { assertEquals("!domainType.firstName like An%", notClause.toString); notClause = not (domainType.firstName _like "An%"); - assertEquals("!domainType.firstName like An%", notClause.toString); + assertEquals("!domainType.firstName like An%", notClause.toString); + } + + @Test + def Java_Collection_Usage(){ + // size + assertEquals("size(domainType.javaCollection)", (domainType.javaCollection _size).toString); + assertEquals("size(domainType.javaSet)", (domainType.javaSet _size).toString); + assertEquals("size(domainType.javaList)", (domainType.javaList _size).toString); + assertEquals("size(domainType.javaMap)", (domainType.javaMap _size).toString); - // FIXME : "eq" and "ne" are already reserved -// assertEquals("domainType.firstName = Hello", (domainType.firstName eq "Hello").toString()); -// assertEquals("domainType.firstName != Hello", (domainType.firstName ne "Hello").toString()); + // is Empty + assertEquals("empty(domainType.javaCollection)", (domainType.javaCollection _isEmpty).toString); + assertEquals("empty(domainType.javaSet)", (domainType.javaSet _isEmpty).toString); + assertEquals("empty(domainType.javaList)", (domainType.javaList _isEmpty).toString); + assertEquals("empty(domainType.javaMap)", (domainType.javaMap _isEmpty).toString); + + // get + assertEquals("domainType.javaList.get(0) is not null", (domainType.javaList.get(0) _isNotNull).toString); + assertEquals("domainType.javaMap.get(xxx) is null", (domainType.javaMap.get("xxx") _isNull).toString); + + // get + like + assertEquals("startsWith(domainType.javaMap.get(xxx),X)", (domainType.javaMap.get("xxx") _startsWith "X").toString); + } + + @Test + def Scala_Collection_Usage(){ + // size + assertEquals("size(domainType.scalaList)", (domainType.scalaList _size).toString); + assertEquals("size(domainType.scalaMap)", (domainType.scalaMap _size).toString); + + // is Empty + assertEquals("empty(domainType.scalaList)", (domainType.scalaList _isEmpty).toString); + assertEquals("empty(domainType.scalaMap)", (domainType.scalaMap _isEmpty).toString); + + // get + assertEquals("domainType.scalaList.get(0) is not null", (domainType.scalaList(0) _isNotNull).toString); + assertEquals("domainType.scalaList.get(0) is not null", (domainType.scalaList(0) _isNotNull).toString); + assertEquals("domainType.scalaMap.get(xxx) is null", (domainType.scalaMap("xxx") _isNull).toString); + + // get + like + assertEquals("startsWith(domainType.scalaMap.get(xxx),X)", (domainType.scalaMap("xxx") _startsWith "X").toString); } // @Test @@ -80,10 +106,3 @@ class AliasTest { } -class DomainType { - - var firstName: String = null; - - var lastName: String = null; - -} \ No newline at end of file diff --git a/querydsl-scala/src/test/scala/com/mysema/query/scala/ExampleDomain.scala b/querydsl-scala/src/test/scala/com/mysema/query/scala/ExampleDomain.scala new file mode 100644 index 000000000..e145e1680 --- /dev/null +++ b/querydsl-scala/src/test/scala/com/mysema/query/scala/ExampleDomain.scala @@ -0,0 +1,21 @@ +package com.mysema.query.scala; + +class DomainType { + + var firstName: String = null; + + var lastName: String = null; + + var scalaList: scala.List[DomainType] = null; + + var scalaMap: scala.collection.Map[String,String] = null; + + var javaCollection: java.util.Collection[DomainType] = null; + + var javaSet: java.util.Set[DomainType] = null; + + var javaList: java.util.List[DomainType] = null; + + var javaMap: java.util.Map[String,String] = null; + +} \ No newline at end of file diff --git a/querydsl-scala/src/test/scala/com/mysema/query/scala/Entities.scala b/querydsl-scala/src/test/scala/com/mysema/query/scala/ExampleSchema.scala similarity index 100% rename from querydsl-scala/src/test/scala/com/mysema/query/scala/Entities.scala rename to querydsl-scala/src/test/scala/com/mysema/query/scala/ExampleSchema.scala