From 81b5da2d0f42a7315e417fe1143866a7cd43075a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net>
Date: Wed, 15 Jul 2015 20:34:18 -0500
Subject: [PATCH] SQLite: Adding benchmarks.

---
 sqlite/benchmark_test.go | 665 +++++++++++++++++++++++++++++++++++++++
 sqlite/database_test.go  | 210 -------------
 2 files changed, 665 insertions(+), 210 deletions(-)
 create mode 100644 sqlite/benchmark_test.go

diff --git a/sqlite/benchmark_test.go b/sqlite/benchmark_test.go
new file mode 100644
index 00000000..27447312
--- /dev/null
+++ b/sqlite/benchmark_test.go
@@ -0,0 +1,665 @@
+package sqlite
+
+import (
+	"fmt"
+	"math/rand"
+	"testing"
+
+	"github.com/jmoiron/sqlx"
+	"upper.io/db"
+)
+
+const (
+	testRows = 1000
+)
+
+func updatedArtistN(i int) string {
+	return fmt.Sprintf("Updated Artist %d", i%testRows)
+}
+
+func artistN(i int) string {
+	return fmt.Sprintf("Artist %d", i%testRows)
+}
+
+func connectAndAddFakeRows() (db.Database, error) {
+	var err error
+	var sess db.Database
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		return nil, err
+	}
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
+		return nil, err
+	}
+
+	for i := 0; i < testRows; i++ {
+		if _, err = driver.Exec(`INSERT INTO "artist" ("name") VALUES(?)`, artistN(i)); err != nil {
+			return nil, err
+		}
+	}
+
+	return sess, nil
+}
+
+// BenchmarkSQLAppend benchmarks raw INSERT SQL queries without using prepared
+// statements nor arguments.
+func BenchmarkSQLAppend(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
+		b.Fatal(err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = driver.Exec(`INSERT INTO "artist" ("name") VALUES('Hayao Miyazaki')`); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLAppendWithArgs benchmarks raw SQL queries with arguments but
+// without using prepared statements. The SQL query looks like the one that is
+// generated by upper.io/db.
+func BenchmarkSQLAppendWithArgs(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
+		b.Fatal(err)
+	}
+
+	args := []interface{}{
+		"Hayao Miyazaki",
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = driver.Exec(`INSERT INTO "artist" ("name") VALUES(?)`, args...); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLPreparedAppend benchmarks raw INSERT SQL queries using prepared
+// statements but no arguments.
+func BenchmarkSQLPreparedAppend(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
+		b.Fatal(err)
+	}
+
+	stmt, err := driver.Prepare(`INSERT INTO "artist" ("name") VALUES('Hayao Miyazaki')`)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = stmt.Exec(); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLAppendWithArgs benchmarks raw INSERT SQL queries with arguments
+// using prepared statements. The SQL query looks like the one that is
+// generated by upper.io/db.
+func BenchmarkSQLPreparedAppendWithArgs(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
+		b.Fatal(err)
+	}
+
+	stmt, err := driver.Prepare(`INSERT INTO "artist" ("name") VALUES(?)`)
+
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	args := []interface{}{
+		"Hayao Miyazaki",
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = stmt.Exec(args...); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLAppendWithVariableArgs benchmarks raw INSERT SQL queries with
+// arguments using prepared statements. The SQL query looks like the one that
+// is generated by upper.io/db.
+func BenchmarkSQLPreparedAppendWithVariableArgs(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
+		b.Fatal(err)
+	}
+
+	stmt, err := driver.Prepare(`INSERT INTO "artist" ("name") VALUES(?)`)
+
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		args := []interface{}{
+			fmt.Sprintf("Hayao Miyazaki %d", rand.Int()),
+		}
+		if _, err = stmt.Exec(args...); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLPreparedAppendTransactionWithArgs benchmarks raw INSERT queries
+// within a transaction block with arguments and prepared statements. SQL
+// queries look like those generated by upper.io/db.
+func BenchmarkSQLPreparedAppendTransactionWithArgs(b *testing.B) {
+	var err error
+	var sess db.Database
+	var tx *sqlx.Tx
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	if tx, err = driver.Beginx(); err != nil {
+		b.Fatal(err)
+	}
+
+	if _, err = tx.Exec(`DELETE FROM "artist"`); err != nil {
+		b.Fatal(err)
+	}
+
+	stmt, err := tx.Preparex(`INSERT INTO "artist" ("name") VALUES(?)`)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	args := []interface{}{
+		"Hayao Miyazaki",
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = stmt.Exec(args...); err != nil {
+			b.Fatal(err)
+		}
+	}
+
+	if err = tx.Commit(); err != nil {
+		b.Fatal(err)
+	}
+}
+
+// BenchmarkUpperAppend benchmarks an insertion by upper.io/db.
+func BenchmarkUpperAppend(b *testing.B) {
+
+	sess, err := db.Open(Adapter, settings)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	artist, err := sess.Collection("artist")
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	artist.Truncate()
+
+	item := struct {
+		Name string `db:"name"`
+	}{"Hayao Miyazaki"}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = artist.Append(item); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkUpperAppendVariableArgs benchmarks an insertion by upper.io/db
+// with variable parameters.
+func BenchmarkUpperAppendVariableArgs(b *testing.B) {
+
+	sess, err := db.Open(Adapter, settings)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	artist, err := sess.Collection("artist")
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	artist.Truncate()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		item := struct {
+			Name string `db:"name"`
+		}{fmt.Sprintf("Hayao Miyazaki %d", rand.Int())}
+		if _, err = artist.Append(item); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkUpperAppendTransaction benchmarks insertion queries by upper.io/db
+// within a transaction operation.
+func BenchmarkUpperAppendTransaction(b *testing.B) {
+	var sess db.Database
+	var err error
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	var tx db.Tx
+	if tx, err = sess.Transaction(); err != nil {
+		b.Fatal(err)
+	}
+
+	var artist db.Collection
+	if artist, err = tx.Collection("artist"); err != nil {
+		b.Fatal(err)
+	}
+
+	if err = artist.Truncate(); err != nil {
+		b.Fatal(err)
+	}
+
+	item := struct {
+		Name string `db:"name"`
+	}{"Hayao Miyazaki"}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = artist.Append(item); err != nil {
+			b.Fatal(err)
+		}
+	}
+
+	if err = tx.Commit(); err != nil {
+		b.Fatal(err)
+	}
+}
+
+// BenchmarkUpperAppendTransactionWithMap benchmarks insertion queries by
+// upper.io/db within a transaction operation using a map instead of a struct.
+func BenchmarkUpperAppendTransactionWithMap(b *testing.B) {
+	var sess db.Database
+	var err error
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	var tx db.Tx
+	if tx, err = sess.Transaction(); err != nil {
+		b.Fatal(err)
+	}
+
+	var artist db.Collection
+	if artist, err = tx.Collection("artist"); err != nil {
+		b.Fatal(err)
+	}
+
+	if err = artist.Truncate(); err != nil {
+		b.Fatal(err)
+	}
+
+	item := map[string]string{
+		"name": "Hayao Miyazaki",
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = artist.Append(item); err != nil {
+			b.Fatal(err)
+		}
+	}
+
+	if err = tx.Commit(); err != nil {
+		b.Fatal(err)
+	}
+}
+
+// BenchmarkSQLSelect benchmarks SQL SELECT queries.
+func BenchmarkSQLSelect(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	var res *sqlx.Rows
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if res, err = driver.Queryx(`SELECT * FROM "artist" WHERE "name" = ?`, artistN(i)); err != nil {
+			b.Fatal(err)
+		}
+		res.Close()
+	}
+}
+
+// BenchmarkSQLPreparedSelect benchmarks SQL select queries using prepared
+// statements.
+func BenchmarkSQLPreparedSelect(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	stmt, err := driver.Preparex(`SELECT * FROM "artist" WHERE "name" = ?`)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	var res *sqlx.Rows
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if res, err = stmt.Queryx(artistN(i)); err != nil {
+			b.Fatal(err)
+		}
+		res.Close()
+	}
+}
+
+// BenchmarkUpperFind benchmarks upper.io/db's One method.
+func BenchmarkUpperFind(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	artist, err := sess.Collection("artist")
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	type artistType struct {
+		Name string `db:"name"`
+	}
+
+	var item artistType
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		res := artist.Find(db.Cond{"name": artistN(i)})
+		if err = res.One(&item); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkUpperFindAll benchmarks upper.io/db's All method.
+func BenchmarkUpperFindAll(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	artist, err := sess.Collection("artist")
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	type artistType struct {
+		Name string `db:"name"`
+	}
+
+	var items []artistType
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		res := artist.Find(db.Or{
+			db.Cond{"name": artistN(i)},
+			db.Cond{"name": artistN(i + 1)},
+			db.Cond{"name": artistN(i + 2)},
+		})
+		if err = res.All(&items); err != nil {
+			b.Fatal(err)
+		}
+		if len(items) != 3 {
+			b.Fatal("Expecting 3 results.")
+		}
+	}
+}
+
+// BenchmarkSQLUpdate benchmarks SQL UPDATE queries.
+func BenchmarkSQLUpdate(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = driver.Exec(`UPDATE "artist" SET "name" = ? WHERE "name" = ?`, updatedArtistN(i), artistN(i)); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLPreparedUpdate benchmarks SQL UPDATE queries.
+func BenchmarkSQLPreparedUpdate(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	stmt, err := driver.Prepare(`UPDATE "artist" SET "name" = ? WHERE "name" = ?`)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = stmt.Exec(updatedArtistN(i), artistN(i)); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkUpperUpdate benchmarks upper.io/db's Update method.
+func BenchmarkUpperUpdate(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	artist, err := sess.Collection("artist")
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	type artistType struct {
+		Name string `db:"name"`
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		newValue := artistType{
+			Name: updatedArtistN(i),
+		}
+		res := artist.Find(db.Cond{"name": artistN(i)})
+		if err = res.Update(newValue); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLDelete benchmarks SQL DELETE queries.
+func BenchmarkSQLDelete(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = driver.Exec(`DELETE FROM "artist" WHERE "name" = ?`, artistN(i)); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkSQLPreparedDelete benchmarks SQL DELETE queries.
+func BenchmarkSQLPreparedDelete(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+	defer sess.Close()
+
+	driver := sess.Driver().(*sqlx.DB)
+
+	stmt, err := driver.Prepare(`DELETE FROM "artist" WHERE "name" = ?`)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = stmt.Exec(artistN(i)); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// BenchmarkUpperRemove benchmarks
+func BenchmarkUpperRemove(b *testing.B) {
+	var err error
+	var sess db.Database
+
+	if sess, err = connectAndAddFakeRows(); err != nil {
+		b.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	artist, err := sess.Collection("artist")
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		res := artist.Find(db.Cond{"name": artistN(i)})
+		if err = res.Remove(); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/sqlite/database_test.go b/sqlite/database_test.go
index bae89a2e..4edf13cb 100644
--- a/sqlite/database_test.go
+++ b/sqlite/database_test.go
@@ -1369,213 +1369,3 @@ func TestDataTypes(t *testing.T) {
 		t.Fatalf("Struct is different.")
 	}
 }
-
-// Benchmarking raw database/sql.
-func BenchmarkAppendRawSQL(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	driver := sess.Driver().(*sqlx.DB)
-
-	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
-		b.Fatal(err)
-	}
-
-	stmt, err := driver.Prepare(`INSERT INTO "artist" ("name") VALUES('Hayao Miyazaki')`)
-	if err != nil {
-		b.Fatal(err)
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err = stmt.Exec(); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-func BenchmarkAppendRawSQLWithArgs(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	driver := sess.Driver().(*sqlx.DB)
-
-	if _, err = driver.Exec(`DELETE FROM "artist"`); err != nil {
-		b.Fatal(err)
-	}
-
-	stmt, err := driver.Prepare(`INSERT INTO "artist" ("name") VALUES(?) RETURNING "id"`)
-	if err != nil {
-		b.Fatal(err)
-	}
-
-	args := []interface{}{
-		"Hayao Miyazaki",
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err = stmt.Query(args...); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-// Benchmarking Append().
-//
-// Contributed by wei2912
-// See: https://github.com/gosexy/db/issues/20#issuecomment-20097801
-func BenchmarkAppendUpper(b *testing.B) {
-	sess, err := db.Open(Adapter, settings)
-
-	if err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	artist, err := sess.Collection("artist")
-	artist.Truncate()
-
-	item := struct {
-		Name string `db:"name"`
-	}{"Hayao Miyazaki"}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err = artist.Append(item); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-// Benchmarking raw database/sql.
-func BenchmarkAppendTxRawSQL(b *testing.B) {
-	var err error
-	var sess db.Database
-	var tx *sql.Tx
-
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	driver := sess.Driver().(*sqlx.DB)
-
-	if tx, err = driver.Begin(); err != nil {
-		b.Fatal(err)
-	}
-
-	if _, err = tx.Exec(`DELETE FROM "artist"`); err != nil {
-		b.Fatal(err)
-	}
-
-	stmt, err := tx.Prepare(`INSERT INTO "artist" ("name") VALUES('Hayao Miyazaki')`)
-	if err != nil {
-		b.Fatal(err)
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err = stmt.Exec(); err != nil {
-			b.Fatal(err)
-		}
-	}
-
-	if err = tx.Commit(); err != nil {
-		b.Fatal(err)
-	}
-}
-
-// Benchmarking Append() with transactions.
-func BenchmarkAppendTxUpper(b *testing.B) {
-	var sess db.Database
-	var err error
-
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	var tx db.Tx
-	if tx, err = sess.Transaction(); err != nil {
-		b.Fatal(err)
-	}
-
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
-
-	if err = artist.Truncate(); err != nil {
-		b.Fatal(err)
-	}
-
-	item := struct {
-		Name string `db:"name"`
-	}{"Hayao Miyazaki"}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err = artist.Append(item); err != nil {
-			b.Fatal(err)
-		}
-	}
-
-	if err = tx.Commit(); err != nil {
-		b.Fatal(err)
-	}
-}
-
-// Benchmarking Append() with map.
-func BenchmarkAppendTxUpperMap(b *testing.B) {
-	var sess db.Database
-	var err error
-
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	var tx db.Tx
-	if tx, err = sess.Transaction(); err != nil {
-		b.Fatal(err)
-	}
-
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
-
-	if err = artist.Truncate(); err != nil {
-		b.Fatal(err)
-	}
-
-	item := map[string]string{"name": "Hayao Miyazaki"}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err = artist.Append(item); err != nil {
-			b.Fatal(err)
-		}
-	}
-
-	if err = tx.Commit(); err != nil {
-		b.Fatal(err)
-	}
-}
-- 
GitLab