.circumflex-orm.2.5.source-code.package.scala Maven / Gradle / Ivy
The newest version!
package ru.circumflex
import core._
import collection.mutable.Stack
import java.util.regex.Pattern
/*!# The `orm` Package
Package `orm` contains different shortcuts, utilities, helpers and implicits --
the basis of DSL of Circumflex ORM.
You should import this package to use Circumflex ORM in your application:
import ru.circumflex.orm._
*/
package object orm {
val ORM_LOG = new Logger("ru.circumflex.orm")
lazy val DEFAULT_ORM_CONF = cx.instantiate[ORMConfiguration](
"orm.configuration", new SimpleORMConfiguration(""))
def ormConf = ctx.get("orm.conf") match {
case Some(c: ORMConfiguration) => c
case _ => DEFAULT_ORM_CONF
}
def tx: Transaction = ormConf.transactionManager.get
def COMMIT() {
tx.commit()
}
def ROLLBACK() {
tx.rollback()
}
def using[A](newConf: ORMConfiguration)(block: => A): A =
Context.executeInNew { ctx =>
ctx.update("orm.conf", newConf)
block
}
def usingAll[A](newConfs: ORMConfiguration*)(block: ORMConfiguration => A): Seq[A] =
newConfs.map { c => using(c) { block(c) } }
/*! ## Alias Stack
Circumflex ORM offers nice DSL to reference fields of aliased tables:
val co = Country AS "co"
val predicate = co.name EQ "Switzerland"
In this example `RelationNode[Country]` with alias `"co"` is implicitly converted
into `Country`, its underlying `Relation`, because only that relation owns field
`name`. However, the information about the alias is lost during this conversion.
We use `aliasStack` to remember it during conversion so it can be accessed later.
*/
object aliasStack {
protected def _stack: Stack[String] = ctx.get("orm.aliasStack") match {
case Some(s: Stack[String]) => s
case _ =>
val s = Stack[String]()
ctx += "orm.aliasStack" -> s
s
}
def pop(): Option[String] = if (_stack.size == 0) None else Some(_stack.pop())
def push(alias: String) {
_stack.push(alias)
}
}
// Pimping core libs
implicit def str2expr(str: String): Expression = prepareExpr(str)
implicit def string2exprHelper(expression: String): SimpleExpressionHelper =
new SimpleExpressionHelper(expression)
implicit def string2nativeHelper(expression: String): NativeQueryHelper =
new NativeQueryHelper(expression)
implicit def pair2proj[T1, T2](t: (Projection[T1], Projection[T2])) =
new PairProjection(t._1, t._2)
// Constants
val NO_ACTION = ForeignKeyAction(ormConf.dialect.fkNoAction)
val CASCADE = ForeignKeyAction(ormConf.dialect.fkCascade)
val RESTRICT = ForeignKeyAction(ormConf.dialect.fkRestrict)
val SET_NULL = ForeignKeyAction(ormConf.dialect.fkSetNull)
val SET_DEFAULT = ForeignKeyAction(ormConf.dialect.fkSetDefault)
val INNER = JoinType(ormConf.dialect.innerJoin)
val LEFT = JoinType(ormConf.dialect.leftJoin)
val RIGHT = JoinType(ormConf.dialect.rightJoin)
val FULL = JoinType(ormConf.dialect.fullJoin)
val OP_UNION = SetOperation(ormConf.dialect.UNION)
val OP_UNION_ALL = SetOperation(ormConf.dialect.UNION_ALL)
val OP_EXCEPT = SetOperation(ormConf.dialect.EXCEPT)
val OP_EXCEPT_ALL = SetOperation(ormConf.dialect.EXCEPT_ALL)
val OP_INTERSECT = SetOperation(ormConf.dialect.INTERSECT)
val OP_INTERSECT_ALL = SetOperation(ormConf.dialect.INTERSECT_ALL)
// Predicates DSL
def AND(predicates: Predicate*) =
new AggregatePredicate(ormConf.dialect.AND, predicates.toSeq)
def OR(predicates: Predicate*) =
new AggregatePredicate(ormConf.dialect.OR, predicates.toSeq)
def NOT(predicate: Predicate) =
new SimpleExpression(ormConf.dialect.not(predicate.toSql), predicate.parameters)
def prepareExpr(expression: String, params: Pair[String, Any]*): SimpleExpression = {
var sqlText = expression
var parameters: Seq[Any] = Nil
val paramsMap = Map[String, Any](params: _*)
val pattern = Pattern.compile(":(\\w+)\\b")
val matcher = pattern.matcher(expression)
while (matcher.find) {
val name = matcher.group(1)
paramsMap.get(name) match {
case Some(param) => parameters ++= List(param)
case _ => parameters ++= List(":" + name)
}
}
sqlText = matcher.replaceAll("?")
new SimpleExpression(sqlText, parameters)
}
// Simple subqueries DSL
def EXISTS(subquery: SQLQuery[_]) =
new SubqueryExpression(ormConf.dialect.EXISTS, subquery)
def NOT_EXISTS(subquery: SQLQuery[_]) =
new SubqueryExpression(ormConf.dialect.NOT_EXISTS, subquery)
// Simple projections
def expr[T](expression: String): ExpressionProjection[T] =
new ExpressionProjection[T](expression)
def COUNT(expr: Expression): Projection[Long] =
new ExpressionProjection[Long](ormConf.dialect.COUNT(expr.toSql))
def COUNT_DISTINCT(expr: Expression): Projection[Long] =
new ExpressionProjection[Long](ormConf.dialect.COUNT_DISTINCT(expr.toSql))
def MAX[T](expr: Expression) =
new ExpressionProjection[T](ormConf.dialect.MAX(expr.toSql))
def MIN[T](expr: Expression) =
new ExpressionProjection[T](ormConf.dialect.MIN(expr.toSql))
def SUM[T](expr: Expression) =
new ExpressionProjection[T](ormConf.dialect.SUM(expr.toSql))
def AVG[T](expr: Expression) =
new ExpressionProjection[T](ormConf.dialect.AVG(expr.toSql))
// Queries DSL
def SELECT[T](p1: Projection[T], p2: Projection[_], pn: Projection[_]*) = {
val projections = List(p1, p2) ++ pn
new Select(new RowProjection(projections))
}
def SELECT[T](projection: Projection[T]): Select[T] = new Select(projection)
def INSERT_INTO[PK, R <: Record[PK, R]](relation: Relation[PK, R]) =
new InsertSelectHelper(relation)
def UPDATE[PK, R <: Record[PK, R]](node: RelationNode[PK, R]) =
new Update(node)
def DELETE[PK, R <: Record[PK, R]](node: RelationNode[PK, R]) =
new Delete(node)
}