Skip to content

Commit

Permalink
DB2 Profile
Browse files Browse the repository at this point in the history
  • Loading branch information
smootoo committed Nov 27, 2015
1 parent c7a64fc commit a34f1f6
Show file tree
Hide file tree
Showing 29 changed files with 754 additions and 145 deletions.
7 changes: 4 additions & 3 deletions .travis.yml
@@ -1,6 +1,6 @@
language: scala
jdk:
- openjdk7
#jdk:
#- openjdk7
scala:
- 2.10.5
- 2.11.5
Expand All @@ -17,7 +17,8 @@ before_install:
- docker version
# docker is struggling in travis env. put in retry loop
#- docker run -d -p 49160:22 -p 49161:1521 wnameless/oracle-xe-11g
- sh -v travis/runcontainer.sh
- sh -v travis/runcontainer.sh oracle
- sh -v travis/runcontainer.sh db2
- docker ps
script:
- sbt ++$TRAVIS_SCALA_VERSION 'set javaOptions ++= Seq("-Dslick.testkit-config=test-dbs/testkit-travis.conf")' clean test +it:test && sbt ++$TRAVIS_SCALA_VERSION 'set javaOptions ++= Seq("-Dslick.testkit-config=test-dbs/testkit-travis.conf")' clean coverage test it:test
Expand Down
15 changes: 8 additions & 7 deletions README.md
@@ -1,7 +1,8 @@
|Driver|Build status|
|------|-----------:|
|SQLServer 2008|[![Build status](https://ci.appveyor.com/api/projects/status/mdrfd7o7067c5vcm/branch/master?svg=true)](https://ci.appveyor.com/project/smootoo/freeslick/branch/master)|
|Oracle 11g|[![Build Status](https://travis-ci.org/smootoo/freeslick.svg?branch=master)](https://travis-ci.org/smootoo/freeslick/branches)|
|Profile|Build status|JDBC Driver|
|-------|-----------:|-----------|
|SQLServer 2008|[![Build status](https://ci.appveyor.com/api/projects/status/mdrfd7o7067c5vcm?svg=true)](https://ci.appveyor.com/project/smootoo/freeslick)|jtds:1.2.8|
|Oracle 11g|[![Build Status](https://travis-ci.org/smootoo/freeslick.svg?branch=master)](https://travis-ci.org/smootoo/freeslick)|ojdbc7:12.1.0.2|
|DB2 10.5|[![Build Status](https://travis-ci.org/smootoo/freeslick.svg?branch=master)](https://travis-ci.org/smootoo/freeslick)|db2jcc4:4.19.20|

[![Coverage Status](https://coveralls.io/repos/smootoo/freeslick/badge.svg?branch=master)](https://coveralls.io/r/smootoo/freeslick?branch=master)

Expand All @@ -16,9 +17,9 @@ We did have tests running against 2000 and 2005, but it's hard to find CI
environments to test against and they are quite old. Let us know if you
need a driver maintained for those versions.

We have added an Oracle driver as well now. This has been written from scratch.
We have now added Oracle and DB2 profiles as well. These have been written from scratch.

If there is some driver combination you are looking for, that isn't covered yet. Let us know.
If there is some driver/database combination you are looking for, that isn't covered yet. Let us know.

# Usage

Expand Down Expand Up @@ -50,7 +51,7 @@ We are using AppVeyor to automate MSSQLServer tests. (https://ci.appveyor.com/pr

To run the tests locally on a docker image, [follow the instructions on the Wiki](https://github.com/smootoo/freeslick/wiki/Locally-running-the-Integration-Tests).

Travis and docker drive the Oracle tests. You can fire up the Oracle 11g docker image to test locally.
Travis and docker drive the Oracle and DB2 tests. You can fire up the Oracle or DB2 docker images to test locally.
Check the .travis.yml file.

We leverage the excellent Slick integration tests to validate our drivers and add some of our own
Expand Down
6 changes: 4 additions & 2 deletions build.sbt
Expand Up @@ -10,9 +10,10 @@ name := "freeslick"

crossScalaVersions := Seq("2.11.5", "2.10.5")

version := "3.1.0"
version := "3.1.0.1-SNAPSHOT"

//resolvers += Resolver.sonatypeRepo("snapshots")
resolvers += Resolver.mavenLocal

configs(IntegrationTest)
inConfig(IntegrationTest)(Defaults.testSettings)
Expand All @@ -36,7 +37,8 @@ libraryDependencies ++= Seq(
"org.apache.derby" % "derby" % "10.9.1.0" % "test;it",
"org.hsqldb" % "hsqldb" % "2.2.8" % "test;it"
) ++ sys.env.get("APPVEYOR").map(_ => Seq()).getOrElse(Seq( //Don't depend on non-public jars in APPVeyor environment
"com.oracle" % "ojdbc7" % "12.1.0.2" % "optional;test;it"
"com.oracle" % "ojdbc7" % "12.1.0.2" % "optional;test;it",
"com.ibm" % "db2jcc4" % "4.19.26" % "optional;test;it"
))

scalacOptions in Compile ++= Seq(
Expand Down
63 changes: 63 additions & 0 deletions src/it/scala/freeslick/profile/DB2Test.scala
@@ -0,0 +1,63 @@
package freeslick.profile

import com.typesafe.slick.testkit
import com.typesafe.slick.testkit.tests._
import com.typesafe.slick.testkit.util._
import freeslick.DB2Profile
import freeslick.testkit._
import org.junit.runner.RunWith
import slick.jdbc.meta.MTable
import slick.util.Logging

import scala.concurrent.ExecutionContext

@RunWith(classOf[Testkit])
class DB2ITTest extends FreeslickDriverTest(DB2Test.DB2Test("db2")) {
override def tests = {
super.tests
.filterNot(_ == classOf[testkit.tests.JoinTest]) // Replaced with a FreeslickJoinTest
.filterNot(_ == classOf[testkit.tests.MutateTest]) // DB2 has restrictions on mutable RowSets see FreeslickMutateTest
//Seq(classOf[UUIDTest])
}
}

@RunWith(classOf[Testkit])
class DB2NoTSITTest extends FreeslickDriverTest(DB2Test.DB2Test("db2NoTableSpace")) {
override def tests = {
Seq(classOf[testkit.tests.ModelBuilderTest]) // testing syntax if no tablespaces specified
}
}

object DB2Test extends Logging {
def DB2Test(testDBName: String): TestDB = new ExternalJdbcTestDB(testDBName) {
val driver = new DB2Profile {
override def connectionConfig = Some(config.getConfig("adminConn"))
}
import driver.api._

def adminSchema: String = config.getConfig("adminConn").getString("user").toUpperCase
def mTableIdentifier(mTable: MTable): String =
mTable.name.schema.map(driver.quoteIdentifier(_) + ".").getOrElse("") + driver.quoteIdentifier(mTable.name.name)
override def localTables(implicit ec: ExecutionContext): DBIO[Vector[String]] = {
MTable.getTables(None, Some(adminSchema), None, Some(Seq("TABLE"))).map(_.map(mq => mTableIdentifier(mq)))
}

override def localSequences(implicit ec: ExecutionContext): DBIO[Vector[String]] = {
sql"select sequence_schema, sequence_name from user_sequences".as[(String, String)].map(_.map{case(schema, name) =>
s"${driver.quoteIdentifier(schema)}.${driver.quoteIdentifier(name)}"})
}

override def dropUserArtifacts(implicit session: profile.Backend#Session) = {
blockingRunOnSession { implicit ec =>
for {
tables <- localTables
_ <- DBIO.seq(tables.map(t => sqlu"""drop table #$t"""): _*)
sequences <- localSequences
_ <- DBIO.seq(sequences.map(s => sqlu"drop sequence #$s"): _*)
} yield ()
}
}

override lazy val capabilities = driver.capabilities + TestDB.capabilities.plainSql
}
}
@@ -1,18 +1,24 @@
package freeslick
package freeslick.profile

import com.typesafe.slick.testkit.tests._
import com.typesafe.slick.testkit.util._
import freeslick.testkit._
import org.junit.runner.RunWith

class FreeslickDriverTest(driver: TestDB) extends DriverTest(driver) {
override def tests: Seq[Class[_ <: GenericTest[_ >: Null <: TestDB]]] = {
super.tests :+
classOf[BooleanTest] :+
classOf[FetchOffsetTest] :+
classOf[FreeslickJoinTest] :+
classOf[FreeslickSubqueryTest] :+
classOf[UUIDTest] :+
classOf[FetchOffsetTest] :+
classOf[FreeslickGroupByTest]
//TODO Sue timestamps, blobs, multiple autoinc column
classOf[FreeslickGroupByTest] :+
classOf[FreeslickMutateTest] :+
classOf[JDBCFunctionTest]
//TODO Sue timestamps, blobs, multiple autoinc column, all the jdbcfunctions
//Seq(classOf[UUIDTest])
}
}

Expand Down
@@ -1,8 +1,10 @@
package freeslick
package freeslick.profile

import com.typesafe.slick.testkit
import com.typesafe.slick.testkit.tests._
import com.typesafe.slick.testkit.util._
import freeslick.MSSQLServerProfile
import freeslick.testkit.{UUIDTest, FreeslickGroupByTest, MSSQLServerPlainSQLTest}
import org.junit.runner.RunWith
import slick.jdbc.meta.MTable
import slick.util.Logging
Expand All @@ -15,7 +17,7 @@ class MSSQLServer2008Test extends FreeslickDriverTest(MSSQLServerTest.testDB) {
super.tests
.filterNot(_ == classOf[testkit.tests.PlainSQLTest]) :+
classOf[MSSQLServerPlainSQLTest]
//Seq(classOf[FreeslickGroupByTest])
//Seq(classOf[UUIDTest])
}
}

Expand Down
@@ -1,24 +1,33 @@
package freeslick
package freeslick.profile

import com.typesafe.slick.testkit
import com.typesafe.slick.testkit.tests._
import com.typesafe.slick.testkit.util._
import freeslick.OracleProfile
import freeslick.testkit._
import org.junit.runner.RunWith
import slick.util.Logging

import scala.concurrent.ExecutionContext

@RunWith(classOf[Testkit])
class OracleITTest extends FreeslickDriverTest(OracleTest.Oracle11gTest) {
class OracleITTest extends FreeslickDriverTest(OracleTest.Oracle11gTest("oracle11g")) {
override def tests = {
super.tests
.filterNot(_ == classOf[testkit.tests.JoinTest]) // Replaced with a FreeslickJoinTest
//Seq(classOf[FreeslickGroupByTest])
//Seq(classOf[ForeignKeyTest], classOf[UniqueIndexFKTest])
}
}

@RunWith(classOf[Testkit])
class OracleNoTSITTest extends FreeslickDriverTest(OracleTest.Oracle11gTest("oracle11gNoTableSpace")) {
override def tests = {
Seq(classOf[testkit.tests.ModelBuilderTest]) // testing syntax if no tablespaces specified
}
}

object OracleTest extends Logging {
lazy val Oracle11gTest: TestDB = new ExternalJdbcTestDB("oracle11g") {
def Oracle11gTest(testDBName: String): TestDB = new ExternalJdbcTestDB(testDBName) {
val driver = new OracleProfile {
override def connectionConfig = Some(config.getConfig("adminConn"))
override def toString() = "OracleDriverTest" // ModelBuilderTest looks for a classname with OracleDriver in
Expand Down
@@ -1,7 +1,6 @@
package freeslick
package freeslick.testkit

import com.typesafe.slick.testkit.util.{AsyncTest, JdbcTestDB}
import slick.jdbc.GetResult

class BooleanTest extends AsyncTest[JdbcTestDB] {

Expand Down
@@ -1,4 +1,4 @@
package freeslick
package freeslick.testkit

import com.typesafe.slick.testkit.util.{AsyncTest, JdbcTestDB}

Expand Down
@@ -1,14 +1,13 @@
package freeslick
package freeslick.testkit

import com.typesafe.slick.testkit.util.{AsyncTest, RelationalTestDB}
import slick.driver.{H2Driver, PostgresDriver}

class FreeslickGroupByTest extends AsyncTest[RelationalTestDB] {

import tdb.profile.api._

def testGroupBy = {
class T(tag: Tag) extends Table[(Int, Option[Int], Int)](tag, "t3") {
class T(tag: Tag) extends Table[(Int, Option[Int], Int)](tag, "t4") {
def a = column[Int]("a")

def b = column[Option[Int]]("b")
Expand Down
@@ -1,7 +1,6 @@
package freeslick
package freeslick.testkit

import com.typesafe.slick.testkit.tests.JoinTest
import com.typesafe.slick.testkit.util.{AsyncTest, JdbcTestDB}

class FreeslickJoinTest extends JoinTest {

Expand Down
65 changes: 65 additions & 0 deletions src/it/scala/freeslick/testkit/FreeslickMutateTest.scala
@@ -0,0 +1,65 @@
package freeslick.testkit

import com.typesafe.slick.testkit.util.{AsyncTest, JdbcTestDB}

class FreeslickMutateTest extends AsyncTest[JdbcTestDB] {

import tdb.profile.api._

def testMutate = ifCapF(jcap.mutable) {
class Data(tag: Tag) extends Table[(Int,String)](tag, "DATA") {
def id = column[Int]("ID", O.PrimaryKey)
def data = column[String]("DATA")
def * = (id, data)
}
val data = TableQuery[Data]

var seenEndMarker = false
db.run(data.schema.create >> (data ++= Seq((1, "a"), (2, "b"), (3, "c"), (4, "d")))).flatMap { _ =>
foreach(db.stream(data.mutate.transactionally)) { m =>
if(!m.end) {
if(m.row._1 == 1) m.row = m.row.copy(_2 = "aa")
else if(m.row._1 == 2) m.delete
else if(m.row._1 == 3) m += ((5, "ee"))
} else seenEndMarker = true
}
}.flatMap { _ =>
seenEndMarker shouldBe false
db.run(data.sortBy(_.id).result).map(_ shouldBe Seq((1, "aa"), (3, "c"), (4, "d"), (5, "ee")))
}
}

def testDeleteMutate = ifCapF(jcap.mutable) {
class T(tag: Tag) extends Table[(Int, Int)](tag, "T_DELMUTABLE") {
def a = column[Int]("A")
def b = column[Int]("B", O.PrimaryKey)
def * = (a, b)
}
val ts = TableQuery[T]
def tsByA = ts.findBy(_.a)

var seenEndMarker = false
val a = seq(
ts.schema.create,
ts ++= Seq((1,1), (1,2), (1,3), (1,4)),
ts ++= Seq((2,5), (2,6), (2,7), (2,8))
) andThen tsByA(1).mutate(sendEndMarker = true).transactionally

val isDB2 = tdb.profile.toString.contains("DB2")
foreach(db.stream(a)){ m =>
if(!m.end) m.delete
else {
seenEndMarker = true
// DB2 can't mutate a result set, once it has gone past the end
// default behaviour to close the result set
if (!isDB2) {
m += ((3, 9))
}
}
}.flatMap { _ =>
seenEndMarker shouldBe true
db.run(ts.to[Set].result).map(_ shouldBe (Set((2,5), (2,6), (2,7), (2,8)) ++
(if (!isDB2) Set((3, 9)) else Set())))
}
}
}
@@ -1,4 +1,4 @@
package freeslick
package freeslick.testkit

import com.typesafe.slick.testkit.util.{AsyncTest, JdbcTestDB}

Expand Down
18 changes: 18 additions & 0 deletions src/it/scala/freeslick/testkit/JDBCFunctionTest.scala
@@ -0,0 +1,18 @@
package freeslick.testkit

import com.typesafe.slick.testkit.util.{JdbcTestDB, AsyncTest}

class JDBCFunctionTest extends AsyncTest[JdbcTestDB] {

import tdb.driver.api._

def testLibraryFunctions = {
for {
_ <- Functions.user.result
_ <- Functions.database.result
_ <- Functions.currentDate.result
_ <- Functions.currentTime.result
_ <- Functions.pi.result
} yield {}
}
}
@@ -1,13 +1,10 @@
// Copied from https://github.com/slick/slick/blob/3.0/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/PlainSQLTest.scala
// and then tweaked for SQLServer
package freeslick
package freeslick.testkit

import com.typesafe.slick.testkit.util.{AsyncTest, JdbcTestDB}
import slick.jdbc.GetResult

import scala.concurrent.Await
import scala.concurrent.duration.Duration

class MSSQLServerPlainSQLTest extends AsyncTest[JdbcTestDB] {

import tdb.driver.api._
Expand Down

0 comments on commit a34f1f6

Please sign in to comment.