As mentioned is this issue
(http://github.com/dpp/liftweb/issues#issue/19), and as came up on the
list recently, Lift currently has no way to specify that a field or an
index be unique. I've coded up a patch that addresses this, and could
also be used for other index types on a project specific basis (for
instance, FULLTEXT or SPATIAL indexes in mysql).
-Cale
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---
From 4436bd234d5a80ebe5e0f027256979fc14b3dea8 Mon Sep 17 00:00:00 2001
From: Calen Pennington <cpenn...@flying-pickle.(none)>
Date: Wed, 8 Jul 2009 22:48:31 -0400
Subject: [PATCH] Adding the ability to create UNIQUE indexes over single or multiple columns
---
.../scala/net/liftweb/mapper/MappedField.scala | 14 ++++++++++++++
.../main/scala/net/liftweb/mapper/MetaMapper.scala | 7 ++++++-
.../main/scala/net/liftweb/mapper/Schemifier.scala | 15 ++++++++-------
3 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/lift-mapper/src/main/scala/net/liftweb/mapper/MappedField.scala b/lift-mapper/src/main/scala/net/liftweb/mapper/MappedField.scala
index 01c739c..298211f 100644
--- a/lift-mapper/src/main/scala/net/liftweb/mapper/MappedField.scala
+++ b/lift-mapper/src/main/scala/net/liftweb/mapper/MappedField.scala
@@ -98,6 +98,11 @@ trait BaseMappedField extends SelectableField with Bindable {
def dbIndexed_? : Boolean
/**
+ * What type of index is this?
+ */
+ def dbIndexType : String
+
+ /**
* Is the field the table's primary key
*/
def dbPrimaryKey_? : Boolean
@@ -165,6 +170,13 @@ trait DBIndexed extends BaseMappedField {
}
/**
+ * Mix this trait into a DBIndexed and it will use a unique index
+ */
+trait UniqueIndexed extends DBIndexed {
+ override def dbIndexType = "UNIQUE"
+}
+
+/**
* The Trait that defines a field that is mapped to a foreign key
*/
trait MappedForeignKey[KeyType, MyOwner <: Mapper[MyOwner], Other <: KeyedMapper[KeyType, Other]] extends MappedField[KeyType, MyOwner] {
@@ -521,6 +533,8 @@ trait MappedField[FieldType <: Any,OwnerType <: Mapper[OwnerType]] extends Typed
def dbPrimaryKey_? : Boolean = false
+ def dbIndexType : String = ""
+
/**
* Is the field a foreign key reference
*/
diff --git a/lift-mapper/src/main/scala/net/liftweb/mapper/MetaMapper.scala b/lift-mapper/src/main/scala/net/liftweb/mapper/MetaMapper.scala
index 0d36c8b..a59a0a8 100644
--- a/lift-mapper/src/main/scala/net/liftweb/mapper/MetaMapper.scala
+++ b/lift-mapper/src/main/scala/net/liftweb/mapper/MetaMapper.scala
@@ -1118,8 +1118,13 @@ object OprEnum extends Enumeration {
val Like = Value(9, "LIKE")
}
+case class Index[A <: Mapper[A]](columns: IndexItem[A]*) {
+ def dbIndexType : String = ""
+}
-case class Index[A <: Mapper[A]](columns: IndexItem[A]*)
+case class UniqueIndex[A <: Mapper[A]](override val columns: IndexItem[A]*) extends Index[A] {
+ override def dbIndexType = "UNIQUE"
+}
abstract class IndexItem[A <: Mapper[A]] {
def field: BaseMappedField
diff --git a/lift-mapper/src/main/scala/net/liftweb/mapper/Schemifier.scala b/lift-mapper/src/main/scala/net/liftweb/mapper/Schemifier.scala
index f24851b..85e0a7f 100644
--- a/lift-mapper/src/main/scala/net/liftweb/mapper/Schemifier.scala
+++ b/lift-mapper/src/main/scala/net/liftweb/mapper/Schemifier.scala
@@ -251,20 +251,21 @@ object Schemifier {
field =>
if (!indexedFields.contains(List(field.dbColumnName.toLowerCase))) {
cmds += maybeWrite(performWrite, logFunc, connection) {
- () => "CREATE INDEX "+(table.dbTableName+"_"+field.dbColumnName)+" ON "+table.dbTableName+" ( "+field.dbColumnName+" )"
+ () => "CREATE "+field.dbIndexType+" INDEX "+(table.dbTableName+"_"+field.dbColumnName)+" ON "+table.dbTableName+" ( "+field.dbColumnName+" )"
}
field.dbAddedIndex.toList
} else Nil
}
table.dbIndexes.foreach {
- index =>
+ index => {
val columns = index.columns.toList
- val fn = columns.map(_.field.dbColumnName.toLowerCase).sort(_ < _)
- if (!indexedFields.contains(fn)) {
- cmds += maybeWrite(performWrite, logFunc, connection) {
- () => "CREATE INDEX "+(table.dbTableName+"_"+columns.map(_.field.dbColumnName).mkString("_"))+" ON "+table.dbTableName+" ( "+columns.map(_.indexDesc).comma+" )"
- }
+ val fn = columns.map(_.field.dbColumnName.toLowerCase).sort(_ < _)
+ if (!indexedFields.contains(fn)) {
+ cmds += maybeWrite(performWrite, logFunc, connection) {
+ () => "CREATE "+index.dbIndexType+" INDEX "+(table.dbTableName+"_"+columns.map(_.field.dbColumnName).mkString("_"))+" ON "+table.dbTableName+" ( "+columns.map(_.indexDesc).comma+" )"
+ }
+ }
}
}
--
1.6.0.4