# HG changeset patch # User Tomas Zeman # Date 1333320523 -7200 # Node ID 94ed9cfdb123b15521788eacccde30924cabeea0 # Parent 641c7190c5661dbba2749efa2b8f80cac298d1b8 Squeryl connection manager instead of mapper-based diff -r 641c7190c566 -r 94ed9cfdb123 build.sbt --- a/build.sbt Mon Apr 02 00:06:52 2012 +0200 +++ b/build.sbt Mon Apr 02 00:48:43 2012 +0200 @@ -10,7 +10,6 @@ val liftVer = "2.4" libraryDependencies ++= Seq( "net.liftweb" %% "lift-squeryl-record" % liftVer, - "net.liftweb" %% "lift-mapper" % liftVer, "net.liftweb" %% "lift-webkit" % liftVer, "net.liftweb" %% "lift-widgets" % liftVer ) diff -r 641c7190c566 -r 94ed9cfdb123 src/main/resources/default.props --- a/src/main/resources/default.props Mon Apr 02 00:06:52 2012 +0200 +++ b/src/main/resources/default.props Mon Apr 02 00:48:43 2012 +0200 @@ -2,4 +2,5 @@ #db.fis.user= #db.fis.pass= +db.fis.driver=org.postgresql.Driver db.fis.url=jdbc:postgresql://localhost:7803/fis_dev diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/bootstrap/liftweb/Boot.scala --- a/src/main/scala/bootstrap/liftweb/Boot.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/main/scala/bootstrap/liftweb/Boot.scala Mon Apr 02 00:48:43 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2011 Tomas Zeman + * 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. @@ -17,27 +17,20 @@ import fis.base.model._ import fis.crm.ui.{ContactSnippet, ContactSnippet2} +import fis.db.SquerylTxMgr import net.liftweb.common._ -import net.liftweb.db.{DB, ConnectionIdentifier} import net.liftweb.http._ import net.liftweb.sitemap._ import net.liftweb.squerylrecord.SquerylRecord import net.liftweb.util._ import net.liftweb.util.Helpers._ import net.tz.lift.boot.ProtoBoot -import net.tz.lift.util.StandardDBVendor class Boot extends ProtoBoot { override def boot = { /* DB stuff */ - val dbVendor = new FisDbVendor - DB.defineConnectionManager(FisConnectionIdentifier, dbVendor) - S.addAround(DB.buildLoanWrapper(List(FisConnectionIdentifier))) - SquerylRecord.init(() => new SeqIdPostgreSqlAdapter) - SquerylTxMgr.initSqueryl(FisConnectionIdentifier, - () => new SeqIdPostgreSqlAdapter) - LiftRules.unloadHooks.append(dbVendor.closeAllConnections_! _) + SquerylTxMgr.init() super.boot @@ -50,47 +43,4 @@ } } -case object FisConnectionIdentifier extends ConnectionIdentifier { - val jndiName = "fis" -} - -import java.sql.Connection - -class FisDbVendor extends StandardDBVendor( - "org.postgresql.Driver", Props.get("db.fis.url", ""), - Props.get("db.fis.user"), Props.get("db.fis.pass")) { - - val testQuery = "SELECT version()" - override protected def testConnection(c: Connection) = { - c.prepareStatement(testQuery).executeQuery - } -} - -import org.squeryl._ -import org.squeryl.internals.DatabaseAdapter - -object SquerylTxMgr { - def initSqueryl(name: ConnectionIdentifier, - mkAdapter: () => DatabaseAdapter) = { - SessionFactory.externalTransactionManagementAdapter = - Some(new SquerylTxMgr(name, mkAdapter)) - } -} - -class SquerylTxMgr(name: ConnectionIdentifier, mkAdapter: () => DatabaseAdapter) - extends Loggable with Function0[Session] { - - private object currentSession extends DynoVar[Session] - - - def apply = currentSession.is openOr { - DB.use(name) { superConn => - val sess = Session.create(superConn.connection, mkAdapter()) - sess.setLogger(s => logger.debug(s)) - currentSession.set(sess) - sess - } - } -} - // vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/fis/base/model/BaseSchema.scala --- a/src/main/scala/fis/base/model/BaseSchema.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/main/scala/fis/base/model/BaseSchema.scala Mon Apr 02 00:48:43 2012 +0200 @@ -68,19 +68,4 @@ object BaseSchema extends BaseSchema -class EntityViewH2Adapter extends SeqIdH2Adapter { - override def writeCreateTable[T](t: Table[T], sw: StatementWriter, - schema: Schema) = schema match { - case sch: BaseSchema if t.name == sch.entityTableName => - sw.write("create view " + t.name + " as ") - val it = sch.entities.tables.iterator - while (it.hasNext) { - sw.write("select id, name, note from " + it.next) - if (it.hasNext) - sw.write(" union ") - } - case _ => super.writeCreateTable(t, sw, schema) - } -} - // vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/fis/base/model/SeqIdH2Adapter.scala --- a/src/main/scala/fis/base/model/SeqIdH2Adapter.scala Mon Apr 02 00:06:52 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +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 java.sql.{SQLException, ResultSet} -import org.squeryl.{Session, Table} -import org.squeryl.adapters.H2Adapter -import org.squeryl.internals.{StatementWriter, FieldMetaData} - -/** - * H2 adapter which takes entity IDs from db sequences instead of - * autoincrements. Sequence names can be reused (multiple entities can use - * the same sequence as ID generator). - * - * The implementation is taken mostly from Postgres adapter which is - * - * Copyright 2010 Maxime Lévesque - * - * and licensed under the same license (Apache 2). - */ -class SeqIdH2Adapter extends H2Adapter { - override def supportsAutoIncrementInColumnDeclaration = false - - override def postCreateTable(t: Table[_], - printSinkWhenWriteOnlyMode: Option[String => Unit]) = { - - val autoIncrementedFields = t.posoMetaData.fieldsMetaData.filter( - _.isAutoIncremented) - - for(fmd <-autoIncrementedFields) { - val sw = new StatementWriter(false, this) - sw.write("create sequence if not exists ", quoteName(fmd.sequenceName)) - - if(printSinkWhenWriteOnlyMode == None) { - val st = Session.currentSession.connection.createStatement - st.execute(sw.statement) - } - else - printSinkWhenWriteOnlyMode.get.apply(sw.statement + ";") - } - } - - override def writeInsert[T](o: T, t: Table[T], sw: StatementWriter): Unit = { - - val o_ = o.asInstanceOf[AnyRef] - - val autoIncPK = t.posoMetaData.fieldsMetaData.find(fmd => - fmd.isAutoIncremented) - - if(autoIncPK == None) { - super.writeInsert(o, t, sw) - return - } - - val f = t.posoMetaData.fieldsMetaData.filter(fmd => fmd != autoIncPK.get) - - val colNames = List(autoIncPK.get) ::: f.toList - val colVals = List("nextval('" + quoteName(autoIncPK.get.sequenceName) - + "')") ::: f.map(fmd => writeValue(o_, fmd, sw)).toList - - sw.write("insert into "); - sw.write(quoteName(t.prefixedName)); - sw.write(" ("); - sw.write(colNames.map(fmd => quoteName(fmd.columnName)).mkString(", ")); - sw.write(") values "); - sw.write(colVals.mkString("(",",",")")); - } -} - -// vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/fis/base/model/SeqIdPostgreSqlAdapter.scala --- a/src/main/scala/fis/base/model/SeqIdPostgreSqlAdapter.scala Mon Apr 02 00:06:52 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +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 org.squeryl.{Session, Table} -import org.squeryl.adapters.PostgreSqlAdapter -import org.squeryl.internals.StatementWriter -import scala.collection.mutable.HashSet - -/** - * Postgres adapter which enables multiple entities to share the same - * sequence. - * - * The implementation is based on Postgres adapter which is - * - * Copyright 2010 Maxime Lévesque - * - * and licensed under the same license (Apache 2). - */ -class SeqIdPostgreSqlAdapter extends PostgreSqlAdapter { - private val seqs = new HashSet[String] - - override def postCreateTable(t: Table[_], - printSinkWhenWriteOnlyMode: Option[String => Unit]) = { - - val autoIncrementedFields = t.posoMetaData.fieldsMetaData. - filter(_.isAutoIncremented). - filter(f => !seqs.contains(f.sequenceName)) - - for(fmd <-autoIncrementedFields) { - val sw = new StatementWriter(false, this) - sw.write("create sequence ", quoteName(fmd.sequenceName)) - seqs += fmd.sequenceName - - if(printSinkWhenWriteOnlyMode == None) { - val st = Session.currentSession.connection.createStatement - st.execute(sw.statement) - } - else - printSinkWhenWriteOnlyMode.get.apply(sw.statement + ";") - } - } -} - -// vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/fis/db/SquerylTxMgr.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/db/SquerylTxMgr.scala Mon Apr 02 00:48:43 2012 +0200 @@ -0,0 +1,58 @@ +/* + * 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.db + +import java.sql.{Connection, DriverManager} +import net.liftweb.common._ +import net.liftweb.http._ +import net.liftweb.squerylrecord.SquerylRecord +import net.liftweb.squerylrecord.RecordTypeMode._ +import net.liftweb.util._ +import org.squeryl.{Session, SessionFactory} +import org.squeryl.adapters.PostgreSqlAdapter + +object SquerylTxMgr extends Loggable { + def init(): Unit = { + for { + dri <- Props.get("db.fis.driver") + url <- Props.get("db.fis.url") + } yield { + Class.forName(dri) + SquerylRecord.initWithSquerylSession { + val con:Connection = (for { + u <- Props.get("db.fis.user") + p <- Props.get("db.fis.pass") + } yield { + DriverManager.getConnection(url, u, p) + }) openOr { DriverManager.getConnection(url) } + val s = Session.create(con, new PostgreSqlAdapter) + if (Props.devMode) + s.setLogger(_s => logger.info(_s)) + s + } + } + + S.addAround(new LoanWrapper { + override def apply[T](f: => T): T = { + val s = Session.currentSessionOption.getOrElse( + SessionFactory.newSession) + s.bindToCurrentThread + transaction { f } + } + }) + } +} +// vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/net/tz/lift/boot/ProtoBoot.scala --- a/src/main/scala/net/tz/lift/boot/ProtoBoot.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/main/scala/net/tz/lift/boot/ProtoBoot.scala Mon Apr 02 00:48:43 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2011 Tomas Zeman + * 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. @@ -17,7 +17,6 @@ import net.liftweb.common._ import net.liftweb.http._ -import net.liftweb.mapper._ import net.liftweb.sitemap._ import net.liftweb.sitemap.Loc._ import net.liftweb.util._ @@ -31,15 +30,6 @@ class ProtoBoot extends Logger { def boot: Unit = { - /* DB stuff */ - /* - S.addAround(DB.buildLoanWrapper()) - */ - - if (Props.mode == Props.RunModes.Development) - DB.addLogFunc { (dbLog, l) => dbLog.statementEntries.foreach { e => - debug("Query: " + e.statement) - }} /* Date format */ LiftRules.dateTimeConverter.default.set { () => YmdDateTimeConverter } @@ -64,12 +54,6 @@ /* Sitemap */ SiteMap.enforceUniqueLinks = false - /* - LiftRules.setSiteMap(SiteMap( - Menu.i("Home") / "index" >> Hidden - )) - */ - /* Menu widget */ MenuWidget.init() diff -r 641c7190c566 -r 94ed9cfdb123 src/main/scala/net/tz/lift/snippet/Panel.scala --- a/src/main/scala/net/tz/lift/snippet/Panel.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/main/scala/net/tz/lift/snippet/Panel.scala Mon Apr 02 00:48:43 2012 +0200 @@ -15,13 +15,13 @@ */ package net.tz.lift.snippet -import net.liftweb.mapper.MappedField +import net.liftweb.util.BaseField import scala.xml.{NodeSeq, Text} object AttrRow { def apply(name: => NodeSeq, value: => NodeSeq) = new AttrRow(name, value, "attr-name", "attr-value") - def apply(f: MappedField[_, _]) = new AttrRow(Text(f.displayName), f.asHtml, + def apply(f: BaseField) = new AttrRow(Text(f.displayName), f.asHtml, "attr-name", "attr-value") def formRow(name: => NodeSeq, input: => NodeSeq) = new AttrRow(name, input, "form-name", "form-value") @@ -42,7 +42,7 @@ object Panel { def apply(attrs: Iterable[AttrRow]) = new Panel(attrs) - def fromFields(fields: Iterable[MappedField[_,_]]) = + def fromFields(fields: Iterable[BaseField]) = new Panel(fields.map(AttrRow(_))) } diff -r 641c7190c566 -r 94ed9cfdb123 src/test/resources/test.default.props --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/resources/test.default.props Mon Apr 02 00:48:43 2012 +0200 @@ -0,0 +1,7 @@ +# Test (default) properties for FIS webapp. + +#db.fis.user= +#db.fis.pass= +db.fis.driver=org.postgresql.Driver +db.fis.url=jdbc:postgresql://localhost:7803/fis_test + diff -r 641c7190c566 -r 94ed9cfdb123 src/test/scala/fis/base/model/AbstractTest.scala --- a/src/test/scala/fis/base/model/AbstractTest.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/test/scala/fis/base/model/AbstractTest.scala Mon Apr 02 00:48:43 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2011 Tomas Zeman + * 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. @@ -15,36 +15,22 @@ */ package fis.base.model +import fis.db.SquerylTxMgr import net.liftweb.common._ -import net.liftweb.mapper.DB -import net.liftweb.squerylrecord.SquerylRecord +import net.liftweb.squerylrecord.RecordTypeMode._ import org.scalatest._ import org.scalatest.matchers.ShouldMatchers abstract class AbstractTest extends FlatSpec with ShouldMatchers with Logger - with BeforeAndAfterEach with BeforeAndAfterAll { - - val db = this.getClass.getSimpleName - val h2vendor = H2Vendor(db) - val ci = TestConnectionIdentifier(db) + with BeforeAndAfterAll { override def beforeAll() { - beforeEach() + SquerylTxMgr.init() } - override def beforeEach() { - super.beforeEach - DB.defineConnectionManager(ci, h2vendor) - SquerylRecord.init(() => new EntityViewH2Adapter) - } - - override def afterEach() { - h2vendor.closeAllConnections_! - } - - def doInDB(block: => Any) { - DB.use(ci) { _ => block } - } + def doInDB(block: => Any) { inTransaction { + block + }} } diff -r 641c7190c566 -r 94ed9cfdb123 src/test/scala/fis/base/model/CodeListSpec.scala --- a/src/test/scala/fis/base/model/CodeListSpec.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/test/scala/fis/base/model/CodeListSpec.scala Mon Apr 02 00:48:43 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2011 Tomas Zeman + * 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. @@ -26,7 +26,8 @@ override def beforeAll { super.beforeAll - doInDB { schema.dropAndCreate } + doInDB { schema.drop } + doInDB { schema.create } } "CodeListItem" should "create/retrieve item" in { diff -r 641c7190c566 -r 94ed9cfdb123 src/test/scala/fis/base/model/H2Vendor.scala --- a/src/test/scala/fis/base/model/H2Vendor.scala Mon Apr 02 00:06:52 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +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.mapper.ConnectionIdentifier -import net.tz.lift.util.StandardDBVendor - -case class H2Vendor(val db: String) extends StandardDBVendor("org.h2.Driver", - "jdbc:h2:mem:"+ db + ";DB_CLOSE_DELAY=-1", Empty, Empty) - -case class TestConnectionIdentifier(val jndiName: String) extends - ConnectionIdentifier - -// vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/test/scala/fis/base/model/SeqIdPostgreSqlAdapterSpec.scala --- a/src/test/scala/fis/base/model/SeqIdPostgreSqlAdapterSpec.scala Mon Apr 02 00:06:52 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +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._ -import org.scalatest.matchers.ShouldMatchers - -class SeqIdPostgreSqlAdapterSpec extends FlatSpec with ShouldMatchers - with Logger with BeforeAndAfterAll { - - import java.sql.Connection - import net.liftweb.mapper.DB - import net.liftweb.squerylrecord.SquerylRecord - import net.tz.lift.util.StandardDBVendor - import org.squeryl.PrimitiveTypeMode._ - import TestSchema._ - - val dbVendor = new StandardDBVendor("org.postgresql.Driver", - "jdbc:postgresql://localhost:7902/fis_test", Empty, Empty) { - val testQuery = "SELECT version()" - override protected def testConnection(c: Connection) = { - c.prepareStatement(testQuery).executeQuery - } - } - DB.defineConnectionManager(PgsqlConnectionIdentifier, dbVendor) - SquerylRecord.init(() => new SeqIdPostgreSqlAdapter) - - override def beforeAll { - //doInDB { dropAndCreate } - } - - override def afterAll { - dbVendor.closeAllConnections_! - } - - "PostgreSqlAdapter" should "create schema" in { - doInDB { dropAndCreate } - } - - it should "create entities" in { - val a1 = Author(0, "f1", "l1", None) - authors.insert(a1) - books.insert(Book(0, "b1", a1.id, None)) - } - - it should "use global sequence" in { - val cnt: Long = from(authors)(a => compute(count)) - info("Authors count: " + cnt) - cnt should be (1) - authors.lookup(1L) should be ('defined) - val bookCnt: Long = from(books)(b => compute(count)) - bookCnt should be (1) - val b = books.lookup(2L) - info("Book: " + b) - b should be ('defined) - } - - def doInDB(block: => Any) { - DB.use(PgsqlConnectionIdentifier) { c => - block - c.commit - } - } -} - -import net.liftweb.db.ConnectionIdentifier - -case object PgsqlConnectionIdentifier extends ConnectionIdentifier { - val jndiName = "pgsql" -} - -import org.squeryl.{KeyedEntity, Schema} -import org.squeryl.PrimitiveTypeMode._ - -case class Author(val id: Long, val firstName: String, val lastName: String, - val email: Option[String]) extends KeyedEntity[Long] { - def this() = this(0,"","",Some("")) -} - -case class Book(val id: Long, var title: String, var authorId: Long, - var coAuthorId: Option[Long]) extends KeyedEntity[Long] { - def this() = this(0,"",0,Some(0L)) -} - -object TestSchema extends Schema { - val authors = table[Author] - val books = table[Book] - - def dropAndCreate { - drop - create - } - - on(authors) { t => declare(t.id.is(autoIncremented("entity_id_seq"))) } - on(books) { t => declare(t.id.is(autoIncremented("entity_id_seq"))) } -} - -// vim: set ts=2 sw=2 et: diff -r 641c7190c566 -r 94ed9cfdb123 src/test/scala/fis/top/model/FisDbSchemaSpec.scala --- a/src/test/scala/fis/top/model/FisDbSchemaSpec.scala Mon Apr 02 00:06:52 2012 +0200 +++ b/src/test/scala/fis/top/model/FisDbSchemaSpec.scala Mon Apr 02 00:48:43 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2011 Tomas Zeman + * 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.