result.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. // Copyright 2021 Ross Light
  2. // SPDX-License-Identifier: ISC
  3. package sqlite
  4. import (
  5. "errors"
  6. "fmt"
  7. "modernc.org/libc"
  8. lib "modernc.org/sqlite/lib"
  9. )
  10. // ResultCode is an SQLite extended result code.
  11. type ResultCode int32
  12. // Primary result codes.
  13. const (
  14. ResultOK ResultCode = lib.SQLITE_OK
  15. ResultError ResultCode = lib.SQLITE_ERROR
  16. ResultInternal ResultCode = lib.SQLITE_INTERNAL
  17. ResultPerm ResultCode = lib.SQLITE_PERM
  18. ResultAbort ResultCode = lib.SQLITE_ABORT
  19. ResultBusy ResultCode = lib.SQLITE_BUSY
  20. ResultLocked ResultCode = lib.SQLITE_LOCKED
  21. ResultNoMem ResultCode = lib.SQLITE_NOMEM
  22. ResultReadOnly ResultCode = lib.SQLITE_READONLY
  23. ResultInterrupt ResultCode = lib.SQLITE_INTERRUPT
  24. ResultIOErr ResultCode = lib.SQLITE_IOERR
  25. ResultCorrupt ResultCode = lib.SQLITE_CORRUPT
  26. ResultNotFound ResultCode = lib.SQLITE_NOTFOUND
  27. ResultFull ResultCode = lib.SQLITE_FULL
  28. ResultCantOpen ResultCode = lib.SQLITE_CANTOPEN
  29. ResultProtocol ResultCode = lib.SQLITE_PROTOCOL
  30. ResultEmpty ResultCode = lib.SQLITE_EMPTY
  31. ResultSchema ResultCode = lib.SQLITE_SCHEMA
  32. ResultTooBig ResultCode = lib.SQLITE_TOOBIG
  33. ResultConstraint ResultCode = lib.SQLITE_CONSTRAINT
  34. ResultMismatch ResultCode = lib.SQLITE_MISMATCH
  35. ResultMisuse ResultCode = lib.SQLITE_MISUSE
  36. ResultNoLFS ResultCode = lib.SQLITE_NOLFS
  37. ResultAuth ResultCode = lib.SQLITE_AUTH
  38. ResultFormat ResultCode = lib.SQLITE_FORMAT
  39. ResultRange ResultCode = lib.SQLITE_RANGE
  40. ResultNotADB ResultCode = lib.SQLITE_NOTADB
  41. ResultNotice ResultCode = lib.SQLITE_NOTICE
  42. ResultWarning ResultCode = lib.SQLITE_WARNING
  43. ResultRow ResultCode = lib.SQLITE_ROW
  44. ResultDone ResultCode = lib.SQLITE_DONE
  45. )
  46. // Extended result codes.
  47. const (
  48. ResultErrorMissingCollSeq ResultCode = lib.SQLITE_ERROR_MISSING_COLLSEQ
  49. ResultErrorRetry ResultCode = lib.SQLITE_ERROR_RETRY
  50. ResultErrorSnapshot ResultCode = lib.SQLITE_ERROR_SNAPSHOT
  51. ResultIOErrRead ResultCode = lib.SQLITE_IOERR_READ
  52. ResultIOErrShortRead ResultCode = lib.SQLITE_IOERR_SHORT_READ
  53. ResultIOErrWrite ResultCode = lib.SQLITE_IOERR_WRITE
  54. ResultIOErrFsync ResultCode = lib.SQLITE_IOERR_FSYNC
  55. ResultIOErrDirFsync ResultCode = lib.SQLITE_IOERR_DIR_FSYNC
  56. ResultIOErrTruncate ResultCode = lib.SQLITE_IOERR_TRUNCATE
  57. ResultIOErrFstat ResultCode = lib.SQLITE_IOERR_FSTAT
  58. ResultIOErrUnlock ResultCode = lib.SQLITE_IOERR_UNLOCK
  59. ResultIOErrReadLock ResultCode = lib.SQLITE_IOERR_RDLOCK
  60. ResultIOErrDelete ResultCode = lib.SQLITE_IOERR_DELETE
  61. ResultIOErrBlocked ResultCode = lib.SQLITE_IOERR_BLOCKED
  62. ResultIOErrNoMem ResultCode = lib.SQLITE_IOERR_NOMEM
  63. ResultIOErrAccess ResultCode = lib.SQLITE_IOERR_ACCESS
  64. ResultIOErrCheckReservedLock ResultCode = lib.SQLITE_IOERR_CHECKRESERVEDLOCK
  65. ResultIOErrLock ResultCode = lib.SQLITE_IOERR_LOCK
  66. ResultIOErrClose ResultCode = lib.SQLITE_IOERR_CLOSE
  67. ResultIOErrDirClose ResultCode = lib.SQLITE_IOERR_DIR_CLOSE
  68. ResultIOErrSHMOpen ResultCode = lib.SQLITE_IOERR_SHMOPEN
  69. ResultIOErrSHMSize ResultCode = lib.SQLITE_IOERR_SHMSIZE
  70. ResultIOErrSHMLock ResultCode = lib.SQLITE_IOERR_SHMLOCK
  71. ResultIOErrSHMMap ResultCode = lib.SQLITE_IOERR_SHMMAP
  72. ResultIOErrSeek ResultCode = lib.SQLITE_IOERR_SEEK
  73. ResultIOErrDeleteNoEnt ResultCode = lib.SQLITE_IOERR_DELETE_NOENT
  74. ResultIOErrMMap ResultCode = lib.SQLITE_IOERR_MMAP
  75. ResultIOErrGetTempPath ResultCode = lib.SQLITE_IOERR_GETTEMPPATH
  76. ResultIOErrConvPath ResultCode = lib.SQLITE_IOERR_CONVPATH
  77. ResultIOErrVNode ResultCode = lib.SQLITE_IOERR_VNODE
  78. ResultIOErrAuth ResultCode = lib.SQLITE_IOERR_AUTH
  79. ResultIOErrBeginAtomic ResultCode = lib.SQLITE_IOERR_BEGIN_ATOMIC
  80. ResultIOErrCommitAtomic ResultCode = lib.SQLITE_IOERR_COMMIT_ATOMIC
  81. ResultIOErrRollbackAtomic ResultCode = lib.SQLITE_IOERR_ROLLBACK_ATOMIC
  82. ResultLockedSharedCache ResultCode = lib.SQLITE_LOCKED_SHAREDCACHE
  83. ResultBusyRecovery ResultCode = lib.SQLITE_BUSY_RECOVERY
  84. ResultBusySnapshot ResultCode = lib.SQLITE_BUSY_SNAPSHOT
  85. ResultCantOpenNoTempDir ResultCode = lib.SQLITE_CANTOPEN_NOTEMPDIR
  86. ResultCantOpenIsDir ResultCode = lib.SQLITE_CANTOPEN_ISDIR
  87. ResultCantOpenFullPath ResultCode = lib.SQLITE_CANTOPEN_FULLPATH
  88. ResultCantOpenConvPath ResultCode = lib.SQLITE_CANTOPEN_CONVPATH
  89. ResultCorruptVTab ResultCode = lib.SQLITE_CORRUPT_VTAB
  90. ResultReadOnlyRecovery ResultCode = lib.SQLITE_READONLY_RECOVERY
  91. ResultReadOnlyCantLock ResultCode = lib.SQLITE_READONLY_CANTLOCK
  92. ResultReadOnlyRollback ResultCode = lib.SQLITE_READONLY_ROLLBACK
  93. ResultReadOnlyDBMoved ResultCode = lib.SQLITE_READONLY_DBMOVED
  94. ResultReadOnlyCantInit ResultCode = lib.SQLITE_READONLY_CANTINIT
  95. ResultReadOnlyDirectory ResultCode = lib.SQLITE_READONLY_DIRECTORY
  96. ResultAbortRollback ResultCode = lib.SQLITE_ABORT_ROLLBACK
  97. ResultConstraintCheck ResultCode = lib.SQLITE_CONSTRAINT_CHECK
  98. ResultConstraintCommitHook ResultCode = lib.SQLITE_CONSTRAINT_COMMITHOOK
  99. ResultConstraintForeignKey ResultCode = lib.SQLITE_CONSTRAINT_FOREIGNKEY
  100. ResultConstraintFunction ResultCode = lib.SQLITE_CONSTRAINT_FUNCTION
  101. ResultConstraintNotNull ResultCode = lib.SQLITE_CONSTRAINT_NOTNULL
  102. ResultConstraintPrimaryKey ResultCode = lib.SQLITE_CONSTRAINT_PRIMARYKEY
  103. ResultConstraintTrigger ResultCode = lib.SQLITE_CONSTRAINT_TRIGGER
  104. ResultConstraintUnique ResultCode = lib.SQLITE_CONSTRAINT_UNIQUE
  105. ResultConstraintVTab ResultCode = lib.SQLITE_CONSTRAINT_VTAB
  106. ResultConstraintRowID ResultCode = lib.SQLITE_CONSTRAINT_ROWID
  107. ResultNoticeRecoverWAL ResultCode = lib.SQLITE_NOTICE_RECOVER_WAL
  108. ResultNoticeRecoverRollback ResultCode = lib.SQLITE_NOTICE_RECOVER_ROLLBACK
  109. ResultWarningAutoIndex ResultCode = lib.SQLITE_WARNING_AUTOINDEX
  110. ResultAuthUser ResultCode = lib.SQLITE_AUTH_USER
  111. )
  112. // ToPrimary returns the primary result code of the given code.
  113. // https://sqlite.org/rescode.html#primary_result_codes_versus_extended_result_codes
  114. func (code ResultCode) ToPrimary() ResultCode {
  115. return code & 0xff
  116. }
  117. // IsSuccess reports whether code indicates success.
  118. func (code ResultCode) IsSuccess() bool {
  119. return code == ResultOK || code == ResultRow || code == ResultDone
  120. }
  121. // String returns the C constant name of the result code.
  122. func (code ResultCode) String() string {
  123. switch code {
  124. case ResultOK:
  125. return "SQLITE_OK"
  126. case ResultError:
  127. return "SQLITE_ERROR"
  128. case ResultInternal:
  129. return "SQLITE_INTERNAL"
  130. case ResultPerm:
  131. return "SQLITE_PERM"
  132. case ResultAbort:
  133. return "SQLITE_ABORT"
  134. case ResultBusy:
  135. return "SQLITE_BUSY"
  136. case ResultLocked:
  137. return "SQLITE_LOCKED"
  138. case ResultNoMem:
  139. return "SQLITE_NOMEM"
  140. case ResultReadOnly:
  141. return "SQLITE_READONLY"
  142. case ResultInterrupt:
  143. return "SQLITE_INTERRUPT"
  144. case ResultIOErr:
  145. return "SQLITE_IOERR"
  146. case ResultCorrupt:
  147. return "SQLITE_CORRUPT"
  148. case ResultNotFound:
  149. return "SQLITE_NOTFOUND"
  150. case ResultFull:
  151. return "SQLITE_FULL"
  152. case ResultCantOpen:
  153. return "SQLITE_CANTOPEN"
  154. case ResultProtocol:
  155. return "SQLITE_PROTOCOL"
  156. case ResultEmpty:
  157. return "SQLITE_EMPTY"
  158. case ResultSchema:
  159. return "SQLITE_SCHEMA"
  160. case ResultTooBig:
  161. return "SQLITE_TOOBIG"
  162. case ResultConstraint:
  163. return "SQLITE_CONSTRAINT"
  164. case ResultMismatch:
  165. return "SQLITE_MISMATCH"
  166. case ResultMisuse:
  167. return "SQLITE_MISUSE"
  168. case ResultNoLFS:
  169. return "SQLITE_NOLFS"
  170. case ResultAuth:
  171. return "SQLITE_AUTH"
  172. case ResultFormat:
  173. return "SQLITE_FORMAT"
  174. case ResultRange:
  175. return "SQLITE_RANGE"
  176. case ResultNotADB:
  177. return "SQLITE_NOTADB"
  178. case ResultNotice:
  179. return "SQLITE_NOTICE"
  180. case ResultWarning:
  181. return "SQLITE_WARNING"
  182. case ResultRow:
  183. return "SQLITE_ROW"
  184. case ResultDone:
  185. return "SQLITE_DONE"
  186. case ResultErrorMissingCollSeq:
  187. return "SQLITE_ERROR_MISSING_COLLSEQ"
  188. case ResultErrorRetry:
  189. return "SQLITE_ERROR_RETRY"
  190. case ResultErrorSnapshot:
  191. return "SQLITE_ERROR_SNAPSHOT"
  192. case ResultIOErrRead:
  193. return "SQLITE_IOERR_READ"
  194. case ResultIOErrShortRead:
  195. return "SQLITE_IOERR_SHORT_READ"
  196. case ResultIOErrWrite:
  197. return "SQLITE_IOERR_WRITE"
  198. case ResultIOErrFsync:
  199. return "SQLITE_IOERR_FSYNC"
  200. case ResultIOErrDirFsync:
  201. return "SQLITE_IOERR_DIR_FSYNC"
  202. case ResultIOErrTruncate:
  203. return "SQLITE_IOERR_TRUNCATE"
  204. case ResultIOErrFstat:
  205. return "SQLITE_IOERR_FSTAT"
  206. case ResultIOErrUnlock:
  207. return "SQLITE_IOERR_UNLOCK"
  208. case ResultIOErrReadLock:
  209. return "SQLITE_IOERR_RDLOCK"
  210. case ResultIOErrDelete:
  211. return "SQLITE_IOERR_DELETE"
  212. case ResultIOErrBlocked:
  213. return "SQLITE_IOERR_BLOCKED"
  214. case ResultIOErrNoMem:
  215. return "SQLITE_IOERR_NOMEM"
  216. case ResultIOErrAccess:
  217. return "SQLITE_IOERR_ACCESS"
  218. case ResultIOErrCheckReservedLock:
  219. return "SQLITE_IOERR_CHECKRESERVEDLOCK"
  220. case ResultIOErrLock:
  221. return "SQLITE_IOERR_LOCK"
  222. case ResultIOErrClose:
  223. return "SQLITE_IOERR_CLOSE"
  224. case ResultIOErrDirClose:
  225. return "SQLITE_IOERR_DIR_CLOSE"
  226. case ResultIOErrSHMOpen:
  227. return "SQLITE_IOERR_SHMOPEN"
  228. case ResultIOErrSHMSize:
  229. return "SQLITE_IOERR_SHMSIZE"
  230. case ResultIOErrSHMLock:
  231. return "SQLITE_IOERR_SHMLOCK"
  232. case ResultIOErrSHMMap:
  233. return "SQLITE_IOERR_SHMMAP"
  234. case ResultIOErrSeek:
  235. return "SQLITE_IOERR_SEEK"
  236. case ResultIOErrDeleteNoEnt:
  237. return "SQLITE_IOERR_DELETE_NOENT"
  238. case ResultIOErrMMap:
  239. return "SQLITE_IOERR_MMAP"
  240. case ResultIOErrGetTempPath:
  241. return "SQLITE_IOERR_GETTEMPPATH"
  242. case ResultIOErrConvPath:
  243. return "SQLITE_IOERR_CONVPATH"
  244. case ResultIOErrVNode:
  245. return "SQLITE_IOERR_VNODE"
  246. case ResultIOErrAuth:
  247. return "SQLITE_IOERR_AUTH"
  248. case ResultIOErrBeginAtomic:
  249. return "SQLITE_IOERR_BEGIN_ATOMIC"
  250. case ResultIOErrCommitAtomic:
  251. return "SQLITE_IOERR_COMMIT_ATOMIC"
  252. case ResultIOErrRollbackAtomic:
  253. return "SQLITE_IOERR_ROLLBACK_ATOMIC"
  254. case ResultLockedSharedCache:
  255. return "SQLITE_LOCKED_SHAREDCACHE"
  256. case ResultBusyRecovery:
  257. return "SQLITE_BUSY_RECOVERY"
  258. case ResultBusySnapshot:
  259. return "SQLITE_BUSY_SNAPSHOT"
  260. case ResultCantOpenNoTempDir:
  261. return "SQLITE_CANTOPEN_NOTEMPDIR"
  262. case ResultCantOpenIsDir:
  263. return "SQLITE_CANTOPEN_ISDIR"
  264. case ResultCantOpenFullPath:
  265. return "SQLITE_CANTOPEN_FULLPATH"
  266. case ResultCantOpenConvPath:
  267. return "SQLITE_CANTOPEN_CONVPATH"
  268. case ResultCorruptVTab:
  269. return "SQLITE_CORRUPT_VTAB"
  270. case ResultReadOnlyRecovery:
  271. return "SQLITE_READONLY_RECOVERY"
  272. case ResultReadOnlyCantLock:
  273. return "SQLITE_READONLY_CANTLOCK"
  274. case ResultReadOnlyRollback:
  275. return "SQLITE_READONLY_ROLLBACK"
  276. case ResultReadOnlyDBMoved:
  277. return "SQLITE_READONLY_DBMOVED"
  278. case ResultReadOnlyCantInit:
  279. return "SQLITE_READONLY_CANTINIT"
  280. case ResultReadOnlyDirectory:
  281. return "SQLITE_READONLY_DIRECTORY"
  282. case ResultAbortRollback:
  283. return "SQLITE_ABORT_ROLLBACK"
  284. case ResultConstraintCheck:
  285. return "SQLITE_CONSTRAINT_CHECK"
  286. case ResultConstraintCommitHook:
  287. return "SQLITE_CONSTRAINT_COMMITHOOK"
  288. case ResultConstraintForeignKey:
  289. return "SQLITE_CONSTRAINT_FOREIGNKEY"
  290. case ResultConstraintFunction:
  291. return "SQLITE_CONSTRAINT_FUNCTION"
  292. case ResultConstraintNotNull:
  293. return "SQLITE_CONSTRAINT_NOTNULL"
  294. case ResultConstraintPrimaryKey:
  295. return "SQLITE_CONSTRAINT_PRIMARYKEY"
  296. case ResultConstraintTrigger:
  297. return "SQLITE_CONSTRAINT_TRIGGER"
  298. case ResultConstraintUnique:
  299. return "SQLITE_CONSTRAINT_UNIQUE"
  300. case ResultConstraintVTab:
  301. return "SQLITE_CONSTRAINT_VTAB"
  302. case ResultConstraintRowID:
  303. return "SQLITE_CONSTRAINT_ROWID"
  304. case ResultNoticeRecoverWAL:
  305. return "SQLITE_NOTICE_RECOVER_WAL"
  306. case ResultNoticeRecoverRollback:
  307. return "SQLITE_NOTICE_RECOVER_ROLLBACK"
  308. case ResultWarningAutoIndex:
  309. return "SQLITE_WARNING_AUTOINDEX"
  310. case ResultAuthUser:
  311. return "SQLITE_AUTH_USER"
  312. default:
  313. return fmt.Sprintf("ResultCode(%d)", int32(code))
  314. }
  315. }
  316. // Message returns the English-language text that describes the result code.
  317. func (code ResultCode) Message() string {
  318. cstr := lib.Xsqlite3_errstr(nil, int32(code))
  319. return libc.GoString(cstr)
  320. }
  321. // ToError converts an error code into an error
  322. // for which ErrCode(code.ToError()) == code.
  323. // If the code indicates success, ToError returns nil.
  324. func (code ResultCode) ToError() error {
  325. if code.IsSuccess() {
  326. return nil
  327. }
  328. return sqliteError{code}
  329. }
  330. type sqliteError struct {
  331. code ResultCode
  332. }
  333. func (e sqliteError) Error() string {
  334. return e.code.Message()
  335. }
  336. // ErrCode returns the error's SQLite error code or ResultError if the error
  337. // does not represent a SQLite error. ErrorCode returns ResultOK if and only if
  338. // the error is nil.
  339. func ErrCode(err error) ResultCode {
  340. if err == nil {
  341. return ResultOK
  342. }
  343. if e := new(sqliteError); errors.As(err, e) {
  344. return e.code
  345. }
  346. return ResultError
  347. }