IreneKnapp/direct-sqlite — pull request #12 by joeyadams (2012-08-19 21:53:07+00:00)
Title: Add modules to direct-sqlite for lower-level access

Sorry, this is a pretty big pull request. The commits trace the development history, which is basically:

* Add a module with FFI bindings.

* Change `Database.SQLite3` to use those bindings.

* Add `Database.SQLite3.Direct`, a lower-level variant of `Database.SQLite3` implemented with the FFI bindings.

* Change `Database.SQLite3` again, to use `Database.SQLite3.Direct`.

### Merging information

This pull request renames SQLite3.hsc to SQLite3.hs, which makes the diff a bit less useful. To see what changed in `Database.SQLite3`, you can do the following:

git remote add joeyadams git://github.com/joeyadams/direct-sqlite.git
git fetch joeyadams
git diff 84efb91:Database/SQLite3.hsc b312202:Database/SQLite3.hs

This pull request includes the commit by @nurpax from [pull request #9][1], with the merge conflict resolved.

[1]: https://github.com/IreneKnapp/direct-sqlite/pull/9

### What this pull request does

This splits direct-sqlite into three levels of abstraction:

* `Database.SQLite3`: Existing API.

* `Database.SQLite3.Direct`: Like `Database.SQLite3`, but return errors instead of throwing them, and only use cheap conversions (meaning no `String` and `Text`).

Note: the `SQLData` type defined here is different from the one in `Database.SQLite3`. The new `SQLData` type has strictness annotations, so it is incompatible with the old type. This should be fixed in a future version, once we decide to break the existing API.

* `Database.SQLite3.Bindings`: Raw FFI bindings, using newtypes to clarify parameters and make the bindings easier to use correctly.

My goal was to avoid breaking the existing API, so people can start using the new internals without compatibility issues. However, some minor changes have been made to the existing API:

* In bindInt, use sqlite3_bind_int64 instead of sqlite3_bind_int, to avoid truncation on platforms where `CInt` is smaller than `Int`.

* bindText no longer truncates to the first NUL character. The database might, though.

* Add Show instances for Database and Statement.

* Tweak documentation of bindParameterCount and bindParameterName.

### Future directions

I took plenty of liberties with `Database.SQLite3.Direct`. It represents the direction I would like to see `Database.SQLite3` go, namely:

* Stronger typing

* More precise error handling

* Hyperlinks to upstream documentation

I'd also want to factor the `Error` type:

data Result
= Okay
| StepResult !StepResult
| Error !Error

-- Extended error types; see http://www.sqlite.org/c3ref/c_abort_rollback.html
| ErrorIO !ErrorIO
| ErrorLocked !ErrorLocked
| ErrorBusy !ErrorBusy
| ErrorCantOpen !ErrorCantOpen
| ErrorCorrupt !ErrorCorrupt
| ErrorReadOnly !ErrorReadOnly
| ErrorAbort !ErrorAbort

But we'd have to remove these data constructors from `Error`:

* `ErrorOK`

* `ErrorRow`

* `ErrorDone`