9fb42f3c37f3e4fe Code list implementation
authorTomas Zeman <tzeman@volny.cz>
Fri, 10 Feb 2012 09:53:03 +0100
changeset 4 bb4478e1cff7
parent 3 ce369fc04c27
child 5 993582ca8d2e
9fb42f3c37f3e4fe Code list implementation
src/main/scala/fis/base/model/BaseSchema.scala
src/main/scala/fis/base/model/CodeList.scala
src/test/scala/fis/base/model/CodeListSpec.scala
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/fis/base/model/BaseSchema.scala	Fri Feb 10 09:53:03 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2011 Tomas Zeman <tzeman@volny.cz>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package fis.base.model
+
+import org.squeryl.Schema
+import net.liftweb.squerylrecord.RecordTypeMode._
+
+trait BaseSchema extends Schema {
+  val codeListItems = table[CodeListItem]
+}
+
+object BaseSchema extends BaseSchema
+
+
+// vim: set ts=2 sw=2 et:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/fis/base/model/CodeList.scala	Fri Feb 10 09:53:03 2012 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2011 Tomas Zeman <tzeman@volny.cz>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package fis.base.model
+
+import net.liftweb.common._
+import net.liftweb.record.{Field, MetaRecord, Record}
+import net.liftweb.record.field._
+import net.liftweb.squerylrecord.KeyedRecord
+import net.liftweb.squerylrecord.RecordTypeMode._
+import scala.xml.{NodeSeq, Text}
+
+class CodeListItem private () extends Record[CodeListItem] with
+  Entity[CodeListItem] {
+
+  def meta = CodeListItem
+
+  /** I18n flag for this item's name. */
+  val i18n = new BooleanField(this)
+  /** Default item flag. */
+  val dflt = new BooleanField(this)
+  /** Reference to code list id (enum id). */
+  val codeListType = new IntField(this)
+
+  override def toXHtml = Text(linkName)
+}
+
+object CodeListItem extends CodeListItem with MetaRecord[CodeListItem] with
+  MetaEntity[CodeListItem] {
+
+  def getTable = BaseSchema.codeListItems
+
+  def items(codeListType: Int) = from(getTable) { cli =>
+    where(cli.codeListType === codeListType)
+    select(cli)
+  }
+
+  def defaultItem(codeListType: Int): Box[CodeListItem] =
+    items(codeListType) find (_.dflt.get)
+}
+
+trait CodeList[T] {
+  def items: Iterable[T]
+  def defaultItem: Box[T]
+  def item(id: Long): Box[T]
+}
+
+class CodeListImpl[T](val id: Int, tr: CodeListItem => T) extends
+  CodeList[T] {
+
+  def items = CodeListItem.items(id) map (tr(_))
+  def defaultItem = CodeListItem.defaultItem(id) map (tr(_))
+  def item(id: Long) = CodeListItem.findByKey(id) map (tr(_))
+}
+
+import net.liftweb.http.SHtml
+import net.liftweb.util.Helpers._
+
+class CodeListItemField[T, OwnerType <: Record[OwnerType]](own: OwnerType,
+  codeListType: Int, tr: CodeListItem => T) extends LongField(own) with
+  Converter0[Box[T]] {
+
+  def item: Box[CodeListItem] = CodeListItem.findByKey(get)
+  def cvt: Box[T] = item map { tr(_) }
+
+  override def defaultValueBox: Box[Long] =
+    CodeListItem.defaultItem(codeListType).map { _.id }
+
+  override def toXHtml = item map { _.toXHtml } openOr NodeSeq.Empty
+
+  protected def buildDisplayList: List[(Long, String)] =
+    CodeListItem.items(codeListType).toList.map { i =>
+      (i.id, i.linkName)
+    }
+
+  private def elem = SHtml.selectObj[Long](buildDisplayList, Full(get),
+    set(_)) % ("tabindex" -> tabIndex.toString)
+
+  override def toForm: Box[NodeSeq] = uniqueFieldId match {
+    case Full(id) => Full(elem % ("id" -> id))
+    case _ => Full(elem)
+  }
+}
+ 
+// vim: set ts=2 sw=2 et:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/fis/base/model/CodeListSpec.scala	Fri Feb 10 09:53:03 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2011 Tomas Zeman <tzeman@volny.cz>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package fis.base.model
+
+import net.liftweb.common._
+import org.scalatest._
+import org.scalatest.matchers.ShouldMatchers
+
+class CodeListSpec extends FlatSpec with ShouldMatchers with Logger
+  with BeforeAndAfterAllFunctions {
+
+  import net.liftweb.mapper.{DB, DefaultConnectionIdentifier, StandardDBVendor}
+  import net.liftweb.squerylrecord.RecordTypeMode._
+  import net.liftweb.squerylrecord.SquerylRecord
+  import org.squeryl.adapters.H2Adapter
+  import TestBaseSchema._
+
+  val dbVendor = new StandardDBVendor("org.h2.Driver",
+    "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", Empty, Empty)
+  DB.defineConnectionManager(DefaultConnectionIdentifier, dbVendor)
+  SquerylRecord.init(() => new H2Adapter)
+
+  beforeAll {
+    doInDB { dropAndCreate }
+  }
+
+  "CodeListItem" should "create/retrieve item" in {
+    doInDB {
+      val cli1 = CodeListItem.createRecord.name("cli1").codeListType(1)
+      codeListItems.insert(cli1)
+      val l1 = from(codeListItems)(cli => select(cli)).toList
+      l1.size should equal (1)
+      val cl = new CodeListImpl(1, { i => i } )
+      val l2 = cl.items
+      l2.size should equal (1)
+      l2.head should equal (cli1)
+    }
+  }
+
+  def doInDB(block: => Any) {
+    DB.use(DefaultConnectionIdentifier) { _ => block }
+  }
+}
+
+object TestBaseSchema extends BaseSchema {
+  def dropAndCreate {
+    drop
+    create
+  }
+}
+
+// vim: set ts=2 sw=2 et: