# HG changeset patch # User Tomas Zeman # Date 1333446423 -7200 # Node ID 0b74e7bbe6ff250d11a604319631e946eb32029d # Parent eba7121e29cdb3086c36fa8238dfdcb77dac61d1 Code lists refactoring diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/base/model/BaseSchema.scala --- a/src/main/scala/fis/base/model/BaseSchema.scala Tue Apr 03 11:47:02 2012 +0200 +++ b/src/main/scala/fis/base/model/BaseSchema.scala Tue Apr 03 11:47:03 2012 +0200 @@ -15,11 +15,17 @@ */ package fis.base.model +import net.liftweb.squerylrecord.RecordTypeMode._ import net.liftweb.util.Helpers.snakify -import org.squeryl.Schema +import org.squeryl._ trait BaseSchema extends Schema { - val codeListItems = table[CodeListItem] + protected def tableWithSeq[T <: KeyedEntity[Long]]()( + implicit manifestT: Manifest[T]): Table[T] = { + val tbl = table()(manifestT) + on(tbl)(t => declare(t.id.is(autoIncremented(tbl.name + "_id_seq")))) + tbl + } override def tableNameFromClass(c: Class[_]): String = snakify(c.getSimpleName) diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/base/model/CodeList.scala --- a/src/main/scala/fis/base/model/CodeList.scala Tue Apr 03 11:47:02 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * 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: CodeListRegister.CodeListRegister, - tr: CodeListItem => T) extends CodeList[T] { - - def items = CodeListItem.items(id.id) map (tr(_)) - def defaultItem = CodeListItem.defaultItem(id.id) map (tr(_)) - def item(id: Long) = CodeListItem.findByKey(id) map (tr(_)) -} - -import net.liftweb.http.SHtml -import net.liftweb.util.Helpers._ -import CodeListRegister.CodeListRegister - -class CodeListItemField[T, OwnerType <: Record[OwnerType]](own: OwnerType, - codeListType: CodeListRegister, tr: CodeListItem => T) - extends AbstractCodeListItemField[T, OwnerType](own, codeListType) { - - def cvt: Box[T] = item map { tr(_) } -} - -abstract class AbstractCodeListItemField[T, OwnerType <: Record[OwnerType]]( - own: OwnerType, codeListType: CodeListRegister) extends LongField(own) with - Converter0[Box[T]] { - - def item: Box[CodeListItem] = CodeListItem.findByKey(get) - - override def defaultValueBox: Box[Long] = - CodeListItem.defaultItem(codeListType.id).map { _.id } - - override def toXHtml = item map { _.toXHtml } openOr NodeSeq.Empty - - protected def buildDisplayList: List[(Long, String)] = - CodeListItem.items(codeListType.id).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 eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/base/model/codeLists.scala --- a/src/main/scala/fis/base/model/codeLists.scala Tue Apr 03 11:47:02 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * 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 - -object CodeListRegister extends Enumeration { - type CodeListRegister = Val - val TestCL = new Val(-1, "TestCL") - -} - -// vim: set ts=2 sw=2 et: diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/cl/model/CodeList.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/cl/model/CodeList.scala Tue Apr 03 11:47:03 2012 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2012 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.cl.model + +import net.liftweb.common._ +import net.liftweb.squerylrecord.RecordTypeMode._ + +/** + * Code list API. + */ +trait CodeListLike[T] { + def items: Iterable[T] + def dflt: Box[T] + def apply(id: Long): Option[T] +} + +case class CodeList(codeList: Symbol) extends CodeListLike[CodeListItem] with + CodeListCrud { + + lazy val codeListStr = codeList.name + + def apply(id: Long) = CodeListSchema.cli.lookup(id) + + def items = from(table)( + i => where(i.codeList === codeListStr and i.deleted === false) + select(i) + orderBy(i.rank asc) + ) + + def dflt = from(table)( + i => where(i.codeList === codeListStr and i.dflt === true) + select(i) + ).page(0, 1) headOption + +} diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/cl/model/CodeListCrud.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/cl/model/CodeListCrud.scala Tue Apr 03 11:47:03 2012 +0200 @@ -0,0 +1,26 @@ +/* + * Copyright 2012 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.cl.model + +import fis.base.model.RecordCrud + +trait CodeListCrud extends RecordCrud[CodeListItem] { + val table = CodeListSchema.cli +} + +object CodeListCrud extends CodeListCrud + +// vim: set ts=2 sw=2 et: diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/cl/model/CodeListItem.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/cl/model/CodeListItem.scala Tue Apr 03 11:47:03 2012 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright 2011-2012 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.cl.model + +import fis.base.model.Entity +import net.liftweb.common._ +import net.liftweb.record.{Field, MetaRecord, Record} +import net.liftweb.record.field._ +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. */ + val codeList = new StringField(this, 40) { + override def setFromAny(in: Any): Box[String] = in match { + case s: Symbol => setFromString(s.name) + case x => super.setFromAny(x) + } + def apply(in: Symbol): CodeListItem = super.apply(in.name) + } + /** Deleted flag. */ + val deleted = new BooleanField(this) + /** Rank - ordering.*/ + val rank = new IntField(this) + + override def toXHtml = Text(linkName) + + val s1 = new StringField(this, 200) + val s2 = new StringField(this, 200) + val s3 = new StringField(this, 200) + + val l1 = new LongField(this) + val l2 = new LongField(this) + val l3 = new LongField(this) + + val i1 = new IntField(this) + val i2 = new IntField(this) + val i3 = new IntField(this) + + val os1 = new OptionalStringField(this, 200) + val os2 = new OptionalStringField(this, 200) + val os3 = new OptionalStringField(this, 200) + + val ol1 = new OptionalLongField(this) + val ol2 = new OptionalLongField(this) + val ol3 = new OptionalLongField(this) + + val oi1 = new OptionalIntField(this) + val oi2 = new OptionalIntField(this) + val oi3 = new OptionalIntField(this) +} + +object CodeListItem extends CodeListItem with MetaRecord[CodeListItem] + + +// vim: set ts=2 sw=2 et: diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/cl/model/CodeListItemField.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/cl/model/CodeListItemField.scala Tue Apr 03 11:47:03 2012 +0200 @@ -0,0 +1,75 @@ +/* + * Copyright 2012 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.cl.model + +import net.tz.lift.model.FieldLabel +import net.liftweb.common._ +import net.liftweb.http.SHtml +import net.liftweb.record.{Field, MetaRecord, Record} +import net.liftweb.record.field._ +import net.liftweb.util.Helpers._ +import scala.xml.{Elem, NodeSeq, Text} + +class CodeListItemField[T <: Record[T]](own: T, val cl: CodeList, + val dispF: CodeListItem => String, val htmlF: CodeListItem => NodeSeq) + extends LongField(own) with FieldLabel { + + def this(o: T, id: Symbol) = this(o, CodeList(id), _.linkName, _.toXHtml) + + def item: Box[CodeListItem] = cl(get) + + override def defaultValueBox: Box[Long] = cl.dflt.map { _.id } + + override def asHtml = item map { htmlF } openOr NodeSeq.Empty + + protected def buildDisplayList: List[(Long, String)] = + cl.items.toList.map { i => (i.id, dispF(i)) } + + 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) + } +} + +class OptionalCodeListItemField[T <: Record[T]](own: T, val cl: CodeList, + val dispF: CodeListItem => String, val htmlF: CodeListItem => NodeSeq) + extends OptionalLongField(own) with FieldLabel { + + def this(o: T, id: Symbol) = this(o, CodeList(id), _.linkName, _.toXHtml) + + def item: Box[CodeListItem] = get flatMap { cl(_) } + + override def defaultValueBox: Box[Long] = cl.dflt.map { _.id } + + override def asHtml = item map { htmlF } openOr NodeSeq.Empty + + protected def buildDisplayList: List[(Box[Long], String)] = + (Empty, "---") :: + cl.items.toList.map { i => (Full(i.id), dispF(i)) } + + private def elem = SHtml.selectObj[Box[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 eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/cl/model/CodeListSchema.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/cl/model/CodeListSchema.scala Tue Apr 03 11:47:03 2012 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright 2012 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.cl.model + +import fis.base.model.BaseSchema +import net.liftweb.squerylrecord.RecordTypeMode._ + +trait CodeListSchema extends BaseSchema { + val cli = tableWithSeq[CodeListItem] + on(cli)(t => declare( + t.codeList defineAs(indexed("code_list_item_code_list_idx")) + )) +} + +object CodeListSchema extends CodeListSchema + + + +// vim: set ts=2 sw=2 et: diff -r eba7121e29cd -r 0b74e7bbe6ff src/main/scala/fis/top/model/FisDbSchema.scala --- a/src/main/scala/fis/top/model/FisDbSchema.scala Tue Apr 03 11:47:02 2012 +0200 +++ b/src/main/scala/fis/top/model/FisDbSchema.scala Tue Apr 03 11:47:03 2012 +0200 @@ -16,10 +16,12 @@ package fis.top.model import fis.base.model.BaseSchema +import fis.cl.model.CodeListSchema import fis.crm.model.CrmSchema import fis.geo.model.GeoSchema trait FisDbSchema extends BaseSchema + with CodeListSchema with CrmSchema with GeoSchema diff -r eba7121e29cd -r 0b74e7bbe6ff src/test/scala/fis/base/model/CodeListSpec.scala --- a/src/test/scala/fis/base/model/CodeListSpec.scala Tue Apr 03 11:47:02 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright 2011-2012 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._ - -class CodeListSpec extends AbstractTest { - - import net.liftweb.squerylrecord.RecordTypeMode._ - import net.liftweb.squerylrecord.SquerylRecord - import BaseSchema._ - - override def beforeAll { - super.beforeAll - doInDB { schema.drop } - doInDB { schema.create } - } - - "CodeListItem" should "create/retrieve item" in { - doInDB { - val cli1 = CodeListItem.createRecord.name("cli1").codeListType(1) - codeListItems.insert(cli1) - cli1.id should equal (1) - val l1 = from(codeListItems)(cli => select(cli)).toList - l1.size should equal (1) - val cl = new CodeListImpl(CodeListRegister.TestCL, { i => i } ) - val l2 = cl.items - l2.size should equal (1) - l2.head should equal (cli1) - } - } - - object schema extends BaseSchema with DropAndCreate -} - -// vim: set ts=2 sw=2 et: diff -r eba7121e29cd -r 0b74e7bbe6ff src/test/scala/fis/cl/model/CodeListSpec.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/scala/fis/cl/model/CodeListSpec.scala Tue Apr 03 11:47:03 2012 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2011-2012 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.cl.model + +import fis.base.model.{AbstractTest, DropAndCreate} +import net.liftweb.common._ +import net.liftweb.squerylrecord.RecordTypeMode._ +import net.liftweb.squerylrecord.SquerylRecord +import org.scalatest._ + +class CodeListSpec extends AbstractTest with BeforeAndAfterAll { + + override def beforeAll { + super.beforeAll + doInDB { schema.drop } + doInDB { schema.create } + } + + "CodeListItem" should "create/retrieve item" in { doInDB { + val cli1 = CodeListItem.createRecord.name("cli1").codeList('test).rank(1) + CodeListCrud.save(cli1) should be ('defined) + debug("Code list item: id=%d, name=%s".format(cli1.id, cli1.linkName)) + cli1.id should equal (1) + val cli2 = CodeListItem.createRecord.name("cli1").codeList('test).rank(2) + CodeListCrud.save(cli2) should be ('defined) + val cl = CodeList('test) + val l = cl.items + l.size should equal (2) + l.head should equal (cli1) + }} + + object schema extends CodeListSchema with DropAndCreate +} + +// vim: set ts=2 sw=2 et: diff -r eba7121e29cd -r 0b74e7bbe6ff src/test/scala/fis/crm/model/ContactSpec.scala --- a/src/test/scala/fis/crm/model/ContactSpec.scala Tue Apr 03 11:47:02 2012 +0200 +++ b/src/test/scala/fis/crm/model/ContactSpec.scala Tue Apr 03 11:47:03 2012 +0200 @@ -32,8 +32,10 @@ "EntityContact" should "create" in { doInDB { val c1 = Contact.createRecord.name("c1") contacts.insert(c1) + /* val t1 = CodeListItem.createRecord.name("t1") codeListItems.insert(t1) + */ val c2 = Contact.createRecord.name("c2") // acts here as entity contacts.insert(c2) /*