Record CRUD
authorTomas Zeman <tzeman@volny.cz>
Tue, 03 Apr 2012 11:47:02 +0200
changeset 30 eba7121e29cd
parent 29 3b6f22661a5a
child 31 0b74e7bbe6ff
Record CRUD
src/main/scala/fis/base/model/RecordCrud.scala
--- /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: