gemini-search

A simple search engine for Geminispace
git clone git://git.laack.co/gemini-search.git
Log | Files | Refs | README

backup.go (2218B)


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