360 lines
13 KiB
Go
360 lines
13 KiB
Go
// Copyright 2021 Ross Light
|
|
// SPDX-License-Identifier: ISC
|
|
|
|
package sqlite
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"modernc.org/libc"
|
|
lib "modernc.org/sqlite/lib"
|
|
)
|
|
|
|
// ResultCode is an SQLite extended result code.
|
|
type ResultCode int32
|
|
|
|
// Primary result codes.
|
|
const (
|
|
ResultOK ResultCode = lib.SQLITE_OK
|
|
ResultError ResultCode = lib.SQLITE_ERROR
|
|
ResultInternal ResultCode = lib.SQLITE_INTERNAL
|
|
ResultPerm ResultCode = lib.SQLITE_PERM
|
|
ResultAbort ResultCode = lib.SQLITE_ABORT
|
|
ResultBusy ResultCode = lib.SQLITE_BUSY
|
|
ResultLocked ResultCode = lib.SQLITE_LOCKED
|
|
ResultNoMem ResultCode = lib.SQLITE_NOMEM
|
|
ResultReadOnly ResultCode = lib.SQLITE_READONLY
|
|
ResultInterrupt ResultCode = lib.SQLITE_INTERRUPT
|
|
ResultIOErr ResultCode = lib.SQLITE_IOERR
|
|
ResultCorrupt ResultCode = lib.SQLITE_CORRUPT
|
|
ResultNotFound ResultCode = lib.SQLITE_NOTFOUND
|
|
ResultFull ResultCode = lib.SQLITE_FULL
|
|
ResultCantOpen ResultCode = lib.SQLITE_CANTOPEN
|
|
ResultProtocol ResultCode = lib.SQLITE_PROTOCOL
|
|
ResultEmpty ResultCode = lib.SQLITE_EMPTY
|
|
ResultSchema ResultCode = lib.SQLITE_SCHEMA
|
|
ResultTooBig ResultCode = lib.SQLITE_TOOBIG
|
|
ResultConstraint ResultCode = lib.SQLITE_CONSTRAINT
|
|
ResultMismatch ResultCode = lib.SQLITE_MISMATCH
|
|
ResultMisuse ResultCode = lib.SQLITE_MISUSE
|
|
ResultNoLFS ResultCode = lib.SQLITE_NOLFS
|
|
ResultAuth ResultCode = lib.SQLITE_AUTH
|
|
ResultFormat ResultCode = lib.SQLITE_FORMAT
|
|
ResultRange ResultCode = lib.SQLITE_RANGE
|
|
ResultNotADB ResultCode = lib.SQLITE_NOTADB
|
|
ResultNotice ResultCode = lib.SQLITE_NOTICE
|
|
ResultWarning ResultCode = lib.SQLITE_WARNING
|
|
ResultRow ResultCode = lib.SQLITE_ROW
|
|
ResultDone ResultCode = lib.SQLITE_DONE
|
|
)
|
|
|
|
// Extended result codes.
|
|
const (
|
|
ResultErrorMissingCollSeq ResultCode = lib.SQLITE_ERROR_MISSING_COLLSEQ
|
|
ResultErrorRetry ResultCode = lib.SQLITE_ERROR_RETRY
|
|
ResultErrorSnapshot ResultCode = lib.SQLITE_ERROR_SNAPSHOT
|
|
ResultIOErrRead ResultCode = lib.SQLITE_IOERR_READ
|
|
ResultIOErrShortRead ResultCode = lib.SQLITE_IOERR_SHORT_READ
|
|
ResultIOErrWrite ResultCode = lib.SQLITE_IOERR_WRITE
|
|
ResultIOErrFsync ResultCode = lib.SQLITE_IOERR_FSYNC
|
|
ResultIOErrDirFsync ResultCode = lib.SQLITE_IOERR_DIR_FSYNC
|
|
ResultIOErrTruncate ResultCode = lib.SQLITE_IOERR_TRUNCATE
|
|
ResultIOErrFstat ResultCode = lib.SQLITE_IOERR_FSTAT
|
|
ResultIOErrUnlock ResultCode = lib.SQLITE_IOERR_UNLOCK
|
|
ResultIOErrReadLock ResultCode = lib.SQLITE_IOERR_RDLOCK
|
|
ResultIOErrDelete ResultCode = lib.SQLITE_IOERR_DELETE
|
|
ResultIOErrBlocked ResultCode = lib.SQLITE_IOERR_BLOCKED
|
|
ResultIOErrNoMem ResultCode = lib.SQLITE_IOERR_NOMEM
|
|
ResultIOErrAccess ResultCode = lib.SQLITE_IOERR_ACCESS
|
|
ResultIOErrCheckReservedLock ResultCode = lib.SQLITE_IOERR_CHECKRESERVEDLOCK
|
|
ResultIOErrLock ResultCode = lib.SQLITE_IOERR_LOCK
|
|
ResultIOErrClose ResultCode = lib.SQLITE_IOERR_CLOSE
|
|
ResultIOErrDirClose ResultCode = lib.SQLITE_IOERR_DIR_CLOSE
|
|
ResultIOErrSHMOpen ResultCode = lib.SQLITE_IOERR_SHMOPEN
|
|
ResultIOErrSHMSize ResultCode = lib.SQLITE_IOERR_SHMSIZE
|
|
ResultIOErrSHMLock ResultCode = lib.SQLITE_IOERR_SHMLOCK
|
|
ResultIOErrSHMMap ResultCode = lib.SQLITE_IOERR_SHMMAP
|
|
ResultIOErrSeek ResultCode = lib.SQLITE_IOERR_SEEK
|
|
ResultIOErrDeleteNoEnt ResultCode = lib.SQLITE_IOERR_DELETE_NOENT
|
|
ResultIOErrMMap ResultCode = lib.SQLITE_IOERR_MMAP
|
|
ResultIOErrGetTempPath ResultCode = lib.SQLITE_IOERR_GETTEMPPATH
|
|
ResultIOErrConvPath ResultCode = lib.SQLITE_IOERR_CONVPATH
|
|
ResultIOErrVNode ResultCode = lib.SQLITE_IOERR_VNODE
|
|
ResultIOErrAuth ResultCode = lib.SQLITE_IOERR_AUTH
|
|
ResultIOErrBeginAtomic ResultCode = lib.SQLITE_IOERR_BEGIN_ATOMIC
|
|
ResultIOErrCommitAtomic ResultCode = lib.SQLITE_IOERR_COMMIT_ATOMIC
|
|
ResultIOErrRollbackAtomic ResultCode = lib.SQLITE_IOERR_ROLLBACK_ATOMIC
|
|
ResultLockedSharedCache ResultCode = lib.SQLITE_LOCKED_SHAREDCACHE
|
|
ResultBusyRecovery ResultCode = lib.SQLITE_BUSY_RECOVERY
|
|
ResultBusySnapshot ResultCode = lib.SQLITE_BUSY_SNAPSHOT
|
|
ResultCantOpenNoTempDir ResultCode = lib.SQLITE_CANTOPEN_NOTEMPDIR
|
|
ResultCantOpenIsDir ResultCode = lib.SQLITE_CANTOPEN_ISDIR
|
|
ResultCantOpenFullPath ResultCode = lib.SQLITE_CANTOPEN_FULLPATH
|
|
ResultCantOpenConvPath ResultCode = lib.SQLITE_CANTOPEN_CONVPATH
|
|
ResultCorruptVTab ResultCode = lib.SQLITE_CORRUPT_VTAB
|
|
ResultReadOnlyRecovery ResultCode = lib.SQLITE_READONLY_RECOVERY
|
|
ResultReadOnlyCantLock ResultCode = lib.SQLITE_READONLY_CANTLOCK
|
|
ResultReadOnlyRollback ResultCode = lib.SQLITE_READONLY_ROLLBACK
|
|
ResultReadOnlyDBMoved ResultCode = lib.SQLITE_READONLY_DBMOVED
|
|
ResultReadOnlyCantInit ResultCode = lib.SQLITE_READONLY_CANTINIT
|
|
ResultReadOnlyDirectory ResultCode = lib.SQLITE_READONLY_DIRECTORY
|
|
ResultAbortRollback ResultCode = lib.SQLITE_ABORT_ROLLBACK
|
|
ResultConstraintCheck ResultCode = lib.SQLITE_CONSTRAINT_CHECK
|
|
ResultConstraintCommitHook ResultCode = lib.SQLITE_CONSTRAINT_COMMITHOOK
|
|
ResultConstraintForeignKey ResultCode = lib.SQLITE_CONSTRAINT_FOREIGNKEY
|
|
ResultConstraintFunction ResultCode = lib.SQLITE_CONSTRAINT_FUNCTION
|
|
ResultConstraintNotNull ResultCode = lib.SQLITE_CONSTRAINT_NOTNULL
|
|
ResultConstraintPrimaryKey ResultCode = lib.SQLITE_CONSTRAINT_PRIMARYKEY
|
|
ResultConstraintTrigger ResultCode = lib.SQLITE_CONSTRAINT_TRIGGER
|
|
ResultConstraintUnique ResultCode = lib.SQLITE_CONSTRAINT_UNIQUE
|
|
ResultConstraintVTab ResultCode = lib.SQLITE_CONSTRAINT_VTAB
|
|
ResultConstraintRowID ResultCode = lib.SQLITE_CONSTRAINT_ROWID
|
|
ResultNoticeRecoverWAL ResultCode = lib.SQLITE_NOTICE_RECOVER_WAL
|
|
ResultNoticeRecoverRollback ResultCode = lib.SQLITE_NOTICE_RECOVER_ROLLBACK
|
|
ResultWarningAutoIndex ResultCode = lib.SQLITE_WARNING_AUTOINDEX
|
|
ResultAuthUser ResultCode = lib.SQLITE_AUTH_USER
|
|
)
|
|
|
|
// ToPrimary returns the primary result code of the given code.
|
|
// https://sqlite.org/rescode.html#primary_result_codes_versus_extended_result_codes
|
|
func (code ResultCode) ToPrimary() ResultCode {
|
|
return code & 0xff
|
|
}
|
|
|
|
// IsSuccess reports whether code indicates success.
|
|
func (code ResultCode) IsSuccess() bool {
|
|
return code == ResultOK || code == ResultRow || code == ResultDone
|
|
}
|
|
|
|
// String returns the C constant name of the result code.
|
|
func (code ResultCode) String() string {
|
|
switch code {
|
|
case ResultOK:
|
|
return "SQLITE_OK"
|
|
case ResultError:
|
|
return "SQLITE_ERROR"
|
|
case ResultInternal:
|
|
return "SQLITE_INTERNAL"
|
|
case ResultPerm:
|
|
return "SQLITE_PERM"
|
|
case ResultAbort:
|
|
return "SQLITE_ABORT"
|
|
case ResultBusy:
|
|
return "SQLITE_BUSY"
|
|
case ResultLocked:
|
|
return "SQLITE_LOCKED"
|
|
case ResultNoMem:
|
|
return "SQLITE_NOMEM"
|
|
case ResultReadOnly:
|
|
return "SQLITE_READONLY"
|
|
case ResultInterrupt:
|
|
return "SQLITE_INTERRUPT"
|
|
case ResultIOErr:
|
|
return "SQLITE_IOERR"
|
|
case ResultCorrupt:
|
|
return "SQLITE_CORRUPT"
|
|
case ResultNotFound:
|
|
return "SQLITE_NOTFOUND"
|
|
case ResultFull:
|
|
return "SQLITE_FULL"
|
|
case ResultCantOpen:
|
|
return "SQLITE_CANTOPEN"
|
|
case ResultProtocol:
|
|
return "SQLITE_PROTOCOL"
|
|
case ResultEmpty:
|
|
return "SQLITE_EMPTY"
|
|
case ResultSchema:
|
|
return "SQLITE_SCHEMA"
|
|
case ResultTooBig:
|
|
return "SQLITE_TOOBIG"
|
|
case ResultConstraint:
|
|
return "SQLITE_CONSTRAINT"
|
|
case ResultMismatch:
|
|
return "SQLITE_MISMATCH"
|
|
case ResultMisuse:
|
|
return "SQLITE_MISUSE"
|
|
case ResultNoLFS:
|
|
return "SQLITE_NOLFS"
|
|
case ResultAuth:
|
|
return "SQLITE_AUTH"
|
|
case ResultFormat:
|
|
return "SQLITE_FORMAT"
|
|
case ResultRange:
|
|
return "SQLITE_RANGE"
|
|
case ResultNotADB:
|
|
return "SQLITE_NOTADB"
|
|
case ResultNotice:
|
|
return "SQLITE_NOTICE"
|
|
case ResultWarning:
|
|
return "SQLITE_WARNING"
|
|
case ResultRow:
|
|
return "SQLITE_ROW"
|
|
case ResultDone:
|
|
return "SQLITE_DONE"
|
|
|
|
case ResultErrorMissingCollSeq:
|
|
return "SQLITE_ERROR_MISSING_COLLSEQ"
|
|
case ResultErrorRetry:
|
|
return "SQLITE_ERROR_RETRY"
|
|
case ResultErrorSnapshot:
|
|
return "SQLITE_ERROR_SNAPSHOT"
|
|
case ResultIOErrRead:
|
|
return "SQLITE_IOERR_READ"
|
|
case ResultIOErrShortRead:
|
|
return "SQLITE_IOERR_SHORT_READ"
|
|
case ResultIOErrWrite:
|
|
return "SQLITE_IOERR_WRITE"
|
|
case ResultIOErrFsync:
|
|
return "SQLITE_IOERR_FSYNC"
|
|
case ResultIOErrDirFsync:
|
|
return "SQLITE_IOERR_DIR_FSYNC"
|
|
case ResultIOErrTruncate:
|
|
return "SQLITE_IOERR_TRUNCATE"
|
|
case ResultIOErrFstat:
|
|
return "SQLITE_IOERR_FSTAT"
|
|
case ResultIOErrUnlock:
|
|
return "SQLITE_IOERR_UNLOCK"
|
|
case ResultIOErrReadLock:
|
|
return "SQLITE_IOERR_RDLOCK"
|
|
case ResultIOErrDelete:
|
|
return "SQLITE_IOERR_DELETE"
|
|
case ResultIOErrBlocked:
|
|
return "SQLITE_IOERR_BLOCKED"
|
|
case ResultIOErrNoMem:
|
|
return "SQLITE_IOERR_NOMEM"
|
|
case ResultIOErrAccess:
|
|
return "SQLITE_IOERR_ACCESS"
|
|
case ResultIOErrCheckReservedLock:
|
|
return "SQLITE_IOERR_CHECKRESERVEDLOCK"
|
|
case ResultIOErrLock:
|
|
return "SQLITE_IOERR_LOCK"
|
|
case ResultIOErrClose:
|
|
return "SQLITE_IOERR_CLOSE"
|
|
case ResultIOErrDirClose:
|
|
return "SQLITE_IOERR_DIR_CLOSE"
|
|
case ResultIOErrSHMOpen:
|
|
return "SQLITE_IOERR_SHMOPEN"
|
|
case ResultIOErrSHMSize:
|
|
return "SQLITE_IOERR_SHMSIZE"
|
|
case ResultIOErrSHMLock:
|
|
return "SQLITE_IOERR_SHMLOCK"
|
|
case ResultIOErrSHMMap:
|
|
return "SQLITE_IOERR_SHMMAP"
|
|
case ResultIOErrSeek:
|
|
return "SQLITE_IOERR_SEEK"
|
|
case ResultIOErrDeleteNoEnt:
|
|
return "SQLITE_IOERR_DELETE_NOENT"
|
|
case ResultIOErrMMap:
|
|
return "SQLITE_IOERR_MMAP"
|
|
case ResultIOErrGetTempPath:
|
|
return "SQLITE_IOERR_GETTEMPPATH"
|
|
case ResultIOErrConvPath:
|
|
return "SQLITE_IOERR_CONVPATH"
|
|
case ResultIOErrVNode:
|
|
return "SQLITE_IOERR_VNODE"
|
|
case ResultIOErrAuth:
|
|
return "SQLITE_IOERR_AUTH"
|
|
case ResultIOErrBeginAtomic:
|
|
return "SQLITE_IOERR_BEGIN_ATOMIC"
|
|
case ResultIOErrCommitAtomic:
|
|
return "SQLITE_IOERR_COMMIT_ATOMIC"
|
|
case ResultIOErrRollbackAtomic:
|
|
return "SQLITE_IOERR_ROLLBACK_ATOMIC"
|
|
case ResultLockedSharedCache:
|
|
return "SQLITE_LOCKED_SHAREDCACHE"
|
|
case ResultBusyRecovery:
|
|
return "SQLITE_BUSY_RECOVERY"
|
|
case ResultBusySnapshot:
|
|
return "SQLITE_BUSY_SNAPSHOT"
|
|
case ResultCantOpenNoTempDir:
|
|
return "SQLITE_CANTOPEN_NOTEMPDIR"
|
|
case ResultCantOpenIsDir:
|
|
return "SQLITE_CANTOPEN_ISDIR"
|
|
case ResultCantOpenFullPath:
|
|
return "SQLITE_CANTOPEN_FULLPATH"
|
|
case ResultCantOpenConvPath:
|
|
return "SQLITE_CANTOPEN_CONVPATH"
|
|
case ResultCorruptVTab:
|
|
return "SQLITE_CORRUPT_VTAB"
|
|
case ResultReadOnlyRecovery:
|
|
return "SQLITE_READONLY_RECOVERY"
|
|
case ResultReadOnlyCantLock:
|
|
return "SQLITE_READONLY_CANTLOCK"
|
|
case ResultReadOnlyRollback:
|
|
return "SQLITE_READONLY_ROLLBACK"
|
|
case ResultReadOnlyDBMoved:
|
|
return "SQLITE_READONLY_DBMOVED"
|
|
case ResultReadOnlyCantInit:
|
|
return "SQLITE_READONLY_CANTINIT"
|
|
case ResultReadOnlyDirectory:
|
|
return "SQLITE_READONLY_DIRECTORY"
|
|
case ResultAbortRollback:
|
|
return "SQLITE_ABORT_ROLLBACK"
|
|
case ResultConstraintCheck:
|
|
return "SQLITE_CONSTRAINT_CHECK"
|
|
case ResultConstraintCommitHook:
|
|
return "SQLITE_CONSTRAINT_COMMITHOOK"
|
|
case ResultConstraintForeignKey:
|
|
return "SQLITE_CONSTRAINT_FOREIGNKEY"
|
|
case ResultConstraintFunction:
|
|
return "SQLITE_CONSTRAINT_FUNCTION"
|
|
case ResultConstraintNotNull:
|
|
return "SQLITE_CONSTRAINT_NOTNULL"
|
|
case ResultConstraintPrimaryKey:
|
|
return "SQLITE_CONSTRAINT_PRIMARYKEY"
|
|
case ResultConstraintTrigger:
|
|
return "SQLITE_CONSTRAINT_TRIGGER"
|
|
case ResultConstraintUnique:
|
|
return "SQLITE_CONSTRAINT_UNIQUE"
|
|
case ResultConstraintVTab:
|
|
return "SQLITE_CONSTRAINT_VTAB"
|
|
case ResultConstraintRowID:
|
|
return "SQLITE_CONSTRAINT_ROWID"
|
|
case ResultNoticeRecoverWAL:
|
|
return "SQLITE_NOTICE_RECOVER_WAL"
|
|
case ResultNoticeRecoverRollback:
|
|
return "SQLITE_NOTICE_RECOVER_ROLLBACK"
|
|
case ResultWarningAutoIndex:
|
|
return "SQLITE_WARNING_AUTOINDEX"
|
|
case ResultAuthUser:
|
|
return "SQLITE_AUTH_USER"
|
|
default:
|
|
return fmt.Sprintf("ResultCode(%d)", int32(code))
|
|
}
|
|
}
|
|
|
|
// Message returns the English-language text that describes the result code.
|
|
func (code ResultCode) Message() string {
|
|
cstr := lib.Xsqlite3_errstr(nil, int32(code))
|
|
return libc.GoString(cstr)
|
|
}
|
|
|
|
type sqliteError struct {
|
|
code ResultCode
|
|
}
|
|
|
|
func reserr(res ResultCode) error {
|
|
if res.IsSuccess() {
|
|
return nil
|
|
}
|
|
return sqliteError{res}
|
|
}
|
|
|
|
func (e sqliteError) Error() string {
|
|
return e.code.Message()
|
|
}
|
|
|
|
// ErrCode returns the error's SQLite error code or ResultError if the error
|
|
// does not represent a SQLite error. ErrorCode returns ResultOK if and only if
|
|
// the error is nil.
|
|
func ErrCode(err error) ResultCode {
|
|
if err == nil {
|
|
return ResultOK
|
|
}
|
|
if e := new(sqliteError); errors.As(err, e) {
|
|
return e.code
|
|
}
|
|
return ResultError
|
|
}
|