[#1773] Add a new jOOQ-Scala project and jooq-scala artefactId, to
contain jOOQ extensions in the Scala language - Added more operators
This commit is contained in:
parent
4f5593d8b4
commit
cd8894e5d1
@ -154,6 +154,13 @@
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scalatest</groupId>
|
||||
<artifactId>scalatest_2.9.0</artifactId>
|
||||
<version>1.8</version>
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -1,59 +1,201 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.scala
|
||||
|
||||
import org.jooq._
|
||||
import org.jooq.impl._
|
||||
import org.jooq.impl.Factory._
|
||||
|
||||
/**
|
||||
* jOOQ type conversions used to enhance the jOOQ Java API with Scala Traits
|
||||
* <p>
|
||||
* Import this object and all of its attributes to profit from an enhanced jOOQ
|
||||
* API in Scala client code. Here is an example:
|
||||
* <code><pre>
|
||||
* import java.sql.DriverManager
|
||||
* import org.jooq._
|
||||
* import org.jooq.impl._
|
||||
* import org.jooq.scala.example.h2.Tables._
|
||||
* import collection.JavaConversions._
|
||||
* import org.jooq.scala.Conversions._
|
||||
*
|
||||
* object Test {
|
||||
* def main(args: Array[String]): Unit = {
|
||||
* val c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
|
||||
* val f = new Factory(c, SQLDialect.H2);
|
||||
*
|
||||
* for (
|
||||
* val r <- f
|
||||
* select (
|
||||
* T_BOOK.ID * T_BOOK.AUTHOR_ID,
|
||||
* T_BOOK.ID + T_BOOK.AUTHOR_ID * 3 + 4,
|
||||
* T_BOOK.TITLE || " abc" || " xy")
|
||||
* from T_BOOK
|
||||
* where (T_BOOK.ID === 3) fetch
|
||||
* ) {
|
||||
*
|
||||
* println(r)
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre></code>
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
object Conversions {
|
||||
import org.{ jooq => j }
|
||||
import j. { impl => ji }
|
||||
|
||||
case class JFieldWrapper[T](val underlying : j.Field[T])
|
||||
extends ji.CustomField[T] (underlying.getName(), underlying.getDataType())
|
||||
with Field[T] {
|
||||
|
||||
/**
|
||||
* A Scala-esque representation of {@link org.jooq.Field}, implementing
|
||||
* overloaded operators for common jOOQ operations
|
||||
*/
|
||||
case class JFieldWrapper[T](val underlying: Field[T])
|
||||
extends CustomField[T] (underlying.getName(), underlying.getDataType())
|
||||
with SField[T] {
|
||||
// ------------------------------------------------------------------------
|
||||
// QueryPart API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
def toSQL(context : RenderContext) = underlying.toSQL(context)
|
||||
def bind(context : BindContext) = underlying.bind(context)
|
||||
|
||||
def *(value : Number) = underlying.mul(value)
|
||||
def *(value : Field[_ <: Number]) = underlying.mul(value)
|
||||
|
||||
def +(value : Number) = underlying.add(value)
|
||||
def bind (context : BindContext) = underlying.bind(context)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Arithmetic operations
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
def +(value : Number) = underlying.add(value)
|
||||
def +(value : Field[_ <: Number]) = underlying.add(value)
|
||||
|
||||
def ||(value : String) = underlying.concat(value)
|
||||
|
||||
def -(value : Number) = underlying.sub(value)
|
||||
def -(value : Field[_ <: Number]) = underlying.sub(value)
|
||||
|
||||
def *(value : Number) = underlying.mul(value)
|
||||
def *(value : Field[_ <: Number]) = underlying.mul(value)
|
||||
|
||||
def /(value : Number) = underlying.div(value)
|
||||
def /(value : Field[_ <: Number]) = underlying.div(value)
|
||||
|
||||
def %(value : Number) = underlying.mod(value)
|
||||
def %(value : Field[_ <: Number]) = underlying.mod(value)
|
||||
|
||||
|
||||
def ||(value : String) = underlying.concat(value)
|
||||
//def ||(value : Field[_]) : underlying.concat(value)
|
||||
|
||||
def ===(value : T) : Condition = underlying.equal(value)
|
||||
// ------------------------------------------------------------------------
|
||||
// Comparison predicates
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
def ===(value : T) : Condition = underlying.equal(value)
|
||||
def ===(value : Field[T]) : Condition = underlying.equal(value)
|
||||
}
|
||||
|
||||
case class SFieldWrapper[T](underlying : Field[T])
|
||||
extends ji.CustomField[T] (underlying.getName(), underlying.getDataType()) {
|
||||
def toSQL(context : RenderContext) = underlying.toSQL(context)
|
||||
def bind(context : BindContext) = underlying.bind(context)
|
||||
|
||||
def !==(value : T) : Condition = underlying.notEqual(value)
|
||||
def !==(value : Field[T]) : Condition = underlying.notEqual(value)
|
||||
|
||||
def <>(value : T) : Condition = underlying.notEqual(value)
|
||||
def <>(value : Field[T]) : Condition = underlying.notEqual(value)
|
||||
|
||||
def >(value : T) : Condition = underlying.greaterThan(value)
|
||||
def >(value : Field[T]) : Condition = underlying.greaterThan(value)
|
||||
|
||||
def >=(value : T) : Condition = underlying.greaterOrEqual(value)
|
||||
def >=(value : Field[T]) : Condition = underlying.greaterOrEqual(value)
|
||||
|
||||
def <(value : T) : Condition = underlying.lessThan(value)
|
||||
def <(value : Field[T]) : Condition = underlying.lessThan(value)
|
||||
|
||||
def <=(value : T) : Condition = underlying.lessOrEqual(value)
|
||||
def <=(value : Field[T]) : Condition = underlying.lessOrEqual(value)
|
||||
}
|
||||
|
||||
implicit def asScalaField[T](f : j.Field[T]): Field[T] = f match {
|
||||
/**
|
||||
* A Scala-esque representation of {@link org.jooq.Field}, adding overloaded
|
||||
* operators for common jOOQ operations
|
||||
*/
|
||||
trait SField[T] extends QueryPartInternal {
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Arithmetic operations
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
def +(value : Number) : Field[T]
|
||||
def +(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def -(value : Number) : Field[T]
|
||||
def -(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def *(value : Number) : Field[T]
|
||||
def *(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def /(value : Number) : Field[T]
|
||||
def /(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def %(value : Number) : Field[T]
|
||||
def %(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def ||(value : String) : Field[String]
|
||||
//def ||(value : Field[_]) : Field[String]
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Comparison predicates
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
def ===(value : T) : Condition
|
||||
def ===(value : Field[T]) : Condition
|
||||
|
||||
def !==(value : T) : Condition
|
||||
def !==(value : Field[T]) : Condition
|
||||
|
||||
def <>(value : T) : Condition
|
||||
def <>(value : Field[T]) : Condition
|
||||
|
||||
def >(value : T) : Condition
|
||||
def >(value : Field[T]) : Condition
|
||||
|
||||
def >=(value : T) : Condition
|
||||
def >=(value : Field[T]) : Condition
|
||||
|
||||
def <(value : T) : Condition
|
||||
def <(value : Field[T]) : Condition
|
||||
|
||||
def <=(value : T) : Condition
|
||||
def <=(value : Field[T]) : Condition
|
||||
}
|
||||
|
||||
implicit def asScalaField[T](f : Field[T]): SField[T] = f match {
|
||||
case JFieldWrapper(f) => f
|
||||
case _ => new JFieldWrapper(f)
|
||||
}
|
||||
|
||||
implicit def asJavaField[T](f : Field[T]): j.Field[T] = f match {
|
||||
case JFieldWrapper(f) => f
|
||||
case _ => new SFieldWrapper(f)
|
||||
}
|
||||
|
||||
trait Field[T] extends QueryPartInternal {
|
||||
def *(value : Number) : Field[T]
|
||||
def *(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def +(value : Number) : Field[T]
|
||||
def +(value : Field[_ <: Number]) : Field[T]
|
||||
|
||||
def ||(value : String) : Field[String]
|
||||
//def ||(value : Field[_]) : Field[String]
|
||||
|
||||
def ===(value : T) : Condition
|
||||
def ===(value : Field[T]) : Condition
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import collection.JavaConversions._
|
||||
|
||||
import java.sql.DriverManager
|
||||
|
||||
import org.jooq._
|
||||
import org.jooq.impl._
|
||||
import org.jooq.scala.example.h2.Tables._
|
||||
import collection.JavaConversions._
|
||||
import org.jooq.scala.Conversions._
|
||||
|
||||
object Test {
|
||||
@ -10,14 +48,13 @@ object Test {
|
||||
val c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
|
||||
val f = new Factory(c, SQLDialect.H2);
|
||||
|
||||
for (
|
||||
val r <- f
|
||||
for (r <- f
|
||||
select (
|
||||
T_BOOK.ID * T_BOOK.AUTHOR_ID,
|
||||
T_BOOK.ID + T_BOOK.AUTHOR_ID * 3 + 4,
|
||||
T_BOOK.TITLE || " abc" || " xy")
|
||||
from T_BOOK
|
||||
where (T_BOOK.ID === 3) fetch
|
||||
where (T_BOOK.ID <> 3) fetch
|
||||
) {
|
||||
|
||||
println(r)
|
||||
|
||||
11
jOOQ-scala/src/test/scala/jooq-settings.xml
Normal file
11
jOOQ-scala/src/test/scala/jooq-settings.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<settings>
|
||||
<renderSchema>false</renderSchema>
|
||||
<renderNameStyle>LOWER</renderNameStyle>
|
||||
<renderKeywordStyle>UPPER</renderKeywordStyle>
|
||||
<renderFormatted>false</renderFormatted>
|
||||
<statementType>PREPARED_STATEMENT</statementType>
|
||||
<executeLogging>true</executeLogging>
|
||||
<executeWithOptimisticLocking>false</executeWithOptimisticLocking>
|
||||
<attachRecords>true</attachRecords>
|
||||
</settings>
|
||||
@ -0,0 +1,45 @@
|
||||
package org.jooq.scala.test
|
||||
|
||||
import collection.JavaConversions._
|
||||
import org.scalatest.FunSuite
|
||||
import org.jooq._
|
||||
import org.jooq.impl._
|
||||
import org.jooq.scala.example.h2.Tables._
|
||||
import org.jooq.scala.Conversions._
|
||||
import org.jooq.conf.Settings
|
||||
import javax.xml.bind.JAXB
|
||||
import org.jooq.conf.SettingsTools
|
||||
|
||||
class OperatorOverloadingTest extends FunSuite {
|
||||
|
||||
test("arithmetic") {
|
||||
val add1 = T_BOOK.ID + T_BOOK.AUTHOR_ID
|
||||
val add2 = T_BOOK.ID + 2
|
||||
val sub1 = T_BOOK.ID - T_BOOK.AUTHOR_ID
|
||||
val sub2 = T_BOOK.ID - 2
|
||||
val mul1 = T_BOOK.ID * T_BOOK.AUTHOR_ID
|
||||
val mul2 = T_BOOK.ID * 2
|
||||
val div1 = T_BOOK.ID / T_BOOK.AUTHOR_ID
|
||||
val div2 = T_BOOK.ID / 2
|
||||
val mod1 = T_BOOK.ID % T_BOOK.AUTHOR_ID
|
||||
val mod2 = T_BOOK.ID % 2
|
||||
|
||||
assert("(t_book.id + t_book.author_id)" == add1.toString(), add1.toString())
|
||||
assert("(t_book.id + 2)" == add2.toString(), add2.toString())
|
||||
assert("(t_book.id - t_book.author_id)" == sub1.toString(), sub1.toString())
|
||||
assert("(t_book.id - 2)" == sub2.toString(), sub2.toString())
|
||||
assert("(t_book.id * t_book.author_id)" == mul1.toString(), mul1.toString())
|
||||
assert("(t_book.id * 2)" == mul2.toString(), mul2.toString())
|
||||
assert("(t_book.id / t_book.author_id)" == div1.toString(), div1.toString())
|
||||
assert("(t_book.id / 2)" == div2.toString(), div2.toString())
|
||||
assert("mod(t_book.id, t_book.author_id)" == mod1.toString(), mod1.toString())
|
||||
assert("mod(t_book.id, 2)" == mod2.toString(), mod2.toString())
|
||||
|
||||
// Check for the correct application of operator precedence
|
||||
val combined1 = T_BOOK.ID + T_BOOK.AUTHOR_ID * 2
|
||||
val combined2 = T_BOOK.ID * T_BOOK.AUTHOR_ID + 2
|
||||
|
||||
assert("(t_book.id + (t_book.author_id * 2))" == combined1.toString(), combined1.toString())
|
||||
assert("((t_book.id * t_book.author_id) + 2)" == combined2.toString(), combined2.toString())
|
||||
}
|
||||
}
|
||||
6
pom.xml
6
pom.xml
@ -119,6 +119,7 @@
|
||||
<!--<module>jOOQ-codegen-maven-example</module>-->
|
||||
<module>jOOQ-console</module>
|
||||
<module>jOOQ-meta</module>
|
||||
<module>jOOQ-scala</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -153,6 +154,11 @@
|
||||
<artifactId>jooq-meta</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-scala</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user