mirror of
				https://github.com/containers/podman.git
				synced 2025-10-31 10:00:01 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			84 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| //go:build !libsqlite3 || sqlite_serialize
 | |
| // +build !libsqlite3 sqlite_serialize
 | |
| 
 | |
| package sqlite3
 | |
| 
 | |
| /*
 | |
| #ifndef USE_LIBSQLITE3
 | |
| #include <sqlite3-binding.h>
 | |
| #else
 | |
| #include <sqlite3.h>
 | |
| #endif
 | |
| #include <stdlib.h>
 | |
| #include <stdint.h>
 | |
| */
 | |
| import "C"
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"math"
 | |
| 	"reflect"
 | |
| 	"unsafe"
 | |
| )
 | |
| 
 | |
| // Serialize returns a byte slice that is a serialization of the database.
 | |
| //
 | |
| // See https://www.sqlite.org/c3ref/serialize.html
 | |
| func (c *SQLiteConn) Serialize(schema string) ([]byte, error) {
 | |
| 	if schema == "" {
 | |
| 		schema = "main"
 | |
| 	}
 | |
| 	var zSchema *C.char
 | |
| 	zSchema = C.CString(schema)
 | |
| 	defer C.free(unsafe.Pointer(zSchema))
 | |
| 
 | |
| 	var sz C.sqlite3_int64
 | |
| 	ptr := C.sqlite3_serialize(c.db, zSchema, &sz, 0)
 | |
| 	if ptr == nil {
 | |
| 		return nil, fmt.Errorf("serialize failed")
 | |
| 	}
 | |
| 	defer C.sqlite3_free(unsafe.Pointer(ptr))
 | |
| 
 | |
| 	if sz > C.sqlite3_int64(math.MaxInt) {
 | |
| 		return nil, fmt.Errorf("serialized database is too large (%d bytes)", sz)
 | |
| 	}
 | |
| 
 | |
| 	cBuf := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
 | |
| 		Data: uintptr(unsafe.Pointer(ptr)),
 | |
| 		Len:  int(sz),
 | |
| 		Cap:  int(sz),
 | |
| 	}))
 | |
| 
 | |
| 	res := make([]byte, int(sz))
 | |
| 	copy(res, cBuf)
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // Deserialize causes the connection to disconnect from the current database and
 | |
| // then re-open as an in-memory database based on the contents of the byte slice.
 | |
| //
 | |
| // See https://www.sqlite.org/c3ref/deserialize.html
 | |
| func (c *SQLiteConn) Deserialize(b []byte, schema string) error {
 | |
| 	if schema == "" {
 | |
| 		schema = "main"
 | |
| 	}
 | |
| 	var zSchema *C.char
 | |
| 	zSchema = C.CString(schema)
 | |
| 	defer C.free(unsafe.Pointer(zSchema))
 | |
| 
 | |
| 	tmpBuf := (*C.uchar)(C.sqlite3_malloc64(C.sqlite3_uint64(len(b))))
 | |
| 	cBuf := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
 | |
| 		Data: uintptr(unsafe.Pointer(tmpBuf)),
 | |
| 		Len:  len(b),
 | |
| 		Cap:  len(b),
 | |
| 	}))
 | |
| 	copy(cBuf, b)
 | |
| 
 | |
| 	rc := C.sqlite3_deserialize(c.db, zSchema, tmpBuf, C.sqlite3_int64(len(b)),
 | |
| 		C.sqlite3_int64(len(b)), C.SQLITE_DESERIALIZE_FREEONCLOSE)
 | |
| 	if rc != C.SQLITE_OK {
 | |
| 		return fmt.Errorf("deserialize failed with return %v", rc)
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | 
![renovate[bot]](/assets/img/avatar_default.png)