distribution/vendor/github.com/go-llsqlite/crawshaw/error.go

395 lines
14 KiB
Go

// Copyright (c) 2018 David Crawshaw <david@zentus.com>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package sqlite
// #include <sqlite3.h>
import "C"
import "errors"
// Error is an error produced by SQLite.
type Error struct {
Code ErrorCode // SQLite extended error code (SQLITE_OK is an invalid value)
Loc string // method name that generated the error
Query string // original SQL query text
Msg string // value of sqlite3_errmsg, set sqlite.ErrMsg = true
}
func (err Error) Error() string {
str := "sqlite"
if err.Loc != "" {
str += "." + err.Loc
}
str += ": " + err.Code.String()
if err.Msg != "" {
str += ": " + err.Msg
}
if err.Query != "" {
str += " (" + err.Query + ")"
}
return str
}
// ErrorCode is an SQLite extended error code.
//
// The three SQLite result codes (SQLITE_OK, SQLITE_ROW, and SQLITE_DONE),
// are not errors so they should not be used in an Error.
type ErrorCode int
func (code ErrorCode) ToError() error {
return Error{Code: code}
}
func (code ErrorCode) String() string {
switch code {
default:
var buf [20]byte
return "SQLITE_UNKNOWN_ERR(" + string(itoa(buf[:], int64(code))) + ")"
case SQLITE_OK:
return "SQLITE_OK(not an error)"
case SQLITE_ROW:
return "SQLITE_ROW(not an error)"
case SQLITE_DONE:
return "SQLITE_DONE(not an error)"
case SQLITE_ERROR:
return "SQLITE_ERROR"
case SQLITE_INTERNAL:
return "SQLITE_INTERNAL"
case SQLITE_PERM:
return "SQLITE_PERM"
case SQLITE_ABORT:
return "SQLITE_ABORT"
case SQLITE_BUSY:
return "SQLITE_BUSY"
case SQLITE_LOCKED:
return "SQLITE_LOCKED"
case SQLITE_NOMEM:
return "SQLITE_NOMEM"
case SQLITE_READONLY:
return "SQLITE_READONLY"
case SQLITE_INTERRUPT:
return "SQLITE_INTERRUPT"
case SQLITE_IOERR:
return "SQLITE_IOERR"
case SQLITE_CORRUPT:
return "SQLITE_CORRUPT"
case SQLITE_NOTFOUND:
return "SQLITE_NOTFOUND"
case SQLITE_FULL:
return "SQLITE_FULL"
case SQLITE_CANTOPEN:
return "SQLITE_CANTOPEN"
case SQLITE_PROTOCOL:
return "SQLITE_PROTOCOL"
case SQLITE_EMPTY:
return "SQLITE_EMPTY"
case SQLITE_SCHEMA:
return "SQLITE_SCHEMA"
case SQLITE_TOOBIG:
return "SQLITE_TOOBIG"
case SQLITE_CONSTRAINT:
return "SQLITE_CONSTRAINT"
case SQLITE_MISMATCH:
return "SQLITE_MISMATCH"
case SQLITE_MISUSE:
return "SQLITE_MISUSE"
case SQLITE_NOLFS:
return "SQLITE_NOLFS"
case SQLITE_AUTH:
return "SQLITE_AUTH"
case SQLITE_FORMAT:
return "SQLITE_FORMAT"
case SQLITE_RANGE:
return "SQLITE_RANGE"
case SQLITE_NOTADB:
return "SQLITE_NOTADB"
case SQLITE_NOTICE:
return "SQLITE_NOTICE"
case SQLITE_WARNING:
return "SQLITE_WARNING"
case SQLITE_ERROR_MISSING_COLLSEQ:
return "SQLITE_ERROR_MISSING_COLLSEQ"
case SQLITE_ERROR_RETRY:
return "SQLITE_ERROR_RETRY"
case SQLITE_ERROR_SNAPSHOT:
return "SQLITE_ERROR_SNAPSHOT"
case SQLITE_IOERR_READ:
return "SQLITE_IOERR_READ"
case SQLITE_IOERR_SHORT_READ:
return "SQLITE_IOERR_SHORT_READ"
case SQLITE_IOERR_WRITE:
return "SQLITE_IOERR_WRITE"
case SQLITE_IOERR_FSYNC:
return "SQLITE_IOERR_FSYNC"
case SQLITE_IOERR_DIR_FSYNC:
return "SQLITE_IOERR_DIR_FSYNC"
case SQLITE_IOERR_TRUNCATE:
return "SQLITE_IOERR_TRUNCATE"
case SQLITE_IOERR_FSTAT:
return "SQLITE_IOERR_FSTAT"
case SQLITE_IOERR_UNLOCK:
return "SQLITE_IOERR_UNLOCK"
case SQLITE_IOERR_RDLOCK:
return "SQLITE_IOERR_RDLOCK"
case SQLITE_IOERR_DELETE:
return "SQLITE_IOERR_DELETE"
case SQLITE_IOERR_BLOCKED:
return "SQLITE_IOERR_BLOCKED"
case SQLITE_IOERR_NOMEM:
return "SQLITE_IOERR_NOMEM"
case SQLITE_IOERR_ACCESS:
return "SQLITE_IOERR_ACCESS"
case SQLITE_IOERR_CHECKRESERVEDLOCK:
return "SQLITE_IOERR_CHECKRESERVEDLOCK"
case SQLITE_IOERR_LOCK:
return "SQLITE_IOERR_LOCK"
case SQLITE_IOERR_CLOSE:
return "SQLITE_IOERR_CLOSE"
case SQLITE_IOERR_DIR_CLOSE:
return "SQLITE_IOERR_DIR_CLOSE"
case SQLITE_IOERR_SHMOPEN:
return "SQLITE_IOERR_SHMOPEN"
case SQLITE_IOERR_SHMSIZE:
return "SQLITE_IOERR_SHMSIZE"
case SQLITE_IOERR_SHMLOCK:
return "SQLITE_IOERR_SHMLOCK"
case SQLITE_IOERR_SHMMAP:
return "SQLITE_IOERR_SHMMAP"
case SQLITE_IOERR_SEEK:
return "SQLITE_IOERR_SEEK"
case SQLITE_IOERR_DELETE_NOENT:
return "SQLITE_IOERR_DELETE_NOENT"
case SQLITE_IOERR_MMAP:
return "SQLITE_IOERR_MMAP"
case SQLITE_IOERR_GETTEMPPATH:
return "SQLITE_IOERR_GETTEMPPATH"
case SQLITE_IOERR_CONVPATH:
return "SQLITE_IOERR_CONVPATH"
case SQLITE_IOERR_VNODE:
return "SQLITE_IOERR_VNODE"
case SQLITE_IOERR_AUTH:
return "SQLITE_IOERR_AUTH"
case SQLITE_IOERR_BEGIN_ATOMIC:
return "SQLITE_IOERR_BEGIN_ATOMIC"
case SQLITE_IOERR_COMMIT_ATOMIC:
return "SQLITE_IOERR_COMMIT_ATOMIC"
case SQLITE_IOERR_ROLLBACK_ATOMIC:
return "SQLITE_IOERR_ROLLBACK_ATOMIC"
case SQLITE_LOCKED_SHAREDCACHE:
return "SQLITE_LOCKED_SHAREDCACHE"
case SQLITE_BUSY_RECOVERY:
return "SQLITE_BUSY_RECOVERY"
case SQLITE_BUSY_SNAPSHOT:
return "SQLITE_BUSY_SNAPSHOT"
case SQLITE_CANTOPEN_NOTEMPDIR:
return "SQLITE_CANTOPEN_NOTEMPDIR"
case SQLITE_CANTOPEN_ISDIR:
return "SQLITE_CANTOPEN_ISDIR"
case SQLITE_CANTOPEN_FULLPATH:
return "SQLITE_CANTOPEN_FULLPATH"
case SQLITE_CANTOPEN_CONVPATH:
return "SQLITE_CANTOPEN_CONVPATH"
case SQLITE_CORRUPT_VTAB:
return "SQLITE_CORRUPT_VTAB"
case SQLITE_READONLY_RECOVERY:
return "SQLITE_READONLY_RECOVERY"
case SQLITE_READONLY_CANTLOCK:
return "SQLITE_READONLY_CANTLOCK"
case SQLITE_READONLY_ROLLBACK:
return "SQLITE_READONLY_ROLLBACK"
case SQLITE_READONLY_DBMOVED:
return "SQLITE_READONLY_DBMOVED"
case SQLITE_READONLY_CANTINIT:
return "SQLITE_READONLY_CANTINIT"
case SQLITE_READONLY_DIRECTORY:
return "SQLITE_READONLY_DIRECTORY"
case SQLITE_ABORT_ROLLBACK:
return "SQLITE_ABORT_ROLLBACK"
case SQLITE_CONSTRAINT_CHECK:
return "SQLITE_CONSTRAINT_CHECK"
case SQLITE_CONSTRAINT_COMMITHOOK:
return "SQLITE_CONSTRAINT_COMMITHOOK"
case SQLITE_CONSTRAINT_FOREIGNKEY:
return "SQLITE_CONSTRAINT_FOREIGNKEY"
case SQLITE_CONSTRAINT_FUNCTION:
return "SQLITE_CONSTRAINT_FUNCTION"
case SQLITE_CONSTRAINT_NOTNULL:
return "SQLITE_CONSTRAINT_NOTNULL"
case SQLITE_CONSTRAINT_PRIMARYKEY:
return "SQLITE_CONSTRAINT_PRIMARYKEY"
case SQLITE_CONSTRAINT_TRIGGER:
return "SQLITE_CONSTRAINT_TRIGGER"
case SQLITE_CONSTRAINT_UNIQUE:
return "SQLITE_CONSTRAINT_UNIQUE"
case SQLITE_CONSTRAINT_VTAB:
return "SQLITE_CONSTRAINT_VTAB"
case SQLITE_CONSTRAINT_ROWID:
return "SQLITE_CONSTRAINT_ROWID"
case SQLITE_NOTICE_RECOVER_WAL:
return "SQLITE_NOTICE_RECOVER_WAL"
case SQLITE_NOTICE_RECOVER_ROLLBACK:
return "SQLITE_NOTICE_RECOVER_ROLLBACK"
case SQLITE_WARNING_AUTOINDEX:
return "SQLITE_WARNING_AUTOINDEX"
case SQLITE_AUTH_USER:
return "SQLITE_AUTH_USER"
}
}
const (
SQLITE_OK = ErrorCode(C.SQLITE_OK) // do not use in Error
SQLITE_ERROR = ErrorCode(C.SQLITE_ERROR)
SQLITE_INTERNAL = ErrorCode(C.SQLITE_INTERNAL)
SQLITE_PERM = ErrorCode(C.SQLITE_PERM)
SQLITE_ABORT = ErrorCode(C.SQLITE_ABORT)
SQLITE_BUSY = ErrorCode(C.SQLITE_BUSY)
SQLITE_LOCKED = ErrorCode(C.SQLITE_LOCKED)
SQLITE_NOMEM = ErrorCode(C.SQLITE_NOMEM)
SQLITE_READONLY = ErrorCode(C.SQLITE_READONLY)
SQLITE_INTERRUPT = ErrorCode(C.SQLITE_INTERRUPT)
SQLITE_IOERR = ErrorCode(C.SQLITE_IOERR)
SQLITE_CORRUPT = ErrorCode(C.SQLITE_CORRUPT)
SQLITE_NOTFOUND = ErrorCode(C.SQLITE_NOTFOUND)
SQLITE_FULL = ErrorCode(C.SQLITE_FULL)
SQLITE_CANTOPEN = ErrorCode(C.SQLITE_CANTOPEN)
SQLITE_PROTOCOL = ErrorCode(C.SQLITE_PROTOCOL)
SQLITE_EMPTY = ErrorCode(C.SQLITE_EMPTY)
SQLITE_SCHEMA = ErrorCode(C.SQLITE_SCHEMA)
SQLITE_TOOBIG = ErrorCode(C.SQLITE_TOOBIG)
SQLITE_CONSTRAINT = ErrorCode(C.SQLITE_CONSTRAINT)
SQLITE_MISMATCH = ErrorCode(C.SQLITE_MISMATCH)
SQLITE_MISUSE = ErrorCode(C.SQLITE_MISUSE)
SQLITE_NOLFS = ErrorCode(C.SQLITE_NOLFS)
SQLITE_AUTH = ErrorCode(C.SQLITE_AUTH)
SQLITE_FORMAT = ErrorCode(C.SQLITE_FORMAT)
SQLITE_RANGE = ErrorCode(C.SQLITE_RANGE)
SQLITE_NOTADB = ErrorCode(C.SQLITE_NOTADB)
SQLITE_NOTICE = ErrorCode(C.SQLITE_NOTICE)
SQLITE_WARNING = ErrorCode(C.SQLITE_WARNING)
SQLITE_ROW = ErrorCode(C.SQLITE_ROW) // do not use in Error
SQLITE_DONE = ErrorCode(C.SQLITE_DONE) // do not use in Error
SQLITE_ERROR_MISSING_COLLSEQ = ErrorCode(C.SQLITE_ERROR_MISSING_COLLSEQ)
SQLITE_ERROR_RETRY = ErrorCode(C.SQLITE_ERROR_RETRY)
SQLITE_ERROR_SNAPSHOT = ErrorCode(C.SQLITE_ERROR_SNAPSHOT)
SQLITE_IOERR_READ = ErrorCode(C.SQLITE_IOERR_READ)
SQLITE_IOERR_SHORT_READ = ErrorCode(C.SQLITE_IOERR_SHORT_READ)
SQLITE_IOERR_WRITE = ErrorCode(C.SQLITE_IOERR_WRITE)
SQLITE_IOERR_FSYNC = ErrorCode(C.SQLITE_IOERR_FSYNC)
SQLITE_IOERR_DIR_FSYNC = ErrorCode(C.SQLITE_IOERR_DIR_FSYNC)
SQLITE_IOERR_TRUNCATE = ErrorCode(C.SQLITE_IOERR_TRUNCATE)
SQLITE_IOERR_FSTAT = ErrorCode(C.SQLITE_IOERR_FSTAT)
SQLITE_IOERR_UNLOCK = ErrorCode(C.SQLITE_IOERR_UNLOCK)
SQLITE_IOERR_RDLOCK = ErrorCode(C.SQLITE_IOERR_RDLOCK)
SQLITE_IOERR_DELETE = ErrorCode(C.SQLITE_IOERR_DELETE)
SQLITE_IOERR_BLOCKED = ErrorCode(C.SQLITE_IOERR_BLOCKED)
SQLITE_IOERR_NOMEM = ErrorCode(C.SQLITE_IOERR_NOMEM)
SQLITE_IOERR_ACCESS = ErrorCode(C.SQLITE_IOERR_ACCESS)
SQLITE_IOERR_CHECKRESERVEDLOCK = ErrorCode(C.SQLITE_IOERR_CHECKRESERVEDLOCK)
SQLITE_IOERR_LOCK = ErrorCode(C.SQLITE_IOERR_LOCK)
SQLITE_IOERR_CLOSE = ErrorCode(C.SQLITE_IOERR_CLOSE)
SQLITE_IOERR_DIR_CLOSE = ErrorCode(C.SQLITE_IOERR_DIR_CLOSE)
SQLITE_IOERR_SHMOPEN = ErrorCode(C.SQLITE_IOERR_SHMOPEN)
SQLITE_IOERR_SHMSIZE = ErrorCode(C.SQLITE_IOERR_SHMSIZE)
SQLITE_IOERR_SHMLOCK = ErrorCode(C.SQLITE_IOERR_SHMLOCK)
SQLITE_IOERR_SHMMAP = ErrorCode(C.SQLITE_IOERR_SHMMAP)
SQLITE_IOERR_SEEK = ErrorCode(C.SQLITE_IOERR_SEEK)
SQLITE_IOERR_DELETE_NOENT = ErrorCode(C.SQLITE_IOERR_DELETE_NOENT)
SQLITE_IOERR_MMAP = ErrorCode(C.SQLITE_IOERR_MMAP)
SQLITE_IOERR_GETTEMPPATH = ErrorCode(C.SQLITE_IOERR_GETTEMPPATH)
SQLITE_IOERR_CONVPATH = ErrorCode(C.SQLITE_IOERR_CONVPATH)
SQLITE_IOERR_VNODE = ErrorCode(C.SQLITE_IOERR_VNODE)
SQLITE_IOERR_AUTH = ErrorCode(C.SQLITE_IOERR_AUTH)
SQLITE_IOERR_BEGIN_ATOMIC = ErrorCode(C.SQLITE_IOERR_BEGIN_ATOMIC)
SQLITE_IOERR_COMMIT_ATOMIC = ErrorCode(C.SQLITE_IOERR_COMMIT_ATOMIC)
SQLITE_IOERR_ROLLBACK_ATOMIC = ErrorCode(C.SQLITE_IOERR_ROLLBACK_ATOMIC)
SQLITE_LOCKED_SHAREDCACHE = ErrorCode(C.SQLITE_LOCKED_SHAREDCACHE)
SQLITE_BUSY_RECOVERY = ErrorCode(C.SQLITE_BUSY_RECOVERY)
SQLITE_BUSY_SNAPSHOT = ErrorCode(C.SQLITE_BUSY_SNAPSHOT)
SQLITE_CANTOPEN_NOTEMPDIR = ErrorCode(C.SQLITE_CANTOPEN_NOTEMPDIR)
SQLITE_CANTOPEN_ISDIR = ErrorCode(C.SQLITE_CANTOPEN_ISDIR)
SQLITE_CANTOPEN_FULLPATH = ErrorCode(C.SQLITE_CANTOPEN_FULLPATH)
SQLITE_CANTOPEN_CONVPATH = ErrorCode(C.SQLITE_CANTOPEN_CONVPATH)
SQLITE_CORRUPT_VTAB = ErrorCode(C.SQLITE_CORRUPT_VTAB)
SQLITE_READONLY_RECOVERY = ErrorCode(C.SQLITE_READONLY_RECOVERY)
SQLITE_READONLY_CANTLOCK = ErrorCode(C.SQLITE_READONLY_CANTLOCK)
SQLITE_READONLY_ROLLBACK = ErrorCode(C.SQLITE_READONLY_ROLLBACK)
SQLITE_READONLY_DBMOVED = ErrorCode(C.SQLITE_READONLY_DBMOVED)
SQLITE_READONLY_CANTINIT = ErrorCode(C.SQLITE_READONLY_CANTINIT)
SQLITE_READONLY_DIRECTORY = ErrorCode(C.SQLITE_READONLY_DIRECTORY)
SQLITE_ABORT_ROLLBACK = ErrorCode(C.SQLITE_ABORT_ROLLBACK)
SQLITE_CONSTRAINT_CHECK = ErrorCode(C.SQLITE_CONSTRAINT_CHECK)
SQLITE_CONSTRAINT_COMMITHOOK = ErrorCode(C.SQLITE_CONSTRAINT_COMMITHOOK)
SQLITE_CONSTRAINT_FOREIGNKEY = ErrorCode(C.SQLITE_CONSTRAINT_FOREIGNKEY)
SQLITE_CONSTRAINT_FUNCTION = ErrorCode(C.SQLITE_CONSTRAINT_FUNCTION)
SQLITE_CONSTRAINT_NOTNULL = ErrorCode(C.SQLITE_CONSTRAINT_NOTNULL)
SQLITE_CONSTRAINT_PRIMARYKEY = ErrorCode(C.SQLITE_CONSTRAINT_PRIMARYKEY)
SQLITE_CONSTRAINT_TRIGGER = ErrorCode(C.SQLITE_CONSTRAINT_TRIGGER)
SQLITE_CONSTRAINT_UNIQUE = ErrorCode(C.SQLITE_CONSTRAINT_UNIQUE)
SQLITE_CONSTRAINT_VTAB = ErrorCode(C.SQLITE_CONSTRAINT_VTAB)
SQLITE_CONSTRAINT_ROWID = ErrorCode(C.SQLITE_CONSTRAINT_ROWID)
SQLITE_NOTICE_RECOVER_WAL = ErrorCode(C.SQLITE_NOTICE_RECOVER_WAL)
SQLITE_NOTICE_RECOVER_ROLLBACK = ErrorCode(C.SQLITE_NOTICE_RECOVER_ROLLBACK)
SQLITE_WARNING_AUTOINDEX = ErrorCode(C.SQLITE_WARNING_AUTOINDEX)
SQLITE_AUTH_USER = ErrorCode(C.SQLITE_AUTH_USER)
)
type causer interface {
Cause() error
}
// ErrCode extracts the SQLite error code from err.
// If err is not a sqlite Error, SQLITE_ERROR is returned.
// If err is nil, SQLITE_OK is returned.
//
// This function supports wrapped errors that implement
//
// interface { Cause() error }
//
// for errors from packages like https://github.com/pkg/errors
func ErrCode(err error) ErrorCode {
var sqliteError Error
if errors.As(err, &sqliteError) {
return sqliteError.Code
}
if err != nil {
if ce, ok := err.(causer); ok {
return ErrCode(ce.Cause())
}
return SQLITE_ERROR
}
return SQLITE_OK
}
func itoa(buf []byte, val int64) []byte {
i := len(buf) - 1
neg := false
if val < 0 {
neg = true
val = 0 - val
}
for val >= 10 {
buf[i] = byte(val%10 + '0')
i--
val /= 10
}
buf[i] = byte(val + '0')
if neg {
i--
buf[i] = '-'
}
return buf[i:]
}