Commit b5f02770 authored by gwenn's avatar gwenn

Introduce a FastExec method.

parent 9669acc1
......@@ -6,6 +6,7 @@ package sqlite_test
import (
. "github.com/gwenn/gosqlite"
"strings"
"testing"
)
......@@ -141,3 +142,27 @@ func BenchmarkNamedInsert(b *testing.B) {
}
panicOnError(b, db.Commit())
}
func BenchmarkExec(b *testing.B) {
b.StopTimer()
db, err := Open(":memory:")
panicOnError(b, err)
defer db.Close()
b.StartTimer()
for i := 0; i < b.N; i++ {
panicOnError(b, db.Exec(strings.Repeat("BEGIN;ROLLBACK;", 5)))
}
}
func BenchmarkFastExec(b *testing.B) {
b.StopTimer()
db, err := Open(":memory:")
panicOnError(b, err)
defer db.Close()
b.StartTimer()
for i := 0; i < b.N; i++ {
panicOnError(b, db.FastExec(strings.Repeat("BEGIN;ROLLBACK;", 5)))
}
}
......@@ -65,7 +65,7 @@ func (c *Conn) SchemaVersion(dbName string) (int, error) {
// Database name is optional (default is 'main').
// (See http://sqlite.org/pragma.html#pragma_recursive_triggers)
func (c *Conn) SetRecursiveTriggers(dbName string, on bool) error {
return c.exec(pragma(dbName, fmt.Sprintf("recursive_triggers=%t", on)))
return c.FastExec(pragma(dbName, fmt.Sprintf("recursive_triggers=%t", on)))
}
// JournalMode queries the current journaling mode for database.
......@@ -132,7 +132,7 @@ func (c *Conn) Synchronous(dbName string) (int, error) {
// Database name is optional (default is 'main').
// (See http://sqlite.org/pragma.html#pragma_synchronous)
func (c *Conn) SetSynchronous(dbName string, mode int) error {
return c.exec(pragma(dbName, fmt.Sprintf("synchronous=%d", mode)))
return c.FastExec(pragma(dbName, fmt.Sprintf("synchronous=%d", mode)))
}
// FkViolation is the description of one foreign key constraint violation.
......@@ -200,7 +200,7 @@ func (c *Conn) QueryOnly(dbName string) (bool, error) {
// Database name is optional (default is 'main').
// (See http://sqlite.org/pragma.html#pragma_query_only)
func (c *Conn) SetQueryOnly(dbName string, mode bool) error {
return c.exec(pragma(dbName, fmt.Sprintf("query_only=%t", mode)))
return c.FastExec(pragma(dbName, fmt.Sprintf("query_only=%t", mode)))
}
// ApplicationId queries the "Application ID" integer located into the database header.
......@@ -219,7 +219,7 @@ func (c *Conn) ApplicationId(dbName string) (int, error) {
// Database name is optional (default is 'main').
// (See http://sqlite.org/pragma.html#pragma_application_id)
func (c *Conn) SetApplicationId(dbName string, id int) error {
return c.exec(pragma(dbName, fmt.Sprintf("application_id=%d", id)))
return c.FastExec(pragma(dbName, fmt.Sprintf("application_id=%d", id)))
}
func pragma(dbName, pragmaName string) string {
......
......@@ -310,7 +310,7 @@ func (c *Conn) Filename(dbName string) string {
return C.GoString(C.sqlite3_db_filename(c.db, cname))
}
// Exec prepares and executes one parameterized statement or many statements (separated by semi-colon).
// Exec prepares and executes one or many parameterized statement(s) (separated by semi-colon).
// Don't use it with SELECT or anything that returns data.
func (c *Conn) Exec(cmd string, args ...interface{}) error {
for len(cmd) > 0 {
......@@ -422,11 +422,11 @@ func (c *Conn) Begin() error {
// (See http://www.sqlite.org/lang_transaction.html)
func (c *Conn) BeginTransaction(t TransactionType) error {
if t == Deferred {
return c.exec("BEGIN")
return c.FastExec("BEGIN")
} else if t == Immediate {
return c.exec("BEGIN IMMEDIATE")
return c.FastExec("BEGIN IMMEDIATE")
} else if t == Exclusive {
return c.exec("BEGIN EXCLUSIVE")
return c.FastExec("BEGIN EXCLUSIVE")
}
panic(fmt.Sprintf("Unsupported transaction type: '%#v'", t))
return nil // Go 1.1 unreachable code
......@@ -435,13 +435,13 @@ func (c *Conn) BeginTransaction(t TransactionType) error {
// Commit commits transaction
func (c *Conn) Commit() error {
// TODO Check autocommit?
return c.exec("COMMIT")
return c.FastExec("COMMIT")
}
// Rollback rollbacks transaction
func (c *Conn) Rollback() error {
// TODO Check autocommit?
return c.exec("ROLLBACK")
return c.FastExec("ROLLBACK")
}
// Transaction is used to execute a function inside an SQLite database transaction.
......@@ -492,19 +492,19 @@ func (c *Conn) Transaction(t TransactionType, f func(c *Conn) error) (err error)
// Savepoint starts a new transaction with a name.
// (See http://sqlite.org/lang_savepoint.html)
func (c *Conn) Savepoint(name string) error {
return c.exec(Mprintf("SAVEPOINT %Q", name))
return c.FastExec(Mprintf("SAVEPOINT %Q", name))
}
// ReleaseSavepoint causes all savepoints back to and including the most recent savepoint with a matching name to be removed from the transaction stack.
// (See http://sqlite.org/lang_savepoint.html)
func (c *Conn) ReleaseSavepoint(name string) error {
return c.exec(Mprintf("RELEASE %Q", name))
return c.FastExec(Mprintf("RELEASE %Q", name))
}
// RollbackSavepoint reverts the state of the database back to what it was just before the corresponding SAVEPOINT.
// (See http://sqlite.org/lang_savepoint.html)
func (c *Conn) RollbackSavepoint(name string) error {
return c.exec(Mprintf("ROLLBACK TO SAVEPOINT %Q", name))
return c.FastExec(Mprintf("ROLLBACK TO SAVEPOINT %Q", name))
}
func (c *Conn) exec(cmd string) error {
......@@ -514,12 +514,19 @@ func (c *Conn) exec(cmd string) error {
}
defer s.finalize()
rv := C.sqlite3_step(s.stmt)
if Errno(rv) != Done {
if Errno(rv) != Done { // this check cannot be done with sqlite3_exec
return s.error(rv, "Conn.exec(%q)", cmd)
}
return nil
}
// FastExec executes one or many non-parameterized statement(s) (separated by semi-colon) with no control and no stmt cache.
func (c *Conn) FastExec(cmd string) error {
cmdstr := C.CString(cmd)
defer C.free(unsafe.Pointer(cmdstr))
return c.error(C.sqlite3_exec(c.db, cmdstr, nil, nil, nil))
}
// Close closes a database connection and any dangling statements.
// (See http://sqlite.org/c3ref/close.html)
func (c *Conn) Close() error {
......
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