All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rcumflex.circumflex-orm.3.0-RC1.source-code.vendor.scala Maven / Gradle / Ivy

The newest version!
package pro.savant.circumflex
package orm

import java.sql._

/*!# Vendor-specific SQL dialects

Following vendors are currently supported by Circumflex ORM:

  * PostgreSQL 8.3+;
  * MySQL 5.7+;
  * H2 database.

We also provide limited support for `Oracle`, `MS SQL Server` and `DB2`.
We would appreciate any commits for better vendors support.
*/
class H2Dialect extends Dialect {

  override def driverClass = "org.h2.Driver"

  override def textType = "VARCHAR"

  override def createIndex(idx: Index): String = {
    var result = "CREATE "
    if (idx.isUnique) result += "UNIQUE "
    result += "INDEX " + idx.name + " ON " + idx.relation.qualifiedName +
        " (" + idx.expression + ")"
    if (idx.whereClause != EmptyPredicate)
      result += " WHERE " + idx.whereClause.toInlineSql
    result
  }

  override def dropSchema(schema: Schema) = "DROP SCHEMA " + schema.name

  override def RANDOM = "RAND()"
}

class PostgreSQLDialect extends Dialect {

  override def driverClass = "org.postgresql.Driver"

  override def timestampType = "TIMESTAMPTZ"

  override def parameterizedIn(ex: String, params: Iterable[String]) = {
    if (params.size == 0) "FALSE"
    else ex + " IN (" + params.mkString(", ") + ")"
  }

}

class MySQLDialect extends Dialect {

  override def supportsSchema = false

  override def driverClass = "com.mysql.jdbc.Driver"

  override def initializeField[R <: Record[_, R]](field: Field[_, R]) {
    // do nothing -- for MySQL you don't need to create manually a sequence for auto-incrementable fields
  }

  override def defaultExpression[R <: Record[_, R]](field: Field[_, R]): String =
    field match {
      case a: AutoIncrementable[_, _] if (a.isAutoIncrement) =>" AUTO_INCREMENT"
      case _ => field.defaultExpression.map(" DEFAULT " + _).getOrElse("")
    }

  override def identityLastIdPredicate[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): Predicate =
    new SimpleExpression(node.alias + "." + node.relation.PRIMARY_KEY.name + " = LAST_INSERT_ID()", Nil)

  override def identityLastIdQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    new Select(expr[PK]("LAST_INSERT_ID()"))

  override def sequenceNextValQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    throw new UnsupportedOperationException("This operation is unsupported in MySQL dialect.")

  override def createIndex(idx: Index): String = {
    var result = "CREATE "
    if (idx.isUnique) result += "UNIQUE "
    result += "INDEX " + idx.name + " USING " + idx.usingClause +
        " ON " + idx.relation.qualifiedName + " (" + idx.expression + ")"
    if (idx.whereClause != EmptyPredicate)
      ORM_LOG.warn("Ignoring WHERE clause of INDEX " + idx.name +
          ": predicates are not supported.")
    result
  }

  override def delete[PK, R <: Record[PK, R]]
  (dml: Delete[PK, R]): String = {
    var result = "DELETE " + dml.node.alias + " FROM " + dml.node.toSql
    if (dml.whereClause != EmptyPredicate) result += " WHERE " + dml.whereClause.toSql
    result
  }

  override def RANDOM = "RAND()"
}

class OracleDialect extends Dialect {

  override def driverClass = "oracle.jdbc.driver.OracleDriver"

  override def fkNoAction = "SET_NULL"
  override def fkRestrict = "SET NULL"
  override def fkSetDefault = "SET NULL"

  override def numericType(precision: Int, scale: Int): String =
    "NUMBER" + (if (precision == -1) "" else "(" + precision + "," + scale + ")")
  override def textType = "VARCHAR2(4000)"
  override def varcharType(length: Int): String =
    "VARCHAR2" + (if (length == -1) "" else "(" + length + ")")
  override def booleanType = "NUMBER(1)"

  override def supportsSchema = false

  override def createIndex(idx: Index): String = {
    var result = "CREATE "
    if (idx.isUnique) result += "UNIQUE "
    result += "INDEX " + idx.name +
        " ON " + idx.relation.qualifiedName + " (" + idx.expression + ")"
    if (idx.whereClause != EmptyPredicate)
      ORM_LOG.warn("Ignoring WHERE clause of INDEX " + idx.name +
          ": predicates are not supported.")
    result
  }

  override def defaultExpression[R <: Record[_, R]]
  (field: Field[_, R]): String =
    field.defaultExpression.map(" DEFAULT " + _).getOrElse("")

  override def sequenceNextValQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    new Select(expr[PK](sequenceName(node.relation.PRIMARY_KEY) + ".nextval FROM dual"))

  override def identityLastIdPredicate[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): Predicate =
    throw new UnsupportedOperationException(
      "This operation is unsupported in Oracle dialect.")

  override def identityLastIdQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    throw new UnsupportedOperationException(
      "This operation is unsupported in Oracle dialect.")

  override def NOW = "CURRENT_TIMESTAMP"

  override def RANDOM = "DBMS_RANDOM.VALUE"
}

class DB2Dialect extends Dialect {
  override def driverClass = "com.ibm.db2.jcc.DB2Driver"

  override def prepareStatement(conn: Connection, sql: String): PreparedStatement =
    conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE)

  override def textType = "VARCHAR(4000)"

  override def booleanType = "SMALLINT"

  override def defaultExpression[R <: Record[_, R]](field: Field[_, R]): String =
    field match {
      case a: AutoIncrementable[_, _] if (a.isAutoIncrement) =>
        " GENERATED BY DEFAULT AS IDENTITY"
      case _ => field.defaultExpression.map(" DEFAULT " + _).getOrElse("")
    }

  override def sequenceNextValQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    new NativeSQLQuery[PK](
      expr[PK]("NEXTVAL FOR " + sequenceName(node.relation.PRIMARY_KEY)),
      prepareExpr("SELECT {*} FROM SYSIBM.SYSDUMMY1"))

  override def identityLastIdPredicate[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): Predicate =
    new SimpleExpression(node.alias + "." + node.relation.PRIMARY_KEY.name +
        " = IDENTITY_VAL_LOCAL()", Nil)

  override def identityLastIdQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    new NativeSQLQuery[PK](expr[PK]("IDENTITY_VAL_LOCAL()"),
      prepareExpr("SELECT {*}  FROM SYSIBM.SYSDUMMY1"))

  override def createIndex(idx: Index): String = {
    var result = "CREATE "
    if (idx.isUnique) result += "UNIQUE "
    result += "INDEX " + idx.name +
        " ON " + idx.relation.qualifiedName + " (" + idx.expression + ")"
    if (idx.whereClause != EmptyPredicate)
      ORM_LOG.warn("Ignoring WHERE clause of INDEX " + idx.name +
          ": predicates are not supported.")
    result
  }

  override def dropSchema(schema: Schema) =
    "DROP SCHEMA " + schema.name + " RESTRICT"

  override def insert[PK, R <: Record[PK, R]](dml: Insert[PK, R]): String = {
    var result = "INSERT INTO " + dml.relation.qualifiedName
    if (dml.fields.size > 0)
      result += " (" + dml.fields.map(_.name).mkString(", ") +
          ") VALUES (" + dml.fields.map(_.placeholder).mkString(", ") + ")"
    else result += " VALUES DEFAULT"
    result
  }

  /*!## Common functions */
  override def NOW = "CURRENT TIMESTAMP"

  override def RANDOM = "RAND()"
}

class MSSQLDialect extends Dialect {
  override def driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver"

  override def booleanType = "BIT"

  override def supportsSchema = false

  override def defaultExpression[R <: Record[_, R]](field: Field[_, R]): String =
    field match {
      case a: AutoIncrementable[_, _] if (a.isAutoIncrement) =>" IDENTITY"
      case _ => field.defaultExpression.map(" DEFAULT " + _).getOrElse("")
    }

  override def columnDefinition[R <: Record[_, R]](field: Field[_, R]): String = {
    var result = field.name + " " + field.sqlType
    result += defaultExpression(field)
    if (field.isNotNull) result += " NOT NULL"
    result
  }

  override def createIndex(idx: Index): String = {
    var result = "CREATE "
    if (idx.isUnique) result += "UNIQUE "
    result += "INDEX " + idx.name + " ON " + idx.relation.qualifiedName +
        " (" + idx.expression + ")"
    if (idx.whereClause != EmptyPredicate)
      result += " WHERE " + idx.whereClause.toInlineSql
    result
  }

  override def sequenceNextValQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    throw new UnsupportedOperationException(
      "This operation is unsupported in MS SQL Server dialect.")

  override def identityLastIdPredicate[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): Predicate =
    new SimpleExpression(node.alias + "." + node.relation.PRIMARY_KEY.name +
        " = @@IDENTITY", Nil)

  override def identityLastIdQuery[PK, R <: Record[PK, R]]
  (node: RelationNode[PK, R]): SQLQuery[PK] =
    new Select(expr[PK]("@@IDENTITY"))


  /*!## Common functions */
  override def NOW = "CURRENT_TIMESTAMP"
  override def RANDOM = "RAND()"
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy