Skip to content

Instantly share code, notes, and snippets.

@frgomes
Created March 9, 2022 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frgomes/890389952ff162af02024c3078f4d3ec to your computer and use it in GitHub Desktop.
Save frgomes/890389952ff162af02024c3078f4d3ec to your computer and use it in GitHub Desktop.
Scala - Read database credentials from file
trait SlickConfig {
import scala.util.{Try, Success, Failure}
private val RegexDB2 = "^jdbc:(db2):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexDerby = "^jdbc:(derby):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexH2 = "^jdbc:(h2):(?:mem):()()([^;]*)[?:;](.*)".r
private val RegexHsqlDB = "^jdbc:(hsqldb):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexSqlServer = "^jdbc:(sqlserver)://(.*):(.*);DatabaseName=([^;]*)[?:;](.*)".r
private val RegexjTDS = "^jdbc:(jtds):sqlserver://(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexMySQL = "^jdbc:(mysql):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexOracle = "^jdbc:(oracle):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexPostgres = "^jdbc:(postgresql):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
private val RegexSQLite = "^jdbc:(sqlite):.*//(.*):(.*)/([^;]*)[?:;](.*)".r
def profileFrom(url: String): Try[slick.jdbc.JdbcProfile] = componentsFrom(url).flatMap { c: JdbcComponents => Try{ c.profile} }
def driverFrom(url: String): Try[String] = componentsFrom(url).flatMap { c: JdbcComponents => Try{ c.driver} }
def credentialsFrom(url: String, username: String, passwordOpt: Option[String]): Try[Credentials] =
passwordOpt match {
case Some(password) => Success(Credentials(username, password))
case None =>
componentsFrom(url).flatMap { c: JdbcComponents =>
credentialsFrom(c.driver, c.pwfile, c.hostname, c.port, c.database, username, c.options)
}
}
def componentsFrom(url: String): Try[JdbcComponents] = url match {
case RegexDB2 (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.DB2Profile, ".db2pass", prefix, "com.ibm.db2.jcc.DB2Driver", hostname, port.toInt, database, Option(options)))
case RegexDerby (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.DerbyProfile, ".derbypass", prefix, "org.apache.derby.jdbc.ClientDriver", hostname, port.toInt, database, Option(options)))
case RegexH2 (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.H2Profile, ".h2pass", prefix, "org.h2.Driver", hostname, int(port), database, Option(options)))
case RegexHsqlDB (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.HsqldbProfile, ".hsqlpass", prefix, "org.hsqldb.jdbcDriver", hostname, port.toInt, database, Option(options)))
case RegexSqlServer(prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.SQLServerProfile, ".mssqlpass", prefix, "com.microsoft.sqlserver.jdbc.SQLServerDriver", hostname, port.toInt, database, Option(options)))
case RegexjTDS (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.SQLServerProfile, ".mssqlpass", prefix, "net.sourceforge.jtds.jdbc.Driver", hostname, port.toInt, database, Option(options)))
case RegexMySQL (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.MySQLProfile, ".mysqlpass", prefix, "com.mysql.jdbc.Driver", hostname, port.toInt, database, Option(options)))
case RegexOracle (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.OracleProfile, ".orapass", prefix, "oracle.jdbc.driver.OracleDriver", hostname, port.toInt, database, Option(options)))
case RegexPostgres (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.PostgresProfile, ".pgpass", prefix, "org.postgresql.Driver", hostname, port.toInt, database, Option(options)))
case RegexSQLite (prefix, hostname, port, database, options) => Success(JdbcComponents(slick.jdbc.SQLiteProfile, ".sqlitepass", prefix, "org.sqlite.JDBC", hostname, port.toInt, database, Option(options)))
case _ => Failure(new IllegalArgumentException(s"Could not infer driver name from URL: ${url}"))
}
private def int(port: String): Int = int(port, -1)
private def int(port: String, default: Int): Int = if(port.length == 0) default else port.toInt
private def credentialsFrom(driver: String, fname: String,
hostname: String, port: Int, database: String, username: String,
options: Option[String] = None): Try[Credentials] = {
import java.io._
val key = s"${hostname}:${port}:${database}:${username}:"
val home: String = System.getProperty("user.home")
val fullname: String = s"${home}/${fname}"
val file = new java.io.File(fullname)
if(file.isFile) {
val is = new FileInputStream(file)
val lines = scala.io.Source.fromInputStream(is).getLines.toStream
val passwd = lines.filter(line => line.startsWith(key)).map(line => line.slice(key.length, line.length)).headOption
if(passwd.isDefined)
Success(Credentials(username, passwd.get))
else
Failure(new IllegalAccessException(s"Cannot find username or password in file: ${fullname}"))
} else Failure(new IOException(s"File does not exist: ${fullname}"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment