Skip to content
Permalink
Browse files

Documentation improvements for 2.0.1.

- Explain TableQuery macro in schemas chapter (#621)
- Fixed some typos
- Add findBy to migration guide (#655)
- Clarify use of .tupled in migration guide (#656)
- Explain schema names in schemas chapter (#659)

Fixes issues #621, #626, #655, #656, #659.
  • Loading branch information
szeiger committed Feb 11, 2014
1 parent f6fa8e6 commit 73064e9abf3666a1240ac09cacd85b430bbbbdd5
Showing with 117 additions and 29 deletions.
  1. +21 −1 src/sphinx/code/LiftedEmbedding.scala
  2. +27 −3 src/sphinx/code/MigrationGuide.scala
  3. +43 −21 src/sphinx/migration.rst
  4. +26 −4 src/sphinx/schemas.rst
@@ -82,10 +82,30 @@ object LiftedEmbedding extends App {
//#foreignkey
//#tabledef
}
//#tabledef
//#tablequery
val coffees = TableQuery[Coffees]
//#tablequery
//#foreignkey
//#tabledef

{
//#schemaname
class Coffees(tag: Tag)
extends Table[(String, Int, Double, Int, Int)](tag, Some("MYSCHEMA"), "COFFEES") {
//...
//#schemaname
def * = ???
def name = column[String]("NAME")
//#schemaname
}
//#schemaname

//#tablequery2
object coffees extends TableQuery(new Coffees(_)) {
val findByName = this.findBy(_.name)
}
//#tablequery2
}
//#reptypes
val q = coffees.filter(_.price > 8.0).map(_.name)
// ^ ^ ^
@@ -2,11 +2,21 @@ package com.typesafe.slick.docs

import scala.slick.driver.H2Driver.simple._

//#caseclassextends
case class Supplier(id: Int, name: String, street: String)

object Supplier // overriding the default companion object
extends ((Int, String, String) => Supplier) { // manually extending the correct function type
//...
}
//#caseclassextends

class MigrationGuide {

val myDB: Database = null
implicit val session: Session = null


{
//#tabledef
class Suppliers(tag: Tag) extends Table[(Int, String, String)](tag, "SUPPLIERS") {
@@ -45,12 +55,26 @@ class MigrationGuide {
}

{
class Suppliers(tag: Tag) extends Table[Nothing](tag, "") {
def * = ???
class Suppliers(tag: Tag) extends Table[Supplier](tag, "SUPPLIERS") {
def id = column[Int]("SUP_ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("SUP_NAME")
def street = column[String]("STREET")
//#mappedprojection2
def * = (id, name, street) <> ((Supplier.apply _).tupled, Supplier.unapply)
//#mappedprojection2
}
Supplier.apply _
}

{
class Suppliers(tag: Tag) extends Table[Int](tag, "") {
def id = column[Int]("ID")
def * = id
}
//#tablequery
object suppliers extends TableQuery(new Suppliers(_)) {
// put extra methods here
// put extra methods here, e.g.:
val findByID = this.findBy(_.id)
}
//#tablequery
}
@@ -5,15 +5,15 @@ Slick 2.0 contains some improvements which are not source compatible with Slick
1.0. When migrating your application from 1.0 to 2.0, you will likely need to
perform changes in the following areas.

Code generation
-----------------
Code Generation
---------------

Instead of writing your table descriptions or plain SQL mappers by hand, in 2.0 you can
now automatically generate them from your database schema. The code-generator
is flexible enough to customize it's output to fit exactly what you need.
:doc:`More info on code generation <code-generation>`.

Table descriptions
Table Descriptions
------------------

In Slick 1.0 tables were defined by a single ``val`` or ``object`` (called the
@@ -41,7 +41,7 @@ support for the old `~` syntax. The simple ``TableQuery[T]`` syntax is a
macro which expands to a proper TableQuery instance that calls the table's
constructor (``new TableQuery(new T(_))``). In Slick 1.0 it was common practice
to place extra static methods associated with a table into that table's object.
You can do the same in 2.0 with a custon ``TableQuery`` object:
You can do the same in 2.0 with a custom ``TableQuery`` object:

.. includecode:: code/MigrationGuide.scala#tablequery

@@ -51,6 +51,44 @@ unexpected places is no longer needed or available. All the places where you
had to use the raw *table object* in Slick 1.0 have been changed to use the
*table query* instead, e.g. inserting (see below) or foreign key references.

The method for creating simple finders has been renamed from ``createFinderBy``
to ``findBy``. It is defined as an *extension method* for ``TableQuery``, so
you have to prefix the call with ``this.`` (see code snippet above).

Mapped Tables
-------------

In 1.0 the ``<>`` method for bidirectional mappings was overloaded for
different arities so you could directly pass a case class's ``apply`` method to
it::

// --------------------- Slick 1.0 code -- does not compile in 2.0 ---------------------

def * = id ~ name ~ street <> (Supplier _, Supplier.unapply)

This is no longer supported in 2.0. One of the reasons is that the overloading
led to complicated error messages.
You now have to use a function with an appropriate tuple type.
If you map to a case class you can simply use ``.tupled`` on its
companion object:

.. includecode:: code/MigrationGuide.scala#mappedprojection

Note that ``.tupled`` is only available for proper Scala *functions*. In 1.0 it
was sufficient to have a *method* like ``apply`` that could be converted to
a function on demand (``<> (Supplier.apply _, Supplier.unapply)``).

When using a case class, the companion object extends the correct function
type by default, but only if you do not define the object yourself. In that
case you should provide the right supertype manually, e.g.:

.. includecode:: code/MigrationGuide.scala#caseclassextends

Alternatively, you can have the Scala compiler first do the lifting to a
function and then call ``.tupled``:

.. includecode:: code/MigrationGuide.scala#mappedprojection2

Profile Hierarchy
-----------------

@@ -112,23 +150,7 @@ projection and Slick will skip the auto-incrementing ``id`` column:
If you really want to insert into an ``AutoInc`` field, you can use the new
methods ``forceInsert`` and ``forceInsertAll``.

In 1.0 the ``<>`` method for bidirectional mappings was overloaded for
different arities so you could directly pass a case class's ``apply`` method to
it::

// --------------------- Slick 1.0 code -- does not compile in 2.0 ---------------------

def * = id ~ name ~ street <> (Supplier _, Supplier.unapply)

This is no longer supported in 2.0. One of the reasons is that the overloading
lead to complicated error messages.
You now have to use a function with an appropriate tuple type.
If you map to a case class you can simply use ``.tupled`` on its
companion object:

.. includecode:: code/MigrationGuide.scala#mappedprojection

Pre-compiled updates
Pre-compiled Updates
-----------------------------
Slick now supports pre-compilation of updates in the same manner like selects, see
:ref:`compiled-queries`.
@@ -7,12 +7,12 @@ how you can write schema descriptions by hand. Instead you
can also use the :doc:`code generator <code-generation>` to
take this work off your hands.

Tables
------
Table Rows
----------

In order to use the *Lifted Embedding* API for type-safe queries, you need to
define ``Table`` row classes and corresponding ``TableQuery`` values for your
database schema:
define ``Table`` row classes for your database schema. These describe the
structure of the tables:

.. includecode:: code/LiftedEmbedding.scala#tabledef

@@ -76,6 +76,28 @@ or omit some columns as you like. The non-lifted type corresponding to the
non-mapped tables, this will be a single column type or a tuple of column
types.

If your database layout requires *schema names*, you can specify the schema
name for a table in front of the table name, wrapped in ``Some()``:

.. includecode:: code/LiftedEmbedding.scala#schemaname

Table Query
-----------

Alongside the ``Table`` row class you also need a ``TableQuery`` value
which represents the actual database table:

.. includecode:: code/LiftedEmbedding.scala#tablequery

The simple ``TableQuery[T]`` syntax is a
macro which expands to a proper TableQuery instance that calls the table's
constructor (``new TableQuery(new T(_))``).

You can also extend ``TableQuery`` to use it as a convenient namespace for
additional functionality associated with the table:

.. includecode:: code/LiftedEmbedding.scala#tablequery2

Mapped Tables
-------------

0 comments on commit 73064e9

Please sign in to comment.
You can’t perform that action at this time.