Skip to content

Commit

Permalink
Fix for issue #27.
Browse files Browse the repository at this point in the history
Deprecated methods added, and the test suite runs.
  • Loading branch information
dflemstr committed Aug 3, 2010
1 parent 5344859 commit 624cc9a
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 75 deletions.
16 changes: 9 additions & 7 deletions src/main/scala/org/squeryl/KeyedEntity.scala
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ trait ReferentialAction {
}

/**
* ForeingKeyDeclaration are to be manipulated only during the Schema definition
* ForeignKeyDeclaration are to be manipulated only during the Schema definition
* (this is why all public methods have the implicit arg (implicit ev: Schema))
*/
class ForeingKeyDeclaration(val idWithinSchema: Int, val foreingKeyColumnName: String, val referencedPrimaryKey: String) {
class ForeignKeyDeclaration(val idWithinSchema: Int, val foreignKeyColumnName: String, val referencedPrimaryKey: String) {
@deprecated("Use foreignKeyColumnName instead")
final def foreingKeyColumnName = foreignKeyColumnName

private var _referentialActions: Option[(Option[ReferentialAction],Option[ReferentialAction])] = None

Expand All @@ -113,27 +115,27 @@ class ForeingKeyDeclaration(val idWithinSchema: Int, val foreingKeyColumnName: S
_referentialActions.get._2

/**
* Causes the foreing key to have no constraint
* Causes the foreign key to have no constraint
*/
def unConstrainReference()(implicit ev: Schema) =
_referentialActions = None

/**
* Will cause a foreing key constraint to be created at schema creation time :
* alter table <tableOfForeingKey> add foreing key (<foreingKey>) references <tableOfPrimaryKey>(<primaryKey>)
* Will cause a foreign key constraint to be created at schema creation time :
* alter table <tableOfForeignKey> add foreign key (<foreignKey>) references <tableOfPrimaryKey>(<primaryKey>)
*/
def constrainReference()(implicit ev: Schema) =
_referentialActions = Some((None, None))

/**
* Does the same as constrainReference, plus adds a ReferentialAction (ex.: foreingKeyDeclaration.constrainReference(onDelete cascade))
* Does the same as constrainReference, plus adds a ReferentialAction (ex.: foreignKeyDeclaration.constrainReference(onDelete cascade))
*/
def constrainReference(a1: ReferentialAction)(implicit ev: Schema) =
_referentialActions = Some((Some(a1), None))

/**
* Does the same as constrainReference, plus adds two ReferentialActions
* (ex.: foreingKeyDeclaration.constrainReference(onDelete cascade, onUpdate restrict))
* (ex.: foreignKeyDeclaration.constrainReference(onDelete cascade, onUpdate restrict))
*/
def constrainReference(a1: ReferentialAction, a2: ReferentialAction)(implicit ev: Schema) =
_referentialActions = Some((Some(a1), Some(a2)))
Expand Down
50 changes: 27 additions & 23 deletions src/main/scala/org/squeryl/Schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,22 @@ trait Schema {
private def _dbAdapter = Session.currentSession.databaseAdapter

/**
* @returns a tuple of (Table[_], Table[_], ForeingKeyDeclaration) where
* ._1 is the foreing key table,
* @returns a tuple of (Table[_], Table[_], ForeignKeyDeclaration) where
* ._1 is the foreign key table,
* ._2 is the primary key table
* ._3 is the ForeingKeyDeclaration between _1 and _2
* ._3 is the ForeignKeyDeclaration between _1 and _2
*/
private def _activeForeingKeySpecs = {
val res = new ArrayBuffer[(Table[_], Table[_], ForeingKeyDeclaration)]
private def _activeForeignKeySpecs = {
val res = new ArrayBuffer[(Table[_], Table[_], ForeignKeyDeclaration)]

for( r <- _oneToManyRelations if r.foreingKeyDeclaration._isActive)
res.append((r.rightTable, r.leftTable, r.foreingKeyDeclaration))
for( r <- _oneToManyRelations if r.foreignKeyDeclaration._isActive)
res.append((r.rightTable, r.leftTable, r.foreignKeyDeclaration))

for(r <- _manyToManyRelations) {
if(r.leftForeingKeyDeclaration._isActive)
res.append((r.thisTable, r.leftTable , r.leftForeingKeyDeclaration))
if(r.rightForeingKeyDeclaration._isActive)
res.append((r.thisTable, r.rightTable, r.rightForeingKeyDeclaration))
if(r.leftForeignKeyDeclaration._isActive)
res.append((r.thisTable, r.leftTable , r.leftForeignKeyDeclaration))
if(r.rightForeignKeyDeclaration._isActive)
res.append((r.thisTable, r.rightTable, r.rightForeignKeyDeclaration))
}

res
Expand Down Expand Up @@ -112,7 +112,7 @@ trait Schema {
def create = {
_createTables
if(_dbAdapter.supportsForeignKeyConstraints)
_declareForeingKeyConstraints
_declareForeignKeyConstraints

_createUniqueConstraints
}
Expand All @@ -122,18 +122,18 @@ trait Schema {
val cs = Session.currentSession
val dba = cs.databaseAdapter

for(fk <- _activeForeingKeySpecs) {
for(fk <- _activeForeignKeySpecs) {
val s = cs.connection.createStatement
dba.dropForeignKeyStatement(fk._1, dba.foreingKeyConstraintName(fk._1, fk._3.idWithinSchema), cs)
dba.dropForeignKeyStatement(fk._1, dba.foreignKeyConstraintName(fk._1, fk._3.idWithinSchema), cs)
}
}

private def _declareForeingKeyConstraints =
for(fk <- _activeForeingKeySpecs) {
private def _declareForeignKeyConstraints =
for(fk <- _activeForeignKeySpecs) {
val fkDecl = fk._3

val fkStatement = _dbAdapter.writeForeingKeyDeclaration(
fk._1, fkDecl.foreingKeyColumnName,
val fkStatement = _dbAdapter.writeForeignKeyDeclaration(
fk._1, fkDecl.foreignKeyColumnName,
fk._2, fkDecl.referencedPrimaryKey,
fkDecl._referentialAction1,
fkDecl._referentialAction2,
Expand Down Expand Up @@ -267,15 +267,19 @@ trait Schema {

private var _fkIdGen = 1

private [squeryl] def _createForeingKeyDeclaration(fkColName: String, pkColName: String) = {
val fkd = new ForeingKeyDeclaration(_fkIdGen, fkColName, pkColName)
private [squeryl] def _createForeignKeyDeclaration(fkColName: String, pkColName: String) = {
val fkd = new ForeignKeyDeclaration(_fkIdGen, fkColName, pkColName)
_fkIdGen += 1
applyDefaultForeingKeyPolicy(fkd)
applyDefaultForeignKeyPolicy(fkd)
fkd
}

def applyDefaultForeingKeyPolicy(foreingKeyDeclaration: ForeingKeyDeclaration) =
foreingKeyDeclaration.constrainReference
def applyDefaultForeignKeyPolicy(foreignKeyDeclaration: ForeignKeyDeclaration) =
foreignKeyDeclaration.constrainReference

@deprecated("Use applyDefaultForeignKeyPolicy instead")
final def applyDefaultForeingKeyPolicy(foreingKeyDeclaration: ForeignKeyDeclaration) =
applyDefaultForeignKeyPolicy(foreingKeyDeclaration)

/**
* @return a Tuple2 with (LengthOfDecimal, Scale) that will determin the storage
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/org/squeryl/adapters/MySQLAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class MySQLAdapter extends DatabaseAdapter {

//override def nvlToken = "ifnull"

override def writeForeingKeyDeclaration(
foreingKeyTable: Table[_], foreingKeyColumnName: String,
override def writeForeignKeyDeclaration(
foreignKeyTable: Table[_], foreignKeyColumnName: String,
primaryKeyTable: Table[_], primaryKeyColumnName: String,
referentialAction1: Option[ReferentialAction],
referentialAction2: Option[ReferentialAction],
Expand All @@ -37,11 +37,11 @@ class MySQLAdapter extends DatabaseAdapter {
val sb = new StringBuilder(256)

sb.append("alter table ")
sb.append(foreingKeyTable.name)
sb.append(foreignKeyTable.name)
sb.append(" add constraint ")
sb.append(foreingKeyConstraintName(foreingKeyTable, fkId))
sb.append(foreignKeyConstraintName(foreignKeyTable, fkId))
sb.append(" foreign key (")
sb.append(foreingKeyColumnName)
sb.append(foreignKeyColumnName)
sb.append(") references ")
sb.append(primaryKeyTable.name)
sb.append("(")
Expand All @@ -61,8 +61,8 @@ class MySQLAdapter extends DatabaseAdapter {
sb.toString
}

override def writeDropForeignKeyStatement(foreingKeyTable: Table[_], fkName: String) =
"alter table " + foreingKeyTable.name + " drop foreign key " + fkName
override def writeDropForeignKeyStatement(foreignKeyTable: Table[_], fkName: String) =
"alter table " + foreignKeyTable.name + " drop foreign key " + fkName

override def isTableDoesNotExistException(e: SQLException) =
e.getErrorCode == 1051
Expand All @@ -78,7 +78,7 @@ class MySQLAdapter extends DatabaseAdapter {
*
* http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
*
* Apparently there are other pre requisites, because creating foreing key constraints still gives :
* Apparently there are other pre requisites, because creating foreign key constraints still gives :
*
* Time Action Response Duration / Fetch
* 0 1 18:26:25 alter table CourseSubscription add constraint CourseSubscriptionFK3
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/org/squeryl/adapters/OracleAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ class OracleAdapter extends DatabaseAdapter {
override def writeSelectElementAlias(se: SelectElement, sw: StatementWriter) =
sw.write(shrinkTo30AndPreserveUniquenessInScope(se.alias, sw.scope))

override def foreingKeyConstraintName(foreingKeyTable: Table[_], idWithinSchema: Int) = {
val name = super.foreingKeyConstraintName(foreingKeyTable, idWithinSchema)
val r = shrinkTo30AndPreserveUniquenessInScope(name, foreingKeyTable.schema._namingScope)
override def foreignKeyConstraintName(foreignKeyTable: Table[_], idWithinSchema: Int) = {
val name = super.foreignKeyConstraintName(foreignKeyTable, idWithinSchema)
val r = shrinkTo30AndPreserveUniquenessInScope(name, foreignKeyTable.schema._namingScope)
r
}
}
Expand All @@ -202,4 +202,4 @@ object OracleAdapter {

val legalOracleSuffixChars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789".toCharArray.toList
}
}
4 changes: 2 additions & 2 deletions src/main/scala/org/squeryl/adapters/PostgreSqlAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ class PostgreSqlAdapter extends DatabaseAdapter {
override def isTableDoesNotExistException(e: SQLException) =
e.getSQLState.equals("42P01")

override def writeDropForeignKeyStatement(foreingKeyTable: Table[_], fkName: String) =
"alter table " + foreingKeyTable.name + " drop constraint " + fkName
override def writeDropForeignKeyStatement(foreignKeyTable: Table[_], fkName: String) =
"alter table " + foreignKeyTable.name + " drop constraint " + fkName

override def failureOfStatementRequiresRollback = true

Expand Down
23 changes: 16 additions & 7 deletions src/main/scala/org/squeryl/dsl/ManyToMany.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
******************************************************************************/
package org.squeryl.dsl

import org.squeryl.{ForeingKeyDeclaration, Table, Query, KeyedEntity}
import org.squeryl.{ForeignKeyDeclaration, Table, Query, KeyedEntity}
import collection.mutable.{HashMap, ArrayBuffer, Buffer}

trait Relation[L <: KeyedEntity[_],R <: KeyedEntity[_]] {
Expand All @@ -27,7 +27,10 @@ trait Relation[L <: KeyedEntity[_],R <: KeyedEntity[_]] {

trait OneToManyRelation[O <: KeyedEntity[_],M <: KeyedEntity[_]] extends Relation[O,M] {

def foreingKeyDeclaration: ForeingKeyDeclaration
def foreignKeyDeclaration: ForeignKeyDeclaration

@deprecated("Use foreignKeyDeclaration instead")
final def foreingKeyDeclaration = foreignKeyDeclaration

def left(leftSide: O): OneToMany[M]

Expand Down Expand Up @@ -92,9 +95,15 @@ trait ManyToManyRelation[L <: KeyedEntity[_], R <: KeyedEntity[_], A <: KeyedEnt

def thisTable: Table[A]

def leftForeingKeyDeclaration: ForeingKeyDeclaration
def leftForeignKeyDeclaration: ForeignKeyDeclaration

@deprecated("Use leftForeignKeyDeclaration instead")
final def leftForeingKeyDeclaration = leftForeignKeyDeclaration

def rightForeingKeyDeclaration: ForeingKeyDeclaration
def rightForeignKeyDeclaration: ForeignKeyDeclaration

@deprecated("Use rightForeignKeyDeclaration instead")
final def rightForeingKeyDeclaration = rightForeignKeyDeclaration

def left(leftSide: L): ManyToMany[R,A]

Expand Down Expand Up @@ -124,7 +133,7 @@ trait ManyToMany[O <: KeyedEntity[_],A <: KeyedEntity[_]] extends Query[O] {
/**
* @param a: the association object
*
* Sets the foreing keys of the association object to the primary keys of the left and right side,
* Sets the foreign keys of the association object to the primary keys of the left and right side,
* this method does not update the database, changes to the association object must be done for
* the operation to be persisted. Alternatively the method 'associate(o, a)' will call this assign(o, a)
* and persist the changes.
Expand All @@ -148,7 +157,7 @@ trait ManyToMany[O <: KeyedEntity[_],A <: KeyedEntity[_]] extends Query[O] {
* Creates a new association object 'a' and calls associate(o,a)
*
* Note that this method will fail if the association object has NOT NULL constraint fields appart from the
* foreing keys in the relations
* foreign keys in the relations
*
*/
def associate(o: O): A
Expand Down Expand Up @@ -228,7 +237,7 @@ trait OneToMany[M] extends Query[M] {
/**
* @param the object on the 'many side' to be associated with this
*
* Sets the foreing key of 'm' to refer to the primary key of the 'one' instance
* Sets the foreign key of 'm' to refer to the primary key of the 'one' instance
*/
def assign(m: M): Unit

Expand Down
14 changes: 7 additions & 7 deletions src/main/scala/org/squeryl/dsl/QueryDsl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ trait QueryDsl

/**
* returns a (FieldMetaData, FieldMetaData) where ._1 is the id of the KeyedEntity on the left or right side,
* and where ._2 is the foreing key of the association object/table
* and where ._2 is the foreign key of the association object/table
*/
private def _splitEquality(ee: EqualityExpression) =
if(ee.left._fieldMetaData.parentMetaData.clasz == aClass) {
Expand All @@ -321,11 +321,11 @@ trait QueryDsl

private val (rightPkFmd, rightFkFmd) = _splitEquality(_rightEqualityExpr)

val leftForeingKeyDeclaration =
schema._createForeingKeyDeclaration(leftFkFmd.columnName, leftPkFmd.columnName)
val leftForeignKeyDeclaration =
schema._createForeignKeyDeclaration(leftFkFmd.columnName, leftPkFmd.columnName)

val rightForeingKeyDeclaration =
schema._createForeingKeyDeclaration(rightFkFmd.columnName, rightPkFmd.columnName)
val rightForeignKeyDeclaration =
schema._createForeignKeyDeclaration(rightFkFmd.columnName, rightPkFmd.columnName)

private def _associate[T <: KeyedEntity[_]](o: T, m2m: ManyToMany[T,A]): A = {
val aInst = m2m.assign(o)
Expand Down Expand Up @@ -506,8 +506,8 @@ trait QueryDsl
ee_.right.asInstanceOf[SelectElementReference[_]].selectElement.asInstanceOf[FieldSelectElement].fieldMataData)
}

val foreingKeyDeclaration =
schema._createForeingKeyDeclaration(_rightFkFmd.columnName, _leftPkFmd.columnName)
val foreignKeyDeclaration =
schema._createForeignKeyDeclaration(_rightFkFmd.columnName, _leftPkFmd.columnName)

def left(leftSide: O): OneToMany[M] = {

Expand Down
36 changes: 28 additions & 8 deletions src/main/scala/org/squeryl/internals/DatabaseAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -543,24 +543,44 @@ trait DatabaseAdapter {
*/
def isNotNullConstraintViolation(e: SQLException): Boolean = false

@deprecated("Use foreignKeyConstraintName instead")
def foreingKeyConstraintName(foreingKeyTable: Table[_], idWithinSchema: Int) =
foreingKeyTable.name + "FK" + idWithinSchema
foreignKeyConstraintName(foreingKeyTable, idWithinSchema)

def foreignKeyConstraintName(foreignKeyTable: Table[_], idWithinSchema: Int) =
foreignKeyTable.name + "FK" + idWithinSchema

@deprecated("Use writeForeignKeyDeclaration instead")
def writeForeingKeyDeclaration(
foreingKeyTable: Table[_], foreingKeyColumnName: String,
primaryKeyTable: Table[_], primaryKeyColumnName: String,
referentialAction1: Option[ReferentialAction],
referentialAction2: Option[ReferentialAction],
fkId: Int) =
writeForeignKeyDeclaration(
foreingKeyTable,
foreingKeyColumnName,
primaryKeyTable,
primaryKeyColumnName,
referentialAction1: Option[ReferentialAction],
referentialAction2: Option[ReferentialAction],
fkId)

def writeForeignKeyDeclaration(
foreignKeyTable: Table[_], foreignKeyColumnName: String,
primaryKeyTable: Table[_], primaryKeyColumnName: String,
referentialAction1: Option[ReferentialAction],
referentialAction2: Option[ReferentialAction],
fkId: Int) = {

val sb = new StringBuilder(256)

sb.append("alter table ")
sb.append(foreingKeyTable.name)
sb.append(foreignKeyTable.name)
sb.append(" add constraint ")
sb.append(foreingKeyConstraintName(foreingKeyTable, fkId))
sb.append(foreignKeyConstraintName(foreignKeyTable, fkId))
sb.append(" foreign key (")
sb.append(foreingKeyColumnName)
sb.append(foreignKeyColumnName)
sb.append(") references ")
sb.append(primaryKeyTable.name)
sb.append("(")
Expand All @@ -583,11 +603,11 @@ trait DatabaseAdapter {
protected def currenSession =
Session.currentSession

def writeDropForeignKeyStatement(foreingKeyTable: Table[_], fkName: String) =
"alter table " + foreingKeyTable.name + " drop constraint " + fkName
def writeDropForeignKeyStatement(foreignKeyTable: Table[_], fkName: String) =
"alter table " + foreignKeyTable.name + " drop constraint " + fkName

def dropForeignKeyStatement(foreingKeyTable: Table[_], fkName: String, session: Session):Unit =
execFailSafeExecute(writeDropForeignKeyStatement(foreingKeyTable, fkName), e => true)
def dropForeignKeyStatement(foreignKeyTable: Table[_], fkName: String, session: Session):Unit =
execFailSafeExecute(writeDropForeignKeyStatement(foreignKeyTable, fkName), e => true)

def isTableDoesNotExistException(e: SQLException): Boolean

Expand Down
Loading

0 comments on commit 624cc9a

Please sign in to comment.