mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Issue #230.
This commit is contained in:
@@ -31,6 +31,7 @@ const (
|
||||
_READONLY _ErrorCode = util.READONLY
|
||||
_IOERR _ErrorCode = util.IOERR
|
||||
_NOTFOUND _ErrorCode = util.NOTFOUND
|
||||
_FULL _ErrorCode = util.FULL
|
||||
_CANTOPEN _ErrorCode = util.CANTOPEN
|
||||
_IOERR_READ _ErrorCode = util.IOERR_READ
|
||||
_IOERR_SHORT_READ _ErrorCode = util.IOERR_SHORT_READ
|
||||
@@ -57,10 +58,12 @@ const (
|
||||
_IOERR_COMMIT_ATOMIC _ErrorCode = util.IOERR_COMMIT_ATOMIC
|
||||
_IOERR_ROLLBACK_ATOMIC _ErrorCode = util.IOERR_ROLLBACK_ATOMIC
|
||||
_IOERR_DATA _ErrorCode = util.IOERR_DATA
|
||||
_IOERR_CORRUPTFS _ErrorCode = util.IOERR_CORRUPTFS
|
||||
_BUSY_SNAPSHOT _ErrorCode = util.BUSY_SNAPSHOT
|
||||
_CANTOPEN_FULLPATH _ErrorCode = util.CANTOPEN_FULLPATH
|
||||
_CANTOPEN_ISDIR _ErrorCode = util.CANTOPEN_ISDIR
|
||||
_READONLY_CANTINIT _ErrorCode = util.READONLY_CANTINIT
|
||||
_READONLY_DIRECTORY _ErrorCode = util.READONLY_DIRECTORY
|
||||
_OK_SYMLINK _ErrorCode = util.OK_SYMLINK
|
||||
)
|
||||
|
||||
|
||||
21
vfs/file.go
21
vfs/file.go
@@ -88,6 +88,9 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
|
||||
oflags |= os.O_RDWR
|
||||
}
|
||||
|
||||
isCreate := flags&(OPEN_CREATE) != 0
|
||||
isJournl := flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0
|
||||
|
||||
var err error
|
||||
var f *os.File
|
||||
if name == nil {
|
||||
@@ -102,6 +105,10 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
|
||||
if errors.Is(err, syscall.EISDIR) {
|
||||
return nil, flags, _CANTOPEN_ISDIR
|
||||
}
|
||||
if isCreate && isJournl && errors.Is(err, fs.ErrPermission) &&
|
||||
osAccess(name.String(), ACCESS_EXISTS) != nil {
|
||||
return nil, flags, _READONLY_DIRECTORY
|
||||
}
|
||||
return nil, flags, err
|
||||
}
|
||||
|
||||
@@ -119,10 +126,8 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
|
||||
File: f,
|
||||
psow: true,
|
||||
readOnly: flags&OPEN_READONLY != 0,
|
||||
syncDir: canSyncDirs &&
|
||||
flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0 &&
|
||||
flags&(OPEN_CREATE) != 0,
|
||||
shm: NewSharedMemory(name.String()+"-shm", flags),
|
||||
syncDir: canSyncDirs && isCreate && isJournl,
|
||||
shm: NewSharedMemory(name.String()+"-shm", flags),
|
||||
}
|
||||
return &file, flags, nil
|
||||
}
|
||||
@@ -154,6 +159,14 @@ func (f *vfsFile) Close() error {
|
||||
return f.File.Close()
|
||||
}
|
||||
|
||||
func (f *vfsFile) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
return osReadAt(f.File, p, off)
|
||||
}
|
||||
|
||||
func (f *vfsFile) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
return osWriteAt(f.File, p, off)
|
||||
}
|
||||
|
||||
func (f *vfsFile) Sync(flags SyncFlag) error {
|
||||
dataonly := (flags & SYNC_DATAONLY) != 0
|
||||
fullsync := (flags & 0x0f) == SYNC_FULL
|
||||
|
||||
13
vfs/os_std_rw.go
Normal file
13
vfs/os_std_rw.go
Normal file
@@ -0,0 +1,13 @@
|
||||
//go:build !unix && (!windows || sqlite3_dotlk)
|
||||
|
||||
package vfs
|
||||
|
||||
import "os"
|
||||
|
||||
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
|
||||
return file.ReadAt(p, off)
|
||||
}
|
||||
|
||||
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
|
||||
return file.WriteAt(p, off)
|
||||
}
|
||||
@@ -25,6 +25,28 @@ func osAccess(path string, flags AccessFlag) error {
|
||||
return unix.Access(path, access)
|
||||
}
|
||||
|
||||
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
|
||||
n, err := file.ReadAt(p, off)
|
||||
if errno, ok := err.(unix.Errno); ok {
|
||||
switch errno {
|
||||
case
|
||||
unix.ERANGE,
|
||||
unix.EIO,
|
||||
unix.ENXIO:
|
||||
return n, _IOERR_CORRUPTFS
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
|
||||
n, err := file.WriteAt(p, off)
|
||||
if errno, ok := err.(unix.Errno); ok && errno == unix.ENOSPC {
|
||||
return n, _FULL
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func osSetMode(file *os.File, modeof string) error {
|
||||
fi, err := os.Stat(modeof)
|
||||
if err != nil {
|
||||
|
||||
@@ -9,6 +9,23 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
|
||||
return file.ReadAt(p, off)
|
||||
}
|
||||
|
||||
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
|
||||
n, err := file.WriteAt(p, off)
|
||||
if errno, ok := err.(windows.Errno); ok {
|
||||
switch errno {
|
||||
case
|
||||
windows.ERROR_HANDLE_DISK_FULL,
|
||||
windows.ERROR_DISK_FULL:
|
||||
return n, _FULL
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func osGetSharedLock(file *os.File) _ErrorCode {
|
||||
// Acquire the PENDING lock temporarily before acquiring a new SHARED lock.
|
||||
rc := osReadLock(file, _PENDING_BYTE, 1, 0)
|
||||
|
||||
Reference in New Issue
Block a user