Anthony
Anthony

Reputation: 35938

How to parameterize table name in Slick

class MyTable(tag: Tag) extends Table[MyEntity](tag, "1970Table") {
  def id = column[Int]("id")

  override def * = 
  (
   id
  ) <> (MyEntity.tupled, MyEntity.unapply)
}

val myTable = TableQuery[MyTable]

class MyRepository(val config: DatabaseConfig[JdbcProfile])
   extends MyRepository[MyTable, String] {
  override val table: config.profile.api.TableQuery[MyTable] = myTable

  def insert(me: MyEntity): Future[Int] = {
     db.run(table += me)
  }
}

I use this in my other classes like this:

  val myRepository = new MyRepository(dbConfig)

  myRepository.insert(myrecord)

Question

I would like to not have a hardcoded tablename but rather make the tablename dynamic.

I would like to change the insert method such that it accepts a year (int) parameter and based on the year parameter it chooses the right table. i.e. if the year passed in is 1970 then table name is 1970Table but if the year passed in is 1980 then the table is 1980Table.

Upvotes: 2

Views: 461

Answers (2)

Artem Vlasov
Artem Vlasov

Reputation: 33

There is two apply methods in TableQuery. val myTable = TableQuery[MyTable] -
this one uses macros to create MyTable. The other one is defined like this:

def apply[E <: AbstractTable[_]](cons: Tag => E): TableQuery[E] =
    new TableQuery[E](cons)

So you can do smth like this

class MyTable(tag: Tag, tableName: String) extends Table[MyEntity](tag, tableName)
...
def myTable(name: String) = TableQuery[MyTable](tag =>  new MyTable(tag, name))

Now you can predefine all tables you need and use them or do smth like this

class MyRepository(val config: DatabaseConfig[JdbcProfile])
   extends MyRepository[MyTable, String] {
  override def table(year: Int): config.profile.api.TableQuery[MyTable] = myTable(year.toString)

  def insert(me: MyEntity, year: Int): Future[Int] = {
     db.run(table(year) += me)
  }
}

Upvotes: 0

Mario Galic
Mario Galic

Reputation: 48410

Try

class MyRepository(val config: DatabaseConfig[JdbcProfile]) {
  import config._
  import profile.api._

  abstract class MyTable(tag: Tag, name: String) extends Table[MyEntity](tag, name) {
    def id = column[Int]("id")
    override def * = (id) <> (MyEntity.tupled, MyEntity.unapply)
  }

  class Table1970(tag: Tag) extends MyTable[MyEntity](tag, "1970Table")
  class Table1980(tag: Tag) extends MyTable[MyEntity](tag, "1980Table")

  val table1970 = TableQuery[Table1970]
  val table1980 = TableQuery[Table1980]

  def insert(me: MyEntity, year: Int): Future[Int] = db.run {
    year match {
      case "1970" => table1970 += me
      case "1980" => table1980 += me 
    }
  }
}

Now

val myRepository = new MyRepository(dbConfig)
myRepository.insert(myrecord, "1970")

Upvotes: 2

Related Questions