# HG changeset patch # User Tomas Zeman # Date 1328863983 -3600 # Node ID bb4478e1cff7cb341b146559844760ef57f98239 # Parent ce369fc04c277732fdfdb80cab5dbc8bf3a385cf 9fb42f3c37f3e4fe Code list implementation diff -r ce369fc04c27 -r bb4478e1cff7 src/main/scala/fis/base/model/BaseSchema.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 + * + * 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: diff -r ce369fc04c27 -r bb4478e1cff7 src/main/scala/fis/base/model/CodeList.scala --- /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 + * + * 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: diff -r ce369fc04c27 -r bb4478e1cff7 src/test/scala/fis/base/model/CodeListSpec.scala --- /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 + * + * 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: