Documentation.

This commit is contained in:
Nuno Cruces
2023-02-28 14:50:15 +00:00
parent 1b3823483f
commit 54046b6adc
8 changed files with 55 additions and 11 deletions

1
.gitignore vendored
View File

@@ -16,4 +16,5 @@
tools
# Project
demo.db
sqlite3/sqlite3*

View File

@@ -49,11 +49,13 @@ and WAL databases are not supported.
- [ ] snapshots
- [ ] session extension
- [ ] resumable bulk update
- [ ] SQL functions
- [ ] shared cache mode
- [ ] custom SQL functions
- [ ] custom VFSes
- [ ] read-only VFS, wrapping an [`io.ReaderAt`](https://pkg.go.dev/io#ReaderAt)
- [ ] in-memory VFS, wrapping a [`bytes.Buffer`](https://pkg.go.dev/bytes#Buffer)
- [ ] expose a custom VFS API
- [ ] cloud-based VFS, based on [Cloud Backed SQLite](https://sqlite.org/cloudsqlite/doc/trunk/www/index.wiki)
- [ ] custom VFS API
### Alternatives

View File

@@ -1,4 +1,27 @@
// Package driver provides a database/sql driver for SQLite.
//
// Importing package driver registers a [database/sql] driver named "sqlite3".
// You may also need to import package embed.
//
// import _ "github.com/ncruces/go-sqlite3/driver"
// import _ "github.com/ncruces/go-sqlite3/embed"
//
// The data source name for "sqlite3" databases can be a filename or a "file:" [URI].
//
// The [TRANSACTION] mode can be specified using "_txlock":
//
// sql.Open("sqlite3", "file:demo.db?_txlock=immediate")
//
// [PRAGMA] statements can be specified using "_pragma":
//
// sql.Open("sqlite3", "file:demo.db?_pragma=busy_timeout(10000)&_pragma=locking_mode(normal)")
//
// If no PRAGMAs are specifed, a busy timeout of 1 minute
// and normal locking mode are used.
//
// [URI]: https://www.sqlite.org/uri.html
// [PRAGMA]: https://www.sqlite.org/pragma.html
// [TRANSACTION]: https://www.sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions
package driver
import (

View File

@@ -72,7 +72,7 @@ func Test_Open_pragma_invalid(t *testing.T) {
t.Errorf("got %d, want sqlite3.ERROR", rc)
}
if got := err.Error(); got != `sqlite3: invalid _pragma: sqlite3: SQL logic error: near "1000": syntax error` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
}
@@ -124,7 +124,7 @@ func Test_Open_txLock_invalid(t *testing.T) {
t.Fatal("want error")
}
if got := err.Error(); got != `sqlite3: invalid _txlock: xclusive` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
}
@@ -201,7 +201,7 @@ func Test_Prepare(t *testing.T) {
t.Errorf("got %d, want sqlite3.ERROR", rc)
}
if got := err.Error(); got != `sqlite3: SQL logic error: incomplete input` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
_, err = db.Prepare(`SELECT 1; SELECT`)
@@ -215,7 +215,7 @@ func Test_Prepare(t *testing.T) {
t.Errorf("got %d, want sqlite3.ERROR", rc)
}
if got := err.Error(); got != `sqlite3: SQL logic error: incomplete input` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
_, err = db.Prepare(`SELECT 1; SELECT 2`)

View File

@@ -11,11 +11,13 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
)
const demo = "demo.db"
func ExampleDriverConn() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := sql.Open("sqlite3", ":memory:")
db, err := sql.Open("sqlite3", demo)
if err != nil {
log.Fatal(err)
}

View File

@@ -1,5 +1,10 @@
// Package embed embeds SQLite into your application.
//
// Importing package embed initializes the [sqlite3.Binary] variable
// with an appropriate build of SQLite:
//
// import _ "github.com/ncruces/go-sqlite3/embed"
//
// You can obtain this build of SQLite from:
// https://github.com/ncruces/go-sqlite3/tree/main/embed
package embed

View File

@@ -54,7 +54,7 @@ func TestConn_Close_BUSY(t *testing.T) {
t.Error("not temporary", err)
}
if got := err.Error(); got != `sqlite3: database is locked: unable to close due to unfinalized statements or unfinished backups` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
}
@@ -182,7 +182,7 @@ func TestConn_Prepare_invalid(t *testing.T) {
t.Errorf("got %d, want sqlite3.ERROR", rc)
}
if got := err.Error(); got != `sqlite3: SQL logic error: incomplete input` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
_, _, err = db.Prepare(`SELECT * FRM sqlite_schema`)
@@ -196,10 +196,10 @@ func TestConn_Prepare_invalid(t *testing.T) {
t.Errorf("got %d, want sqlite3.ERROR", rc)
}
if got := serr.SQL(); got != `FRM sqlite_schema` {
t.Error("got SQL: ", got)
t.Error("got SQL:", got)
}
if got := serr.Error(); got != `sqlite3: SQL logic error: near "FRM": syntax error` {
t.Error("got message: ", got)
t.Error("got message:", got)
}
}

11
time.go
View File

@@ -11,6 +11,9 @@ import (
// TimeFormat specifies how to encode/decode time values.
//
// See the documentation for the [TimeFormatDefault] constant
// for formats recognized by SQLite.
//
// https://www.sqlite.org/lang_datefunc.html
type TimeFormat string
@@ -59,6 +62,14 @@ const (
// [TimeFormatDefault] and [TimeFormatAuto] encode using [time.RFC3339Nano],
// with nanosecond accuracy, and preserving any timezone offset.
//
// This is the format used by the database/sql driver:
// [database/sql.Row.Scan] is able to decode as [time.Time]
// values encoded with [time.RFC3339Nano].
//
// Time values encoded with [time.RFC3339Nano] cannot be sorted as strings
// to produce a time-ordered sequence.
// Use [TimeFormat7TZ] for time-ordered encoding.
//
// Formats [TimeFormat1] through [TimeFormat10]
// convert time values to UTC before encoding.
//