--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/fis/base/model/RecordCrud.scala Tue Apr 03 11:47:02 2012 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2012 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.Record
+import net.liftweb.squerylrecord.KeyedRecord
+import net.liftweb.squerylrecord.RecordTypeMode._
+import net.liftweb.util.Helpers._
+import org.squeryl.Table
+
+/**
+ * Provides base CRUD functionality for lift records.
+ */
+trait RecordCrud[T <: Record[T] with KeyedRecord[Long]] {
+
+ /** Returns table associated with this record. */
+ def table: Table[T]
+
+ /** Returns record by its key. */
+ def get(k: Long): Box[T] = table lookup k
+
+ /** Returns record by its key (supplied as string). */
+ def get(id: String): Box[T] = asLong(id) flatMap { get _ }
+
+ /**
+ * Saves a record.
+ * Calls:
+ * - beforeCreate/Update
+ * - beforeSave
+ * - save operation in db (if hooks return Full)
+ * - afterSave
+ * - afterCreate/Update
+ */
+ def save(v: T): Box[T] = {
+ val isCreate = v.id == v.idField.defaultValue
+ val res = for {
+ b <- if (isCreate) beforeCreate(v) else beforeUpdate(v)
+ bs <- beforeSave(b)
+ r <- tryo { table insertOrUpdate bs }
+ } yield { r }
+ val as = afterSave(res)
+ if (isCreate) afterCreate(as) else afterUpdate(as)
+ }
+
+ /**
+ * Deletes a record.
+ */
+ def delete(v: T): Box[Boolean] = for {
+ b <- beforeDelete(v)
+ r <- tryo { table delete (b.id) } $ { x => afterDelete(v, x) }
+ } yield { r }
+
+ protected def beforeCreate(v: T): Box[T] = {
+ v.meta.foreachCallback(v, _.beforeCreate)
+ Full(v)
+ }
+
+ protected def afterCreate(v: Box[T]): Box[T] = {
+ v foreach { r => r.meta.foreachCallback(r, _.afterCreate) }
+ v
+ }
+
+ protected def beforeUpdate(v: T): Box[T] = {
+ v.meta.foreachCallback(v, _.beforeUpdate)
+ Full(v)
+ }
+
+ protected def afterUpdate(v: Box[T]): Box[T] = {
+ v foreach { r => r.meta.foreachCallback(r, _.afterUpdate) }
+ v
+ }
+
+ protected def beforeSave(v: T): Box[T] = {
+ v.meta.foreachCallback(v, _.beforeSave)
+ Full(v)
+ }
+
+ protected def afterSave(v: Box[T]): Box[T] = {
+ v foreach { r => r.meta.foreachCallback(r, _.afterSave) }
+ v
+ }
+
+ protected def beforeDelete(v: T): Box[T] = {
+ v.meta.foreachCallback(v, _.beforeDelete)
+ Full(v)
+ }
+
+ protected def afterDelete(v: T, delRes: Box[Boolean]) {
+ v.meta.foreachCallback(v, _.afterDelete)
+ }
+
+}
+
+// vim: set ts=2 sw=2 et: