Permalink
Browse files

Add table truncate feature

  • Loading branch information...
1 parent 1a0a642 commit 15350e6705bb2bc36c549168ae66a9d81867ad62 @trevorsibanda trevorsibanda committed Aug 13, 2016
@@ -172,4 +172,24 @@ class ActionTest extends AsyncTest[RelationalTestDB] {
}
} yield ()
}
+
+ def testTruncate = {
+ class T(_tag: Tag) extends Table[Int](_tag , "truncate_test"){
+ def a = column[Int]("a")
+ def * = a
+ }
+
+ val ts = TableQuery[T]
+ for{
+ _ <- ts.schema.create
+ initial <- ts.result
+ _ = assert(initial.toSet == Set())
+ res <- (ts ++= Seq(2, 3, 1, 5, 4)) >>
+ ts.result
+ _ = assert(res.toSet == Set(2, 3, 1, 5, 4))
+ newRes <- ts.schema.truncate >>
+ ts.result
+ _ = assert(newRes.toSet == Set())
+ } yield ()
+ }
}
@@ -290,6 +290,11 @@ trait JdbcActionComponent extends SqlActionComponent { self: JdbcProfile =>
for(s <- sql) ctx.session.withPreparedStatement(s)(_.execute)
}
+ def truncate: ProfileAction[Unit, NoStream, Effect.Schema] = new SimpleJdbcProfileAction[Unit]("schema.truncate" , schema.truncateStatements.toVector ){
+ def run(ctx: Backend#Context, sql: Vector[String]): Unit =
+ for(s <- sql) ctx.session.withPreparedStatement(s)(_.execute)
+ }
+
def drop: ProfileAction[Unit, NoStream, Effect.Schema] = new SimpleJdbcProfileAction[Unit]("schema.drop", schema.dropStatements.toVector) {
def run(ctx: Backend#Context, sql: Vector[String]): Unit =
for(s <- sql) ctx.session.withPreparedStatement(s)(_.execute)
@@ -589,13 +589,14 @@ trait JdbcStatementBuilderComponent { self: JdbcProfile =>
if(primaryKeys.size > 1)
throw new SlickException("Table "+tableNode.tableName+" defines multiple primary keys ("
+ primaryKeys.map(_.name).mkString(", ") + ")")
- DDL(createPhase1, createPhase2, dropPhase1, dropPhase2)
+ DDL(createPhase1, createPhase2, dropPhase1, dropPhase2 , truncatePhase)
}
protected def createPhase1 = Iterable(createTable) ++ primaryKeys.map(createPrimaryKey) ++ indexes.map(createIndex)
protected def createPhase2 = foreignKeys.map(createForeignKey)
protected def dropPhase1 = foreignKeys.map(dropForeignKey)
protected def dropPhase2 = primaryKeys.map(dropPrimaryKey) ++ Iterable(dropTable)
+ protected def truncatePhase = Iterable(truncateTable)
protected def createTable: String = {
val b = new StringBuilder append "create table " append quoteTableName(tableNode) append " ("
@@ -613,6 +614,8 @@ trait JdbcStatementBuilderComponent { self: JdbcProfile =>
protected def dropTable: String = "drop table "+quoteTableName(tableNode)
+ protected def truncateTable: String = "truncate table "+ quoteTableName(tableNode)
+
protected def createIndex(idx: Index): String = {
val b = new StringBuilder append "create "
if(idx.unique) b append "unique "
@@ -204,6 +204,8 @@ trait SQLiteProfile extends JdbcProfile {
addForeignKey(fk, b)
}
}
+
+ override def truncateTable = "delete from " + quoteTableName(tableNode)
}
class ColumnDDLBuilder(column: FieldSymbol) extends super.ColumnDDLBuilder(column) {
@@ -55,6 +55,9 @@ trait HeapBackend extends RelationalBackend with Logging {
if(!tables.remove(name).isDefined)
throw new SlickException(s"Table $name does not exist")
}
+ def truncateTable(name: String): Unit = synchronized{
+ getTable(name).data.clear
+ }
def getTables: IndexedSeq[HeapTable] = synchronized {
tables.values.toVector
}
@@ -93,7 +96,7 @@ trait HeapBackend extends RelationalBackend with Logging {
class HeapTable(val name: String, val columns: IndexedSeq[HeapBackend.Column],
indexes: IndexedSeq[Index], constraints: IndexedSeq[Constraint]) {
- protected val data: ArrayBuffer[Row] = new ArrayBuffer[Row]
+ protected[HeapBackend] val data: ArrayBuffer[Row] = new ArrayBuffer[Row]
def rows: Iterable[Row] = data
@@ -168,6 +168,10 @@ trait MemoryProfile extends RelationalProfile with MemoryQueryingProfile { self:
def drop = dbAction { session =>
tables.foreach(t => session.database.dropTable(t.tableName))
}
+
+ def truncate = dbAction{ session =>
+ tables.foreach(t => session.database.truncateTable(t.tableName) )
+ }
}
class InsertActionExtensionMethodsImpl[T](compiled: CompiledInsert) extends super.InsertActionExtensionMethodsImpl[T] {
@@ -247,5 +247,8 @@ trait RelationalActionComponent extends BasicActionComponent { self: RelationalP
/** Create an Action that drops the entities described by this schema description. */
def drop: ProfileAction[Unit, NoStream, Effect.Schema]
+
+ /** Create an Action that truncates entries described by this schema description */
+ def truncate: ProfileAction[Unit, NoStream, Effect.Schema]
}
}
@@ -41,6 +41,11 @@ trait SqlProfile extends RelationalProfile with SqlTableComponent with SqlAction
/** All statements to execute for drop() */
def dropStatements: Iterator[String] = dropPhase1.iterator ++ dropPhase2.iterator
+ /** Statements to execute first for truncate() */
+ protected def truncatePhase: Iterable[String]
+ /** All statements to execute for truncate */
+ def truncateStatements: Iterator[String] = truncatePhase.iterator
+
/**
* Create a new DDL object which combines this and the other DDL object.
*
@@ -52,31 +57,34 @@ trait SqlProfile extends RelationalProfile with SqlTableComponent with SqlAction
protected lazy val createPhase2 = self.createPhase2 ++ other.createPhase2
protected lazy val dropPhase1 = other.dropPhase1 ++ self.dropPhase1
protected lazy val dropPhase2 = other.dropPhase2 ++ self.dropPhase2
+ protected lazy val truncatePhase = other.truncatePhase ++ self.truncatePhase
}
override def hashCode() =
- Vector(self.createPhase1, self.createPhase2, self.dropPhase1, self.dropPhase2).hashCode
+ Vector(self.createPhase1, self.createPhase2, self.dropPhase1, self.dropPhase2 , self.truncatePhase).hashCode
override def equals(o: Any) = o match {
case ddl: DDL =>
self.createPhase1 == ddl.createPhase1 &&
self.createPhase2 == ddl.createPhase2 &&
self.dropPhase1 == ddl.dropPhase1 &&
- self.dropPhase2 == ddl.dropPhase2
+ self.dropPhase2 == ddl.dropPhase2 &&
+ self.truncatePhase == ddl.truncatePhase
case _ => false
}
}
- object DDL {
+ object DDL {
def apply(create1: Iterable[String], create2: Iterable[String], drop1: Iterable[String],
- drop2: Iterable[String]): DDL = new DDL {
+ drop2: Iterable[String] , truncate: Iterable[String]): DDL = new DDL {
protected def createPhase1 = create1
protected def createPhase2 = create2
protected def dropPhase1 = drop1
protected def dropPhase2 = drop2
+ protected def truncatePhase = truncate
}
- def apply(create1: Iterable[String], drop2: Iterable[String]): DDL = apply(create1, Nil, Nil, drop2)
+ def apply(create1: Iterable[String], drop2: Iterable[String]): DDL = apply(create1, Nil, Nil, drop2 , Nil)
def apply(create1: String, drop2: String): DDL = apply(Iterable(create1), Iterable(drop2))
}
@@ -167,6 +167,7 @@ object LiftedEmbedding extends App {
//#ddl2
schema.create.statements.foreach(println)
+ schema.truncate.statements.foreach(println)
schema.drop.statements.foreach(println)
//#ddl2
TableQuery[A].schema.create.statements.foreach(println)
@@ -189,7 +189,7 @@ Data Definition Language
DDL statements for a table can be created with its ``TableQuery``'s ``schema`` method. Multiple
``DDL`` objects can be concatenated with ``++`` to get a compound ``DDL`` object which can create
and drop all entities in the correct order, even in the presence of cyclic dependencies between
-tables. The ``create`` and ``drop`` methods produce the Actions for executing the DDL statements:
+tables. The ``create``, ``drop`` and ``truncate`` methods produce the Actions for executing the DDL statements:
.. includecode:: code/LiftedEmbedding.scala#ddl

0 comments on commit 15350e6

Please sign in to comment.