You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
1.9 KiB

  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. #ifndef USE_LIBSQLITE3
  8. #include <sqlite3-binding.h>
  9. #else
  10. #include <sqlite3.h>
  11. #endif
  12. #include <stdlib.h>
  13. */
  14. import "C"
  15. import (
  16. "runtime"
  17. "unsafe"
  18. )
  19. type SQLiteBackup struct {
  20. b *C.sqlite3_backup
  21. }
  22. func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteBackup, error) {
  23. destptr := C.CString(dest)
  24. defer C.free(unsafe.Pointer(destptr))
  25. srcptr := C.CString(src)
  26. defer C.free(unsafe.Pointer(srcptr))
  27. if b := C.sqlite3_backup_init(c.db, destptr, conn.db, srcptr); b != nil {
  28. bb := &SQLiteBackup{b: b}
  29. runtime.SetFinalizer(bb, (*SQLiteBackup).Finish)
  30. return bb, nil
  31. }
  32. return nil, c.lastError()
  33. }
  34. // Backs up for one step. Calls the underlying `sqlite3_backup_step` function.
  35. // This function returns a boolean indicating if the backup is done and
  36. // an error signalling any other error. Done is returned if the underlying C
  37. // function returns SQLITE_DONE (Code 101)
  38. func (b *SQLiteBackup) Step(p int) (bool, error) {
  39. ret := C.sqlite3_backup_step(b.b, C.int(p))
  40. if ret == C.SQLITE_DONE {
  41. return true, nil
  42. } else if ret != 0 && ret != C.SQLITE_LOCKED && ret != C.SQLITE_BUSY {
  43. return false, Error{Code: ErrNo(ret)}
  44. }
  45. return false, nil
  46. }
  47. func (b *SQLiteBackup) Remaining() int {
  48. return int(C.sqlite3_backup_remaining(b.b))
  49. }
  50. func (b *SQLiteBackup) PageCount() int {
  51. return int(C.sqlite3_backup_pagecount(b.b))
  52. }
  53. func (b *SQLiteBackup) Finish() error {
  54. return b.Close()
  55. }
  56. func (b *SQLiteBackup) Close() error {
  57. ret := C.sqlite3_backup_finish(b.b)
  58. // sqlite3_backup_finish() never fails, it just returns the
  59. // error code from previous operations, so clean up before
  60. // checking and returning an error
  61. b.b = nil
  62. runtime.SetFinalizer(b, nil)
  63. if ret != 0 {
  64. return Error{Code: ErrNo(ret)}
  65. }
  66. return nil
  67. }