Skip to content

Instantly share code, notes, and snippets.

@yareally
Created February 24, 2016 20:32
Show Gist options
  • Save yareally/39fc3210d943bd5b511d to your computer and use it in GitHub Desktop.
Save yareally/39fc3210d943bd5b511d to your computer and use it in GitHub Desktop.
package Extensions
import dispatch._
import slick.dbio.{NoStream, Effect}
import slick.jdbc.JdbcBackend
import slick.profile.{SqlAction, SqlStreamingAction}
import scala.concurrent.Await
import scala.concurrent.duration.Duration
/**
* SQL extension methods for slick.
*/
object DbExtensions {
// SqlAction[Int, NoStream, Effect]
/**
* Queries the db and returns a result. Use if wanting a result from the db.
*
* Requirements (import the db and api bits altering as needed):
*
* val conn = DatabaseConfig.forConfig[JdbcProfile]("db_config_here_from_application_conf")
* import conn.driver.api._
* import Extensions.DbExtensions._
* implicit val db: JdbcBackend#DatabaseDef = conn.db
*
* Example usage (blocking):
*
* def sqlQueryTest = sql"""SELECT * FROM drinks LIMIT 50""".as[Drink].foreach(drink ⇒ println(drink)
*
* Example usage (non-blocking):
*
* def sqlQueryTest = async {
* await(sql"""SELECT * FROM drinks LIMIT 50""".as[Drink].runAsync).foreach(drink ⇒ println(drink))
* }
*
* @param sql
* @tparam T
*/
implicit class ActionStreamExtensions[T](sql: SqlStreamingAction[Vector[T], T, Effect]) {
/**
* Executes a SQL statement on a db and blocks while waiting for the result.
*
* @param db - the db connection. Must be within the scope of the called function below.
* @return the matched db rows as a collection (even if there's only one)
*/
def run(implicit db: JdbcBackend#DatabaseDef): Vector[T] = Await.result(db.run(sql), Duration.Inf)
/**
* Executes a SQL statement on the db and asynchronously listens returns the result later.
*
* @param db - the db connection. Must be within the scope of the called function below.
* @return a future (task) that will return the results when finished. Use async/await or a promise/callback to get results.
*/
def runAsync(implicit db: JdbcBackend#DatabaseDef): Future[Vector[T]] = db.run(sql)
}
/**
* Same requirements as ActionStreamExtensions.
*
* Executes a SQL query. Does NOT return a result other than one of the following:
*
* 1) Rows affected by the SQL query execution
* 2) The last inserted primary key for the executed SQL (when using the "RETURNING primary key" SQL feature).
*
* Example usage (blocking):
*
* def sqlQueryTest = sql"""INSERT INTO drinks(name, drink_size_id) VALUES ('drinkName', 1) RETURNING id""".exec
*
* Example usage (non-blocking):
*
* def sqlQueryTest = sql"""INSERT INTO drinks(name, drink_size_id) VALUES ('drinkName', 1)""".execAsync
*
* @param sql
* @tparam T
*/
implicit class ActionExtensions[T](sql: SqlAction[T, NoStream, Effect]) {
def exec(implicit db: JdbcBackend#DatabaseDef): T = Await.result(db.run(sql), Duration.Inf)
def execAsync(implicit db: JdbcBackend#DatabaseDef): Future[T] = db.run(sql)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment