backup.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package sqlite3
  6. /*
  7. #include <sqlite3-binding.h>
  8. #include <stdlib.h>
  9. */
  10. import "C"
  11. import (
  12. "runtime"
  13. "unsafe"
  14. )
  15. type SQLiteBackup struct {
  16. b *C.sqlite3_backup
  17. }
  18. func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteBackup, error) {
  19. destptr := C.CString(dest)
  20. defer C.free(unsafe.Pointer(destptr))
  21. srcptr := C.CString(src)
  22. defer C.free(unsafe.Pointer(srcptr))
  23. if b := C.sqlite3_backup_init(c.db, destptr, conn.db, srcptr); b != nil {
  24. bb := &SQLiteBackup{b: b}
  25. runtime.SetFinalizer(bb, (*SQLiteBackup).Finish)
  26. return bb, nil
  27. }
  28. return nil, c.lastError()
  29. }
  30. // Backs up for one step. Calls the underlying `sqlite3_backup_step` function.
  31. // This function returns a boolean indicating if the backup is done and
  32. // an error signalling any other error. Done is returned if the underlying C
  33. // function returns SQLITE_DONE (Code 101)
  34. func (b *SQLiteBackup) Step(p int) (bool, error) {
  35. ret := C.sqlite3_backup_step(b.b, C.int(p))
  36. if ret == C.SQLITE_DONE {
  37. return true, nil
  38. } else if ret != 0 && ret != C.SQLITE_LOCKED && ret != C.SQLITE_BUSY {
  39. return false, Error{Code: ErrNo(ret)}
  40. }
  41. return false, nil
  42. }
  43. func (b *SQLiteBackup) Remaining() int {
  44. return int(C.sqlite3_backup_remaining(b.b))
  45. }
  46. func (b *SQLiteBackup) PageCount() int {
  47. return int(C.sqlite3_backup_pagecount(b.b))
  48. }
  49. func (b *SQLiteBackup) Finish() error {
  50. return b.Close()
  51. }
  52. func (b *SQLiteBackup) Close() error {
  53. ret := C.sqlite3_backup_finish(b.b)
  54. if ret != 0 {
  55. return Error{Code: ErrNo(ret)}
  56. }
  57. b.b = nil
  58. runtime.SetFinalizer(b, nil)
  59. return nil
  60. }