From 69b156d7d5a3dfdf8bf0af9adc7c3d58bc03c90c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net>
Date: Sun, 20 Mar 2016 12:21:16 -0600
Subject: [PATCH] Changing Collection() signature. Closes #148

---
 db.go                           |  15 ++--
 db_test.go                      |  42 +--------
 internal/schema/schema.go       |  82 +++++++++++-------
 internal/sqladapter/database.go |  36 ++------
 mongo/benchmark_test.go         |  63 ++------------
 mongo/database.go               |  21 +----
 mongo/database_test.go          |  63 +++-----------
 mysql/benchmark_test.go         |  98 +++------------------
 mysql/database.go               | 125 ++++++++-------------------
 mysql/database_test.go          |  81 +++++------------
 postgresql/benchmark_test.go    | 100 +++------------------
 postgresql/database.go          | 127 ++++++++-------------------
 postgresql/database_test.go     | 132 +++++++---------------------
 ql/benchmark_test.go            |  98 +++------------------
 ql/database.go                  |  93 +++++---------------
 ql/database_test.go             | 148 +++++---------------------------
 sqlite/benchmark_test.go        |  98 +++------------------
 sqlite/database.go              | 134 +++++++++++------------------
 sqlite/database_test.go         |  81 +++++------------
 19 files changed, 370 insertions(+), 1267 deletions(-)

diff --git a/db.go b/db.go
index 216d1927..961b37f9 100644
--- a/db.go
+++ b/db.go
@@ -193,15 +193,12 @@ type Database interface {
 	// Close closes the currently active connection to the database.
 	Close() error
 
-	// C is a short-hand for `Collection()`. If the given collection does not
-	// exists subsequent calls to any `Collection{}` or `Result{}` method that
-	// expect the collection to exists will fail returning the original error a
-	// call to `Collection()` would have returned. The output of `C()` may be a
-	// cached collection value.
-	C(string) Collection
-
-	// Collection returns a `Collection{}` given a table name.
-	Collection(string) (Collection, error)
+	// Collection returns a Collection given a table name. The collection may or
+	// may not exists and that could be an error when querying depending on the
+	// database you're working with, MongoDB does not care but SQL databases do
+	// care. If you want to know if a Collection exists use the Exists() method
+	// on a Collection.
+	Collection(string) Collection
 
 	// Collections returns the names of all non-system tables on the database.
 	Collections() ([]string, error)
diff --git a/db_test.go b/db_test.go
index ad9692ba..fdaac5b1 100644
--- a/db_test.go
+++ b/db_test.go
@@ -549,18 +549,9 @@ func TestSimpleCRUD(t *testing.T) {
 				BornUT: timeType{born},
 			}
 
-			col, err := sess.Collection(`birthdays`)
-
-			if err != nil {
-				if wrapper == `mongo` && err == db.ErrCollectionDoesNotExist {
-					// Expected error with mongodb.
-				} else {
-					t.Fatalf(`Could not use collection with wrapper %s: %q`, wrapper, err)
-				}
-			}
+			col := sess.Collection(`birthdays`)
 
 			var id interface{}
-
 			if id, err = col.Append(controlItem); err != nil {
 				t.Fatalf(`Could not append item with wrapper %s: %q`, wrapper, err)
 			}
@@ -693,16 +684,7 @@ func TestFibonacci(t *testing.T) {
 			}
 			defer sess.Close()
 
-			var col db.Collection
-			col, err = sess.Collection("fibonacci")
-
-			if err != nil {
-				if wrapper == `mongo` && err == db.ErrCollectionDoesNotExist {
-					// Expected error with mongodb.
-				} else {
-					t.Fatalf(`Could not use collection with wrapper %s: %q`, wrapper, err)
-				}
-			}
+			col := sess.Collection("fibonacci")
 
 			// Adding some items.
 			var i uint64
@@ -962,16 +944,7 @@ func TestEven(t *testing.T) {
 			}
 			defer sess.Close()
 
-			var col db.Collection
-			col, err = sess.Collection("is_even")
-
-			if err != nil {
-				if wrapper == `mongo` && err == db.ErrCollectionDoesNotExist {
-					// Expected error with mongodb.
-				} else {
-					t.Fatalf(`Could not use collection with wrapper %s: %q`, wrapper, err)
-				}
-			}
+			col := sess.Collection("is_even")
 
 			// Adding some items.
 			var i int
@@ -1067,7 +1040,6 @@ func TestEven(t *testing.T) {
 
 func TestExplicitAndDefaultMapping(t *testing.T) {
 	var err error
-	var col db.Collection
 	var sess db.Database
 	var res db.Result
 
@@ -1087,13 +1059,7 @@ func TestExplicitAndDefaultMapping(t *testing.T) {
 
 			defer sess.Close()
 
-			if col, err = sess.Collection("CaSe_TesT"); err != nil {
-				if wrapper == `mongo` && err == db.ErrCollectionDoesNotExist {
-					// Nothing, this is expected.
-				} else {
-					t.Fatal(err)
-				}
-			}
+			col := sess.Collection("CaSe_TesT")
 
 			if err = col.Truncate(); err != nil {
 				if wrapper == `mongo` {
diff --git a/internal/schema/schema.go b/internal/schema/schema.go
index 76272006..3293466e 100644
--- a/internal/schema/schema.go
+++ b/internal/schema/schema.go
@@ -22,52 +22,74 @@
 // Package schema provides basic information on relational database schemas.
 package schema
 
+import (
+	"sync"
+)
+
 // DatabaseSchema represents a collection of tables.
 type DatabaseSchema struct {
-	Name      string
-	Alias     string
-	Tables    []string
-	TableInfo map[string]*TableSchema
+	name   string
+	tables map[string]*TableSchema
+
+	mu sync.RWMutex
 }
 
 // TableSchema represents a single table.
 type TableSchema struct {
-	PrimaryKey []string
-	Alias      string
-	Columns    []string
+	pk []string
+
+	mu sync.RWMutex
 }
 
 // NewDatabaseSchema creates and returns a database schema.
 func NewDatabaseSchema() *DatabaseSchema {
-	schema := new(DatabaseSchema)
-	schema.Tables = []string{}
-	schema.TableInfo = make(map[string]*TableSchema)
-	return schema
+	s := &DatabaseSchema{
+		tables: make(map[string]*TableSchema),
+	}
+	return s
 }
 
-// AddTable adds a table into the database schema. If the table does not exists
-// it is created before being added.
-func (d *DatabaseSchema) AddTable(name string) {
-	if _, ok := d.TableInfo[name]; !ok {
-		table := new(TableSchema)
-		table.PrimaryKey = []string{}
-		table.Columns = []string{}
-		d.TableInfo[name] = table
-		d.Tables = append(d.Tables, name)
-	}
+// Name returns the name of the database.
+func (s *DatabaseSchema) Name() string {
+	s.mu.RLock()
+	defer s.mu.RUnlock()
+	return s.name
+}
+
+// Set name sets the name of the database.
+func (s *DatabaseSchema) SetName(name string) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.name = name
 }
 
 // Table retrives a table from the schema.
-func (d *DatabaseSchema) Table(name string) *TableSchema {
-	d.AddTable(name)
-	return d.TableInfo[name]
+func (s *DatabaseSchema) Table(name string) *TableSchema {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	if _, ok := s.tables[name]; !ok {
+		s.tables[name] = &TableSchema{}
+	}
+
+	return s.tables[name]
 }
 
-// HasTable returns true if the given table is already defined within the
-// schema.
-func (d *DatabaseSchema) HasTable(name string) bool {
-	if _, ok := d.TableInfo[name]; ok {
-		return true
+func (t *TableSchema) SetPrimaryKeys(pk []string) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
+	if len(pk) == 0 {
+		t.pk = []string{} // if nil or empty array
+		return
 	}
-	return false
+
+	t.pk = pk
+}
+
+func (t *TableSchema) PrimaryKeys() []string {
+	t.mu.RLock()
+	defer t.mu.RUnlock()
+
+	return t.pk
 }
diff --git a/internal/sqladapter/database.go b/internal/sqladapter/database.go
index 8332b439..094145bb 100644
--- a/internal/sqladapter/database.go
+++ b/internal/sqladapter/database.go
@@ -10,7 +10,6 @@ import (
 	"upper.io/db.v2/builder/cache"
 	"upper.io/db.v2/builder/sqlbuilder"
 	"upper.io/db.v2/builder/sqlgen"
-	"upper.io/db.v2/internal/adapter"
 	"upper.io/db.v2/internal/debug"
 	"upper.io/db.v2/internal/schema"
 	"upper.io/db.v2/internal/sqlutil/tx"
@@ -92,8 +91,9 @@ func (d *BaseDatabase) Tx() *sqltx.Tx {
 	return d.tx
 }
 
-func (d *BaseDatabase) NewSchema() {
+func (d *BaseDatabase) NewSchema() *schema.DatabaseSchema {
 	d.schema = schema.NewDatabaseSchema()
+	return d.schema
 }
 
 func (d *BaseDatabase) Schema() *schema.DatabaseSchema {
@@ -146,39 +146,19 @@ func (d *BaseDatabase) Close() error {
 	return nil
 }
 
-// C returns a collection interface.
-func (d *BaseDatabase) C(name string) db.Collection {
+// Collection returns a Collection given a name.
+func (d *BaseDatabase) Collection(name string) db.Collection {
+	d.collectionsMu.Lock()
 	if c, ok := d.collections[name]; ok {
+		d.collectionsMu.Unlock()
 		return c
 	}
 
-	c, err := d.Collection(name)
-	if err != nil {
-		return &adapter.NonExistentCollection{Err: err}
-	}
-
-	return c
-}
-
-// Collection returns the table that matches the given name.
-func (d *BaseDatabase) Collection(name string) (db.Collection, error) {
-	if d.tx != nil {
-		if d.tx.Done() {
-			return nil, sql.ErrTxDone
-		}
-	}
-
-	if err := d.partial.TableExists(name); err != nil {
-		return nil, err
-	}
-
 	col := d.partial.NewTable(name)
-
-	d.collectionsMu.Lock()
 	d.collections[name] = col
 	d.collectionsMu.Unlock()
 
-	return col, nil
+	return col
 }
 
 func (d *BaseDatabase) ConnectionURL() db.ConnectionURL {
@@ -187,7 +167,7 @@ func (d *BaseDatabase) ConnectionURL() db.ConnectionURL {
 
 // Name returns the name of the database.
 func (d *BaseDatabase) Name() string {
-	return d.schema.Name
+	return d.schema.Name()
 }
 
 // Exec compiles and executes a statement that does not return any rows.
diff --git a/mongo/benchmark_test.go b/mongo/benchmark_test.go
index c15d72da..ca6d3a81 100644
--- a/mongo/benchmark_test.go
+++ b/mongo/benchmark_test.go
@@ -80,10 +80,7 @@ func BenchmarkUpperAppend(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -110,10 +107,7 @@ func BenchmarkUpperAppendVariableArgs(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -193,10 +187,7 @@ func BenchmarkUpperFind(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `bson:"name"`
@@ -213,32 +204,6 @@ func BenchmarkUpperFind(b *testing.B) {
 	}
 }
 
-// BenchmarkUpperFindWithC benchmarks upper.io/db.v2's One method.
-func BenchmarkUpperFindWithC(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = connectAndAddFakeRows(); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	type artistType struct {
-		Name string `db:"name"`
-	}
-
-	var item artistType
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		res := sess.C("artist").Find(db.Cond{"name": artistN(i)})
-		if err = res.One(&item); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
 // BenchmarkUpperFindAll benchmarks upper.io/db.v2's All method.
 func BenchmarkUpperFindAll(b *testing.B) {
 	var err error
@@ -250,10 +215,7 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `bson:"name"`
@@ -309,10 +271,7 @@ func BenchmarkUpperUpdate(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `bson:"name"`
@@ -362,10 +321,7 @@ func BenchmarkUpperRemove(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
@@ -389,10 +345,7 @@ func BenchmarkUpperGetCollection(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := sess.Collection("artist")
-		if err != nil {
-			b.Fatal(err)
-		}
+		sess.Collection("artist")
 	}
 }
 
@@ -409,6 +362,6 @@ func BenchmarkUpperC(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		sess.C("artist")
+		sess.Collection("artist")
 	}
 }
diff --git a/mongo/database.go b/mongo/database.go
index 55ab52a3..44d61e4b 100644
--- a/mongo/database.go
+++ b/mongo/database.go
@@ -156,21 +156,8 @@ func (s *Source) Collections() (cols []string, err error) {
 	return cols, nil
 }
 
-// C returns a collection interface.
-func (s *Source) C(name string) db.Collection {
-	if col, ok := s.collections[name]; ok {
-		// We can safely ignore if the collection exists or not.
-		return col
-	}
-
-	c, _ := s.Collection(name)
-	return c
-}
-
 // Collection returns a collection by name.
-func (s *Source) Collection(name string) (db.Collection, error) {
-	var err error
-
+func (s *Source) Collection(name string) db.Collection {
 	s.collectionsMu.Lock()
 	defer s.collectionsMu.Unlock()
 
@@ -185,11 +172,7 @@ func (s *Source) Collection(name string) (db.Collection, error) {
 		s.collections[name] = col
 	}
 
-	if !col.Exists() {
-		err = db.ErrCollectionDoesNotExist
-	}
-
-	return col, err
+	return col
 }
 
 func (s *Source) versionAtLeast(version ...int) bool {
diff --git a/mongo/database_test.go b/mongo/database_test.go
index 3bf44d6f..93e297db 100644
--- a/mongo/database_test.go
+++ b/mongo/database_test.go
@@ -239,10 +239,7 @@ func TestTruncate(t *testing.T) {
 	for _, name := range collections {
 
 		// Pointing the collection.
-		col, err := sess.Collection(name)
-		if err != nil {
-			t.Fatal(err)
-		}
+		col := sess.Collection(name)
 
 		// The collection may ot may not exists.
 		exists := col.Exists()
@@ -276,14 +273,7 @@ func TestAppend(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
-		// We can use the collection even if it does not exists.
-		if err != db.ErrCollectionDoesNotExist {
-			t.Fatal(err)
-		}
-	}
+	artist := sess.Collection("artist")
 
 	// Appending a map.
 	id, err = artist.Append(map[string]string{
@@ -423,7 +413,7 @@ func TestResultCount(t *testing.T) {
 	defer sess.Close()
 
 	// We should close the database when it's no longer in use.
-	artist, _ := sess.Collection("artist")
+	artist := sess.Collection("artist")
 
 	res = artist.Find()
 
@@ -457,18 +447,10 @@ func TestGroup(t *testing.T) {
 
 	defer sess.Close()
 
-	if stats, err = sess.Collection("statsTest"); err != nil {
-		if err != db.ErrCollectionDoesNotExist {
-			t.Fatal(err)
-		}
-	}
+	stats = sess.Collection("statsTest")
 
 	// Truncating table.
-	if err == nil {
-		if err = stats.Truncate(); err != nil {
-			t.Fatal(err)
-		}
-	}
+	stats.Truncate()
 
 	// Adding row append.
 	for i := 0; i < 1000; i++ {
@@ -512,7 +494,7 @@ func TestResultNonExistentCount(t *testing.T) {
 
 	defer sess.Close()
 
-	total, err := sess.C("notartist").Find().Count()
+	total, err := sess.Collection("notartist").Find().Count()
 
 	if err != nil {
 		t.Fatal("MongoDB should not care about a non-existent collecton.", err)
@@ -539,11 +521,7 @@ func TestResultFetch(t *testing.T) {
 	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Testing map
 	res = artist.Find()
@@ -709,11 +687,7 @@ func TestUpdate(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Value
 	value := struct {
@@ -810,11 +784,7 @@ func TestOperators(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	rowS := struct {
 		ID   uint64
@@ -846,11 +816,7 @@ func TestRemove(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Getting the first artist.
 	res := artist.Find(db.Cond{"_id $ne": nil}).Limit(1)
@@ -889,11 +855,7 @@ func TestSetterAndConstrainer(t *testing.T) {
 
 	defer sess.Close()
 
-	if compositeKeys, err = sess.Collection("composite_keys"); err != nil {
-		if err != db.ErrCollectionDoesNotExist {
-			t.Fatal(err)
-		}
-	}
+	compositeKeys = sess.Collection("composite_keys")
 
 	//n := rand.Intn(100000)
 
@@ -953,8 +915,7 @@ func TestDataTypes(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "data_types" collection.
-	dataTypes, err := sess.Collection("data_types")
-	dataTypes.Truncate()
+	dataTypes := sess.Collection("data_types")
 
 	// Appending our test subject.
 	id, err := dataTypes.Append(testValues)
diff --git a/mysql/benchmark_test.go b/mysql/benchmark_test.go
index 0aa29074..17faf062 100644
--- a/mysql/benchmark_test.go
+++ b/mysql/benchmark_test.go
@@ -261,10 +261,7 @@ func BenchmarkUpperAppend(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -291,10 +288,7 @@ func BenchmarkUpperAppendVariableArgs(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -327,10 +321,7 @@ func BenchmarkUpperAppendTransaction(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -370,10 +361,7 @@ func BenchmarkUpperAppendTransactionWithMap(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -459,10 +447,7 @@ func BenchmarkUpperFind(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -479,32 +464,6 @@ func BenchmarkUpperFind(b *testing.B) {
 	}
 }
 
-// BenchmarkUpperFindWithC benchmarks upper.io/db.v2's One method.
-func BenchmarkUpperFindWithC(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = connectAndAddFakeRows(); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	type artistType struct {
-		Name string `db:"name"`
-	}
-
-	var item artistType
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		res := sess.C("artist").Find(db.Cond{"name": artistN(i)})
-		if err = res.One(&item); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
 // BenchmarkUpperFindAll benchmarks upper.io/db.v2's All method.
 func BenchmarkUpperFindAll(b *testing.B) {
 	var err error
@@ -516,10 +475,7 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -601,10 +557,7 @@ func BenchmarkUpperUpdate(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -679,10 +632,7 @@ func BenchmarkUpperRemove(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
@@ -706,27 +656,7 @@ func BenchmarkUpperGetCollection(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := sess.Collection("artist")
-		if err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-// BenchmarkUpperC
-func BenchmarkUpperC(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()
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sess.C("artist")
+		sess.Collection("artist")
 	}
 }
 
@@ -749,10 +679,7 @@ func BenchmarkUpperCommitManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
@@ -793,10 +720,7 @@ func BenchmarkUpperRollbackManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
diff --git a/mysql/database.go b/mysql/database.go
index 7da20f45..95485b09 100644
--- a/mysql/database.go
+++ b/mysql/database.go
@@ -27,9 +27,9 @@ import (
 	"database/sql"
 
 	_ "github.com/go-sql-driver/mysql" // MySQL driver.
+	"upper.io/db.v2"
 	"upper.io/db.v2/builder/sqlgen"
 	template "upper.io/db.v2/builder/template/mysql"
-	"upper.io/db.v2"
 	"upper.io/db.v2/internal/sqladapter"
 	"upper.io/db.v2/internal/sqlutil/tx"
 )
@@ -107,31 +107,29 @@ func (d *database) NewTable(name string) db.Collection {
 // Collections returns a list of non-system tables from the database.
 func (d *database) Collections() (collections []string, err error) {
 
-	if len(d.Schema().Tables) == 0 {
-		q := d.Builder().Select("table_name").
-			From("information_schema.tables").
-			Where("table_schema = ?", d.Schema().Name)
+	q := d.Builder().Select("table_name").
+		From("information_schema.tables").
+		Where("table_schema = ?", d.Schema().Name())
 
-		iter := q.Iterator()
-		defer iter.Close()
+	iter := q.Iterator()
+	defer iter.Close()
 
-		for iter.Next() {
-			var tableName string
-			if err := iter.Scan(&tableName); err != nil {
-				return nil, err
-			}
-			d.Schema().AddTable(tableName)
+	for iter.Next() {
+		var tableName string
+		if err := iter.Scan(&tableName); err != nil {
+			return nil, err
 		}
+		collections = append(collections, tableName)
 	}
 
-	return d.Schema().Tables, nil
+	return collections, nil
 }
 
 // Drop removes all tables from the current database.
 func (d *database) Drop() error {
 	stmt := &sqlgen.Statement{
 		Type:     sqlgen.DropDatabase,
-		Database: sqlgen.DatabaseWithName(d.Schema().Name),
+		Database: sqlgen.DatabaseWithName(d.Schema().Name()),
 	}
 	if _, err := d.Builder().Exec(stmt); err != nil {
 		return err
@@ -166,105 +164,52 @@ func (d *database) Transaction() (db.Tx, error) {
 
 // PopulateSchema looks up for the table info in the database and populates its
 // schema for internal use.
-func (d *database) PopulateSchema() (err error) {
-	var collections []string
-
-	d.NewSchema()
+func (d *database) PopulateSchema() error {
+	schema := d.NewSchema()
 
 	q := d.Builder().Select(db.Raw("DATABASE() AS name"))
 
-	var dbName string
-
 	iter := q.Iterator()
 	defer iter.Close()
 
 	if iter.Next() {
-		if err := iter.Scan(&dbName); err != nil {
-			return err
-		}
-	} else {
-		return iter.Err()
-	}
-
-	d.Schema().Name = dbName
-
-	if collections, err = d.Collections(); err != nil {
+		var name string
+		err := iter.Scan(&name)
+		schema.SetName(name)
 		return err
 	}
-
-	for i := range collections {
-		if _, err = d.Collection(collections[i]); err != nil {
-			return err
-		}
-	}
-
-	return err
+	return iter.Err()
 }
 
 // TableExists checks whether a table exists and returns an error in case it doesn't.
 func (d *database) TableExists(name string) error {
-	if d.Schema().HasTable(name) {
-		return nil
-	}
-
 	q := d.Builder().Select("table_name").
 		From("information_schema.tables").
-		Where("table_schema = ? AND table_name = ?", d.Schema().Name, name)
+		Where("table_schema = ? AND table_name = ?", d.Schema().Name(), name)
 
 	iter := q.Iterator()
 	defer iter.Close()
 
 	if iter.Next() {
-		var tableName string
-		if err := iter.Scan(&tableName); err != nil {
+		var name string
+		if err := iter.Scan(&name); err != nil {
 			return err
 		}
-	} else {
-		return db.ErrCollectionDoesNotExist
-	}
-
-	return nil
-}
-
-// TableColumns returns all columns from the given table.
-func (d *database) TableColumns(tableName string) ([]string, error) {
-	s := d.Schema()
-
-	if len(s.Table(tableName).Columns) == 0 {
-
-		q := d.Builder().Select("column_name").
-			From("information_schema.columns").
-			Where("table_schema = ? AND table_name = ?", d.Schema().Name, tableName)
-
-		var rows []struct {
-			Name string `db:"column_name"`
-		}
-
-		if err := q.Iterator().All(&rows); err != nil {
-			return nil, err
-		}
-
-		s.TableInfo[tableName].Columns = make([]string, 0, len(rows))
-
-		for i := range rows {
-			s.TableInfo[tableName].Columns = append(s.TableInfo[tableName].Columns, rows[i].Name)
-		}
+		return nil
 	}
-
-	return s.Table(tableName).Columns, nil
+	return db.ErrCollectionDoesNotExist
 }
 
 // TablePrimaryKey returns all primary keys from the given table.
 func (d *database) TablePrimaryKey(tableName string) ([]string, error) {
-	s := d.Schema()
+	tableSchema := d.Schema().Table(tableName)
 
-	ts := s.Table(tableName)
-
-	if len(ts.PrimaryKey) != 0 {
-		return ts.PrimaryKey, nil
+	pk := tableSchema.PrimaryKeys()
+	if pk != nil {
+		return pk, nil
 	}
 
-	ts.PrimaryKey = make([]string, 0, 1)
+	pk = []string{}
 
 	q := d.Builder().Select("k.column_name").
 		From("information_schema.table_constraints AS t").
@@ -274,21 +219,23 @@ func (d *database) TablePrimaryKey(tableName string) ([]string, error) {
 			t.constraint_type = 'primary key'
 			AND t.table_schema = ?
 			AND t.table_name = ?
-		`, d.Schema().Name, tableName).
+		`, d.Schema().Name(), tableName).
 		OrderBy("k.ordinal_position")
 
 	iter := q.Iterator()
 	defer iter.Close()
 
 	for iter.Next() {
-		var pKey string
-		if err := iter.Scan(&pKey); err != nil {
+		var k string
+		if err := iter.Scan(&k); err != nil {
 			return nil, err
 		}
-		ts.PrimaryKey = append(ts.PrimaryKey, pKey)
+		pk = append(pk, k)
 	}
 
-	return ts.PrimaryKey, nil
+	tableSchema.SetPrimaryKeys(pk)
+
+	return pk, nil
 }
 
 func (d *database) clone() (*database, error) {
diff --git a/mysql/database_test.go b/mysql/database_test.go
index fd901537..5bda572b 100644
--- a/mysql/database_test.go
+++ b/mysql/database_test.go
@@ -267,12 +267,10 @@ func TestTruncate(t *testing.T) {
 	for _, name := range collections {
 
 		// Getting a collection.
-		if col, err = sess.Collection(name); err != nil {
-			t.Fatal(err)
-		}
+		col = sess.Collection(name)
 
 		// Table must exists before we can use it.
-		if col.Exists() == true {
+		if col.Exists() {
 			// Truncating the table.
 			if err = col.Truncate(); err != nil {
 				t.Fatal(err)
@@ -295,9 +293,7 @@ func TestAppend(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Attempt to append a map.
 	itemMap := map[string]string{
@@ -389,9 +385,7 @@ func TestNullableFields(t *testing.T) {
 
 	var test testType
 
-	if col, err = sess.Collection(`data_types`); err != nil {
-		t.Fatal(err)
-	}
+	col = sess.Collection(`data_types`)
 
 	if err = col.Truncate(); err != nil {
 		t.Fatal(err)
@@ -473,9 +467,7 @@ func TestGroup(t *testing.T) {
 
 	defer sess.Close()
 
-	if stats, err = sess.Collection("stats_test"); err != nil {
-		t.Fatal(err)
-	}
+	stats = sess.Collection("stats_test")
 
 	// Truncating table.
 	if err = stats.Truncate(); err != nil {
@@ -523,9 +515,7 @@ func TestResultCount(t *testing.T) {
 	defer sess.Close()
 
 	// We should close the database when it's no longer in use.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining a set with no conditions.
 	res = artist.Find()
@@ -550,9 +540,9 @@ func TestResultNonExistentCount(t *testing.T) {
 
 	defer sess.Close()
 
-	total, err := sess.C("notartist").Find().Count()
+	total, err := sess.Collection("notartist").Find().Count()
 
-	if err != db.ErrCollectionDoesNotExist {
+	if err == nil {
 		t.Fatal("Expecting a specific error, got", err)
 	}
 
@@ -574,9 +564,7 @@ func TestResultFetch(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Dumping into a map.
 	rowMap := map[string]interface{}{}
@@ -707,9 +695,7 @@ func TestUpdate(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining destination struct
 	value := struct {
@@ -797,9 +783,7 @@ func TestFunction(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	rowStruct := struct {
 		ID   uint64
@@ -885,9 +869,7 @@ func TestRemove(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Getting the artist with id = 1
 	res = artist.Find(db.Cond{"id": 1})
@@ -920,10 +902,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		t.Fatal(err)
@@ -939,7 +918,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Attempt to use the same transaction should fail.
-	if _, err = tx.Collection("artist"); err == nil {
+	if err = tx.Commit(); err == nil {
 		t.Fatalf("Illegal, transaction has already been commited.")
 	}
 
@@ -950,9 +929,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistType{2, "Second"}); err != nil {
@@ -978,9 +955,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	var count uint64
 	if count, err = artist.Find().Count(); err != nil {
@@ -998,9 +973,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistType{2, "Second"}); err != nil {
@@ -1022,9 +995,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -1041,9 +1012,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistType{2, "Second"}); err != nil {
@@ -1070,9 +1039,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we have 4 rows.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -1096,9 +1063,7 @@ func TestCompositeKeys(t *testing.T) {
 
 	defer sess.Close()
 
-	if compositeKeys, err = sess.Collection("composite_keys"); err != nil {
-		t.Fatal(err)
-	}
+	compositeKeys = sess.Collection("composite_keys")
 
 	n := rand.Intn(100000)
 
@@ -1150,9 +1115,7 @@ func TestDataTypes(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "data_types" collection.
-	if dataTypes, err = sess.Collection("data_types"); err != nil {
-		t.Fatal(err)
-	}
+	dataTypes = sess.Collection("data_types")
 
 	// Removing all data.
 	if err = dataTypes.Truncate(); err != nil {
diff --git a/postgresql/benchmark_test.go b/postgresql/benchmark_test.go
index d1fcab85..b05eda59 100644
--- a/postgresql/benchmark_test.go
+++ b/postgresql/benchmark_test.go
@@ -413,11 +413,7 @@ func BenchmarkUpperAppend(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
-
+	artist := sess.Collection("artist")
 	artist.Truncate()
 
 	item := struct {
@@ -443,11 +439,7 @@ func BenchmarkUpperAppendVariableArgs(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
-
+	artist := sess.Collection("artist")
 	artist.Truncate()
 
 	b.ResetTimer()
@@ -479,10 +471,7 @@ func BenchmarkUpperAppendTransaction(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -522,10 +511,7 @@ func BenchmarkUpperAppendTransactionWithMap(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -668,10 +654,7 @@ func BenchmarkUpperFind(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -688,32 +671,6 @@ func BenchmarkUpperFind(b *testing.B) {
 	}
 }
 
-// BenchmarkUpperFindWithC benchmarks upper.io/db.v2's One method.
-func BenchmarkUpperFindWithC(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = connectAndAddFakeRows(); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	type artistType struct {
-		Name string `db:"name"`
-	}
-
-	var item artistType
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		res := sess.C("artist").Find(db.Cond{"name": artistN(i)})
-		if err = res.One(&item); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
 // BenchmarkUpperFindAll benchmarks upper.io/db.v2's All method.
 func BenchmarkUpperFindAll(b *testing.B) {
 	var err error
@@ -725,10 +682,7 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -810,10 +764,7 @@ func BenchmarkUpperUpdate(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -888,10 +839,7 @@ func BenchmarkUpperRemove(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
@@ -915,27 +863,7 @@ func BenchmarkUpperGetCollection(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := sess.Collection("artist")
-		if err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-// BenchmarkUpperC
-func BenchmarkUpperC(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()
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sess.C("artist")
+		sess.Collection("artist")
 	}
 }
 
@@ -958,10 +886,7 @@ func BenchmarkUpperCommitManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
@@ -1002,10 +927,7 @@ func BenchmarkUpperRollbackManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
diff --git a/postgresql/database.go b/postgresql/database.go
index 1fd3a0d3..700daac6 100644
--- a/postgresql/database.go
+++ b/postgresql/database.go
@@ -28,9 +28,9 @@ import (
 	"database/sql"
 
 	_ "github.com/lib/pq" // PostgreSQL driver.
+	"upper.io/db.v2"
 	"upper.io/db.v2/builder/sqlgen"
 	template "upper.io/db.v2/builder/template/postgresql"
-	"upper.io/db.v2"
 	"upper.io/db.v2/internal/sqladapter"
 	"upper.io/db.v2/internal/sqlutil/tx"
 )
@@ -67,9 +67,6 @@ func (d *database) Err(err error) error {
 		if strings.Contains(s, `too many clients`) || strings.Contains(s, `remaining connection slots are reserved`) {
 			return db.ErrTooManyClients
 		}
-		if strings.Contains(s, `relation`) && strings.Contains(s, `does not exist`) {
-			return db.ErrCollectionDoesNotExist
-		}
 	}
 	return err
 }
@@ -122,32 +119,29 @@ func (d *database) NewTable(name string) db.Collection {
 
 // Collections returns a list of non-system tables from the database.
 func (d *database) Collections() (collections []string, err error) {
+	q := d.Builder().Select("table_name").
+		From("information_schema.tables").
+		Where("table_schema = ?", "public")
 
-	if len(d.Schema().Tables) == 0 {
-		q := d.Builder().Select("table_name").
-			From("information_schema.tables").
-			Where("table_schema = ?", "public")
-
-		iter := q.Iterator()
-		defer iter.Close()
+	iter := q.Iterator()
+	defer iter.Close()
 
-		for iter.Next() {
-			var tableName string
-			if err := iter.Scan(&tableName); err != nil {
-				return nil, err
-			}
-			d.Schema().AddTable(tableName)
+	for iter.Next() {
+		var tableName string
+		if err := iter.Scan(&tableName); err != nil {
+			return nil, err
 		}
+		collections = append(collections, tableName)
 	}
 
-	return d.Schema().Tables, nil
+	return collections, nil
 }
 
 // Drop removes all tables from the current database.
 func (d *database) Drop() error {
 	stmt := &sqlgen.Statement{
 		Type:     sqlgen.DropDatabase,
-		Database: sqlgen.DatabaseWithName(d.Schema().Name),
+		Database: sqlgen.DatabaseWithName(d.Schema().Name()),
 	}
 	if _, err := d.Builder().Exec(stmt); err != nil {
 		return err
@@ -182,105 +176,52 @@ func (d *database) Transaction() (db.Tx, error) {
 
 // PopulateSchema looks up for the table info in the database and populates its
 // schema for internal use.
-func (d *database) PopulateSchema() (err error) {
-	var collections []string
-
-	d.NewSchema()
+func (d *database) PopulateSchema() error {
+	schema := d.NewSchema()
 
 	q := d.Builder().Select(db.Raw("CURRENT_DATABASE() AS name"))
 
-	var dbName string
-
 	iter := q.Iterator()
 	defer iter.Close()
 
 	if iter.Next() {
-		if err := iter.Scan(&dbName); err != nil {
-			return err
-		}
-	} else {
-		return iter.Err()
-	}
-
-	d.Schema().Name = dbName
-
-	if collections, err = d.Collections(); err != nil {
+		var name string
+		err := iter.Scan(&name)
+		schema.SetName(name)
 		return err
 	}
-
-	for i := range collections {
-		if _, err = d.Collection(collections[i]); err != nil {
-			return err
-		}
-	}
-
-	return err
+	return iter.Err()
 }
 
 // TableExists checks whether a table exists and returns an error in case it doesn't.
 func (d *database) TableExists(name string) error {
-	if d.Schema().HasTable(name) {
-		return nil
-	}
-
 	q := d.Builder().Select("table_name").
 		From("information_schema.tables").
-		Where("table_catalog = ? AND table_name = ?", d.Schema().Name, name)
+		Where("table_catalog = ? AND table_name = ?", d.Schema().Name(), name)
 
 	iter := q.Iterator()
 	defer iter.Close()
 
 	if iter.Next() {
-		var tableName string
-		if err := iter.Scan(&tableName); err != nil {
+		var name string
+		if err := iter.Scan(&name); err != nil {
 			return err
 		}
-	} else {
-		return db.ErrCollectionDoesNotExist
-	}
-
-	return nil
-}
-
-// TableColumns returns all columns from the given table.
-func (d *database) TableColumns(tableName string) ([]string, error) {
-	s := d.Schema()
-
-	if len(s.Table(tableName).Columns) == 0 {
-
-		q := d.Builder().Select("column_name").
-			From("information_schema.columns").
-			Where("table_catalog = ? AND table_name = ?", d.Schema().Name, tableName)
-
-		var rows []struct {
-			Name string `db:"column_name"`
-		}
-
-		if err := q.Iterator().All(&rows); err != nil {
-			return nil, err
-		}
-
-		s.TableInfo[tableName].Columns = make([]string, 0, len(rows))
-
-		for i := range rows {
-			s.TableInfo[tableName].Columns = append(s.TableInfo[tableName].Columns, rows[i].Name)
-		}
+		return nil
 	}
-
-	return s.Table(tableName).Columns, nil
+	return db.ErrCollectionDoesNotExist
 }
 
 // TablePrimaryKey returns all primary keys from the given table.
 func (d *database) TablePrimaryKey(tableName string) ([]string, error) {
-	s := d.Schema()
-
-	ts := s.Table(tableName)
+	tableSchema := d.Schema().Table(tableName)
 
-	if len(ts.PrimaryKey) != 0 {
-		return ts.PrimaryKey, nil
+	pk := tableSchema.PrimaryKeys()
+	if pk != nil {
+		return pk, nil
 	}
 
-	ts.PrimaryKey = make([]string, 0, 1)
+	pk = []string{}
 
 	q := d.Builder().Select("pg_attribute.attname AS pkey").
 		From("pg_index", "pg_class", "pg_attribute").
@@ -296,14 +237,16 @@ func (d *database) TablePrimaryKey(tableName string) ([]string, error) {
 	defer iter.Close()
 
 	for iter.Next() {
-		var pKey string
-		if err := iter.Scan(&pKey); err != nil {
+		var k string
+		if err := iter.Scan(&k); err != nil {
 			return nil, err
 		}
-		ts.PrimaryKey = append(ts.PrimaryKey, pKey)
+		pk = append(pk, k)
 	}
 
-	return ts.PrimaryKey, nil
+	tableSchema.SetPrimaryKeys(pk)
+
+	return pk, nil
 }
 
 func (d *database) clone() (*database, error) {
diff --git a/postgresql/database_test.go b/postgresql/database_test.go
index d2e8bb10..55862df4 100644
--- a/postgresql/database_test.go
+++ b/postgresql/database_test.go
@@ -223,31 +223,11 @@ func SkipTestOpenWithWrongData(t *testing.T) {
 	}
 }
 
-// Test Use
-func TestUse(t *testing.T) {
-	var err error
-	var sess db.Database
-
-	// Opening database, no error expected.
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		t.Fatal(err)
-	}
-
-	// Connecting to another database, error expected.
-	if err = sess.Use("Another database"); err == nil {
-		t.Fatal("This database should not exist!")
-	}
-
-	// Closing connection.
-	sess.Close()
-}
-
 // Attempts to get all collections and truncate each one of them.
 func TestTruncate(t *testing.T) {
 	var err error
 	var sess db.Database
 	var collections []string
-	var col db.Collection
 
 	// Opening database.
 	if sess, err = db.Open(Adapter, settings); err != nil {
@@ -270,12 +250,10 @@ func TestTruncate(t *testing.T) {
 	for _, name := range collections {
 
 		// Getting a collection.
-		if col, err = sess.Collection(name); err != nil {
-			t.Fatal(err)
-		}
+		col := sess.Collection(name)
 
 		// Table must exists before we can use it.
-		if col.Exists() == true {
+		if col.Exists() {
 			// Truncating the table.
 			if err = col.Truncate(); err != nil {
 				t.Fatal(err)
@@ -292,10 +270,7 @@ func TestSetCursorError(t *testing.T) {
 	}
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// trigger Postgres error. "" is not an int.
 	res := artist.Find(db.Cond{"id": ""})
@@ -322,9 +297,7 @@ func TestAppend(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Attempt to append a map.
 	itemMap := map[string]string{
@@ -408,9 +381,7 @@ func TestResultCount(t *testing.T) {
 	defer sess.Close()
 
 	// We should close the database when it's no longer in use.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining a set with no conditions.
 	res = artist.Find()
@@ -435,10 +406,10 @@ func TestResultNonExistentCount(t *testing.T) {
 
 	defer sess.Close()
 
-	total, err := sess.C("notartist").Find().Count()
+	total, err := sess.Collection("notartist").Find().Count()
 
-	if err != db.ErrCollectionDoesNotExist {
-		t.Fatal("Expecting a specific error, got", err)
+	if err == nil {
+		t.Fatal("Expecting an error")
 	}
 
 	if total != 0 {
@@ -451,7 +422,6 @@ func TestResultFetch(t *testing.T) {
 	var err error
 	var res db.Result
 	var sess db.Database
-	var artist db.Collection
 
 	if sess, err = db.Open(Adapter, settings); err != nil {
 		t.Fatal(err)
@@ -459,9 +429,7 @@ func TestResultFetch(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Dumping into a map.
 	rowMap := map[string]interface{}{}
@@ -583,7 +551,6 @@ func TestResultFetch(t *testing.T) {
 func TestResultFetchOne(t *testing.T) {
 	var err error
 	var sess db.Database
-	var artist db.Collection
 
 	if sess, err = db.Open(Adapter, settings); err != nil {
 		t.Fatal(err)
@@ -591,9 +558,7 @@ func TestResultFetchOne(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Fetching one struct
 	var someArtist artistType
@@ -627,7 +592,6 @@ func TestResultFetchOne(t *testing.T) {
 func TestResultFetchAll(t *testing.T) {
 	var err error
 	var sess db.Database
-	var artist db.Collection
 
 	if sess, err = db.Open(Adapter, settings); err != nil {
 		t.Fatal(err)
@@ -635,9 +599,7 @@ func TestResultFetchAll(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Fetching all artists into struct
 	artists := []artistType{}
@@ -698,9 +660,7 @@ func TestInlineStructs(t *testing.T) {
 
 	defer sess.Close()
 
-	if review, err = sess.Collection("review"); err != nil {
-		t.Fatal(err)
-	}
+	review = sess.Collection("review")
 
 	if err = review.Truncate(); err != nil {
 		t.Fatal(err)
@@ -742,7 +702,6 @@ func TestInlineStructs(t *testing.T) {
 func TestUpdate(t *testing.T) {
 	var err error
 	var sess db.Database
-	var artist db.Collection
 
 	if sess, err = db.Open(Adapter, settings); err != nil {
 		t.Fatal(err)
@@ -750,9 +709,7 @@ func TestUpdate(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	// Defining destination struct
 	value := struct {
@@ -859,9 +816,7 @@ func TestFunction(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	rowStruct := struct {
 		ID   uint64
@@ -957,9 +912,7 @@ func TestNullableFields(t *testing.T) {
 
 	var test testType
 
-	if col, err = sess.Collection(`data_types`); err != nil {
-		t.Fatal(err)
-	}
+	col = sess.Collection(`data_types`)
 
 	if err = col.Truncate(); err != nil {
 		t.Fatal(err)
@@ -1044,9 +997,7 @@ func TestGroup(t *testing.T) {
 
 	defer sess.Close()
 
-	if stats, err = sess.Collection("stats_test"); err != nil {
-		t.Fatal(err)
-	}
+	stats = sess.Collection("stats_test")
 
 	// Truncating table.
 	if err = stats.Truncate(); err != nil {
@@ -1092,9 +1043,7 @@ func TestRemove(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Getting the artist with id = 1
 	res = artist.Find(db.Cond{"id": 1})
@@ -1122,10 +1071,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		t.Fatal(err)
@@ -1141,7 +1087,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// An attempt to use the same transaction must fail.
-	if _, err = tx.Collection("artist"); err == nil {
+	if err = tx.Commit(); err == nil {
 		t.Fatalf("Illegal, transaction has already been commited.")
 	}
 
@@ -1152,9 +1098,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistType{2, "Second"}); err != nil {
@@ -1180,9 +1124,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	var count uint64
 	if count, err = artist.Find().Count(); err != nil {
@@ -1200,9 +1142,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistType{2, "Second"}); err != nil {
@@ -1224,9 +1164,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -1243,9 +1181,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistType{2, "Second"}); err != nil {
@@ -1272,9 +1208,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we have 4 rows.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -1298,9 +1232,7 @@ func TestCompositeKeys(t *testing.T) {
 
 	defer sess.Close()
 
-	if compositeKeys, err = sess.Collection("composite_keys"); err != nil {
-		t.Fatal(err)
-	}
+	compositeKeys = sess.Collection("composite_keys")
 
 	n := rand.Intn(100000)
 
@@ -1353,9 +1285,7 @@ func TestDataTypes(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "data_types" collection.
-	if dataTypes, err = sess.Collection("data_types"); err != nil {
-		t.Fatal(err)
-	}
+	dataTypes = sess.Collection("data_types")
 
 	// Removing all data.
 	if err = dataTypes.Truncate(); err != nil {
@@ -1411,9 +1341,7 @@ func TestOptionTypes(t *testing.T) {
 
 	defer sess.Close()
 
-	if optionTypes, err = sess.Collection("option_types"); err != nil {
-		t.Fatal(err)
-	}
+	optionTypes = sess.Collection("option_types")
 
 	if err = optionTypes.Truncate(); err != nil {
 		t.Fatal(err)
@@ -1616,9 +1544,7 @@ func TestOptionTypeJsonbStruct(t *testing.T) {
 
 	defer sess.Close()
 
-	if optionTypes, err = sess.Collection("option_types"); err != nil {
-		t.Fatal(err)
-	}
+	optionTypes = sess.Collection("option_types")
 
 	if err = optionTypes.Truncate(); err != nil {
 		t.Fatal(err)
diff --git a/ql/benchmark_test.go b/ql/benchmark_test.go
index 08072c2d..533d088c 100644
--- a/ql/benchmark_test.go
+++ b/ql/benchmark_test.go
@@ -339,10 +339,7 @@ func BenchmarkUpperAppend(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -369,10 +366,7 @@ func BenchmarkUpperAppendVariableArgs(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -405,10 +399,7 @@ func BenchmarkUpperAppendTransaction(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -448,10 +439,7 @@ func BenchmarkUpperAppendTransactionWithMap(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -538,10 +526,7 @@ func BenchmarkUpperFind(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -558,32 +543,6 @@ func BenchmarkUpperFind(b *testing.B) {
 	}
 }
 
-// BenchmarkUpperFindWithC benchmarks upper.io/db.v2's One method.
-func BenchmarkUpperFindWithC(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = connectAndAddFakeRows(); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	type artistType struct {
-		Name string `db:"name"`
-	}
-
-	var item artistType
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		res := sess.C("artist").Find(db.Cond{"name": artistN(i)})
-		if err = res.One(&item); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
 // BenchmarkUpperFindAll benchmarks upper.io/db.v2's All method.
 func BenchmarkUpperFindAll(b *testing.B) {
 	var err error
@@ -595,10 +554,7 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -694,10 +650,7 @@ func BenchmarkUpperUpdate(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -786,10 +739,7 @@ func BenchmarkUpperRemove(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
@@ -813,27 +763,7 @@ func BenchmarkUpperGetCollection(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := sess.Collection("artist")
-		if err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-// BenchmarkUpperC
-func BenchmarkUpperC(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()
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sess.C("artist")
+		sess.Collection("artist")
 	}
 }
 
@@ -856,10 +786,7 @@ func BenchmarkUpperCommitManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
@@ -900,10 +827,7 @@ func BenchmarkUpperRollbackManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
diff --git a/ql/database.go b/ql/database.go
index e1a3956b..91b7946a 100644
--- a/ql/database.go
+++ b/ql/database.go
@@ -28,9 +28,9 @@ import (
 	"sync/atomic"
 
 	_ "github.com/cznic/ql/driver" // QL driver
+	"upper.io/db.v2"
 	"upper.io/db.v2/builder/sqlgen"
 	template "upper.io/db.v2/builder/template/ql"
-	"upper.io/db.v2"
 	"upper.io/db.v2/internal/sqladapter"
 	"upper.io/db.v2/internal/sqlutil/tx"
 )
@@ -156,35 +156,32 @@ func (d *database) NewTable(name string) db.Collection {
 
 // Collections returns a list of non-system tables from the database.
 func (d *database) Collections() (collections []string, err error) {
+	q := d.Builder().Select("Name").
+		From("__Table")
 
-	if len(d.Schema().Tables) == 0 {
-		q := d.Builder().Select("Name").
-			From("__Table")
-
-		iter := q.Iterator()
-		defer iter.Close()
+	iter := q.Iterator()
+	defer iter.Close()
 
-		if iter.Err() != nil {
-			return nil, iter.Err()
-		}
+	if iter.Err() != nil {
+		return nil, iter.Err()
+	}
 
-		for iter.Next() {
-			var tableName string
-			if err := iter.Scan(&tableName); err != nil {
-				return nil, err
-			}
-			d.Schema().AddTable(tableName)
+	for iter.Next() {
+		var tableName string
+		if err := iter.Scan(&tableName); err != nil {
+			return nil, err
 		}
+		collections = append(collections, tableName)
 	}
 
-	return d.Schema().Tables, nil
+	return collections, nil
 }
 
 // Drop removes all tables from the current database.
 func (d *database) Drop() error {
 	stmt := &sqlgen.Statement{
 		Type:     sqlgen.DropDatabase,
-		Database: sqlgen.DatabaseWithName(d.Schema().Name),
+		Database: sqlgen.DatabaseWithName(d.Schema().Name()),
 	}
 	if _, err := d.Builder().Exec(stmt); err != nil {
 		return err
@@ -220,36 +217,20 @@ func (d *database) Transaction() (db.Tx, error) {
 // PopulateSchema looks up for the table info in the database and populates its
 // schema for internal use.
 func (d *database) PopulateSchema() (err error) {
-	var collections []string
-
-	d.NewSchema()
+	schema := d.NewSchema()
 
 	var connURL ConnectionURL
 	if connURL, err = ParseURL(d.ConnectionURL().String()); err != nil {
 		return err
 	}
 
-	d.Schema().Name = connURL.Database
-
-	if collections, err = d.Collections(); err != nil {
-		return err
-	}
+	schema.SetName(connURL.Database)
 
-	for i := range collections {
-		if _, err = d.Collection(collections[i]); err != nil {
-			return err
-		}
-	}
-
-	return err
+	return nil
 }
 
 // TableExists checks whether a table exists and returns an error in case it doesn't.
 func (d *database) TableExists(name string) error {
-	if d.Schema().HasTable(name) {
-		return nil
-	}
-
 	q := d.Builder().Select("Name").
 		From("__Table").
 		Where("Name == ?", name)
@@ -258,43 +239,13 @@ func (d *database) TableExists(name string) error {
 	defer iter.Close()
 
 	if iter.Next() {
-		var tableName string
-		if err := iter.Scan(&tableName); err != nil {
+		var name string
+		if err := iter.Scan(&name); err != nil {
 			return err
 		}
-	} else {
-		return db.ErrCollectionDoesNotExist
-	}
-
-	return nil
-}
-
-// TableColumns returns all columns from the given table.
-func (d *database) TableColumns(tableName string) ([]string, error) {
-	s := d.Schema()
-
-	if len(s.Table(tableName).Columns) == 0 {
-
-		q := d.Builder().Select("Name").
-			From("__Column").
-			Where("TableName == ?", tableName)
-
-		var rows []struct {
-			Name string `db:"column_name"`
-		}
-
-		if err := q.Iterator().All(&rows); err != nil {
-			return nil, err
-		}
-
-		s.TableInfo[tableName].Columns = make([]string, 0, len(rows))
-
-		for i := range rows {
-			s.TableInfo[tableName].Columns = append(s.TableInfo[tableName].Columns, rows[i].Name)
-		}
+		return nil
 	}
-
-	return s.Table(tableName).Columns, nil
+	return db.ErrCollectionDoesNotExist
 }
 
 // TablePrimaryKey returns all primary keys from the given table.
diff --git a/ql/database_test.go b/ql/database_test.go
index 43010a78..6da065f7 100644
--- a/ql/database_test.go
+++ b/ql/database_test.go
@@ -138,25 +138,6 @@ func TestOpenFailed(t *testing.T) {
 	}
 }
 
-// Test USE
-func TestUse(t *testing.T) {
-	var err error
-	var sess db.Database
-
-	// Opening database, no error expected.
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		t.Fatal(err)
-	}
-
-	// Connecting to another database, error expected.
-	if err = sess.Use("."); err == nil {
-		t.Fatal("This is not a database")
-	}
-
-	// Closing connection.
-	sess.Close()
-}
-
 // Attempts to get all collections and truncate each one of them.
 func TestTruncate(t *testing.T) {
 	var err error
@@ -185,9 +166,7 @@ func TestTruncate(t *testing.T) {
 	for _, name := range collections {
 
 		// Getting a collection.
-		if col, err = sess.Collection(name); err != nil {
-			t.Fatal(err)
-		}
+		col = sess.Collection(name)
 
 		// Table must exists before we can use it.
 		if col.Exists() == true {
@@ -214,9 +193,7 @@ func TestAppend(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Attempt to append a map.
 	itemMap := map[string]string{
@@ -289,9 +266,7 @@ func TestGroup(t *testing.T) {
 
 	defer sess.Close()
 
-	if stats, err = sess.Collection("stats_test"); err != nil {
-		t.Fatal(err)
-	}
+	stats = sess.Collection("stats_test")
 
 	// Truncating table.
 	if err = stats.Truncate(); err != nil {
@@ -342,9 +317,7 @@ func TestResultCount(t *testing.T) {
 	defer sess.Close()
 
 	// We should close the database when it's no longer in use.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining a set with no conditions.
 	res = artist.Find()
@@ -369,10 +342,10 @@ func TestResultNonExistentCount(t *testing.T) {
 
 	defer sess.Close()
 
-	total, err := sess.C("notartist").Find().Count()
+	total, err := sess.Collection("notartist").Find().Count()
 
-	if err != db.ErrCollectionDoesNotExist {
-		t.Fatal("Expecting a specific error, got", err)
+	if err == nil {
+		t.Fatal("Expecting error")
 	}
 
 	if total != 0 {
@@ -393,9 +366,7 @@ func TestResultFetch(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Dumping into a map.
 	rowMap := map[string]interface{}{}
@@ -526,9 +497,7 @@ func TestUpdate(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining destination struct
 	value := struct {
@@ -616,9 +585,7 @@ func TestFunction(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	rowStruct := struct {
 		ID   uint64
@@ -704,9 +671,7 @@ func TestRemove(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Getting the artist with id = 1
 	res = artist.Find(db.Cond{"id()": 1})
@@ -738,10 +703,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		t.Fatal(err)
@@ -757,7 +719,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Attempt to use the same transaction should fail.
-	if _, err = tx.Collection("artist"); err == nil {
+	if err = tx.Commit(); err == nil {
 		t.Fatalf("Illegal, transaction has already been commited.")
 	}
 
@@ -768,9 +730,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistT{Name: "Second"}); err != nil {
@@ -796,9 +756,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	var count uint64
 	if count, err = artist.Find().Count(); err != nil {
@@ -816,9 +774,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistT{Name: "Second"}); err != nil {
@@ -840,9 +796,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -859,9 +813,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistT{Name: "Second"}); err != nil {
@@ -888,9 +840,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we have 4 rows.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -916,9 +866,7 @@ func TestCompositeKeys(t *testing.T) {
 
 	defer sess.Close()
 
-	if compositeKeys, err = sess.Collection("composite_keys"); err != nil {
-		t.Fatal(err)
-	}
+	compositeKeys = sess.Collection("composite_keys")
 
 	//n := rand.Intn(100000)
 
@@ -962,62 +910,6 @@ func TestCompositeKeys(t *testing.T) {
 
 }
 
-/*
-// Attempts to add many different datatypes to a single row in a collection,
-// then it tries to get the stored datatypes and check if the stored and the
-// original values match.
-func TestDataTypes(t *testing.T) {
-	var res db.Result
-	var sess db.Database
-	var dataTypes db.Collection
-	var err error
-	var id interface{}
-	var exists uint64
-
-	if sess, err = db.Open(Adapter, settings); err != nil {
-		t.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	// Getting a pointer to the "data_types" collection.
-	if dataTypes, err = sess.Collection("data_types"); err != nil {
-		t.Fatal(err)
-	}
-
-	// Removing all data.
-	if err = dataTypes.Truncate(); err != nil {
-		t.Fatal(err)
-	}
-
-	// Appending our test subject.
-	if id, err = dataTypes.Append(testValues); err != nil {
-		t.Fatal(err)
-	}
-
-	// Defining our set.
-	res = dataTypes.Find(db.Cond{"id()": id})
-
-	if exists, err = res.Count(); err != nil {
-		t.Fatal(err)
-	}
-
-	if exists == 0 {
-		t.Fatalf("Expecting an item.")
-	}
-
-	// Trying to dump the subject into an empty structure of the same type.
-	var item testValuesStruct
-
-	res.One(&item)
-
-	// The original value and the test subject must match.
-	if reflect.DeepEqual(item, testValues) == false {
-		t.Fatalf("Struct is different.")
-	}
-}
-*/
-
 // TestExhaustConnections simulates a "too many connections" situation
 // triggered by opening more transactions than available connections.
 // upper.io/db.v2 deals with this problem by waiting a bit more for the connection
diff --git a/sqlite/benchmark_test.go b/sqlite/benchmark_test.go
index 0dfa8c9d..162b9fba 100644
--- a/sqlite/benchmark_test.go
+++ b/sqlite/benchmark_test.go
@@ -261,10 +261,7 @@ func BenchmarkUpperAppend(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -291,10 +288,7 @@ func BenchmarkUpperAppendVariableArgs(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	artist.Truncate()
 
@@ -327,10 +321,7 @@ func BenchmarkUpperAppendTransaction(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -370,10 +361,7 @@ func BenchmarkUpperAppendTransactionWithMap(b *testing.B) {
 	}
 	defer tx.Close()
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		b.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		b.Fatal(err)
@@ -459,10 +447,7 @@ func BenchmarkUpperFind(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -479,32 +464,6 @@ func BenchmarkUpperFind(b *testing.B) {
 	}
 }
 
-// BenchmarkUpperFindWithC benchmarks upper.io/db.v2's One method.
-func BenchmarkUpperFindWithC(b *testing.B) {
-	var err error
-	var sess db.Database
-
-	if sess, err = connectAndAddFakeRows(); err != nil {
-		b.Fatal(err)
-	}
-
-	defer sess.Close()
-
-	type artistType struct {
-		Name string `db:"name"`
-	}
-
-	var item artistType
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		res := sess.C("artist").Find(db.Cond{"name": artistN(i)})
-		if err = res.One(&item); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
 // BenchmarkUpperFindAll benchmarks upper.io/db.v2's All method.
 func BenchmarkUpperFindAll(b *testing.B) {
 	var err error
@@ -516,10 +475,7 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -601,10 +557,7 @@ func BenchmarkUpperUpdate(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	type artistType struct {
 		Name string `db:"name"`
@@ -679,10 +632,7 @@ func BenchmarkUpperRemove(b *testing.B) {
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	if err != nil {
-		b.Fatal(err)
-	}
+	artist := sess.Collection("artist")
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
@@ -706,27 +656,7 @@ func BenchmarkUpperGetCollection(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := sess.Collection("artist")
-		if err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-// BenchmarkUpperC
-func BenchmarkUpperC(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()
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sess.C("artist")
+		sess.Collection("artist")
 	}
 }
 
@@ -749,10 +679,7 @@ func BenchmarkUpperCommitManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
@@ -793,10 +720,7 @@ func BenchmarkUpperRollbackManyTransactions(b *testing.B) {
 			b.Fatal(err)
 		}
 
-		var artist db.Collection
-		if artist, err = tx.Collection("artist"); err != nil {
-			b.Fatal(err)
-		}
+		artist := tx.Collection("artist")
 
 		if err = artist.Truncate(); err != nil {
 			b.Fatal(err)
diff --git a/sqlite/database.go b/sqlite/database.go
index c2e0ee4e..5752917f 100644
--- a/sqlite/database.go
+++ b/sqlite/database.go
@@ -29,10 +29,10 @@ import (
 	"database/sql"
 
 	_ "github.com/mattn/go-sqlite3" // SQLite3 driver.
+	"upper.io/db.v2"
 	"upper.io/db.v2/builder/sqlbuilder"
 	"upper.io/db.v2/builder/sqlgen"
 	template "upper.io/db.v2/builder/template/sqlite"
-	"upper.io/db.v2"
 	"upper.io/db.v2/internal/sqladapter"
 	"upper.io/db.v2/internal/sqlutil/tx"
 )
@@ -146,36 +146,29 @@ func (d *database) NewTable(name string) db.Collection {
 
 // Collections returns a list of non-system tables from the database.
 func (d *database) Collections() (collections []string, err error) {
+	q := d.Builder().Select("tbl_name").
+		From("sqlite_master").
+		Where("type = ?", "table")
 
-	if len(d.Schema().Tables) == 0 {
-		q := d.Builder().Select("tbl_name").
-			From("sqlite_master").
-			Where("type = ?", "table")
-
-		iter := q.Iterator()
-		defer iter.Close()
-
-		if iter.Err() != nil {
-			return nil, iter.Err()
-		}
+	iter := q.Iterator()
+	defer iter.Close()
 
-		for iter.Next() {
-			var tableName string
-			if err := iter.Scan(&tableName); err != nil {
-				return nil, err
-			}
-			d.Schema().AddTable(tableName)
+	for iter.Next() {
+		var tableName string
+		if err := iter.Scan(&tableName); err != nil {
+			return nil, err
 		}
+		collections = append(collections, tableName)
 	}
 
-	return d.Schema().Tables, nil
+	return collections, nil
 }
 
 // Drop removes all tables from the current database.
 func (d *database) Drop() error {
 	stmt := &sqlgen.Statement{
 		Type:     sqlgen.DropDatabase,
-		Database: sqlgen.DatabaseWithName(d.Schema().Name),
+		Database: sqlgen.DatabaseWithName(d.Schema().Name()),
 	}
 	if _, err := d.Builder().Exec(stmt); err != nil {
 		return err
@@ -211,36 +204,20 @@ func (d *database) Transaction() (db.Tx, error) {
 // PopulateSchema looks up for the table info in the database and populates its
 // schema for internal use.
 func (d *database) PopulateSchema() (err error) {
-	var collections []string
-
-	d.NewSchema()
+	schema := d.NewSchema()
 
 	var connURL ConnectionURL
 	if connURL, err = ParseURL(d.ConnectionURL().String()); err != nil {
 		return err
 	}
 
-	d.Schema().Name = connURL.Database
+	schema.SetName(connURL.Database)
 
-	if collections, err = d.Collections(); err != nil {
-		return err
-	}
-
-	for i := range collections {
-		if _, err = d.Collection(collections[i]); err != nil {
-			return err
-		}
-	}
-
-	return err
+	return nil
 }
 
 // TableExists checks whether a table exists and returns an error in case it doesn't.
 func (d *database) TableExists(name string) error {
-	if d.Schema().HasTable(name) {
-		return nil
-	}
-
 	q := d.Builder().Select("tbl_name").
 		From("sqlite_master").
 		Where("type = 'table' AND tbl_name = ?", name)
@@ -249,77 +226,62 @@ func (d *database) TableExists(name string) error {
 	defer iter.Close()
 
 	if iter.Next() {
-		var tableName string
-		if err := iter.Scan(&tableName); err != nil {
+		var name string
+		if err := iter.Scan(&name); err != nil {
 			return err
 		}
-	} else {
-		return db.ErrCollectionDoesNotExist
+		return nil
 	}
-
-	return nil
+	return db.ErrCollectionDoesNotExist
 }
 
-// TableColumns returns all columns from the given table.
-func (d *database) TableColumns(tableName string) ([]string, error) {
-	s := d.Schema()
-
-	if len(s.Table(tableName).Columns) == 0 {
-
-		stmt := sqlgen.RawSQL(fmt.Sprintf(`PRAGMA TABLE_INFO('%s')`, tableName))
-
-		rows, err := d.Builder().Query(stmt)
-		if err != nil {
-			return nil, err
-		}
-
-		if d.columns == nil {
-			d.columns = make(map[string][]columnSchemaT)
-		}
-
-		columns := []columnSchemaT{}
+// TablePrimaryKey returns all primary keys from the given table.
+func (d *database) TablePrimaryKey(tableName string) ([]string, error) {
+	tableSchema := d.Schema().Table(tableName)
 
-		if err := sqlbuilder.NewIterator(rows).All(&columns); err != nil {
-			return nil, err
-		}
+	pk := tableSchema.PrimaryKeys()
+	if pk != nil {
+		return pk, nil
+	}
 
-		d.columns[tableName] = columns
+	pk = []string{}
 
-		s.TableInfo[tableName].Columns = make([]string, 0, len(columns))
+	stmt := sqlgen.RawSQL(fmt.Sprintf(`PRAGMA TABLE_INFO('%s')`, tableName))
 
-		for _, col := range d.columns[tableName] {
-			s.TableInfo[tableName].Columns = append(s.TableInfo[tableName].Columns, col.Name)
-		}
+	rows, err := d.Builder().Query(stmt)
+	if err != nil {
+		return nil, err
 	}
 
-	return s.Table(tableName).Columns, nil
-}
+	if d.columns == nil {
+		d.columns = make(map[string][]columnSchemaT)
+	}
 
-// TablePrimaryKey returns all primary keys from the given table.
-func (d *database) TablePrimaryKey(tableName string) ([]string, error) {
-	tableSchema := d.Schema().Table(tableName)
+	columns := []columnSchemaT{}
 
-	d.TableColumns(tableName)
+	if err := sqlbuilder.NewIterator(rows).All(&columns); err != nil {
+		return nil, err
+	}
 
 	maxValue := -1
 
-	for i := range d.columns[tableName] {
-		if d.columns[tableName][i].PK > 0 && d.columns[tableName][i].PK > maxValue {
-			maxValue = d.columns[tableName][i].PK
+	for _, column := range columns {
+		if column.PK > 0 && column.PK > maxValue {
+			maxValue = column.PK
 		}
 	}
 
 	if maxValue > 0 {
-		tableSchema.PrimaryKey = make([]string, maxValue)
-
-		for i := range d.columns[tableName] {
-			if d.columns[tableName][i].PK > 0 {
-				tableSchema.PrimaryKey[d.columns[tableName][i].PK-1] = d.columns[tableName][i].Name
+		for _, column := range columns {
+			if column.PK > 0 {
+				pk = append(pk, column.Name)
 			}
 		}
 	}
 
-	return tableSchema.PrimaryKey, nil
+	tableSchema.SetPrimaryKeys(pk)
+
+	return pk, nil
 }
 
 func (d *database) clone() (*database, error) {
diff --git a/sqlite/database_test.go b/sqlite/database_test.go
index 6f68da14..38a8f3ec 100644
--- a/sqlite/database_test.go
+++ b/sqlite/database_test.go
@@ -217,9 +217,7 @@ func TestTruncate(t *testing.T) {
 	for _, name := range collections {
 
 		// Getting a collection.
-		if col, err = sess.Collection(name); err != nil {
-			t.Fatal(err)
-		}
+		col = sess.Collection(name)
 
 		// Table must exists before we can use it.
 		if col.Exists() == true {
@@ -245,9 +243,7 @@ func TestAppend(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Attempt to append a map.
 	itemMap := map[string]string{
@@ -338,9 +334,7 @@ func TestNullableFields(t *testing.T) {
 
 	var test testType
 
-	if col, err = sess.Collection(`data_types`); err != nil {
-		t.Fatal(err)
-	}
+	col = sess.Collection(`data_types`)
 
 	if err = col.Truncate(); err != nil {
 		t.Fatal(err)
@@ -426,9 +420,7 @@ func TestGroup(t *testing.T) {
 
 	defer sess.Close()
 
-	if stats, err = sess.Collection("stats_test"); err != nil {
-		t.Fatal(err)
-	}
+	stats = sess.Collection("stats_test")
 
 	// Truncating table.
 	if err = stats.Truncate(); err != nil {
@@ -479,9 +471,7 @@ func TestResultCount(t *testing.T) {
 	defer sess.Close()
 
 	// We should close the database when it's no longer in use.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining a set with no conditions.
 	res = artist.Find()
@@ -506,10 +496,10 @@ func TestResultNonExistentCount(t *testing.T) {
 
 	defer sess.Close()
 
-	total, err := sess.C("notartist").Find().Count()
+	total, err := sess.Collection("notartist").Find().Count()
 
-	if err != db.ErrCollectionDoesNotExist {
-		t.Fatal("Expecting a specific error, got", err)
+	if err == nil {
+		t.Fatal("Expecting an error")
 	}
 
 	if total != 0 {
@@ -530,9 +520,7 @@ func TestResultFetch(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Dumping into a map.
 	rowMap := map[string]interface{}{}
@@ -663,9 +651,7 @@ func TestUpdate(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Defining destination struct
 	value := struct {
@@ -753,9 +739,7 @@ func TestFunction(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	rowStruct := struct {
 		ID   uint64
@@ -841,9 +825,7 @@ func TestRemove(t *testing.T) {
 
 	defer sess.Close()
 
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	// Getting the artist with id = 1
 	res = artist.Find(db.Cond{"id": 1})
@@ -876,10 +858,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	var artist db.Collection
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist := tx.Collection("artist")
 
 	if err = artist.Truncate(); err != nil {
 		t.Fatal(err)
@@ -895,7 +874,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Attempt to use the same transaction should fail.
-	if _, err = tx.Collection("artist"); err == nil {
+	if err = tx.Commit(); err == nil {
 		t.Fatalf("Illegal, transaction has already been commited.")
 	}
 
@@ -906,9 +885,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistT{2, "Second"}); err != nil {
@@ -934,9 +911,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	var count uint64
 	if count, err = artist.Find().Count(); err != nil {
@@ -954,9 +929,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistT{2, "Second"}); err != nil {
@@ -978,9 +951,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we still have one element.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -997,9 +968,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if artist, err = tx.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = tx.Collection("artist")
 
 	// Won't fail.
 	if _, err = artist.Append(artistT{2, "Second"}); err != nil {
@@ -1026,9 +995,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 	}
 
 	// Let's verify we have 4 rows.
-	if artist, err = sess.Collection("artist"); err != nil {
-		t.Fatal(err)
-	}
+	artist = sess.Collection("artist")
 
 	if count, err = artist.Find().Count(); err != nil {
 		t.Fatal(err)
@@ -1052,9 +1019,7 @@ func TestCompositeKeys(t *testing.T) {
 
 	defer sess.Close()
 
-	if compositeKeys, err = sess.Collection("composite_keys"); err != nil {
-		t.Fatal(err)
-	}
+	compositeKeys = sess.Collection("composite_keys")
 
 	n := rand.Intn(100000)
 
@@ -1106,9 +1071,7 @@ func TestDataTypes(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a pointer to the "data_types" collection.
-	if dataTypes, err = sess.Collection("data_types"); err != nil {
-		t.Fatal(err)
-	}
+	dataTypes = sess.Collection("data_types")
 
 	// Removing all data.
 	if err = dataTypes.Truncate(); err != nil {
-- 
GitLab