Slick: dynamic sortBy in a query with left join - scala

This is a problem derived from another question. I need to be able to dynamically pass a column to be sorted on in a Slick query which has a left join. The problem in this particular situation is that left joined table becomes optional and I have no idea how to handle that. If I make table Company not optional I'm getting SlickException: Read NULL value for ResultSet column Path
Example:
def list(filter: String, orderBy: Int) = {
DB.withDynSession {
val data = for {
(computer, company) <- Computer.where(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company.?)
val sortedData = orderBy match {
case 2 => data.sortBy(_._1.name) //Works ok, column from a primary table
case 3 => data.sortBy(_._2.name) //Error "Cannot resolve symbol name", because table is optional
}
}
}
Slick auto generated table classes used in example above:
package tables
// AUTO-GENERATED Slick data model
/** Stand-alone Slick data model for immediate use */
object Tables extends {
val profile = scala.slick.driver.H2Driver
} with Tables
/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */
trait Tables {
val profile: scala.slick.driver.JdbcProfile
import profile.simple._
import scala.slick.model.ForeignKeyAction
// NOTE: GetResult mappers for plain SQL are only generated for tables where Slick knows how to map the types of all columns.
import scala.slick.jdbc.{GetResult => GR}
/** DDL for all tables. Call .create to execute. */
lazy val ddl = Company.ddl ++ Computer.ddl
/** Entity class storing rows of table Company
* #param id Database column ID PrimaryKey
* #param name Database column NAME */
case class CompanyRow(id: Long, name: String)
/** GetResult implicit for fetching CompanyRow objects using plain SQL queries */
implicit def GetResultCompanyRow(implicit e0: GR[Long], e1: GR[String]): GR[CompanyRow] = GR{
prs => import prs._
CompanyRow.tupled((<<[Long], <<[String]))
}
/** Table description of table COMPANY. Objects of this class serve as prototypes for rows in queries. */
class Company(tag: Tag) extends Table[CompanyRow](tag, "COMPANY") {
def * = (id, name) <> (CompanyRow.tupled, CompanyRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, name.?).shaped.<>({r=>import r._; _1.map(_=> CompanyRow.tupled((_1.get, _2.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column ID PrimaryKey */
val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
/** Database column NAME */
val name: Column[String] = column[String]("NAME")
}
/** Collection-like TableQuery object for table Company */
lazy val Company = new TableQuery(tag => new Company(tag))
/** Entity class storing rows of table Computer
* #param id Database column ID PrimaryKey
* #param name Database column NAME
* #param introduced Database column INTRODUCED
* #param discontinued Database column DISCONTINUED
* #param companyId Database column COMPANY_ID */
case class ComputerRow(id: Long, name: String, introduced: Option[java.sql.Timestamp], discontinued: Option[java.sql.Timestamp], companyId: Option[Long])
/** GetResult implicit for fetching ComputerRow objects using plain SQL queries */
implicit def GetResultComputerRow(implicit e0: GR[Long], e1: GR[String], e2: GR[Option[java.sql.Timestamp]], e3: GR[Option[Long]]): GR[ComputerRow] = GR{
prs => import prs._
ComputerRow.tupled((<<[Long], <<[String], <<?[java.sql.Timestamp], <<?[java.sql.Timestamp], <<?[Long]))
}
/** Table description of table COMPUTER. Objects of this class serve as prototypes for rows in queries. */
class Computer(tag: Tag) extends Table[ComputerRow](tag, "COMPUTER") {
def * = (id, name, introduced, discontinued, companyId) <> (ComputerRow.tupled, ComputerRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, name.?, introduced, discontinued, companyId).shaped.<>({r=>import r._; _1.map(_=> ComputerRow.tupled((_1.get, _2.get, _3, _4, _5)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column ID PrimaryKey */
val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
/** Database column NAME */
val name: Column[String] = column[String]("NAME")
/** Database column INTRODUCED */
val introduced: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("INTRODUCED")
/** Database column DISCONTINUED */
val discontinued: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("DISCONTINUED")
/** Database column COMPANY_ID */
val companyId: Column[Option[Long]] = column[Option[Long]]("COMPANY_ID")
/** Foreign key referencing Company (database name FK_COMPUTER_COMPANY_1) */
lazy val companyFk = foreignKey("FK_COMPUTER_COMPANY_1", companyId, Company)(r => r.id, onUpdate=ForeignKeyAction.Restrict, onDelete=ForeignKeyAction.Restrict)
}
/** Collection-like TableQuery object for table Computer */
lazy val Computer = new TableQuery(tag => new Computer(tag))
}

.? is implemented using <> which prevents you from later accessing members. So you need to apply the sorting before you do the .?
val data = for {
(computer, company) <- Computer.where(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company) // <- no .?
val sortedData = orderBy match {
case 2 => data.sortBy(_._1.name) //Works ok, column from a primary table
case 3 => data.sortBy(_._2.name) //Error "Cannot resolve symbol name", because table is optional
}
val optionalJoinData = sortedData.map{
case (computer, company) => (computer, company.?)
} // <- do .? last

Related

Too many arguments for method += with Slick-generated code

I'm trying out Slick in a Scala project to access a relational (PostgreSQL) database.
The project uses Scala 2.12.14, Slick 3.3.3 and Slick Codegen 3.3.3.
I've started by creating a very simple database table:
create table example (
id uuid not null primary key,
name varchar
);
Next, I've run the Slick codegen to generate the Table and TableRow classes for me. They result in this Scala file:
object Tables extends {
val profile = slick.jdbc.PostgresProfile
} with Tables
/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */
trait Tables {
val profile: slick.jdbc.JdbcProfile
import profile.api._
import slick.model.ForeignKeyAction
// NOTE: GetResult mappers for plain SQL are only generated for tables where Slick knows how to map the types of all columns.
import slick.jdbc.{GetResult => GR}
/** DDL for all tables. Call .create to execute. */
lazy val schema: profile.SchemaDescription = Example.schema
#deprecated("Use .schema instead of .ddl", "3.0")
def ddl = schema
/** Entity class storing rows of table Example
* #param id Database column id SqlType(uuid), PrimaryKey
* #param name Database column name SqlType(varchar), Default(None) */
case class ExampleRow(id: java.util.UUID, name: Option[String] = None)
/** GetResult implicit for fetching ExampleRow objects using plain SQL queries */
implicit def GetResultExampleRow(implicit e0: GR[java.util.UUID], e1: GR[Option[String]]): GR[ExampleRow] = GR{
prs => import prs._
ExampleRow.tupled((<<[java.util.UUID], <<?[String]))
}
/** Table description of table example. Objects of this class serve as prototypes for rows in queries. */
class Example(_tableTag: Tag) extends profile.api.Table[ExampleRow](_tableTag, "example") {
def * = (id, name) <> (ExampleRow.tupled, ExampleRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = ((Rep.Some(id), name)).shaped.<>({r=>import r._; _1.map(_=> ExampleRow.tupled((_1.get, _2)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column id SqlType(uuid), PrimaryKey */
val id: Rep[java.util.UUID] = column[java.util.UUID]("id", O.PrimaryKey)
/** Database column name SqlType(varchar), Default(None) */
val name: Rep[Option[String]] = column[Option[String]]("name", O.Default(None))
}
/** Collection-like TableQuery object for table Example */
lazy val Example = new TableQuery(tag => new Example(tag))
}
From what I can tell, this seems to make sense.
Then I've tried to actually use this schema to insert a record into the "example" table:
val config = DatabaseConfig.forURI[JdbcProfile](URI.create("...not relevant..."))
config.db.run(DBIO.seq(
Tables.Example += (UUID.randomUUID(), "Whatever"),
))
Compiling this code fails with:
too many arguments (2) for method +=: (value: Tables.ExampleRow)slick.sql.FixedSqlAction[Int,slick.dbio.NoStream,slick.dbio.Effect.Write]
Any ideas?
As you have bidirectional mapping using <> for the * projection
def * = (id, name) <> (ExampleRow.tupled, ExampleRow.unapply)
then the following should work
Tables.Example += ExampleRow(UUID.randomUUID(), Some("Whatever")),

Slick: How to filter by isBefore Timestamp database attribute?

I naively did the following on Slick 4.0.1. I have an expiry database field and I need to find all the rows where the expiry is before a given timestamp.
This is what the Slick mapping looks like:
/** Table description of table auth_token. Objects of this class serve as prototypes for rows in queries. */
class AuthToken(_tableTag: Tag) extends profile.api.Table[AuthTokenRow](_tableTag, Some("myappdb"), "auth_token") with IdentifyableTable[Long] {
override def id = userId
def * = (userId, tokenId, expiry) <> (AuthTokenRow.tupled, AuthTokenRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = ((Rep.Some(userId), Rep.Some(tokenId), Rep.Some(expiry))).shaped.<>({ r => import r._; _1.map(_ => AuthTokenRow.tupled((_1.get, _2.get, _3.get))) }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column user_id SqlType(BIGINT UNSIGNED) */
val userId: Rep[Long] = column[Long]("user_id")
/** Database column token_id SqlType(CHAR), Length(36,false) */
val tokenId: Rep[String] = column[String]("token_id", O.Length(36, varying = false))
/** Database column expiry SqlType(TIMESTAMP) */
val expiry: Rep[java.sql.Timestamp] = column[java.sql.Timestamp]("expiry")
/** Foreign key referencing User (database name auth_token_ibfk_1) */
lazy val userFk = foreignKey("auth_token_ibfk_1", userId, User)(r => r.id, onUpdate = ForeignKeyAction.NoAction, onDelete = ForeignKeyAction.Cascade)
/** Index over (tokenId) (database name idx_token_id) */
val index1 = index("idx_token_id", tokenId)
}
/** Collection-like TableQuery object for table AuthToken */
lazy val AuthToken = new TableQuery(tag => new AuthToken(tag))
and then I need to do:
/**
* Finds expired tokens.
*
* #param dateTime The current date time.
*/
def findExpired(dateTime: org.joda.time.DateTime): Future[Seq[AuthTokenRow]] = {
val action = AuthToken.filter(authToken => authToken.expiry.isBefore(dateTime)).result
db.run(action)
}
How to cover this use-case correctly/officially in Slick?
I solved this by reusing the project slick-joda-mapper. This solution is a bit involved because of working with the Slick generator etc but it is VERY clean, I love it. Basically it enables mapping database date time types to the Joda types like org.joda.time.DateTime. Therefore my solution becomes as simple as using comparison operators supported by Joda DateTime:
/**
* Finds expired tokens.
*
* #param dateTime The current date time.
*/
override def findExpired(dateTime: org.joda.time.DateTime): Future[Seq[AuthTokenRow]] = {
val action = AuthToken.filter(authToken => authToken.expiry < dateTime).result
db.run(action)
}

Dynamic query parameters in Slick (sorting)

I'm trying to convert anorm queries to slick in one of Play 2.3 samples, but I'm not sure how to implement dynamic sorting.
This is the original method:
def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%"): Page[(Computer, Option[Company])] = {
val offest = pageSize * page
DB.withConnection { implicit connection =>
val computers = SQL(
"""
select * from computer
left join company on computer.company_id = company.id
where computer.name like {filter}
order by {orderBy} nulls last
limit {pageSize} offset {offset}
"""
).on(
'pageSize -> pageSize,
'offset -> offest,
'filter -> filter,
'orderBy -> orderBy
).as(Computer.withCompany *)
val totalRows = SQL(
"""
select count(*) from computer
left join company on computer.company_id = company.id
where computer.name like {filter}
"""
).on(
'filter -> filter
).as(scalar[Long].single)
Page(computers, page, offest, totalRows)
}
}
So far I've got this far with the first query:
val computers_ = (for {
(computer, company) <- Computer.where(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company.?)).list
How do I do the "order by" part in slick, bearing in mind it's a column name passed to the method dynamically as a parameter?
Scala 2.10.4 / Play 2.3 / Slick 2.0.2
Table classes generated by Slick code generator below:
package tables
// AUTO-GENERATED Slick data model
/** Stand-alone Slick data model for immediate use */
object Tables extends {
val profile = scala.slick.driver.H2Driver
} with Tables
/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */
trait Tables {
val profile: scala.slick.driver.JdbcProfile
import profile.simple._
import scala.slick.model.ForeignKeyAction
// NOTE: GetResult mappers for plain SQL are only generated for tables where Slick knows how to map the types of all columns.
import scala.slick.jdbc.{GetResult => GR}
/** DDL for all tables. Call .create to execute. */
lazy val ddl = Company.ddl ++ Computer.ddl
/** Entity class storing rows of table Company
* #param id Database column ID PrimaryKey
* #param name Database column NAME */
case class CompanyRow(id: Long, name: String)
/** GetResult implicit for fetching CompanyRow objects using plain SQL queries */
implicit def GetResultCompanyRow(implicit e0: GR[Long], e1: GR[String]): GR[CompanyRow] = GR{
prs => import prs._
CompanyRow.tupled((<<[Long], <<[String]))
}
/** Table description of table COMPANY. Objects of this class serve as prototypes for rows in queries. */
class Company(tag: Tag) extends Table[CompanyRow](tag, "COMPANY") {
def * = (id, name) <> (CompanyRow.tupled, CompanyRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, name.?).shaped.<>({r=>import r._; _1.map(_=> CompanyRow.tupled((_1.get, _2.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column ID PrimaryKey */
val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
/** Database column NAME */
val name: Column[String] = column[String]("NAME")
}
/** Collection-like TableQuery object for table Company */
lazy val Company = new TableQuery(tag => new Company(tag))
/** Entity class storing rows of table Computer
* #param id Database column ID PrimaryKey
* #param name Database column NAME
* #param introduced Database column INTRODUCED
* #param discontinued Database column DISCONTINUED
* #param companyId Database column COMPANY_ID */
case class ComputerRow(id: Long, name: String, introduced: Option[java.sql.Timestamp], discontinued: Option[java.sql.Timestamp], companyId: Option[Long])
/** GetResult implicit for fetching ComputerRow objects using plain SQL queries */
implicit def GetResultComputerRow(implicit e0: GR[Long], e1: GR[String], e2: GR[Option[java.sql.Timestamp]], e3: GR[Option[Long]]): GR[ComputerRow] = GR{
prs => import prs._
ComputerRow.tupled((<<[Long], <<[String], <<?[java.sql.Timestamp], <<?[java.sql.Timestamp], <<?[Long]))
}
/** Table description of table COMPUTER. Objects of this class serve as prototypes for rows in queries. */
class Computer(tag: Tag) extends Table[ComputerRow](tag, "COMPUTER") {
def * = (id, name, introduced, discontinued, companyId) <> (ComputerRow.tupled, ComputerRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, name.?, introduced, discontinued, companyId).shaped.<>({r=>import r._; _1.map(_=> ComputerRow.tupled((_1.get, _2.get, _3, _4, _5)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column ID PrimaryKey */
val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
/** Database column NAME */
val name: Column[String] = column[String]("NAME")
/** Database column INTRODUCED */
val introduced: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("INTRODUCED")
/** Database column DISCONTINUED */
val discontinued: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("DISCONTINUED")
/** Database column COMPANY_ID */
val companyId: Column[Option[Long]] = column[Option[Long]]("COMPANY_ID")
/** Foreign key referencing Company (database name FK_COMPUTER_COMPANY_1) */
lazy val companyFk = foreignKey("FK_COMPUTER_COMPANY_1", companyId, Company)(r => r.id, onUpdate=ForeignKeyAction.Restrict, onDelete=ForeignKeyAction.Restrict)
}
/** Collection-like TableQuery object for table Computer */
lazy val Computer = new TableQuery(tag => new Computer(tag))
}
UPDATE - SOLUTION The final solution is in this question.
My first answer plugs in the sorting function at the right place, but quickly grows complicated because of Slick's complicated typing. You can avoid these typing issues by using Slick's query composition to modify the query directly based on the desired ordering.
def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%") = {
//..
val q = for {
(computer, company) <- Computer.where(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company.?)
val sortedQ = orderBy match {
case 1 => q.sortBy(_._1.id)
case 2 => q.sortBy(_._1.description)
// Others
}
val pagedQ = sortedQ.drop(page * pageSize).take(pageSize)
pagedQ.list
}
The difference between Slick and Anorm is that Slick's queries are checked by the Scala compiler. Implementing such a dynamic parameter takes a bit more effort in Slick, but you get type safety in return. It is made particularly cumbersome to do in this case since your query ordering is a join of multiple tables.
In general, it should look roughly like this:
def orderings(code: Int): ((Computer, Company)) => Column[_] = {
code match {
case 1 => _._1.id
case 2 => _._1.description
// Other orderings
}
)
def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%") = {
//..
val computers_ = (for {
(computer, company) <- Computer.where(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company.?))
.sortBy(orderings(orderBy).nullsLast)
.drop(page * pageSize)
.take(pageSize)
.list
//..
}
The general idea to map the integers you receive to the Slick columns on which you want to sort is the answer to your question.
Not sure if this is the best idea in the world but you could technically use shapeless to help you get a numbered tuple element, this will obviously be at the cost of compile-time safety. First convert the Company case class into a tuple with Company.unapply and then use shapeless's at(N) method (note that it's a 0-based index). Here's what that would look like:
def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%") = {
//..
val computers_ = (for {
(computer, company) <- Computer.where(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company.?))
.sortBy(Company.unapply(_._1).get.at(orderBy-1).nullsLast)
.drop(page * pageSize)
.take(pageSize)
.list
//..
}
In order to do this you will need shapeless:
<dependency>
<groupId>com.chuusai</groupId>
<artifactId>shapeless_2.11</artifactId>
<version>2.3.1</version>
</dependency>
...and the following import:
import shapeless.syntax.std.tuple._
Use this technique at your own risk.

Slick 2.0.2 Error: value === is not a member of Tables.profile.simple.Column[String]

I am trying to start using slick. I have a h2-database and generated classes with scala.slick.model.codegen.SourceCodeGenerator. But when try I try following the examples and query my db using these classes I get scala-errors.
The generated code looks as follows:
/** Entity class storing rows of table User
* #param id Database column ID PrimaryKey
* #param firstname Database column FIRSTNAME
* #param lastname Database column LASTNAME */
case class UserRow(id: String, firstname: Option[String], lastname: Option[String])
/** GetResult implicit for fetching UserRow objects using plain SQL queries */
implicit def GetResultUserRow(implicit e0: GR[String], e1: GR[Option[String]]): GR[UserRow] = GR{
prs => import prs._
UserRow.tupled((<<[String], <<?[String], <<?[String]))
}
/** Table description of table USER. Objects of this class serve as prototypes for rows in queries. */
class User(tag: Tag) extends Table[UserRow](tag, "USER") {
def * = (id, firstname, lastname) <> (UserRow.tupled, UserRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, firstname, lastname).shaped.<>({r=>import r._; _1.map(_=> UserRow.tupled((_1.get, _2, _3)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column ID PrimaryKey */
val id: Column[String] = column[String]("ID", O.PrimaryKey)
/** Database column FIRSTNAME */
val firstname: Column[Option[String]] = column[Option[String]]("FIRSTNAME")
/** Database column LASTNAME */
val lastname: Column[Option[String]] = column[Option[String]]("LASTNAME")
}
/** Collection-like TableQuery object for table User */
lazy val User = new TableQuery(tag => new User(tag))
And this is my query:
val userResultList = for {
u <- User if u.id === "foo"
} yield u
which results in:
Error:(137, 29) value === is not a member of db.Tables.profile.simple.Column[String]
u <- User if u.id === user.id
^
What's wrong?
For slick 2.x, just import XXXDriver.simple._ and the compiler will be happy.
For slick 3.x, its XXXDriver.api._

How make simple slick insert with Lifted query and Option columns

I can't seem to understand how to make a simple insert into a Database using Slick. I'm using tables generator with my Oracle db and I'm getting something like this:
case class SimulatonRow(id: scala.math.BigDecimal, startDate: Option[java.sql.Timestamp], endDate: Option[java.sql.Timestamp], numberOfProc: Option[scala.math.BigDecimal], code: String)
/** GetResult implicit for fetching SimulatonRow objects using plain SQL queries */
implicit def GetResultSimulatonRow(implicit e0: GR[scala.math.BigDecimal], e1: GR[Option[java.sql.Timestamp]], e2: GR[Option[scala.math.BigDecimal]], e3: GR[String]): GR[SimulatonRow] = GR{
prs => import prs._
SimulatonRow.tupled((<<[scala.math.BigDecimal], <<?[java.sql.Timestamp], <<?[java.sql.Timestamp], <<?[scala.math.BigDecimal], <<[String]))
}
class Simulaton(tag: Tag) extends Table[SimulatonRow](tag, Some("BPRISK"), "SIMULATON") {
def * = (id, startDate, endDate, numberOfProc, code) <> (SimulatonRow.tupled, SimulatonRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, startDate, endDate, numberOfProc, code.?).shaped.<>({r=>import r._; _1.map(_=> SimulatonRow.tupled((_1.get, _2, _3, _4, _5.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column ID PrimaryKey */
val id: Column[scala.math.BigDecimal] = column[scala.math.BigDecimal]("ID", O.PrimaryKey, O.AutoInc)
/** Database column START_DATE */
val startDate: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("START_DATE")
/** Database column END_DATE */
val endDate: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("END_DATE")
/** Database column NUMBER_OF_PROC */
val numberOfProc: Column[Option[scala.math.BigDecimal]] = column[Option[scala.math.BigDecimal]]("NUMBER_OF_PROC")
/** Database column CODE */
val code: Column[String] = column[String]("CODE")
}
Then I add AutoInc option to the primary key.
I tried variations of 'insert' with TableQuery[Simulaton].map or InsertInvoker, but the code cannot be compiled.
How does it work?
I need to make an 'insert' with autoincremental PK and columns - code, startDate.
// import driver specific stuff
import MySQLDriver.simple._
// import generated code
import Tables._
// define db connection
val db = Database.for...
// create a connection
db.withSession{ implicit session =>
// select what should be inserted into
TableQuery[Simulaton].map(s => (s.code,s.startDate))
// insert instead or running the query
.insert( ("some code",Some(DateTime.now)) )
}