mirror of
https://github.com/mumble-voip/grumble.git
synced 2025-12-19 21:59:59 -08:00
Remove pkg/sqlite.
This commit is contained in:
parent
96d725691a
commit
6ab358c5e1
4 changed files with 0 additions and 130067 deletions
|
|
@ -1,26 +0,0 @@
|
||||||
# Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
# Use of this source code is governed by a BSD-style
|
|
||||||
# license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
include $(GOROOT)/src/Make.inc
|
|
||||||
|
|
||||||
TARG=grumble/sqlite
|
|
||||||
|
|
||||||
CGOFILES=sqlite.go
|
|
||||||
|
|
||||||
ifneq ($(GOOS),windows)
|
|
||||||
CGO_OFILES=sqlite3.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(GOOS),linux)
|
|
||||||
CGO_LDFLAGS=-lpthread -ldl
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(GOOS),windows)
|
|
||||||
# requires a .dll and .def in c:\sqlite
|
|
||||||
# beware of version incompatibilities:
|
|
||||||
# build uses sqlite3.h header from this dir
|
|
||||||
CGO_LDFLAGS=-Lc:/sqlite -lsqlite3
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(GOROOT)/src/Make.pkg
|
|
||||||
|
|
@ -1,403 +0,0 @@
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package sqlite provides access to the SQLite library, version 3.
|
|
||||||
package sqlite
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include "sqlite3.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// These wrappers are necessary because SQLITE_TRANSIENT
|
|
||||||
// is a pointer constant, and cgo doesn't translate them correctly.
|
|
||||||
// The definition in sqlite3.h is:
|
|
||||||
//
|
|
||||||
// typedef void (*sqlite3_destructor_type)(void*);
|
|
||||||
// #define SQLITE_STATIC ((sqlite3_destructor_type)0)
|
|
||||||
// #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
|
|
||||||
|
|
||||||
static int my_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) {
|
|
||||||
return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
|
|
||||||
}
|
|
||||||
static int my_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
|
|
||||||
return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Errno int
|
|
||||||
|
|
||||||
func (e Errno) Error() string {
|
|
||||||
s := errText[e]
|
|
||||||
if s == "" {
|
|
||||||
return fmt.Sprintf("errno %d", int(e))
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrError error = Errno(1) // /* SQL error or missing database */
|
|
||||||
ErrInternal error = Errno(2) // /* Internal logic error in SQLite */
|
|
||||||
ErrPerm error = Errno(3) // /* Access permission denied */
|
|
||||||
ErrAbort error = Errno(4) // /* Callback routine requested an abort */
|
|
||||||
ErrBusy error = Errno(5) // /* The database file is locked */
|
|
||||||
ErrLocked error = Errno(6) // /* A table in the database is locked */
|
|
||||||
ErrNoMem error = Errno(7) // /* A malloc() failed */
|
|
||||||
ErrReadOnly error = Errno(8) // /* Attempt to write a readonly database */
|
|
||||||
ErrInterrupt error = Errno(9) // /* Operation terminated by sqlite3_interrupt()*/
|
|
||||||
ErrIOErr error = Errno(10) // /* Some kind of disk I/O error occurred */
|
|
||||||
ErrCorrupt error = Errno(11) // /* The database disk image is malformed */
|
|
||||||
ErrFull error = Errno(13) // /* Insertion failed because database is full */
|
|
||||||
ErrCantOpen error = Errno(14) // /* Unable to open the database file */
|
|
||||||
ErrEmpty error = Errno(16) // /* Database is empty */
|
|
||||||
ErrSchema error = Errno(17) // /* The database schema changed */
|
|
||||||
ErrTooBig error = Errno(18) // /* String or BLOB exceeds size limit */
|
|
||||||
ErrConstraint error = Errno(19) // /* Abort due to constraint violation */
|
|
||||||
ErrMismatch error = Errno(20) // /* Data type mismatch */
|
|
||||||
ErrMisuse error = Errno(21) // /* Library used incorrectly */
|
|
||||||
ErrNolfs error = Errno(22) // /* Uses OS features not supported on host */
|
|
||||||
ErrAuth error = Errno(23) // /* Authorization denied */
|
|
||||||
ErrFormat error = Errno(24) // /* Auxiliary database format error */
|
|
||||||
ErrRange error = Errno(25) // /* 2nd parameter to sqlite3_bind out of range */
|
|
||||||
ErrNotDB error = Errno(26) // /* File opened that is not a database file */
|
|
||||||
Row = Errno(100) // /* sqlite3_step() has another row ready */
|
|
||||||
Done = Errno(101) // /* sqlite3_step() has finished executing */
|
|
||||||
)
|
|
||||||
|
|
||||||
var errText = map[Errno]string{
|
|
||||||
1: "SQL error or missing database",
|
|
||||||
2: "Internal logic error in SQLite",
|
|
||||||
3: "Access permission denied",
|
|
||||||
4: "Callback routine requested an abort",
|
|
||||||
5: "The database file is locked",
|
|
||||||
6: "A table in the database is locked",
|
|
||||||
7: "A malloc() failed",
|
|
||||||
8: "Attempt to write a readonly database",
|
|
||||||
9: "Operation terminated by sqlite3_interrupt()*/",
|
|
||||||
10: "Some kind of disk I/O error occurred",
|
|
||||||
11: "The database disk image is malformed",
|
|
||||||
12: "NOT USED. Table or record not found",
|
|
||||||
13: "Insertion failed because database is full",
|
|
||||||
14: "Unable to open the database file",
|
|
||||||
15: "NOT USED. Database lock protocol error",
|
|
||||||
16: "Database is empty",
|
|
||||||
17: "The database schema changed",
|
|
||||||
18: "String or BLOB exceeds size limit",
|
|
||||||
19: "Abort due to constraint violation",
|
|
||||||
20: "Data type mismatch",
|
|
||||||
21: "Library used incorrectly",
|
|
||||||
22: "Uses OS features not supported on host",
|
|
||||||
23: "Authorization denied",
|
|
||||||
24: "Auxiliary database format error",
|
|
||||||
25: "2nd parameter to sqlite3_bind out of range",
|
|
||||||
26: "File opened that is not a database file",
|
|
||||||
100: "sqlite3_step() has another row ready",
|
|
||||||
101: "sqlite3_step() has finished executing",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) error(rv C.int) error {
|
|
||||||
if c == nil || c.db == nil {
|
|
||||||
return errors.New("nil sqlite database")
|
|
||||||
}
|
|
||||||
if rv == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if rv == 21 { // misuse
|
|
||||||
return Errno(rv)
|
|
||||||
}
|
|
||||||
return errors.New(Errno(rv).Error() + ": " + C.GoString(C.sqlite3_errmsg(c.db)))
|
|
||||||
}
|
|
||||||
|
|
||||||
type Conn struct {
|
|
||||||
db *C.sqlite3
|
|
||||||
}
|
|
||||||
|
|
||||||
func Version() string {
|
|
||||||
p := C.sqlite3_libversion()
|
|
||||||
return C.GoString(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Open(filename string) (*Conn, error) {
|
|
||||||
if C.sqlite3_threadsafe() == 0 {
|
|
||||||
return nil, errors.New("sqlite library was not compiled for thread-safe operation")
|
|
||||||
}
|
|
||||||
|
|
||||||
var db *C.sqlite3
|
|
||||||
name := C.CString(filename)
|
|
||||||
defer C.free(unsafe.Pointer(name))
|
|
||||||
rv := C.sqlite3_open_v2(name, &db,
|
|
||||||
C.SQLITE_OPEN_FULLMUTEX|
|
|
||||||
C.SQLITE_OPEN_READWRITE|
|
|
||||||
C.SQLITE_OPEN_CREATE,
|
|
||||||
nil)
|
|
||||||
if rv != 0 {
|
|
||||||
return nil, Errno(rv)
|
|
||||||
}
|
|
||||||
if db == nil {
|
|
||||||
return nil, errors.New("sqlite succeeded without returning a database")
|
|
||||||
}
|
|
||||||
return &Conn{db}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBackup(dst *Conn, dstTable string, src *Conn, srcTable string) (*Backup, error) {
|
|
||||||
dname := C.CString(dstTable)
|
|
||||||
sname := C.CString(srcTable)
|
|
||||||
defer C.free(unsafe.Pointer(dname))
|
|
||||||
defer C.free(unsafe.Pointer(sname))
|
|
||||||
|
|
||||||
sb := C.sqlite3_backup_init(dst.db, dname, src.db, sname)
|
|
||||||
if sb == nil {
|
|
||||||
return nil, dst.error(C.sqlite3_errcode(dst.db))
|
|
||||||
}
|
|
||||||
return &Backup{sb, dst, src}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Backup struct {
|
|
||||||
sb *C.sqlite3_backup
|
|
||||||
dst, src *Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Backup) Step(npage int) error {
|
|
||||||
rv := C.sqlite3_backup_step(b.sb, C.int(npage))
|
|
||||||
if rv == 0 || Errno(rv) == ErrBusy || Errno(rv) == ErrLocked {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return Errno(rv)
|
|
||||||
}
|
|
||||||
|
|
||||||
type BackupStatus struct {
|
|
||||||
Remaining int
|
|
||||||
PageCount int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Backup) Status() BackupStatus {
|
|
||||||
return BackupStatus{int(C.sqlite3_backup_remaining(b.sb)), int(C.sqlite3_backup_pagecount(b.sb))}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Backup) Run(npage int, sleepNs int64, c chan<- BackupStatus) error {
|
|
||||||
var err error
|
|
||||||
for {
|
|
||||||
err = b.Step(npage)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if c != nil {
|
|
||||||
c <- b.Status()
|
|
||||||
}
|
|
||||||
time.Sleep(sleepNs)
|
|
||||||
}
|
|
||||||
return b.dst.error(C.sqlite3_errcode(b.dst.db))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Backup) Close() error {
|
|
||||||
if b.sb == nil {
|
|
||||||
return os.EINVAL
|
|
||||||
}
|
|
||||||
C.sqlite3_backup_finish(b.sb)
|
|
||||||
b.sb = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) BusyTimeout(ms int) error {
|
|
||||||
rv := C.sqlite3_busy_timeout(c.db, C.int(ms))
|
|
||||||
if rv == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return Errno(rv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) Exec(cmd string, args ...interface{}) error {
|
|
||||||
s, err := c.Prepare(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer s.Finalize()
|
|
||||||
err = s.Exec(args...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rv := C.sqlite3_step(s.stmt)
|
|
||||||
if Errno(rv) != Done {
|
|
||||||
return c.error(rv)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Stmt struct {
|
|
||||||
c *Conn
|
|
||||||
stmt *C.sqlite3_stmt
|
|
||||||
err error
|
|
||||||
t0 int64
|
|
||||||
sql string
|
|
||||||
args string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) Prepare(cmd string) (*Stmt, error) {
|
|
||||||
if c == nil || c.db == nil {
|
|
||||||
return nil, errors.New("nil sqlite database")
|
|
||||||
}
|
|
||||||
cmdstr := C.CString(cmd)
|
|
||||||
defer C.free(unsafe.Pointer(cmdstr))
|
|
||||||
var stmt *C.sqlite3_stmt
|
|
||||||
var tail *C.char
|
|
||||||
rv := C.sqlite3_prepare_v2(c.db, cmdstr, C.int(len(cmd)+1), &stmt, &tail)
|
|
||||||
if rv != 0 {
|
|
||||||
return nil, c.error(rv)
|
|
||||||
}
|
|
||||||
return &Stmt{c: c, stmt: stmt, sql: cmd, t0: time.Now()}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Exec(args ...interface{}) error {
|
|
||||||
s.args = fmt.Sprintf(" %v", []interface{}(args))
|
|
||||||
rv := C.sqlite3_reset(s.stmt)
|
|
||||||
if rv != 0 {
|
|
||||||
return s.c.error(rv)
|
|
||||||
}
|
|
||||||
|
|
||||||
n := int(C.sqlite3_bind_parameter_count(s.stmt))
|
|
||||||
if n != len(args) {
|
|
||||||
return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range args {
|
|
||||||
var str string
|
|
||||||
switch v := v.(type) {
|
|
||||||
case []byte:
|
|
||||||
var p *byte
|
|
||||||
if len(v) > 0 {
|
|
||||||
p = &v[0]
|
|
||||||
}
|
|
||||||
if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 {
|
|
||||||
return s.c.error(rv)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
|
|
||||||
case bool:
|
|
||||||
if v {
|
|
||||||
str = "1"
|
|
||||||
} else {
|
|
||||||
str = "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
str = fmt.Sprint(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
cstr := C.CString(str)
|
|
||||||
rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
|
|
||||||
C.free(unsafe.Pointer(cstr))
|
|
||||||
if rv != 0 {
|
|
||||||
return s.c.error(rv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Error() error {
|
|
||||||
return s.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Next() bool {
|
|
||||||
rv := C.sqlite3_step(s.stmt)
|
|
||||||
err := Errno(rv)
|
|
||||||
if err == Row {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if err != Done {
|
|
||||||
s.err = s.c.error(rv)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Reset() error {
|
|
||||||
C.sqlite3_reset(s.stmt)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Scan(args ...interface{}) error {
|
|
||||||
n := int(C.sqlite3_column_count(s.stmt))
|
|
||||||
if n != len(args) {
|
|
||||||
return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range args {
|
|
||||||
n := C.sqlite3_column_bytes(s.stmt, C.int(i))
|
|
||||||
p := C.sqlite3_column_blob(s.stmt, C.int(i))
|
|
||||||
if p == nil && n > 0 {
|
|
||||||
return errors.New("got nil blob")
|
|
||||||
}
|
|
||||||
var data []byte
|
|
||||||
if n > 0 {
|
|
||||||
data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
|
|
||||||
}
|
|
||||||
switch v := v.(type) {
|
|
||||||
case *[]byte:
|
|
||||||
*v = data
|
|
||||||
case *string:
|
|
||||||
*v = string(data)
|
|
||||||
case *bool:
|
|
||||||
*v = string(data) == "1"
|
|
||||||
case *int:
|
|
||||||
x, err := strconv.Atoi(string(data))
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("arg " + strconv.Itoa(i) + " as int: " + err.Error())
|
|
||||||
}
|
|
||||||
*v = x
|
|
||||||
case *int64:
|
|
||||||
x, err := strconv.ParseInt(string(data), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
|
|
||||||
}
|
|
||||||
*v = x
|
|
||||||
case *float64:
|
|
||||||
x, err := strconv.ParseFloat(string(data), 64)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("arg " + strconv.Itoa(i) + " as float64: " + err.Error())
|
|
||||||
}
|
|
||||||
*v = x
|
|
||||||
default:
|
|
||||||
return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) SQL() string {
|
|
||||||
return s.sql + s.args
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Nanoseconds() int64 {
|
|
||||||
return time.Now().Sub(s.t0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Finalize() error {
|
|
||||||
rv := C.sqlite3_finalize(s.stmt)
|
|
||||||
if rv != 0 {
|
|
||||||
return s.c.error(rv)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) Close() error {
|
|
||||||
if c == nil || c.db == nil {
|
|
||||||
return errors.New("nil sqlite database")
|
|
||||||
}
|
|
||||||
rv := C.sqlite3_close(c.db)
|
|
||||||
if rv != 0 {
|
|
||||||
return c.error(rv)
|
|
||||||
}
|
|
||||||
c.db = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
123309
pkg/sqlite/sqlite3.c
123309
pkg/sqlite/sqlite3.c
File diff suppressed because it is too large
Load diff
6329
pkg/sqlite/sqlite3.h
6329
pkg/sqlite/sqlite3.h
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue