Permalink
Browse files

Add DB2,Oracle into travis build and add Appveyor build for SQLServer

1 parent a0eb1ee commit 6e8b1bb8652668f970bdbbc8c42037c47bab0c5e @smootoo smootoo committed Feb 10, 2016
View
@@ -0,0 +1,3 @@
+[submodule "suegithub"]
+ path = travis/ZNonPublicDeps
+ url = https://github.com/smootoo/ZNonPublicDeps.git
View
@@ -1,6 +1,12 @@
-sudo: false
language: scala
-script: sbt -jvm-opts jvmopts.travis -Dslick.testkit-config=test-dbs/testkit.travis.conf +testAll
+sudo: required
+before_install:
+# TZ needed for Oracle driver!
+- export TZ=Asia/Kamchatka
+- sh -v ./travis/extractNonPublicDeps
+- docker version
+- sh -v travis/runcontainer.sh oracle db2
+- docker ps
jdk:
- oraclejdk8
notifications:
@@ -9,11 +15,15 @@ notifications:
services:
- mysql
- postgresql
+ - docker
addons:
apt:
packages:
- graphviz
- python-sphinx
+ - mysql-server
+script:
+- sbt -jvm-opts jvmopts.travis -Dslick.testkit-config=test-dbs/testkit.travis.conf clean +testAll
cache:
directories:
- $HOME/.sbt
View
@@ -11,17 +11,21 @@ instead of SQL, thus profiting from the static checking, compile-time safety
and compositionality of Scala. Slick features an extensible query compiler
which can generate code for different backends.
-The following database systems are directly supported for type-safe queries:
-
-- Derby/JavaDB
-- H2
-- HSQLDB/HyperSQL
-- MySQL
-- PostgreSQL
-- SQLite
-- Oracle 11g
-- IBM DB2 LUW 10
-- Microsoft SQL Server 2008
+The following database systems are directly supported for type-safe queries.
+These are the databases and driver versions that have explicit automated tests.
+
+|Database|JDBC Driver|Build status|
+|--------|-----------|-----------:|
+|SQLServer 2008, 2012, 2014|[jtds:1.2.8](http://sourceforge.net/projects/jtds/files/jtds/) and [msjdbc:4.2](https://www.microsoft.com/en-gb/download/details.aspx?id=11774)|[![Build status](https://ci.appveyor.com/api/projects/status/mdrfd7o7067c5vcm?svg=true&branch=master)](https://ci.appveyor.com/project/slick/slick)|
+|Oracle 11g|[ojdbc7:12.1.0.2](http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html)|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|DB2 10.5|[db2jcc4:4.19.20](http://www-01.ibm.com/support/docview.wss?uid=swg21363866)|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|MySQL|mysql-connector-java:5.1.23|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|PostgreSQL|postgresql:9.1-901.jdbc4|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|SQLite|sqlite-jdbc:3.8.7|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|Derby/JavaDB|derby:10.9.1.0|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|HSQLDB/HyperSQL|hsqldb:2.2.8|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+|H2|com.h2database.h2:1.4.187|[![Build Status](https://travis-ci.org/slick/slick.svg?branch=master)](https://travis-ci.org/slick/slick)|
+
Accessing other database systems is possible, with a reduced feature set.
View
@@ -0,0 +1,60 @@
+install:
+ - git submodule update --init --recursive
+ - ps: |
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+ if (!(Test-Path -Path "C:\sbt" )) {
+ (new-object System.Net.WebClient).DownloadFile(
+ 'https://dl.bintray.com/sbt/native-packages/sbt/0.13.9/sbt-0.13.9.zip',
+ 'C:\sbt-bin.zip'
+ )
+ [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\sbt-bin.zip", "C:\sbt")
+ }
+ - cmd: SET JDK_HOME=C:\Program Files\Java\jdk1.8.0
+ - cmd: SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0
+ - cmd: SET PATH=C:\sbt\sbt\bin;%JDK_HOME%\bin;%PATH%
+ - cmd: SET SBT_OPTS=-Xmx4g -Xss2m -Dslick.testkit-config=test-dbs/testkit-appveyor.conf
+# Start up sqlservers: 2008 on port 1433, 2012 on 1533, 2014 on 1633. Enable tcp connections
+ - ps: |
+ [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null;
+ [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null;
+ $port = 1433
+ foreach($instancename in @('SQL2008R2SP2', 'SQL2012SP1', 'SQL2014'))
+ {
+ $wmi = New-Object('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer');
+ $tcp = $wmi.GetSmoObject("ManagedComputer[@Name='${env:computername}']/ServerInstance[@Name='${instancename}']/ServerProtocol[@Name='Tcp']");
+ $tcp.IsEnabled = $true;
+ foreach ($ipAddress in $tcp.IPAddresses)
+ {
+ $ipAddress.IPAddressProperties["TcpDynamicPorts"].Value = ""
+ $ipAddress.IPAddressProperties["TcpPort"].Value = "${port}"
+ }
+ $tcp.Alter();
+ Start-Service -Name "MSSQL`$$instancename";
+ $wmi = New-Object('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer');
+ $ipall = $wmi.GetSmoObject("ManagedComputer[@Name='${env:computername}']/ServerInstance[@Name='${instancename}']/ServerProtocol[@Name='Tcp']/IPAddress[@Name='IPAll']");
+ $config = @{
+ instanceName = $instancename;
+ config = @{
+ server = "localhost";
+ userName = "sa";
+ password = "Password12!";
+ options = @{
+ port = ${port};
+ database = "master";
+ cryptoCredentialsDetails = @{
+ ciphers = "RC4-MD5"
+ }
+ }
+ }
+ } | ConvertTo-Json -Depth 3;
+ Write-Host "${config}"
+ $port += 100
+ }
+ - bash -v ./travis/extractNonPublicDeps
+build_script:
+ - sbt clean compile test:compile
+test_script:
+ - sbt testkit/test:test
+cache:
+ - C:\sbt\
+ - C:\Users\appveyor\.ivy2
@@ -13,8 +13,10 @@ trait SlickOsgiHelper {
private def makeBundle(file: File): exam.Option =
bundle(file.toURI.toASCIIString)
- private def allBundleFiles: Array[File] =
- Option(sys.props("slick.osgi.bundlepath")).getOrElse("").split(":").map(new File(_))
+ private def allBundleFiles: Array[File] = {
+ val paths = Option(sys.props("slick.osgi.bundlepath")).getOrElse("")
+ paths.split("@").map(new File(_))
+ }
def standardOptions: Array[exam.Option] =
allBundleFiles.map(makeBundle) ++ Array[exam.Option](junitBundles())
View
@@ -282,7 +282,7 @@ object SlickBuild extends Build {
).configs(DocTest).settings(inConfig(DocTest)(Defaults.testSettings): _*).settings(
unmanagedSourceDirectories in DocTest += (baseDirectory in slickProject).value / "src/sphinx/code",
unmanagedResourceDirectories in DocTest += (baseDirectory in slickProject).value / "src/sphinx/resources"
- ) dependsOn(slickProject, slickCodegenProject % "compile->compile", slickHikariCPProject % "test->compile")
+ ) dependsOn(slickProject, slickCodegenProject % "compile->compile", slickHikariCPProject)
lazy val slickCodegenProject = Project(id = "codegen", base = file("slick-codegen"),
settings = Defaults.coreDefaultSettings ++ sdlcSettings ++ sharedSettings ++ extTarget("codegen") ++ commonSdlcSettings ++ Seq(
@@ -339,7 +339,8 @@ object SlickBuild extends Build {
fork in Test := true,
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s", "-a"),
javaOptions in Test ++= Seq(
- "-Dslick.osgi.bundlepath=" + osgiBundleFiles.value.map(_.getCanonicalPath).mkString(":"),
+ // Use '@' as a seperator that shouldn't appear in any filepaths or names
+ "-Dslick.osgi.bundlepath=" + osgiBundleFiles.value.map(_.getCanonicalPath).mkString("@"),
"-Dorg.ops4j.pax.logging.DefaultServiceLog.level=WARN"
),
osgiBundleFiles := Seq((OsgiKeys.bundle in slickProject).value),
@@ -26,8 +26,6 @@ object HikariCPJdbcDataSource extends JdbcDataSourceFactory {
import com.zaxxer.hikari._
def forConfig(c: Config, driver: Driver, name: String, classLoader: ClassLoader): HikariCPJdbcDataSource = {
- if(driver ne null)
- throw new SlickException("An explicit Driver object is not supported by HikariCPJdbcDataSource")
val hconf = new HikariConfig()
// Connection settings
@@ -45,7 +45,7 @@ class JdbcMetaTest extends AsyncTest[JdbcTestDB] {
DBIO.sequence(ps.map(_.getProcedureColumns()))
}.named("Procedures from DatabaseMetaData"),
- MTable.getTables(None, None, None, None).flatMap { ts =>
+ tdb.profile.defaultTables.flatMap { ts =>
DBIO.sequence(ts.filter(t => Set("users", "orders") contains t.name.name).map { t =>
DBIO.seq(
t.getColumns.flatMap { cs =>
@@ -68,7 +68,7 @@ class JdbcMetaTest extends AsyncTest[JdbcTestDB] {
ifCap(tcap.jdbcMetaGetClientInfoProperties)(MClientInfoProperty.getClientInfoProperties)
.named("Client Info Properties from DatabaseMetaData"),
- MTable.getTables(None, None, None, None).map(_.should(ts =>
+ tdb.profile.defaultTables.map(_.should(ts =>
Set("orders_xx", "users_xx") subsetOf ts.map(_.name.name).toSet
)).named("Tables before deleting")
@@ -11,6 +11,8 @@ import slick.jdbc._
import slick.jdbc.GetResult._
import slick.jdbc.meta.MTable
import org.junit.Assert
+import slick.util.ConfigExtensionMethods._
+
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext}
@@ -182,24 +184,19 @@ object StandardTestDBs {
val profile = SQLServerProfile
import profile.api.actionBasedSQLInterpolation
- val defaultSchema = config.getString("defaultSchema")
// sqlserver has valid "select for update" syntax, but in testing on Appveyor, the test hangs due to lock escalation
// so exclude from explicit ForUpdate testing
override def capabilities = super.capabilities - TestDB.capabilities.selectForUpdateRowLocking
+ val defaultSchema = config.getStringOpt("defaultSchema")
- override def localTables(implicit ec: ExecutionContext): DBIO[Vector[String]] =
- ResultSetAction[(String,String,String, String)](_.conn.getMetaData().getTables(testDB, defaultSchema, null, null)).map { ts =>
- ts.map(_._3).sorted
- }
+ override def localTables(implicit ec: ExecutionContext): DBIO[Vector[String]] = {
+ MTable.getTables(None, defaultSchema, None, Some(Seq("TABLE"))).map(_.map(_.name.name).sorted)
+ }
override def dropUserArtifacts(implicit session: profile.Backend#Session) = blockingRunOnSession { implicit ec =>
for {
- constraints <- sql"""select constraint_name, table_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY'""".as[(String, String)]
- constraintStatements = constraints.collect { case (c, t) if !c.startsWith("SQL") =>
- sqlu"alter table #${profile.quoteIdentifier(t)} drop constraint #${profile.quoteIdentifier(c)}"
- }
- _ <- DBIO.sequence(constraintStatements)
tables <- localTables
+ _ <- DBIO.sequence(tables.map(t => sqlu"exec sp_MSdropconstraints #$t"))
tableStatements = tables.map(t => sqlu"drop table #${profile.quoteIdentifier(t)}")
_ <- DBIO.sequence(tableStatements)
} yield ()
@@ -209,9 +206,21 @@ object StandardTestDBs {
lazy val SQLServerJTDS = new SQLServerDB("sqlserver-jtds") {
override def capabilities = super.capabilities - TestDB.capabilities.plainSql
}
+ lazy val SQLServer2012JTDS = new SQLServerDB("sqlserver2012-jtds") {
+ override def capabilities = super.capabilities - TestDB.capabilities.plainSql
+ }
+ lazy val SQLServer2014JTDS = new SQLServerDB("sqlserver2014-jtds") {
+ override def capabilities = super.capabilities - TestDB.capabilities.plainSql
+ }
lazy val SQLServerSQLJDBC = new SQLServerDB("sqlserver-sqljdbc") {
override def capabilities = profile.capabilities - JdbcCapabilities.createModel
}
+ lazy val SQLServer2012SQLJDBC = new SQLServerDB("sqlserver2012-sqljdbc") {
+ override def capabilities = profile.capabilities - JdbcCapabilities.createModel
+ }
+ lazy val SQLServer2014SQLJDBC = new SQLServerDB("sqlserver2014-sqljdbc") {
+ override def capabilities = profile.capabilities - JdbcCapabilities.createModel
+ }
lazy val Oracle = new ExternalJdbcTestDB("oracle") {
val profile = OracleProfile
@@ -221,13 +230,26 @@ object StandardTestDBs {
override def capabilities =
super.capabilities - TestDB.capabilities.jdbcMetaGetIndexInfo - TestDB.capabilities.transactionIsolation
- /* Only drop and recreate the user. This is much faster than dropping
- * the tablespace. */
- override def dropUserArtifacts(implicit session: profile.Backend#Session) = {
- session.close()
- val a = DBIO.sequence(Seq(drop(0), create(1), create(2)).map(s => sqlu"#$s"))
- await(databaseFor("adminConn").run(a))
+ override def localTables(implicit ec: ExecutionContext): DBIO[Vector[String]] = {
+ val tableNames = profile.defaultTables.map(_.map(_.name.name)).map(_.toVector)
+ tableNames
}
+
+ override def localSequences(implicit ec: ExecutionContext): DBIO[Vector[String]] = {
+ // user_sequences much quicker than going to metadata if you don't know the schema they are going to be in
+ sql"select sequence_Name from user_sequences".as[String]
+ }
+
+ override def dropUserArtifacts(implicit session: profile.Backend#Session) =
+ blockingRunOnSession { implicit ec =>
+ for {
+ tables <- localTables
+ sequences <- localSequences
+ _ <- DBIO.seq(tables.map(t => sqlu"drop table #${profile.quoteIdentifier(t)} cascade constraints") ++
+ sequences.map(s => sqlu"drop sequence #${profile.quoteIdentifier(s)}"): _*)
+ } yield ()
+ }
+
}
}
@@ -1,5 +1,7 @@
package com.typesafe.slick.testkit.util
+import java.lang.reflect.Method
+
import com.typesafe.config.Config
import org.junit.Assert
@@ -265,7 +267,21 @@ object ExternalTestDB {
// A cache for custom drivers to avoid excessive reloading and memory leaks
private[this] val driverCache = new mutable.HashMap[(String, String), Driver]()
- def getCustomDriver(url: String, driverClass: String): Driver = synchronized {
+ def getCustomDriver(url: String, driverClass: String) = synchronized {
+ val sysloader = java.lang.ClassLoader.getSystemClassLoader
+ val sysclass = classOf[URLClassLoader]
+
+ // Add the supplied jar onto the system classpath
+ // Doing this allows Hikari to initialise the driver, if needed
+ try {
+ val method = sysclass.getDeclaredMethod("addURL", classOf[URL])
+ method.setAccessible(true)
+ method.invoke(sysloader, new URL(url))
+ } catch {
+ case t: Throwable =>
+ t.printStackTrace()
+ throw new IOException(s"Error, could not add URL $url to system classloader");
+ }
driverCache.getOrElseUpdate((url, driverClass),
new URLClassLoader(Array(new URL(url)), getClass.getClassLoader).loadClass(driverClass).newInstance.asInstanceOf[Driver]
)
@@ -49,4 +49,16 @@ class OracleTest extends ProfileTest(StandardTestDBs.Oracle)
class SQLServerJTDSTest extends ProfileTest(StandardTestDBs.SQLServerJTDS)
@RunWith(classOf[Testkit])
+class SQLServer2012JTDSTest extends ProfileTest(StandardTestDBs.SQLServer2012JTDS)
+
+@RunWith(classOf[Testkit])
+class SQLServer2014JTDSTest extends ProfileTest(StandardTestDBs.SQLServer2014JTDS)
+
+@RunWith(classOf[Testkit])
class SQLServerSQLJDBCTest extends ProfileTest(StandardTestDBs.SQLServerSQLJDBC)
+
+@RunWith(classOf[Testkit])
+class SQLServer2012SQLJDBCTest extends ProfileTest(StandardTestDBs.SQLServer2012SQLJDBC)
+
+@RunWith(classOf[Testkit])
+class SQLServer2014SQLJDBCTest extends ProfileTest(StandardTestDBs.SQLServer2014SQLJDBC)
@@ -96,8 +96,7 @@ trait OracleProfile extends JdbcProfile {
override def defaultTables(implicit ec: ExecutionContext): DBIO[Seq[MTable]] = {
for {
user <- SimpleJdbcAction(_.session.metaData.getUserName)
- tables <- SQLActionBuilder(Seq("select TABLE_NAME from all_tables where OWNER = ?"), implicitly[SetParameter[String]].applied(user)).as[String]
- mtables <- MTable.getTables(None, None, None, Some(Seq("TABLE"))).map(_.filter(t => tables contains t.name.name)) // FIXME: this should check schema and maybe more
+ mtables <- MTable.getTables(None, Some(user), None, Some(Seq("TABLE")))
} yield mtables
}
@@ -107,8 +107,13 @@ trait SQLServerProfile extends JdbcProfile {
override def createModelBuilder(tables: Seq[MTable], ignoreInvalidDefaults: Boolean)(implicit ec: ExecutionContext): JdbcModelBuilder =
new ModelBuilder(tables, ignoreInvalidDefaults)
- override def defaultTables(implicit ec: ExecutionContext): DBIO[Seq[MTable]] =
- MTable.getTables(None, None, None, Some(Seq("TABLE")))
+ override def defaultTables(implicit ec: ExecutionContext): DBIO[Seq[MTable]] = {
+ import api._
+ for {
+ schema <- Functions.user.result
+ mtables <- MTable.getTables(None, Some(schema), None, Some(Seq("TABLE")))
+ } yield mtables
+ }
override def defaultSqlTypeName(tmd: JdbcType[_], sym: Option[FieldSymbol]): String = tmd.sqlType match {
case java.sql.Types.VARCHAR =>
Oops, something went wrong.

0 comments on commit 6e8b1bb

Please sign in to comment.