From 746b16216bf6fa75cb7e56610c7d4bf775bc2095 Mon Sep 17 00:00:00 2001 From: Daniel Erat Date: Wed, 20 Jul 2011 00:43:21 +0000 Subject: [PATCH] sqlite: implement write. simple test passes now! Change-Id: I260c71bdf4fcf6c35cb9caf73f430a31cdeebb78 --- misc/sqlite/sqlite3_os_go.c | 3 +-- misc/sqlite/vfs.go | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/misc/sqlite/sqlite3_os_go.c b/misc/sqlite/sqlite3_os_go.c index 2119c4192..c927074bb 100644 --- a/misc/sqlite/sqlite3_os_go.c +++ b/misc/sqlite/sqlite3_os_go.c @@ -28,8 +28,7 @@ static int go_file_read(sqlite3_file* file, void* dest, int iAmt, sqlite3_int64 } static int go_file_write(sqlite3_file* file, const void* src, int iAmt, sqlite3_int64 iOfst) { - fprintf(stderr, "write\n"); - return 0; + return GoFileWrite(((GoFile*) file)->fd, src, iAmt, iOfst); } static int go_file_truncate(sqlite3_file* file, sqlite3_int64 size) { diff --git a/misc/sqlite/vfs.go b/misc/sqlite/vfs.go index 66705a68a..96c5dff00 100644 --- a/misc/sqlite/vfs.go +++ b/misc/sqlite/vfs.go @@ -34,7 +34,7 @@ func GoFileClose(fd C.int) (int) { } //export GoFileRead -// Returns SQLite error codes to be returned by xRead: +// Returns SQLite error code to be returned by xRead: // SQLITE_OK: read n bytes // SQLITE_IOERR_READ: got error while reading // SQLITE_IOERR_SHORT_READ: read fewer than n bytes; rest will be zeroed @@ -71,6 +71,40 @@ func GoFileRead(fd C.int, dst *C.char, n C.int, offset C.long) (rv int) { return C.SQLITE_OK } +//export GoFileWrite +// Returns SQLite error code to be returned by xWrite: +// SQLITE_OK: wrote n bytes +// SQLITE_IOERR_WRITE: got error while writing +// SQLITE_FULL: partial write +func GoFileWrite(fd C.int, src *C.char, n C.int, offset C.long) (rv int) { + println("writing", n, "bytes at offset", offset, "to fd", fd); + defer func() { + println("write returning", rv); + }() + + file := GetFile(int(fd)) + if file == nil { + return C.SQLITE_IOERR_WRITE + } + + // TODO: avoid this copy + buf := make([]byte, n) + C.memcpy(unsafe.Pointer(&buf[0]), unsafe.Pointer(src), C.size_t(len(buf))) + + nwritten, err := file.WriteAt(buf, int64(offset)) + if err != nil { + if err == os.ENOSPC { + return C.SQLITE_FULL + } + return C.SQLITE_IOERR_WRITE + } + if nwritten != int(n) { + return C.SQLITE_IOERR_WRITE + } + + return C.SQLITE_OK +} + //export GoFileFileSize // return[0]: 0 on success and -1 on error. // return[1]: size