Add CREATE/DROP TABLE schema helpers

CREATE TABLE uses a builder to create a table. Our usual example:

    db.create(table: users) { t in
        t.column(id, primaryKey: true)
        t.column(email, null: false, unique: true)
        t.column(manager_id, references: users[id])
    }
    // CREATE TABLE users(
    //     id INTEGER PRIMARY KEY,
    //     email TEXT NOT NULL UNIQUE,
    //     manager_id INTEGER REFERENCES users(id)
    // )

There are other table-level helpers for PRIMARY KEY (for composite
keys), UNIQUE, CHECK, and FOREIGN KEY (for UPDATE/DELETE hooks).

A few notes on foreign keys:

 1. The shorthand, `references:` only supports INTEGER PRIMARY KEYs
    right now. This is subject to change, but single primary keys are
    generally INTEGERs, so let's encourage it as a best practice for
    now. (It's still possible to use the `foreignKey` function to link
    non-integer keys.)

 2. Foreign keys do not work out-of-the-box with SQLite, as foreign key
    support is off by default. We'll probably want to enable them by
    default in the (near) future.

 3. Composite foreign keys are not supported (yet).

DROP TABLE omits the builder.

    db.drop(table: users)
    // DROP TABLE users

Both `create` and `drop` functions call `table` out as an explicitly
named parameter to both emphasize the action and provide room for INDEX
helpers (and, potentially, TRIGGER and VIEW helpers).

Neither yet support the IF NOT EXISTS clause. This wordiness doesn't
feel right as a named parameter.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add CREATE/DROP INDEX helpers

Index name is auto-generated.

    db.create(index: users, on: email, unique: true)
    // CREATE UNIQUE INDEX index_users_on_email ON users (email)

    db.drop(index: users, on: email)
    // DROP INDEX index_users_on_email

Partial indexes are available where applicable. At this time, Yosemite
ships with support; iOS does not.

    db.create(index: users.filter(verified), on: email)
    // CREATE INDEX index_users_on_email ON users (email) WHERE verified

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Remove partial index support (for now)

It's not widely available: SQLite3 3.8.0 introduced it, which appears to
ship with Yosemite, but not iOS. Regardless, the build is failing on
Travis's new Mac VMs, so more investigation is necessary to support
this properly.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add Database userVersion getter/setter

For getting/setting the PRAGMA user_version.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add protection around foreign key constraints

SQLite3 disables foreign key constraints by default. Let's throw an
assertion to alert developers when they create a constraint with a
connection that hasn't enabled them.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Throw assertions for all non-constraint-based errors

Even constraint failures can be programmer error, so we probably want to
revisit this in the future.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Clean up tests to use Query alias/subscript

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Optional changes around Database.lastChanges and Query.{update,delete}

 1. Database.lastChanges will no longer return an optional. We could
    still scope it by checking totalChanges > 0, but it doesn't seem
    worth it for that one case. This gives us a bit more flexibility.

 2. Query.update and Query.delete now return optional Ints for changes.
    This makes it easier to check if a statement succeeded or not using
    `if`-`let`, and it makes it easier to run fire-and-forget statements
    by simply tacking on a `?` or `!`.

        // used for the flat map on an optional new ROWID, below
        let findByID: Int -> Query { users.filter(id == $0) }

        let alice = users.insert(email <- "alice@me.com").map(findByID)
        alice?.update(admin <- true)?
        alice?.delete()?

    Optionals make it easier to disambiguate inline.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Conform statement to BooleanType

Makes it easy to use `if` for whether or not a statement ran and succeeded.

Ideally, this would also disambiguate Query.{insert,update,delete}, but
it does not (rdar forthcoming).

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Update README for legibility

This removes some of the more powerful examples in the spirit of being
more readable. A wiki is coming, and so is a revamped playground, but
writing is hard :)

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add optional support to NULLable expressions

This adds support for Expression<T?> to denote SQL expessions that may
evaluate to NULL. It's verbose given the number of permutations to
overload most operators, but brings a lot of benefits to the table:

 1. Stricter typing. The compiler will let you know if you do something
    like try to compare a NOT NULL column to nil.

        let age = Expression<Int?>("age")
        let id = Expression<Int>("id")
        users.filter(age == nil)
        users.filter(id == nil) // Won't compile. Meaningless.

    Functions like coalesce and ifnull will also require optional
    expressions.

 2. Automatic NOT NULL support during schema creation.

        t.column(age) // age INTEGER
        t.column(id)  // id INTEGER NOT NULL

 3. Perhaps most importantly, the ability to automatically unwrap a row
    and return a value directly.

        user[age]     // Optional(30)
        user[id]      // 1

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Update README with NULLable, optional expressions

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
More README tweaks

Show non-optional vs. optional return values.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
README fixes

Feels more like REREADME.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add missing question

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add `make repl`

Gives us easy SQLite.swift access in the Swift REPL on the command line.

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Accuracy in README output

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Remove println

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Support default expressions (like CURRENT_*)

Signed-off-by: Stephen Celis <stephen@stephencelis.com>
Add ALTER TABLE schema helpers

Supports RENAME TO:

    db.alter(table: users, rename: "people")

And ADD COLUMN:

    let name = Expression<String?>("name")
    db.alter(table: users, add: name)

Signed-off-by: Stephen Celis <stephen@stephencelis.com>