Documentation.

This commit is contained in:
Nuno Cruces
2023-02-18 03:43:17 +00:00
parent a51cdb04e6
commit ec5bd236f8
8 changed files with 60 additions and 27 deletions

View File

@@ -6,8 +6,8 @@
⚠️ CAUTION ⚠️
This is still very much a WIP.\
DO NOT USE this with data you care about.
This is a WIP.\
DO NOT USE with data you care about.
Roadmap:
- [x] build SQLite using `zig cc --target=wasm32-wasi`
@@ -15,6 +15,7 @@ Roadmap:
- [x] port [`test_demovfs.c`](https://www.sqlite.org/src/doc/trunk/src/test_demovfs.c) to Go
- branch [`wasi`](https://github.com/ncruces/go-sqlite3/tree/wasi) uses `test_demovfs.c` directly
- [x] design a simple, nice API, enough for simple use cases
- [x] minimal `database/sql` driver
- [x] provide a simple `database/sql` driver
- [x] file locking, compatible with SQLite on Windows/Unix
- [ ] shared memory, compatible with SQLite on Windows/Unix
- [ ] shared memory, compatible with SQLite on Windows/Unix
- needed for improved WAL mode

1
api.go
View File

@@ -1,3 +1,4 @@
// Package sqlite3 wraps the C SQLite API.
package sqlite3
import (

View File

@@ -205,6 +205,10 @@ func (c *Conn) PrepareFlags(sql string, flags PrepareFlag) (stmt *Stmt, tail str
return
}
// LastInsertRowID returns the rowid of the most recent successful INSERT
// on the database connection.
//
// https://www.sqlite.org/c3ref/last_insert_rowid.html
func (c *Conn) LastInsertRowID() uint64 {
r, err := c.api.lastRowid.Call(c.ctx, uint64(c.handle))
if err != nil {
@@ -213,6 +217,11 @@ func (c *Conn) LastInsertRowID() uint64 {
return r[0]
}
// Changes returns the number of rows modified, inserted or deleted
// by the most recently completed INSERT, UPDATE or DELETE statement
// on the database connection.
//
// https://www.sqlite.org/c3ref/changes.html
func (c *Conn) Changes() uint64 {
r, err := c.api.changes.Call(c.ctx, uint64(c.handle))
if err != nil {

View File

@@ -15,6 +15,9 @@ const (
ptrlen = 4
)
// ErrorCode is a result code that [Error.Code] might return.
//
// https://www.sqlite.org/rescode.html
type ErrorCode uint8
const (
@@ -48,6 +51,9 @@ const (
WARNING ErrorCode = 28 /* Warnings from sqlite3_log() */
)
// ExtendedErrorCode is a result code that [Error.ExtendedCode] might return.
//
// https://www.sqlite.org/rescode.html
type (
ExtendedErrorCode uint16
xErrorCode = ExtendedErrorCode
@@ -129,6 +135,9 @@ const (
AUTH_USER ExtendedErrorCode = xErrorCode(AUTH) | (1 << 8)
)
// OpenFlag is a flag for a file open operation.
//
// https://www.sqlite.org/c3ref/c_open_autoproxy.html
type OpenFlag uint32
const (
@@ -156,14 +165,17 @@ const (
OPEN_EXRESCODE OpenFlag = 0x02000000 /* Extended result codes */
)
type AccessFlag uint32
type _AccessFlag uint32
const (
ACCESS_EXISTS AccessFlag = 0
ACCESS_READWRITE AccessFlag = 1 /* Used by PRAGMA temp_store_directory */
ACCESS_READ AccessFlag = 2 /* Unused */
_ACCESS_EXISTS _AccessFlag = 0
_ACCESS_READWRITE _AccessFlag = 1 /* Used by PRAGMA temp_store_directory */
_ACCESS_READ _AccessFlag = 2 /* Unused */
)
// PrepareFlag is a flag that can be passed to [Conn.PrepareFlags].
//
// https://www.sqlite.org/c3ref/c_prepare_normalize.html
type PrepareFlag uint32
const (
@@ -172,6 +184,9 @@ const (
PREPARE_NO_VTAB PrepareFlag = 0x04
)
// Datatype is a fundamental datatype of SQLite.
//
// https://www.sqlite.org/c3ref/c_blob.html
type Datatype uint32
const (

View File

@@ -1,5 +1,7 @@
package driver_test
// Adapted from: https://go.dev/doc/tutorial/database-access
import (
"database/sql"
"fmt"
@@ -12,9 +14,14 @@ import (
var db *sql.DB
func Example() {
// Adapted from: https://go.dev/doc/tutorial/database-access
type Album struct {
ID int64
Title string
Artist string
Price float32
}
func Example() {
// Get a database handle.
var err error
db, err = sql.Open("sqlite3", "./recordings.db")
@@ -24,7 +31,7 @@ func Example() {
defer db.Close()
defer os.Remove("./recordings.db")
err = setupDatabase()
err = createAlbumsTable()
if err != nil {
log.Fatal(err)
}
@@ -58,14 +65,7 @@ func Example() {
// ID of added album: 5
}
type Album struct {
ID int64
Title string
Artist string
Price float32
}
func setupDatabase() error {
func createAlbumsTable() error {
_, err := db.Exec(`
DROP TABLE IF EXISTS album;
CREATE TABLE album (

View File

@@ -1,4 +1,4 @@
package main
package sqlite3_test
import (
"fmt"
@@ -8,8 +8,10 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
)
func main() {
db, err := sqlite3.Open(":memory:")
const memory = ":memory:"
func Example() {
db, err := sqlite3.Open(memory)
if err != nil {
log.Fatal(err)
}
@@ -45,4 +47,9 @@ func main() {
if err != nil {
log.Fatal(err)
}
// Output:
// 0 go
// 1 zig
// 2 whatever
}

6
vfs.go
View File

@@ -148,7 +148,7 @@ func vfsDelete(ctx context.Context, mod api.Module, pVfs, zPath, syncDir uint32)
return _OK
}
func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath uint32, flags AccessFlag, pResOut uint32) uint32 {
func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath uint32, flags _AccessFlag, pResOut uint32) uint32 {
// Consider using [syscall.Access] for [ACCESS_READWRITE]/[ACCESS_READ]
// (as the Unix VFS does).
@@ -157,7 +157,7 @@ func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath uint32, flags Ac
var res uint32
switch {
case flags == ACCESS_EXISTS:
case flags == _ACCESS_EXISTS:
switch {
case err == nil:
res = 1
@@ -169,7 +169,7 @@ func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath uint32, flags Ac
case err == nil:
var want fs.FileMode = syscall.S_IRUSR
if flags == ACCESS_READWRITE {
if flags == _ACCESS_READWRITE {
want |= syscall.S_IWUSR
}
if fi.IsDir() {

View File

@@ -166,7 +166,7 @@ func Test_vfsAccess(t *testing.T) {
mem := newMemory(128 + _MAX_PATHNAME)
mem.writeString(8, t.TempDir())
rc := vfsAccess(context.TODO(), mem.mod, 0, 8, ACCESS_EXISTS, 4)
rc := vfsAccess(context.TODO(), mem.mod, 0, 8, _ACCESS_EXISTS, 4)
if rc != _OK {
t.Fatal("returned", rc)
}
@@ -174,7 +174,7 @@ func Test_vfsAccess(t *testing.T) {
t.Error("directory did not exist")
}
rc = vfsAccess(context.TODO(), mem.mod, 0, 8, ACCESS_READWRITE, 4)
rc = vfsAccess(context.TODO(), mem.mod, 0, 8, _ACCESS_READWRITE, 4)
if rc != _OK {
t.Fatal("returned", rc)
}