Created
March 9, 2022 19:50
-
-
Save frgomes/890389952ff162af02024c3078f4d3ec to your computer and use it in GitHub Desktop.
Scala - Read database credentials from file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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