/sqlite/sqlite.go

https://code.google.com/p/gosqlite/ · Go · 404 lines · 339 code · 39 blank · 26 comment · 90 complexity · b7535656a0b9da013369b575208bcd42 MD5 · raw file

  1. // Copyright 2010 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package sqlite provides access to the SQLite library, version 3.
  5. package sqlite
  6. /*
  7. #cgo LDFLAGS: -lsqlite3
  8. #include <sqlite3.h>
  9. #include <stdlib.h>
  10. // These wrappers are necessary because SQLITE_TRANSIENT
  11. // is a pointer constant, and cgo doesn't translate them correctly.
  12. // The definition in sqlite3.h is:
  13. //
  14. // typedef void (*sqlite3_destructor_type)(void*);
  15. // #define SQLITE_STATIC ((sqlite3_destructor_type)0)
  16. // #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
  17. static int my_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) {
  18. return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
  19. }
  20. static int my_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
  21. return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
  22. }
  23. */
  24. import "C"
  25. import (
  26. "errors"
  27. "fmt"
  28. "reflect"
  29. "strconv"
  30. "time"
  31. "unsafe"
  32. )
  33. type Errno int
  34. func (e Errno) Error() string {
  35. s := errText[e]
  36. if s == "" {
  37. return fmt.Sprintf("errno %d", int(e))
  38. }
  39. return s
  40. }
  41. var (
  42. ErrError error = Errno(1) // /* SQL error or missing database */
  43. ErrInternal error = Errno(2) // /* Internal logic error in SQLite */
  44. ErrPerm error = Errno(3) // /* Access permission denied */
  45. ErrAbort error = Errno(4) // /* Callback routine requested an abort */
  46. ErrBusy error = Errno(5) // /* The database file is locked */
  47. ErrLocked error = Errno(6) // /* A table in the database is locked */
  48. ErrNoMem error = Errno(7) // /* A malloc() failed */
  49. ErrReadOnly error = Errno(8) // /* Attempt to write a readonly database */
  50. ErrInterrupt error = Errno(9) // /* Operation terminated by sqlite3_interrupt()*/
  51. ErrIOErr error = Errno(10) // /* Some kind of disk I/O error occurred */
  52. ErrCorrupt error = Errno(11) // /* The database disk image is malformed */
  53. ErrFull error = Errno(13) // /* Insertion failed because database is full */
  54. ErrCantOpen error = Errno(14) // /* Unable to open the database file */
  55. ErrEmpty error = Errno(16) // /* Database is empty */
  56. ErrSchema error = Errno(17) // /* The database schema changed */
  57. ErrTooBig error = Errno(18) // /* String or BLOB exceeds size limit */
  58. ErrConstraint error = Errno(19) // /* Abort due to constraint violation */
  59. ErrMismatch error = Errno(20) // /* Data type mismatch */
  60. ErrMisuse error = Errno(21) // /* Library used incorrectly */
  61. ErrNolfs error = Errno(22) // /* Uses OS features not supported on host */
  62. ErrAuth error = Errno(23) // /* Authorization denied */
  63. ErrFormat error = Errno(24) // /* Auxiliary database format error */
  64. ErrRange error = Errno(25) // /* 2nd parameter to sqlite3_bind out of range */
  65. ErrNotDB error = Errno(26) // /* File opened that is not a database file */
  66. Row = Errno(100) // /* sqlite3_step() has another row ready */
  67. Done = Errno(101) // /* sqlite3_step() has finished executing */
  68. )
  69. var errText = map[Errno]string{
  70. 1: "SQL error or missing database",
  71. 2: "Internal logic error in SQLite",
  72. 3: "Access permission denied",
  73. 4: "Callback routine requested an abort",
  74. 5: "The database file is locked",
  75. 6: "A table in the database is locked",
  76. 7: "A malloc() failed",
  77. 8: "Attempt to write a readonly database",
  78. 9: "Operation terminated by sqlite3_interrupt()*/",
  79. 10: "Some kind of disk I/O error occurred",
  80. 11: "The database disk image is malformed",
  81. 12: "NOT USED. Table or record not found",
  82. 13: "Insertion failed because database is full",
  83. 14: "Unable to open the database file",
  84. 15: "NOT USED. Database lock protocol error",
  85. 16: "Database is empty",
  86. 17: "The database schema changed",
  87. 18: "String or BLOB exceeds size limit",
  88. 19: "Abort due to constraint violation",
  89. 20: "Data type mismatch",
  90. 21: "Library used incorrectly",
  91. 22: "Uses OS features not supported on host",
  92. 23: "Authorization denied",
  93. 24: "Auxiliary database format error",
  94. 25: "2nd parameter to sqlite3_bind out of range",
  95. 26: "File opened that is not a database file",
  96. 100: "sqlite3_step() has another row ready",
  97. 101: "sqlite3_step() has finished executing",
  98. }
  99. func (c *Conn) error(rv C.int) error {
  100. if c == nil || c.db == nil {
  101. return errors.New("nil sqlite database")
  102. }
  103. if rv == 0 {
  104. return nil
  105. }
  106. if rv == 21 { // misuse
  107. return Errno(rv)
  108. }
  109. return errors.New(Errno(rv).Error() + ": " + C.GoString(C.sqlite3_errmsg(c.db)))
  110. }
  111. type Conn struct {
  112. db *C.sqlite3
  113. }
  114. func Version() string {
  115. p := C.sqlite3_libversion()
  116. return C.GoString(p)
  117. }
  118. func Open(filename string) (*Conn, error) {
  119. if C.sqlite3_threadsafe() == 0 {
  120. return nil, errors.New("sqlite library was not compiled for thread-safe operation")
  121. }
  122. var db *C.sqlite3
  123. name := C.CString(filename)
  124. defer C.free(unsafe.Pointer(name))
  125. rv := C.sqlite3_open_v2(name, &db,
  126. C.SQLITE_OPEN_FULLMUTEX|
  127. C.SQLITE_OPEN_READWRITE|
  128. C.SQLITE_OPEN_CREATE,
  129. nil)
  130. if rv != 0 {
  131. return nil, Errno(rv)
  132. }
  133. if db == nil {
  134. return nil, errors.New("sqlite succeeded without returning a database")
  135. }
  136. return &Conn{db}, nil
  137. }
  138. func NewBackup(dst *Conn, dstTable string, src *Conn, srcTable string) (*Backup, error) {
  139. dname := C.CString(dstTable)
  140. sname := C.CString(srcTable)
  141. defer C.free(unsafe.Pointer(dname))
  142. defer C.free(unsafe.Pointer(sname))
  143. sb := C.sqlite3_backup_init(dst.db, dname, src.db, sname)
  144. if sb == nil {
  145. return nil, dst.error(C.sqlite3_errcode(dst.db))
  146. }
  147. return &Backup{sb, dst, src}, nil
  148. }
  149. type Backup struct {
  150. sb *C.sqlite3_backup
  151. dst, src *Conn
  152. }
  153. func (b *Backup) Step(npage int) error {
  154. rv := C.sqlite3_backup_step(b.sb, C.int(npage))
  155. if rv == 0 || Errno(rv) == ErrBusy || Errno(rv) == ErrLocked {
  156. return nil
  157. }
  158. return Errno(rv)
  159. }
  160. type BackupStatus struct {
  161. Remaining int
  162. PageCount int
  163. }
  164. func (b *Backup) Status() BackupStatus {
  165. return BackupStatus{int(C.sqlite3_backup_remaining(b.sb)), int(C.sqlite3_backup_pagecount(b.sb))}
  166. }
  167. func (b *Backup) Run(npage int, period time.Duration, c chan<- BackupStatus) error {
  168. var err error
  169. for {
  170. err = b.Step(npage)
  171. if err != nil {
  172. break
  173. }
  174. if c != nil {
  175. c <- b.Status()
  176. }
  177. time.Sleep(period)
  178. }
  179. return b.dst.error(C.sqlite3_errcode(b.dst.db))
  180. }
  181. func (b *Backup) Close() error {
  182. if b.sb == nil {
  183. return errors.New("backup already closed")
  184. }
  185. C.sqlite3_backup_finish(b.sb)
  186. b.sb = nil
  187. return nil
  188. }
  189. func (c *Conn) BusyTimeout(ms int) error {
  190. rv := C.sqlite3_busy_timeout(c.db, C.int(ms))
  191. if rv == 0 {
  192. return nil
  193. }
  194. return Errno(rv)
  195. }
  196. func (c *Conn) Exec(cmd string, args ...interface{}) error {
  197. s, err := c.Prepare(cmd)
  198. if err != nil {
  199. return err
  200. }
  201. defer s.Finalize()
  202. err = s.Exec(args...)
  203. if err != nil {
  204. return err
  205. }
  206. rv := C.sqlite3_step(s.stmt)
  207. if Errno(rv) != Done {
  208. return c.error(rv)
  209. }
  210. return nil
  211. }
  212. type Stmt struct {
  213. c *Conn
  214. stmt *C.sqlite3_stmt
  215. err error
  216. t0 time.Time
  217. sql string
  218. args string
  219. }
  220. func (c *Conn) Prepare(cmd string) (*Stmt, error) {
  221. if c == nil || c.db == nil {
  222. return nil, errors.New("nil sqlite database")
  223. }
  224. cmdstr := C.CString(cmd)
  225. defer C.free(unsafe.Pointer(cmdstr))
  226. var stmt *C.sqlite3_stmt
  227. var tail *C.char
  228. rv := C.sqlite3_prepare_v2(c.db, cmdstr, C.int(len(cmd)+1), &stmt, &tail)
  229. if rv != 0 {
  230. return nil, c.error(rv)
  231. }
  232. return &Stmt{c: c, stmt: stmt, sql: cmd, t0: time.Now()}, nil
  233. }
  234. func (s *Stmt) Exec(args ...interface{}) error {
  235. s.args = fmt.Sprintf(" %v", []interface{}(args))
  236. rv := C.sqlite3_reset(s.stmt)
  237. if rv != 0 {
  238. return s.c.error(rv)
  239. }
  240. n := int(C.sqlite3_bind_parameter_count(s.stmt))
  241. if n != len(args) {
  242. return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n))
  243. }
  244. for i, v := range args {
  245. var str string
  246. switch v := v.(type) {
  247. case []byte:
  248. var p *byte
  249. if len(v) > 0 {
  250. p = &v[0]
  251. }
  252. if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 {
  253. return s.c.error(rv)
  254. }
  255. continue
  256. case bool:
  257. if v {
  258. str = "1"
  259. } else {
  260. str = "0"
  261. }
  262. default:
  263. str = fmt.Sprint(v)
  264. }
  265. cstr := C.CString(str)
  266. rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
  267. C.free(unsafe.Pointer(cstr))
  268. if rv != 0 {
  269. return s.c.error(rv)
  270. }
  271. }
  272. return nil
  273. }
  274. func (s *Stmt) Error() error {
  275. return s.err
  276. }
  277. func (s *Stmt) Next() bool {
  278. rv := C.sqlite3_step(s.stmt)
  279. err := Errno(rv)
  280. if err == Row {
  281. return true
  282. }
  283. if err != Done {
  284. s.err = s.c.error(rv)
  285. }
  286. return false
  287. }
  288. func (s *Stmt) Reset() error {
  289. C.sqlite3_reset(s.stmt)
  290. return nil
  291. }
  292. func (s *Stmt) Scan(args ...interface{}) error {
  293. n := int(C.sqlite3_column_count(s.stmt))
  294. if n != len(args) {
  295. return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n))
  296. }
  297. for i, v := range args {
  298. n := C.sqlite3_column_bytes(s.stmt, C.int(i))
  299. p := C.sqlite3_column_blob(s.stmt, C.int(i))
  300. if p == nil && n > 0 {
  301. return errors.New("got nil blob")
  302. }
  303. var data []byte
  304. if n > 0 {
  305. data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
  306. }
  307. switch v := v.(type) {
  308. case *[]byte:
  309. *v = data
  310. case *string:
  311. *v = string(data)
  312. case *bool:
  313. *v = string(data) == "1"
  314. case *int:
  315. x, err := strconv.Atoi(string(data))
  316. if err != nil {
  317. return errors.New("arg " + strconv.Itoa(i) + " as int: " + err.Error())
  318. }
  319. *v = x
  320. case *int64:
  321. x, err := strconv.ParseInt(string(data), 10, 64)
  322. if err != nil {
  323. return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
  324. }
  325. *v = x
  326. case *float64:
  327. x, err := strconv.ParseFloat(string(data), 64)
  328. if err != nil {
  329. return errors.New("arg " + strconv.Itoa(i) + " as float64: " + err.Error())
  330. }
  331. *v = x
  332. default:
  333. return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String())
  334. }
  335. }
  336. return nil
  337. }
  338. func (s *Stmt) SQL() string {
  339. return s.sql + s.args
  340. }
  341. func (s *Stmt) Nanoseconds() int64 {
  342. return time.Now().Sub(s.t0).Nanoseconds()
  343. }
  344. func (s *Stmt) Finalize() error {
  345. rv := C.sqlite3_finalize(s.stmt)
  346. if rv != 0 {
  347. return s.c.error(rv)
  348. }
  349. return nil
  350. }
  351. func (c *Conn) Close() error {
  352. if c == nil || c.db == nil {
  353. return errors.New("nil sqlite database")
  354. }
  355. rv := C.sqlite3_close(c.db)
  356. if rv != 0 {
  357. return c.error(rv)
  358. }
  359. c.db = nil
  360. return nil
  361. }