Commit d8830656 authored by gwenn's avatar gwenn

Move configuation specific functions to a dedicated file.

parent b4fde85e
// 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 <sqlite3.h>
//#include "_cgo_export.h"
int goSqlite3ConfigThreadMode(int mode) {
return sqlite3_config(mode);
}
int goSqlite3Config(int op, int mode) {
return sqlite3_config(op, mode);
}
\ No newline at end of file
// 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
/*
#include <sqlite3.h>
#include <stdlib.h>
// cgo doesn't support varargs
static inline int my_db_config(sqlite3 *db, int op, int v, int *ok) {
return sqlite3_db_config(db, op, v, ok);
}
int goSqlite3ConfigThreadMode(int mode);
int goSqlite3Config(int op, int mode);
*/
import "C"
import "unsafe"
// ThreadingMode enumerates SQLite threading mode
// See ConfigThreadingMode
type ThreadingMode int32
const (
SingleThread ThreadingMode = C.SQLITE_CONFIG_SINGLETHREAD
MultiThread ThreadingMode = C.SQLITE_CONFIG_MULTITHREAD
Serialized ThreadingMode = C.SQLITE_CONFIG_SERIALIZED
)
// ConfigThreadingMode alters threading mode.
// (See sqlite3_config(SQLITE_CONFIG_SINGLETHREAD|SQLITE_CONFIG_MULTITHREAD|SQLITE_CONFIG_SERIALIZED): http://sqlite.org/c3ref/config.html)
func ConfigThreadingMode(mode ThreadingMode) error {
rv := C.goSqlite3ConfigThreadMode(C.int(mode))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
// ConfigMemStatus enables or disables the collection of memory allocation statistics.
// (See sqlite3_config(SQLITE_CONFIG_MEMSTATUS): http://sqlite.org/c3ref/config.html)
func ConfigMemStatus(b bool) error {
rv := C.goSqlite3Config(C.SQLITE_CONFIG_MEMSTATUS, btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
// ConfigUri enables or disables URI handling.
// (See sqlite3_config(SQLITE_CONFIG_URI): http://sqlite.org/c3ref/config.html)
func ConfigUri(b bool) error {
rv := C.goSqlite3Config(C.SQLITE_CONFIG_URI, btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
// EnableSharedCache enables or disables shared pager cache
// (See http://sqlite.org/c3ref/enable_shared_cache.html)
func EnableSharedCache(b bool) error {
rv := C.sqlite3_enable_shared_cache(btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
// EnableFKey enables or disables the enforcement of foreign key constraints.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, b).
// Another way is PRAGMA foreign_keys = boolean;
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) EnableFKey(b bool) (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_FKEY, btocint(b))
}
// IsFKeyEnabled reports if the enforcement of foreign key constraints is enabled or not.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, -1).
// Another way is PRAGMA foreign_keys;
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) IsFKeyEnabled() (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_FKEY, -1)
}
// EnableTriggers enables or disables triggers.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_TRIGGER, b).
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) EnableTriggers(b bool) (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_TRIGGER, btocint(b))
}
// AreTriggersEnabled checks if triggers are enabled.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_TRIGGER, -1)
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) AreTriggersEnabled() (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_TRIGGER, -1)
}
func (c *Conn) queryOrSetEnableDbConfig(key, i C.int) (bool, error) {
var ok C.int
rv := C.my_db_config(c.db, key, i, &ok)
if rv == C.SQLITE_OK {
return (ok == 1), nil
}
return false, c.error(rv)
}
// EnableExtendedResultCodes enables or disables the extended result codes feature of SQLite.
// (See http://sqlite.org/c3ref/extended_result_codes.html)
func (c *Conn) EnableExtendedResultCodes(b bool) error {
return c.error(C.sqlite3_extended_result_codes(c.db, btocint(b)), "Conn.EnableExtendedResultCodes")
}
// EnableLoadExtension enables or disables extension loading.
// (See http://sqlite.org/c3ref/enable_load_extension.html)
func (c *Conn) EnableLoadExtension(b bool) error {
rv := C.sqlite3_enable_load_extension(c.db, btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return c.error(rv, "Conn.EnableLoadExtension")
}
// LoadExtension loads an extension
// (See http://sqlite.org/c3ref/load_extension.html)
func (c *Conn) LoadExtension(file string, proc ...string) error {
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
var cproc *C.char
if len(proc) > 0 {
cproc = C.CString(proc[0])
defer C.free(unsafe.Pointer(cproc))
}
var errMsg *C.char
rv := C.sqlite3_load_extension(c.db, cfile, cproc, &errMsg)
if rv != C.SQLITE_OK {
defer C.sqlite3_free(unsafe.Pointer(errMsg))
return c.error(rv, C.GoString(errMsg))
}
return nil
}
// 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_test
import (
"fmt"
"testing"
"github.com/bmizerany/assert"
. "github.com/gwenn/gosqlite"
)
func init() {
err := ConfigThreadingMode(Serialized)
if err != nil {
panic(fmt.Sprintf("cannot change threading mode: '%s'", err))
}
err = ConfigMemStatus(true)
if err != nil {
panic(fmt.Sprintf("cannot activate mem status: '%s'", err))
}
err = ConfigUri(true)
if err != nil {
panic(fmt.Sprintf("cannot activate uri handling: '%s'", err))
}
err = EnableSharedCache(false)
if err != nil {
panic(fmt.Sprintf("couldn't disable shared cache: '%s'", err))
}
}
func TestEnableFKey(t *testing.T) {
db := open(t)
defer checkClose(db, t)
b := Must(db.IsFKeyEnabled())
if !b {
b = Must(db.EnableFKey(true))
assert.T(t, b, "cannot enable FK")
}
}
func TestEnableTriggers(t *testing.T) {
db := open(t)
defer checkClose(db, t)
b := Must(db.AreTriggersEnabled())
if !b {
b = Must(db.EnableTriggers(true))
assert.T(t, b, "cannot enable triggers")
}
}
func TestEnableExtendedResultCodes(t *testing.T) {
db := open(t)
defer checkClose(db, t)
checkNoError(t, db.EnableExtendedResultCodes(true), "cannot enable extended result codes: %s")
}
func TestConnSettings(t *testing.T) {
db := open(t)
defer checkClose(db, t)
err := db.EnableLoadExtension(false)
checkNoError(t, err, "EnableLoadExtension error: %s")
err = db.SetRecursiveTriggers("main", true)
checkNoError(t, err, "SetRecursiveTriggers error: %s")
}
......@@ -10,11 +10,6 @@ package sqlite
#include <sqlite3.h>
#include <stdlib.h>
// cgo doesn't support varargs
static inline int my_db_config(sqlite3 *db, int op, int v, int *ok) {
return sqlite3_db_config(db, op, v, ok);
}
*/
import "C"
......@@ -257,55 +252,6 @@ func (c *Conn) BusyTimeout(d time.Duration) error {
return c.error(C.sqlite3_busy_timeout(c.db, C.int(d/time.Millisecond)), "Conn.BusyTimeout")
}
// EnableFKey enables or disables the enforcement of foreign key constraints.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, b).
// Another way is PRAGMA foreign_keys = boolean;
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) EnableFKey(b bool) (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_FKEY, btocint(b))
}
// IsFKeyEnabled reports if the enforcement of foreign key constraints is enabled or not.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, -1).
// Another way is PRAGMA foreign_keys;
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) IsFKeyEnabled() (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_FKEY, -1)
}
// EnableTriggers enables or disables triggers.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_TRIGGER, b).
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) EnableTriggers(b bool) (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_TRIGGER, btocint(b))
}
// AreTriggersEnabled checks if triggers are enabled.
// Calls sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_TRIGGER, -1)
//
// (See http://sqlite.org/c3ref/c_dbconfig_enable_fkey.html)
func (c *Conn) AreTriggersEnabled() (bool, error) {
return c.queryOrSetEnableDbConfig(C.SQLITE_DBCONFIG_ENABLE_TRIGGER, -1)
}
func (c *Conn) queryOrSetEnableDbConfig(key, i C.int) (bool, error) {
var ok C.int
rv := C.my_db_config(c.db, key, i, &ok)
if rv == C.SQLITE_OK {
return (ok == 1), nil
}
return false, c.error(rv)
}
// EnableExtendedResultCodes enables or disables the extended result codes feature of SQLite.
// (See http://sqlite.org/c3ref/extended_result_codes.html)
func (c *Conn) EnableExtendedResultCodes(b bool) error {
return c.error(C.sqlite3_extended_result_codes(c.db, btocint(b)), "Conn.EnableExtendedResultCodes")
}
// Readonly determines if a database is read-only.
// (See http://sqlite.org/c3ref/db_readonly.html)
func (c *Conn) Readonly(dbName string) (bool, error) {
......@@ -592,42 +538,3 @@ func (c *Conn) Close() error {
func (c *Conn) IsClosed() bool {
return c == nil || c.db == nil
}
// EnableLoadExtension enables or disables extension loading.
// (See http://sqlite.org/c3ref/enable_load_extension.html)
func (c *Conn) EnableLoadExtension(b bool) error {
rv := C.sqlite3_enable_load_extension(c.db, btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return c.error(rv, "Conn.EnableLoadExtension")
}
// LoadExtension loads an extension
// (See http://sqlite.org/c3ref/load_extension.html)
func (c *Conn) LoadExtension(file string, proc ...string) error {
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
var cproc *C.char
if len(proc) > 0 {
cproc = C.CString(proc[0])
defer C.free(unsafe.Pointer(cproc))
}
var errMsg *C.char
rv := C.sqlite3_load_extension(c.db, cfile, cproc, &errMsg)
if rv != C.SQLITE_OK {
defer C.sqlite3_free(unsafe.Pointer(errMsg))
return c.error(rv, C.GoString(errMsg))
}
return nil
}
// EnableSharedCache enables or disables shared pager cache
// (See http://sqlite.org/c3ref/enable_shared_cache.html)
func EnableSharedCache(b bool) error {
rv := C.sqlite3_enable_shared_cache(btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
......@@ -75,32 +75,6 @@ func TestOpenFailure(t *testing.T) {
//println(err.Error())
}
func TestEnableFKey(t *testing.T) {
db := open(t)
defer checkClose(db, t)
b := Must(db.IsFKeyEnabled())
if !b {
b = Must(db.EnableFKey(true))
assert.T(t, b, "cannot enable FK")
}
}
func TestEnableTriggers(t *testing.T) {
db := open(t)
defer checkClose(db, t)
b := Must(db.AreTriggersEnabled())
if !b {
b = Must(db.EnableTriggers(true))
assert.T(t, b, "cannot enable triggers")
}
}
func TestEnableExtendedResultCodes(t *testing.T) {
db := open(t)
defer checkClose(db, t)
checkNoError(t, db.EnableExtendedResultCodes(true), "cannot enable extended result codes: %s")
}
func TestCreateTable(t *testing.T) {
db := open(t)
defer checkClose(db, t)
......@@ -249,15 +223,6 @@ func TestReadonlyMisuse(t *testing.T) {
//println(err.Error())
}
func TestConnSettings(t *testing.T) {
db := open(t)
defer checkClose(db, t)
err := db.EnableLoadExtension(false)
checkNoError(t, err, "EnableLoadExtension error: %s")
err = db.SetRecursiveTriggers("main", true)
checkNoError(t, err, "SetRecursiveTriggers error: %s")
}
func TestComplete(t *testing.T) {
assert.T(t, Complete("SELECT 1;"), "expected complete statement")
}
......
......@@ -45,11 +45,3 @@ int goSqlite3ConfigLog(void *udp) {
return sqlite3_config(SQLITE_CONFIG_LOG, NULL, NULL);
}
}
int goSqlite3ConfigThreadMode(int mode) {
return sqlite3_config(mode);
}
int goSqlite3Config(int op, int mode) {
return sqlite3_config(op, mode);
}
\ No newline at end of file
......@@ -20,8 +20,6 @@ static inline void my_log(int iErrCode, char *msg) {
}
int goSqlite3ConfigLog(void *udp);
int goSqlite3ConfigThreadMode(int mode);
int goSqlite3Config(int op, int mode);
*/
import "C"
......@@ -393,46 +391,6 @@ func ConfigLog(f Logger, udp interface{}) error {
return Errno(rv)
}
// ThreadingMode enumerates SQLite threading mode
// See ConfigThreadingMode
type ThreadingMode int32
const (
SingleThread ThreadingMode = C.SQLITE_CONFIG_SINGLETHREAD
MultiThread ThreadingMode = C.SQLITE_CONFIG_MULTITHREAD
Serialized ThreadingMode = C.SQLITE_CONFIG_SERIALIZED
)
// ConfigThreadingMode alters threading mode.
// (See sqlite3_config(SQLITE_CONFIG_SINGLETHREAD|SQLITE_CONFIG_MULTITHREAD|SQLITE_CONFIG_SERIALIZED): http://sqlite.org/c3ref/config.html)
func ConfigThreadingMode(mode ThreadingMode) error {
rv := C.goSqlite3ConfigThreadMode(C.int(mode))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
// ConfigMemStatus enables or disables the collection of memory allocation statistics.
// (See sqlite3_config(SQLITE_CONFIG_MEMSTATUS): http://sqlite.org/c3ref/config.html)
func ConfigMemStatus(b bool) error {
rv := C.goSqlite3Config(C.SQLITE_CONFIG_MEMSTATUS, btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
// ConfigUri enables or disables URI handling.
// (See sqlite3_config(SQLITE_CONFIG_URI): http://sqlite.org/c3ref/config.html)
func ConfigUri(b bool) error {
rv := C.goSqlite3Config(C.SQLITE_CONFIG_URI, btocint(b))
if rv == C.SQLITE_OK {
return nil
}
return Errno(rv)
}
func (s *Stmt) ExplainQueryPlan(w io.Writer) error {
sql := s.SQL()
if len(sql) == 0 {
......
......@@ -15,33 +15,17 @@ import (
)
func init() {
err := ConfigThreadingMode(Serialized)
if err != nil {
panic(fmt.Sprintf("cannot change threading mode: '%s'", err))
}
err = ConfigMemStatus(true)
if err != nil {
panic(fmt.Sprintf("cannot activate mem status: '%s'", err))
}
err = ConfigUri(true)
if err != nil {
panic(fmt.Sprintf("cannot activate uri handling: '%s'", err))
}
if os.Getenv("SQLITE_LOG") == "" {
err = ConfigLog(func(d interface{}, err error, msg string) {
err := ConfigLog(func(d interface{}, err error, msg string) {
fmt.Printf("%s: %s, %s\n", d, err, msg)
}, "SQLITE")
if err != nil {
panic(fmt.Sprintf("couldn't config log: '%s'", err))
}
err = ConfigLog(nil, "")
}
if err != nil {
panic(fmt.Sprintf("couldn't unset logger: '%s'", err))
}
err = EnableSharedCache(false)
if err != nil {
panic(fmt.Sprintf("couldn't disable shared cache: '%s'", err))
if err != nil {
panic(fmt.Sprintf("couldn't unset logger: '%s'", err))
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment