Permalink
Browse files

Some documentation improvements

  • Loading branch information...
1 parent 3b3bd36 commit f8fde98961fa08e10a07c13c44105adf7cb57f0c @szeiger szeiger committed Oct 9, 2015
@@ -1,26 +1,39 @@
# These settings are read by slick.util.SlickConfig
slick {
- # Use ANSI color sequences in tree dumps
+ # Use ANSI color sequences in tree dumps (as used in log messages and
+ # exceptions of type SlickTreeException).
ansiDump = false
- # Use Unicode box characters in tree and table dumps
+ # Use Unicode box characters in tree and table dumps (as used in log
+ # messages). If this option is not enabled, ASCII approximations are used
+ # instead.
unicodeDump = false
- # Dump individual Select and Ref nodes instead of a single Path
+ # Dump individual "Select" and "Ref" nodes instead of combining them into a
+ # single "Path" element when creating a tree dump (as used in log messages
+ # and exceptions of type SlickTreeException).
dumpPaths = false
- # Use multi-line, indented formatting for SQL statements
+ # Use multi-line, indented formatting for SQL statements. If not enabled,
+ # statements are generated without any linebreaks or indentation. This
+ # option applies to all generated statements (but not to the Plain SQL API).
sqlIndent = false
- # Verify types after each query compiler phase
+ # Verify types after each query compiler phase. This is useful for debugging
+ # the query compiler but should generally not be enabled in production
+ # environments because it makes query compilation considerably slower.
verifyTypes = false
- # Detect unnecessary rebuilding of the AST after every query compiler phase
+ # Detect unnecessary rebuilding of the AST after every query compiler phase.
+ # This is useful for debugging the query compiler. Query compilation
+ # performance is negatively affected by this if phase logging is enabled.
detectRebuild = false
}
+# Profile-specific settings for MySQLProfile
slick.jdbc.MySQLProfile {
# The default SQL type for strings without an explicit size limit.
- # When set to null / undefined, pick "TEXT" where possible, otherwise fall back to "VARCHAR(254)"
+ # When set to null / undefined, pick "TEXT" where possible, otherwise fall back
+ # to "VARCHAR(254)"
defaultStringType = null
}
@@ -78,11 +78,13 @@ class QueryCompiler(val phases: Vector[Phase]) extends Logging {
protected[this] def runPhase(p: Phase, state: CompilerState): CompilerState = state.symbolNamer.use {
val s2 = p(state)
if(s2.tree ne state.tree) {
- if(GlobalConfig.detectRebuild && s2.tree == state.tree) {
- val rebuilt = detectRebuiltLeafs(state.tree, s2.tree)
- logger.debug("After phase "+p.name+": (no change but not identical)", s2.tree, (d => rebuilt.contains(RefId(d))))
- } else
- logger.debug("After phase "+p.name+":", s2.tree)
+ if(logger.isDebugEnabled) {
+ if(GlobalConfig.detectRebuild && s2.tree == state.tree) {
+ val rebuilt = detectRebuiltLeafs(state.tree, s2.tree)
+ logger.debug("After phase "+p.name+": (no change but not identical)", s2.tree, (d => rebuilt.contains(RefId(d))))
+ } else
+ logger.debug("After phase "+p.name+":", s2.tree)
+ }
if(GlobalConfig.verifyTypes && s2.wellTyped)
(new VerifyTypes(after = Some(p))).apply(s2)
}
@@ -89,6 +89,7 @@ object Connection extends App {
val a = q.result
val p1: DatabasePublisher[Blob] = db.stream(a)
val p2: DatabasePublisher[Array[Byte]] = p1.mapResult { b =>
+ // Executed synchronously on the database thread
b.getBytes(0, b.length().toInt)
}
//#streamblob
@@ -0,0 +1,29 @@
+package com.typesafe.slick.docs
+
+import scala.concurrent.ExecutionContext.Implicits.global
+import slick.jdbc.H2Profile.api._
+
+object DBIOCombinators extends App {
+ class Coffees(tag: Tag) extends Table[(String, Double)](tag, "COFFEES") {
+ def name = column[String]("COF_NAME", O.PrimaryKey)
+ def price = column[Double]("PRICE")
+ def * = (name, price)
+ }
+ val coffees = TableQuery[Coffees]
+ ;{
+ //#combinators1
+ val ins1: DBIO[Int] = coffees += ("Colombian", 7.99)
+ val ins2: DBIO[Int] = coffees += ("French_Roast", 8.99)
+
+ val a1: DBIO[Unit] = DBIO.seq(ins1, ins2)
+
+ val a2: DBIO[Int] = ins1 andThen ins2
+
+ val a3: DBIO[(Int, Int)] = ins1 zip ins2
+
+ val a4: DBIO[Vector[Int]] = DBIO.sequence(Vector(ins1, ins2))
+ //#combinators1
+
+ ()
+ }
+}
@@ -0,0 +1,67 @@
+.. index:: concepts
+
+Core Concepts
+=============
+
+When you use Slick, you start by composing *Scala queries*, then get *actions* (like "get results" or "insert data")
+associated with these queries, and finally run the actions on a *database* to obtain *results*.
+
+This chapter explains how these core concepts relate to each other and how they fit into your application design.
+
+Scala Queries
+-------------
+
+The main type used by queries is :api:`slick.lifted.Rep`. A ``Rep[T]`` is a *representation* of a type ``T`` that
+provides the necessary operations for building queries. Collection-valued queries are always of type
+:api:`slick.lifted.Query`, which is a ``Rep`` of a collection type like ``Rep[Seq[Int]]``. Queries can be composed
+from representations of database tables (:api:`slick.lifted.TableQuery`), literal values and parameters. Query
+composition does not require a database or execute any part of the query. It only builds a description of what to
+execute at a later point.
+
+Database I/O Actions
+--------------------
+
+Operations that can be executed on a database are called *database I/O actions* (:api:`slick.dbio.DBIOAction`).
+Several operations on *queries* and *tables* create I/O actions, for example ``myQuery.result``,
+``myQuery.result.headOption``, ``myQuery += data`` or ``myTable.schema.create``. Actions can be composed with
+combinators like ``andThen``, ``flatMap``, ``DBIO.seq`` or ``transactionally``.
+
+Just like a query, an I/O action is only a *description* of an operation. Creating or composing actions does not execute
+anything on a database. Combined actions always consist of *strictly linear sequences* of other actions. Parts of an
+action never run concurrently.
+
+Plain SQL Statements
+--------------------
+
+As an alternative to Scala queries you can write queries and other database statements in SQL. This is done with
+string interpolators, for example ``sql"select id from mytable".as[Int]`` or
+``sqlu"insert into mytable (id) values (1)"``. These interpolators (in the case of ``sql`` with an extra ``.as`` call)
+all produce *database I/O actions*.
+
+Databases
+---------
+
+A :api:`Database <slick.jdbc.JdbcBackend@Database:Database>` object encapsulates the resources that are required to
+connect to a specific database. This *can* be just a number of connection parameters but in most cases it includes a
+*connection pool* and a *thread pool*. You should usually create a single ``Database`` object when your application
+starts and shut it down when your application shuts down to ensure that all resources are released.
+
+Results
+-------
+
+Any *action* can be run on a database to obtain the results (or perform side effects such as updating the database).
+Execution is always asynchronous, i.e. it does not block the caller thread. Any kind of action can be run to obtain
+a ``Future`` that is eventually completed with a result when the execution is finished (``myDatabase.run(myAction)``).
+Actions that produce a sequence of values usually support streaming results as well. Such an action can be combined
+with a database to produce a `Reactive Streams`_ ``Publisher`` (``myDatabase.stream(myAction)``). The action is
+executed when a consumer subscribes to the Publisher.
+
+Profiles
+--------
+
+Even when using a standard interface for database drivers like JDBC_ there are many differences between databases in
+the SQL dialect they understand, the way they encode data types, or other idiosyncracies. Slick abstracts over these
+differences with *profiles*. Whenever you write queries (whether in Scala or SQL) or produce other database actions,
+you need a concrete profile for your database. Usually these profiles extend the abstract :api:`slick.jdbc.JdbcProfile`.
+``Database`` objects are interchangeable between all subtypes of JdbcProfile but they are usually configured together
+with the profile because you need to pick the correct profile for the database.
@@ -0,0 +1,55 @@
+.. index:: configuration, options
+
+Configuration
+=============
+
+In addition to configuring your :doc:`database connections <database>` in ``application.conf`` you can also set some
+global options in this file or through system properties (see the `Typesafe Config`_ documentation for details).
+These are the available options and their default values as defined in Slick's own ``reference.conf``:
+
+.. includecode:: ../main/resources/reference.conf
+ :language: sh
+
+.. index:: logging, slf4j
+
+.. _logging:
+
+Logging
+=======
+
+Slick uses SLF4J_ for logging. How to configure loggers and appenders depends on the actual logging framework that you
+use in your application. The following Logback_ configuration is used internally for testing and debugging of Slick. It
+contains a list of all loggers that are used by Slick for debug output:
+
+.. includecode:: ../../../common-test-resources/logback.xml
+ :language: xml
+
+.. note::
+ Messages on WARNING and ERROR levels may also be emitted by loggers that are not explicitly mentioned in this
+ configuration.
+
+You should generally enable logging for the root package ``slick`` at level ``INFO`` (currently unused)
+or ``WARNING``. Debug logging should only be enabled selectively for individual loggers, otherwise you will get a huge
+amount of log output.
+
+The following loggers are particularly interesting:
+
+``slick.basic.BasicBackend.action``
+ Shows the execution of every :doc:`Database I/O Action <dbio>`.
+
+``slick.compiler.QueryCompiler``
+ Shows a dump of the AST after every phase of the query compiler when compiling a query.
+
+``slick.jdbc.DriverDataSource``
+ Shows information about JDBC_ drivers being loaded by :api:`slick.jdbc.DriverDataSource`. Does not
+ apply when using a connection pool unless you explicitly use a DriverDataSource as the source for the connection
+ pool.
+
+``slick.jdbc.JdbcBackend.statement``
+ Shows all SQL statements which are executed.
+
+``slick.jdbc.JdbcBackend.benchmark``
+ Shows execution times for SQL statements.
+
+``slick.jdbc.StatementInvoker.result``
+ Shows the first rows of the result set when a query is executed. Does not apply to streaming results.
Oops, something went wrong.

0 comments on commit f8fde98

Please sign in to comment.