mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Time collation tests.
This commit is contained in:
17
README.md
17
README.md
@@ -18,6 +18,10 @@ embeds a build of SQLite into your application.
|
||||
|
||||
### Caveats
|
||||
|
||||
This module replaces the SQLite [OS Interface](https://www.sqlite.org/vfs.html) (aka VFS)
|
||||
with a pure Go implementation.
|
||||
This has numerous benefits, but also comes with some caveats.
|
||||
|
||||
#### Write-Ahead Logging
|
||||
|
||||
Because WASM does not support shared memory,
|
||||
@@ -45,15 +49,14 @@ OFD locks are fully compatible with process-associated POSIX advisory locks,
|
||||
and are supported on Linux, macOS and illumos.
|
||||
As a work around for other Unixes, you can use [`nolock=1`](https://www.sqlite.org/uri.html).
|
||||
|
||||
#### Testing
|
||||
|
||||
The pure Go VFS is stress tested by running an unmodified build of SQLite's
|
||||
[mptest](https://github.com/sqlite/sqlite/blob/master/mptest/mptest.c)
|
||||
on Linux, macOS and Windows.
|
||||
|
||||
### Roadmap
|
||||
|
||||
- [x] build SQLite using `zig cc --target=wasm32-wasi`
|
||||
- [x] `:memory:` databases
|
||||
- [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 nice API, enough for simple use cases
|
||||
- [x] provide a simple `database/sql` driver
|
||||
- [x] file locking, compatible with SQLite on macOS/Linux/Windows
|
||||
- [ ] advanced SQLite features
|
||||
- [x] nested transactions
|
||||
- [x] incremental BLOB I/O
|
||||
|
||||
2
conn.go
2
conn.go
@@ -99,6 +99,8 @@ func (c *Conn) openDB(filename string, flags OpenFlag) (uint32, error) {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
c.call(c.api.timeCollation, uint64(handle))
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -46,4 +46,5 @@ sqlite3_backup_step
|
||||
sqlite3_backup_finish
|
||||
sqlite3_backup_remaining
|
||||
sqlite3_backup_pagecount
|
||||
sqlite3_time_collation
|
||||
sqlite3_interrupt_offset
|
||||
Binary file not shown.
@@ -155,6 +155,7 @@ func newModule(mod api.Module) (m *module, err error) {
|
||||
backupFinish: getFun("sqlite3_backup_finish"),
|
||||
backupRemaining: getFun("sqlite3_backup_remaining"),
|
||||
backupPageCount: getFun("sqlite3_backup_pagecount"),
|
||||
timeCollation: getFun("sqlite3_time_collation"),
|
||||
interrupt: getVal("sqlite3_interrupt_offset"),
|
||||
}
|
||||
if err != nil {
|
||||
@@ -348,5 +349,6 @@ type sqliteAPI struct {
|
||||
backupFinish api.Function
|
||||
backupRemaining api.Function
|
||||
backupPageCount api.Function
|
||||
timeCollation api.Function
|
||||
interrupt uint32
|
||||
}
|
||||
|
||||
@@ -24,6 +24,5 @@ static int time_collation(void *pArg, int nKey1, const void *pKey1, int nKey2,
|
||||
}
|
||||
|
||||
int sqlite3_time_collation(sqlite3 *db) {
|
||||
return sqlite3_create_collation_v2(db, "TIME", SQLITE_UTF8, 0, time_collation,
|
||||
0);
|
||||
return sqlite3_create_collation(db, "TIME", SQLITE_UTF8, 0, time_collation);
|
||||
}
|
||||
@@ -118,3 +118,52 @@ func TestTimeFormat_Decode(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDB_timeCollation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, err := sqlite3.Open(":memory:")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
err = db.Exec(`CREATE TABLE IF NOT EXISTS times (tstamp COLLATE TIME)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stmt, _, err := db.Prepare(`INSERT INTO times VALUES (?), (?), (?)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
stmt.BindTime(1, time.Unix(0, 0).UTC(), sqlite3.TimeFormatDefault)
|
||||
stmt.BindTime(2, time.Unix(0, -1).UTC(), sqlite3.TimeFormatDefault)
|
||||
stmt.BindTime(3, time.Unix(0, +1).UTC(), sqlite3.TimeFormatDefault)
|
||||
stmt.Step()
|
||||
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stmt, _, err = db.Prepare(`SELECT tstamp FROM times ORDER BY tstamp`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var t0 time.Time
|
||||
for stmt.Step() {
|
||||
t1 := stmt.ColumnTime(0, sqlite3.TimeFormatAuto)
|
||||
if t0.After(t1) {
|
||||
t.Errorf("got %v after %v", t0, t1)
|
||||
}
|
||||
t0 = t1
|
||||
}
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user