From 3909ea94ad67f9a64328726dd4e91ceb0a3b42d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <xiam@menteslibres.org>
Date: Mon, 23 Jul 2012 18:33:44 -0500
Subject: [PATCH] Updating docs.

---
 db/README.md                      | 149 +++++++++++++++---------------
 db/db.go                          |  32 +++----
 db/mongo/README.md                |  23 +++++
 db/mongo/examples/mongo.go        |   8 +-
 db/mongo/mongo.go                 |  16 ++--
 db/mongo/mongo_test.go            |  22 ++---
 db/mysql/README.md                |  23 +++++
 db/mysql/mysql.go                 |  16 ++--
 db/mysql/mysql_test.go            |  22 ++---
 db/postgresql/README.md           |  23 +++++
 db/postgresql/postgresql.go       |  14 +--
 db/postgresql/postgresql_test.go  |  22 ++---
 db/sqlite/README.md               |  23 +++++
 db/sqlite/dumps/gotest.sqlite3.db | Bin 5120 -> 5120 bytes
 db/sqlite/sqlite.go               |  14 +--
 db/sqlite/sqlite_test.go          |  22 ++---
 16 files changed, 259 insertions(+), 170 deletions(-)
 create mode 100644 db/mongo/README.md
 create mode 100644 db/mysql/README.md
 create mode 100644 db/postgresql/README.md
 create mode 100644 db/sqlite/README.md

diff --git a/db/README.md b/db/README.md
index 06e98aa0..7144f2ec 100644
--- a/db/README.md
+++ b/db/README.md
@@ -1,39 +1,37 @@
 # gosexy/db
 
-This package is a wrapper of [mgo](http://launchpad.net/mgo), [database/sql](http://golang.org/pkg/database/sql) and some of its database drivers friends, the goal of this abstraction is to provide a common, simplified, consistent layer for working with different databases using Go.
-
-**IMPORTANT:** Recent changes have rendered this documentation inaccurate, please wait until I can review and update it.
+This package is a wrapper of many third party database drivers. The goal of this abstraction is to provide a common, simplified, consistent later for working with different databases without the need of SQL statements.
 
 ## Installation
 
-Please read docs on the [gosexy](https://github.com/xiam/gosexy) package before rushing to install ``gosexy/db``
+Use ``go get`` to download and install ``gosexy/db``.
 
     $ go get github.com/xiam/gosexy/db
 
-## Available interfaces
+This package provides shared interfaces and datatypes only, in order to connect to an actual database a driver is required.
 
-* MongoDB via [mgo](http://launchpad.net/mgo)
-* MySQL via [go-mysql-driver](http://code.google.com/p/go-mysql-driver/)
-* PostgreSQL via (a fork of) [pq](https://github.com/bmizerany/pq)
-* SQLite3 via (a fork of) [sqlite3](https://github.com/mattn/go-sqlite3)
+Please refer to the database driver documentation to learn how to install a specific driver.
 
-## Recommended usage
+## Available drivers
 
-For the sake of ease, it is recommended that you import ``github.com/xiam/gosexy/db`` into the current namespace, this will allow your Go program to use unprefixed structures, for example, it would be a lot easier to write ``Item`` or ``Where`` rather than ``db.Item`` or ``db.Where``.
+* [mongo](/xiam/gosexy/tree/master/db/mongo)
+* [mysql](/xiam/gosexy/tree/master/db/mysql)
+* [postgresql](/xiam/gosexy/tree/master/db/postgresql)
+* [sqlite](/xiam/gosexy/tree/master/db/sqlite)
 
-    import . "github.com/xiam/gosexy/db"
+### Importing the database
 
-All the examples in this page are shown without prefixes.
+Once you've installed a driver, you need to import it into your Go code:
 
-### Setting up a database source
+    import "github.com/xiam/gosexy/db/mysql"
 
-The first step is to choose a driver and set up the connection using a ``DataSource``, this is how it would be done using ``MysqlSession``
+### Setting up a database source
 
-    sess := MysqlSession(DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
+We are going to use the [mysql](/xiam/gosexy/tree/master/db/mysql) driver in our examples. If you want to use another driver (such as ``mongo``) just replace ``mysql`` with the name of your driver and everything should work the same.
 
-Please note that each database has its very specific way of doing the same task, but the interface and methods of ``gosexy/db`` are the same for any of them.
+    sess := mysql.Session(db.DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
 
-The ``DataSource`` is a generic structure than can store connection values in a consistent way.
+The ``db.DataSource`` is a generic structure than can store connection values for any database in a consistent way.
 
     // Connection and authentication data.
     type DataSource struct {
@@ -44,22 +42,20 @@ The ``DataSource`` is a generic structure than can store connection values in a
       Password string
     }
 
-You may use other drivers to setup a connection, available drivers are ``MysqlSession``, ``MongodbSession``, ``PostgresqlSession`` and ``SqliteSession`` each one of them receives a ``DataSource`` and returns a ``Database``.
-
-### Connecting to the database
+### Connecting to a database
 
-Use your recently configured ``Database`` to request the driver to actually connect to the selected database using ``Database.Open()``.
+Use your recently configured ``db.Database`` to request the driver to actually connect to the selected database using ``db.Database.Open()``.
 
     // Setting up database.
-    sess := MysqlSession(DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
+    sess := mysql.Session(db.DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
     sess.Open()
 
     // Don't forget to close the connection when it's not required anymore.
     defer sess.Close()
 
-### Database methods.
+### db.Database methods
 
-The ``Database`` interface exposes the very same methods for all databases.
+The ``db.Database`` interface exposes the very same methods for all databases.
 
     // Database methods.
     type Database interface {
@@ -75,39 +71,39 @@ The ``Database`` interface exposes the very same methods for all databases.
       Drop() error
     }
 
-#### Database.Driver() interface{}
+#### db.Database.Driver() interface{}
 
-Returns the raw driver as an ``interface{}``, for example, if you're using ``MongoSession`` it will return an interface to ``*mgo.Session``, and if you're using ``MysqlSession`` it will return an interface to ``*sql.DB``, this is the only method that may return different data structures on different databases.
+Returns the raw driver as an ``interface{}``, for example, if you're using ``mongo.Session`` it will return an interface to ``*mgo.Session``, and if you're using ``mysql.Session`` it will return an interface to ``*sql.DB``, this is the only method that may return different data structures on different databases.
 
-#### Database.Open() error
+#### db.Database.Open() error
 
-Requests a connection to the database session. Returns an error if it fails.
+Requests a connection to the database session. Returns an error if something goes wrong.
 
-#### Database.Close() error
+#### db.Database.Close() error
 
-Disconnects from the database session. Returns an error if it fails.
+Disconnects from the database session. Returns an error if something goes wrong.
 
-#### Database.Collection(name string) Collection
+#### db.Database.Collection(name string) Collection
 
-Returns a ``Collection`` object from the current database given the name, collections are sets of rows or documents, this could be a MongoDB collection or a MySQL/PostgreSQL/SQLite table. You can create, read, update or delete rows from a collection. Please read all the methods avaiable for ``Collection`` further into this manual.
+Returns a ``db.Collection`` object from the current database given the name, collections are sets of rows or documents, this could be a MongoDB collection or a MySQL/PostgreSQL/SQLite table. You can create, read, update or delete rows from a collection. Please read all the methods avaiable for ``db.Collection`` further into this manual.
 
-#### Database.Collections() []string
+#### db.Database.Collections() []string
 
 Returns the names of all the collections in the current database.
 
-#### Database.Use(name string) error
+#### db.Database.Use(name string) error
 
 Makes the session switch between databases given the name. Returns an error if it fails.
 
-#### Database.Drop() error
+#### db.Database.Drop() error
 
 Erases the entire database and all the collections. Returns an error if it fails.
 
-### Collection methods
+### db.Collection methods
 
 Collections are sets of rows or documents, this could be a MongoDB collection or a MySQL/PostgreSQL/SQLite table. You can create, read, update or delete rows from a collection.
 
-When you request data from a Collection with ``Collection.Find()`` or ``Collection.FindAll()``, a special object with structure ``Item`` will be returned.
+When you request data from a Collection with ``db.Collection.Find()`` or ``db.Collection.FindAll()``, a special object with structure ``db.Item`` is returned.
 
     // Collection methods.
     type Collection interface {
@@ -128,29 +124,29 @@ When you request data from a Collection with ``Collection.Find()`` or ``Collecti
     // Rows from a result.
     type Item map[string]interface{}
 
-#### Collection.Append(...interface{}) bool
+#### db.Collection.Append(...interface{}) bool
 
 Appends one or more items to the collection.
 
     collection.Append(Item { "name": "Peter" })
 
-#### Collection.Count(...interface{}) int
+#### db.Collection.Count(...interface{}) int
 
 Returns the number of total items matching the provided conditions.
 
     total := collection.Count(Where { "name": "Peter" })
 
-#### Collection.Find(...interface{}) Item
+#### db.Collection.Find(...interface{}) db.Item
 
 Return the first Item of the collection that matches all the provided conditions. Ordering of the conditions does not matter, but you must take in account that they are evaluated from left to right and from top to bottom.
 
     // The following statement is equivalent to WHERE name = "John" AND last_name = "Doe" AND (age = 15 OR age = 20)
     collection.Find(
-     Where { "name": "John" },
-     Where { "last_name": "Doe" },
-     Or {
-       Where { "age": 15 },
-       Where { "age": 20 },
+     db.Where { "name": "John" },
+     db.Where { "last_name": "Doe" },
+     db.Or {
+       db.Where { "age": 15 },
+       db.Where { "age": 20 },
      },
     )
 
@@ -158,82 +154,82 @@ You can also use relations in your definition
 
     collection.FindAll(
       // One-to-one relation with the table "places".
-      Relate{
-        "lives_in": On{
+      db.Relate{
+        "lives_in": db.On{
           session.Collection("places"),
           // Relates rows of the table "places" where place.code_id = collection.place_code_id.
-          Where{"code_id": "{place_code_id}"},
+          db.Where{"code_id": "{place_code_id}"},
         },
       },
-      RelateAll{
+      db.RelateAll{
         // One-to-many relation with the table "children".
         "has_children": On{
           session.Collection("children"),
           // Relates rows of the table "children" where children.parent_id = collection.id
-          Where{"parent_id": "{id}"},
+          db.Where{"parent_id": "{id}"},
         },
         // One-to-many relation with the table "visits".
-        "has_visited": On{
+        "has_visited": db.On{
           session.Collection("visits"),
           // Relates rows of the table "visits" where visits.person_id = collection.id
-          Where{"person_id": "{id}"},
+          db.Where{"person_id": "{id}"},
           // A nested relation
-          Relate{
+          db.Relate{
             // Relates rows of the table "places" with the "visits" table.
-            "place": On{
+            "place": db.On{
               session.Collection("places"),
               // Where places.id = visits.place_id
-              Where{"id": "{place_id}"},
+              db.Where{"id": "{place_id}"},
             },
           },
         },
       },
     )
 
-#### Collection.FindAll(...interface{}) []Item
+#### db.Collection.FindAll(...interface{}) []db.Item
 
-Returns all the Items (``[]Item``) of the collection that match all the provided conditions. See ``Collection.Find()``.
+Returns all the Items (``[]db.Item``) of the collection that match all the provided conditions. See ``db.Collection.Find()``.
 
-Be aware that there are some extra parameters that you can pass to ``Collection.FindAll()`` but not to ``Collection.Find()``, like ``Limit(n)`` or ``Offset(n)``.
+Be aware that there are some extra parameters that you can pass to ``db.Collection.FindAll()`` but not to ``db.Collection.Find()``, like ``db.Limit(n)`` or ``db.Offset(n)``.
 
     // Just give me the the first 10 rows with last_name = "Smith"
     collection.Find(
-      Where { "last_name": "Smith" },
-      Limit(10),
+      db.Where { "last_name": "Smith" },
+      db.Limit(10),
     )
 
-#### Collection.Update(...interface{}) bool
+#### db.Collection.Update(...interface{}) bool
 
-Updates all the items of the collection that match all the provided conditions. You can specify the modification type by using ``Set``, ``Modify`` or ``Upsert``. At the time of this writing ``Modify`` and ``Upsert`` are only available for MongoSession.
+Updates all the items of the collection that match all the provided conditions. You can specify the modification type by using ``db.Set``, ``db.Modify`` or ``db.Upsert``. At the time of this writing ``db.Modify`` and ``db.Upsert`` are only available for ``mongo.Session``.
 
     // Example of assigning field values with Set:
     collection.Update(
-      Where { "name": "José" },
-      Set { "name": "Joseph"},
+      db.Where { "name": "José" },
+      db.Set { "name": "Joseph"},
     )
 
-    // Example of custom modification with Modify (for MongoSession):
+    // Example of custom modification with db.Modify (for mongo.Session):
     collection.Update(
-      Where { "times <": "10" },
-      Modify { "$inc": { "times": 1 } },
+      db.Where { "times <": "10" },
+      db.Modify { "$inc": { "times": 1 } },
     )
 
-    // Example of inserting if none matches with Upsert (for MongoSession):
+    // Example of inserting if none matches with db.Upsert (for mongo.Session):
     collection.Update(
-      Where { "name": "Roberto" },
-      Upsert { "name": "Robert"},
+      db.Where { "name": "Roberto" },
+      db.Upsert { "name": "Robert"},
     )
 
-#### Collection.Remove(...interface{}) bool
+#### db.Collection.Remove(...interface{}) bool
 
 Deletes all the items of the collection that match the provided conditions.
 
     collection.Remove(
-      Where { "name": "Peter" },
-      Where { "last_name": "Parker" },
+      db.Where { "name": "Peter" },
+      db.Where { "last_name": "Parker" },
     )
 
-#### Collection.Truncate() bool
+#### db.Collection.Truncate() bool
 
 Deletes the whole collection.
 
@@ -249,7 +245,7 @@ Or you can [browse it](http://go.pkgdoc.org/github.com/xiam/gosexy/db) online.
 
 ## TO-DO
 
-* Add Upsert and Modify for SQL databases.
+* Add db.Upsert and db.Modify for SQL databases.
 * Add Go time datatype.
 * Improve datatype guessing.
 * Improve error handling.
@@ -257,4 +253,5 @@ Or you can [browse it](http://go.pkgdoc.org/github.com/xiam/gosexy/db) online.
 
 ## Changelog
 
+2012/07/23 - Splitted databases wrapper into packages. Changed ``Where`` to ``Cond``.
 2012/07/09 - First public beta with MySQL, MongoDB, PostgreSQL and SQLite3.
diff --git a/db/db.go b/db/db.go
index e5b85e35..742c7827 100644
--- a/db/db.go
+++ b/db/db.go
@@ -27,30 +27,30 @@ package db
 //
 // Examples:
 //
-// Where { "age": 18 } // Means the condition is to have the "age" field equal to 18.
+// Cond { "age": 18 } // Means the condition is to have the "age" field equal to 18.
 //
-// Where { "age $lt": 18 } // $lt is a MongoDB operator, if you're using MongoDB, means that you want the "age" field to be lower than 18.
+// Cond { "age $lt": 18 } // $lt is a MongoDB operator, if you're using MongoDB, means that you want the "age" field to be lower than 18.
 //
-// Where { "age >=": 18 } // >= is a SQL operator, if you're using SQL, means that you want the "age" field to be mayor or equal to 18.
-type Where map[string]interface{}
+// Cond { "age >=": 18 } // >= is a SQL operator, if you're using SQL, means that you want the "age" field to be mayor or equal to 18.
+type Cond map[string]interface{}
 
-// Handles "And", "Or" and "Where" types in an expression.
+// Handles "And", "Or" and "Cond" types in an expression.
 //
 // Example:
 //
 // And (
-//   Where { "name": "Peter" },
-//   Where { "last_name": "Parker "},
+//   Cond { "name": "Peter" },
+//   Cond { "last_name": "Parker "},
 // )
 type And []interface{}
 
-// Handles "And", "Or" and "Where" types.
+// Handles "And", "Or" and "Cond" types.
 //
 // Example:
 //
 // Or (
-//   Where { "year": 2012 },
-//   Where { "year": 1987 },
+//   Cond { "year": 2012 },
+//   Cond { "year": 1987 },
 // )
 type Or []interface{}
 
@@ -76,13 +76,13 @@ type Modify map[string]interface{}
 
 // Specifies relations with external collections, the specific relation with the parent expression can be determined with
 // the name of field on the external collection plus the name of the referred parent column between brackets, however this can be only
-// used along with Where keytypes.
+// used along with Cond keytypes.
 //
 // Example:
 //
 // On {
 //   db.Collection("external"),
-//   Where { "external_key": "{parent_value}" }, // Relation exists where the "external_key" field is equal to the parent's "parent_value".
+//   Cond { "external_key": "{parent_value}" }, // Relation exists where the "external_key" field is equal to the parent's "parent_value".
 // }
 type On []interface{}
 
@@ -96,8 +96,8 @@ type On []interface{}
 // Relate {
 //   "father": On {
 //     db.Collection("people"),
-//     Where { "gender": "man" },
-//     Where { "id": "{parent_id}" },
+//     Cond { "gender": "man" },
+//     Cond { "id": "{parent_id}" },
 //   }
 // }
 type Relate map[string]On
@@ -112,8 +112,8 @@ type Relate map[string]On
 // RelateAll {
 //   "children": On {
 //     db.Collection("people"),
-//     Where { "age $lt": 12 },
-//     Where { "parent_id": "{_id}" },
+//     Cond { "age $lt": 12 },
+//     Cond { "parent_id": "{_id}" },
 //   }
 // }
 type RelateAll map[string]On
diff --git a/db/mongo/README.md b/db/mongo/README.md
new file mode 100644
index 00000000..0eb33836
--- /dev/null
+++ b/db/mongo/README.md
@@ -0,0 +1,23 @@
+# gosexy/db/mongo
+
+	This driver is a wrapper of [mgo](http://labix.org/mgo)
+
+## Installation
+
+		$ go get github.com/xiam/gosexy/db/mongo
+
+## Usage
+
+		import (
+			"github.com/xiam/gosexy/db"
+			"github.com/xiam/gosexy/db/mongo"
+		)
+
+## Connecting to a database
+
+		sess := mongo.Session(db.DataSource{Host: "127.0.0.1"})
+
+		err := sess.Open()
+		defer sess.Close()
+
+Read full documentation and examples on the [gosexy/db](/xiam/gosexy/tree/master/db) manual.
diff --git a/db/mongo/examples/mongo.go b/db/mongo/examples/mongo.go
index ea069b68..b3a7b7bb 100644
--- a/db/mongo/examples/mongo.go
+++ b/db/mongo/examples/mongo.go
@@ -23,21 +23,21 @@ func main() {
 		db.Relate{
 			"lives_in": db.On{
 				sess.Collection("places"),
-				db.Where{"code_id": "{place_code_id}"},
+				db.Cond{"code_id": "{place_code_id}"},
 			},
 		},
 		db.RelateAll{
 			"has_children": db.On{
 				sess.Collection("children"),
-				db.Where{"parent_id": "{_id}"},
+				db.Cond{"parent_id": "{_id}"},
 			},
 			"has_visited": db.On{
 				sess.Collection("visits"),
-				db.Where{"person_id": "{_id}"},
+				db.Cond{"person_id": "{_id}"},
 				db.Relate{
 					"place": db.On{
 						sess.Collection("places"),
-						db.Where{"_id": "{place_id}"},
+						db.Cond{"_id": "{place_id}"},
 					},
 				},
 			},
diff --git a/db/mongo/mongo.go b/db/mongo/mongo.go
index 9d65a259..7b2240ea 100644
--- a/db/mongo/mongo.go
+++ b/db/mongo/mongo.go
@@ -49,8 +49,8 @@ type MongoDataSourceCollection struct {
 	collection *mgo.Collection
 }
 
-// Converts db.Where keytypes into something that mgo can understand.
-func (c *MongoDataSourceCollection) marshal(where db.Where) map[string]interface{} {
+// Converts db.Cond keytypes into something that mgo can understand.
+func (c *MongoDataSourceCollection) marshal(where db.Cond) map[string]interface{} {
 	conds := make(map[string]interface{})
 
 	for key, val := range where {
@@ -139,9 +139,9 @@ func (c *MongoDataSourceCollection) compileConditions(term interface{}) interfac
 			condition := map[string]interface{}{"$and": values}
 			return condition
 		}
-	case db.Where:
+	case db.Cond:
 		{
-			return c.marshal(term.(db.Where))
+			return c.marshal(term.(db.Cond))
 		}
 	}
 	return nil
@@ -443,10 +443,10 @@ func (c *MongoDataSourceCollection) FindAll(terms ...interface{}) []db.Item {
 				term = relation["terms"].(db.On)[k]
 
 				switch term.(type) {
-				// Just waiting for db.Where statements.
-				case db.Where:
+				// Just waiting for db.Cond statements.
+				case db.Cond:
 					{
-						for wkey, wval := range term.(db.Where) {
+						for wkey, wval := range term.(db.Cond) {
 							//if reflect.TypeOf(wval).Kind() == reflect.String { // does not always work.
 							if reflect.TypeOf(wval).Name() == "string" {
 								// Matching dynamic values.
@@ -454,7 +454,7 @@ func (c *MongoDataSourceCollection) FindAll(terms ...interface{}) []db.Item {
 								if matched {
 									// Replacing dynamic values.
 									kname := strings.Trim(wval.(string), "{}")
-									term = db.Where{wkey: item[kname]}
+									term = db.Cond{wkey: item[kname]}
 								}
 							}
 						}
diff --git a/db/mongo/mongo_test.go b/db/mongo/mongo_test.go
index 42e797d2..9f2975ed 100644
--- a/db/mongo/mongo_test.go
+++ b/db/mongo/mongo_test.go
@@ -93,7 +93,7 @@ func TestMgFind(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	result := col.Find(db.Where{"name": "José"})
+	result := col.Find(db.Cond{"name": "José"})
 
 	if result["name"] != "José" {
 		t.Error("Could not find a recently appended item.")
@@ -113,9 +113,9 @@ func TestMgDelete(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Remove(db.Where{"name": "Juan"})
+	col.Remove(db.Cond{"name": "Juan"})
 
-	result := col.Find(db.Where{"name": "Juan"})
+	result := col.Find(db.Cond{"name": "Juan"})
 
 	if len(result) > 0 {
 		t.Error("Could not remove a recently appended item.")
@@ -134,9 +134,9 @@ func TestMgUpdate(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Update(db.Where{"name": "José"}, db.Set{"name": "Joseph"})
+	col.Update(db.Cond{"name": "José"}, db.Set{"name": "Joseph"})
 
-	result := col.Find(db.Where{"name": "Joseph"})
+	result := col.Find(db.Cond{"name": "Joseph"})
 
 	if len(result) == 0 {
 		t.Error("Could not update a recently appended item.")
@@ -179,13 +179,13 @@ func TestMgPopulate(t *testing.T) {
 
 		// Lives in
 		sess.Collection("people").Update(
-			db.Where{"_id": person["_id"]},
+			db.Cond{"_id": person["_id"]},
 			db.Set{"place_code_id": int(rand.Float32() * float32(len(places)))},
 		)
 
 		// Has visited
 		for k := 0; k < 3; k++ {
-			place := sess.Collection("places").Find(db.Where{
+			place := sess.Collection("places").Find(db.Cond{
 				"code_id": int(rand.Float32() * float32(len(places))),
 			})
 			sess.Collection("visits").Append(db.Item{
@@ -213,21 +213,21 @@ func TestMgRelation(t *testing.T) {
 		db.Relate{
 			"lives_in": db.On{
 				sess.Collection("places"),
-				db.Where{"code_id": "{place_code_id}"},
+				db.Cond{"code_id": "{place_code_id}"},
 			},
 		},
 		db.RelateAll{
 			"has_children": db.On{
 				sess.Collection("children"),
-				db.Where{"parent_id": "{_id}"},
+				db.Cond{"parent_id": "{_id}"},
 			},
 			"has_visited": db.On{
 				sess.Collection("visits"),
-				db.Where{"person_id": "{_id}"},
+				db.Cond{"person_id": "{_id}"},
 				db.Relate{
 					"place": db.On{
 						sess.Collection("places"),
-						db.Where{"_id": "{place_id}"},
+						db.Cond{"_id": "{place_id}"},
 					},
 				},
 			},
diff --git a/db/mysql/README.md b/db/mysql/README.md
new file mode 100644
index 00000000..3f5e9250
--- /dev/null
+++ b/db/mysql/README.md
@@ -0,0 +1,23 @@
+# gosexy/db/mysql
+
+	This driver is a wrapper of [go-mysql-driver](http://code.google.com/p/go-mysql-driver/)
+
+## Installation
+
+		$ go get github.com/xiam/gosexy/db/mysql
+
+## Usage
+
+		import (
+			"github.com/xiam/gosexy/db"
+			"github.com/xiam/gosexy/db/mysql"
+		)
+
+## Connecting to a database
+
+		sess := mysql.Session(db.DataSource{Host: "127.0.0.1"})
+
+		err := sess.Open()
+		defer sess.Close()
+
+Read full documentation and examples on the [gosexy/db](/xiam/gosexy/tree/master/db) manual.
diff --git a/db/mysql/mysql.go b/db/mysql/mysql.go
index a50d1baf..ee3ea3fe 100644
--- a/db/mysql/mysql.go
+++ b/db/mysql/mysql.go
@@ -365,9 +365,9 @@ func (t *MysqlTable) compileConditions(term interface{}) (string, db.SqlArgs) {
 				return "(" + strings.Join(sql, " AND ") + ")", args
 			}
 		}
-	case db.Where:
+	case db.Cond:
 		{
-			return t.marshal(term.(db.Where))
+			return t.marshal(term.(db.Cond))
 
 		}
 	}
@@ -375,8 +375,8 @@ func (t *MysqlTable) compileConditions(term interface{}) (string, db.SqlArgs) {
 	return "", args
 }
 
-// Converts db.Where{} structures into SQL before processing them in a query.
-func (t *MysqlTable) marshal(where db.Where) (string, []string) {
+// Converts db.Cond{} structures into SQL before processing them in a query.
+func (t *MysqlTable) marshal(where db.Cond) (string, []string) {
 
 	for key, val := range where {
 		key = strings.Trim(key, " ")
@@ -592,10 +592,10 @@ func (t *MysqlTable) FindAll(terms ...interface{}) []db.Item {
 				term = relation["terms"].(db.On)[k]
 
 				switch term.(type) {
-				// Just waiting for db.Where statements.
-				case db.Where:
+				// Just waiting for db.Cond statements.
+				case db.Cond:
 					{
-						for wkey, wval := range term.(db.Where) {
+						for wkey, wval := range term.(db.Cond) {
 							//if reflect.TypeOf(wval).Kind() == reflect.String { // does not always work.
 							if reflect.TypeOf(wval).Name() == "string" {
 								// Matching dynamic values.
@@ -603,7 +603,7 @@ func (t *MysqlTable) FindAll(terms ...interface{}) []db.Item {
 								if matched {
 									// Replacing dynamic values.
 									kname := strings.Trim(wval.(string), "{}")
-									term = db.Where{wkey: item[kname]}
+									term = db.Cond{wkey: item[kname]}
 								}
 							}
 						}
diff --git a/db/mysql/mysql_test.go b/db/mysql/mysql_test.go
index bd2ca96d..e18fec50 100644
--- a/db/mysql/mysql_test.go
+++ b/db/mysql/mysql_test.go
@@ -77,7 +77,7 @@ func TestMyFind(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	result := col.Find(db.Where{"name": "José"})
+	result := col.Find(db.Cond{"name": "José"})
 
 	if result["name"] != "José" {
 		t.Error("Could not find a recently appended item.")
@@ -97,9 +97,9 @@ func TestMyDelete(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Remove(db.Where{"name": "Juan"})
+	col.Remove(db.Cond{"name": "Juan"})
 
-	result := col.Find(db.Where{"name": "Juan"})
+	result := col.Find(db.Cond{"name": "Juan"})
 
 	if len(result) > 0 {
 		t.Error("Could not remove a recently appended item.")
@@ -120,9 +120,9 @@ func TestMyUpdate(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Update(db.Where{"name": "José"}, db.Set{"name": "Joseph"})
+	col.Update(db.Cond{"name": "José"}, db.Set{"name": "Joseph"})
 
-	result := col.Find(db.Where{"name": "Joseph"})
+	result := col.Find(db.Cond{"name": "Joseph"})
 
 	if len(result) == 0 {
 		t.Error("Could not update a recently appended item.")
@@ -169,13 +169,13 @@ func TestMyPopulate(t *testing.T) {
 
 		// Lives in
 		sess.Collection("people").Update(
-			db.Where{"id": person["id"]},
+			db.Cond{"id": person["id"]},
 			db.Set{"place_code_id": int(rand.Float32() * float32(len(places)))},
 		)
 
 		// Has visited
 		for k := 0; k < 3; k++ {
-			place := sess.Collection("places").Find(db.Where{
+			place := sess.Collection("places").Find(db.Cond{
 				"code_id": int(rand.Float32() * float32(len(places))),
 			})
 			sess.Collection("visits").Append(db.Item{
@@ -203,21 +203,21 @@ func TestMyRelation(t *testing.T) {
 		db.Relate{
 			"lives_in": db.On{
 				sess.Collection("places"),
-				db.Where{"code_id": "{place_code_id}"},
+				db.Cond{"code_id": "{place_code_id}"},
 			},
 		},
 		db.RelateAll{
 			"has_children": db.On{
 				sess.Collection("children"),
-				db.Where{"parent_id": "{id}"},
+				db.Cond{"parent_id": "{id}"},
 			},
 			"has_visited": db.On{
 				sess.Collection("visits"),
-				db.Where{"person_id": "{id}"},
+				db.Cond{"person_id": "{id}"},
 				db.Relate{
 					"place": db.On{
 						sess.Collection("places"),
-						db.Where{"id": "{place_id}"},
+						db.Cond{"id": "{place_id}"},
 					},
 				},
 			},
diff --git a/db/postgresql/README.md b/db/postgresql/README.md
new file mode 100644
index 00000000..c9e608c6
--- /dev/null
+++ b/db/postgresql/README.md
@@ -0,0 +1,23 @@
+# gosexy/db/postgresql
+
+	This driver is a wrapper of [pq](https://github.com/bmizerany/pq). In order to work with ``gosexy/db`` the original driver had to be [forked](https://github.com/xiam/gopostgresql) as the changes made to it are incompatible with some of pq's own features.
+
+## Installation
+
+		$ go get github.com/xiam/gosexy/db/postgresql
+
+## Usage
+
+		import (
+			"github.com/xiam/gosexy/db"
+			"github.com/xiam/gosexy/db/postgresql"
+		)
+
+## Connecting to a database
+
+		sess := postgresql.Session(db.DataSource{Host: "127.0.0.1"})
+
+		err := sess.Open()
+		defer sess.Close()
+
+Read full documentation and examples on the [gosexy/db](/xiam/gosexy/tree/master/db) manual.
diff --git a/db/postgresql/postgresql.go b/db/postgresql/postgresql.go
index 4a8d1afd..3bc0f5af 100644
--- a/db/postgresql/postgresql.go
+++ b/db/postgresql/postgresql.go
@@ -360,9 +360,9 @@ func (t *PostgresqlTable) compileConditions(term interface{}) (string, db.SqlArg
 				return "(" + strings.Join(sql, " AND ") + ")", args
 			}
 		}
-	case db.Where:
+	case db.Cond:
 		{
-			return t.marshal(term.(db.Where))
+			return t.marshal(term.(db.Cond))
 
 		}
 	}
@@ -370,7 +370,7 @@ func (t *PostgresqlTable) compileConditions(term interface{}) (string, db.SqlArg
 	return "", args
 }
 
-func (t *PostgresqlTable) marshal(where db.Where) (string, []string) {
+func (t *PostgresqlTable) marshal(where db.Cond) (string, []string) {
 
 	for key, val := range where {
 		key = strings.Trim(key, " ")
@@ -586,10 +586,10 @@ func (t *PostgresqlTable) FindAll(terms ...interface{}) []db.Item {
 				term = relation["terms"].(db.On)[k]
 
 				switch term.(type) {
-				// Just waiting for db.Where statements.
-				case db.Where:
+				// Just waiting for db.Cond statements.
+				case db.Cond:
 					{
-						for wkey, wval := range term.(db.Where) {
+						for wkey, wval := range term.(db.Cond) {
 							//if reflect.TypeOf(wval).Kind() == reflect.String { // does not always work.
 							if reflect.TypeOf(wval).Name() == "string" {
 								// Matching dynamic values.
@@ -597,7 +597,7 @@ func (t *PostgresqlTable) FindAll(terms ...interface{}) []db.Item {
 								if matched {
 									// Replacing dynamic values.
 									kname := strings.Trim(wval.(string), "{}")
-									term = db.Where{wkey: item[kname]}
+									term = db.Cond{wkey: item[kname]}
 								}
 							}
 						}
diff --git a/db/postgresql/postgresql_test.go b/db/postgresql/postgresql_test.go
index 0e450429..dd2b940c 100644
--- a/db/postgresql/postgresql_test.go
+++ b/db/postgresql/postgresql_test.go
@@ -76,7 +76,7 @@ func TestPgFind(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	result := col.Find(db.Where{"name": "José"})
+	result := col.Find(db.Cond{"name": "José"})
 
 	if result["name"] != "José" {
 		t.Error("Could not find a recently appended item.")
@@ -96,9 +96,9 @@ func TestPgDelete(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Remove(db.Where{"name": "Juan"})
+	col.Remove(db.Cond{"name": "Juan"})
 
-	result := col.Find(db.Where{"name": "Juan"})
+	result := col.Find(db.Cond{"name": "Juan"})
 
 	if len(result) > 0 {
 		t.Error("Could not remove a recently appended item.")
@@ -119,9 +119,9 @@ func TestPgUpdate(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Update(db.Where{"name": "José"}, db.Set{"name": "Joseph"})
+	col.Update(db.Cond{"name": "José"}, db.Set{"name": "Joseph"})
 
-	result := col.Find(db.Where{"name": "Joseph"})
+	result := col.Find(db.Cond{"name": "Joseph"})
 
 	if len(result) == 0 {
 		t.Error("Could not update a recently appended item.")
@@ -168,13 +168,13 @@ func TestPgPopulate(t *testing.T) {
 
 		// Lives in
 		sess.Collection("people").Update(
-			db.Where{"id": person["id"]},
+			db.Cond{"id": person["id"]},
 			db.Set{"place_code_id": int(rand.Float32() * float32(len(places)))},
 		)
 
 		// Has visited
 		for k := 0; k < 3; k++ {
-			place := sess.Collection("places").Find(db.Where{
+			place := sess.Collection("places").Find(db.Cond{
 				"code_id": int(rand.Float32() * float32(len(places))),
 			})
 			sess.Collection("visits").Append(db.Item{
@@ -202,21 +202,21 @@ func TestPgRelation(t *testing.T) {
 		db.Relate{
 			"lives_in": db.On{
 				sess.Collection("places"),
-				db.Where{"code_id": "{place_code_id}"},
+				db.Cond{"code_id": "{place_code_id}"},
 			},
 		},
 		db.RelateAll{
 			"has_children": db.On{
 				sess.Collection("children"),
-				db.Where{"parent_id": "{id}"},
+				db.Cond{"parent_id": "{id}"},
 			},
 			"has_visited": db.On{
 				sess.Collection("visits"),
-				db.Where{"person_id": "{id}"},
+				db.Cond{"person_id": "{id}"},
 				db.Relate{
 					"place": db.On{
 						sess.Collection("places"),
-						db.Where{"id": "{place_id}"},
+						db.Cond{"id": "{place_id}"},
 					},
 				},
 			},
diff --git a/db/sqlite/README.md b/db/sqlite/README.md
new file mode 100644
index 00000000..c98dd6f8
--- /dev/null
+++ b/db/sqlite/README.md
@@ -0,0 +1,23 @@
+# gosexy/db/postgresql
+
+	This driver is a wrapper of [sqlite3](https://github.com/mattn/go-sqlite3). In order to work with ``gosexy/db`` the original driver had to be [forked](https://github.com/xiam/gosqlite3) as the changes made to it are incompatible with some of sqlite3's own features.
+
+## Installation
+
+		$ go get github.com/xiam/gosexy/db/postgresql
+
+## Usage
+
+		import (
+			"github.com/xiam/gosexy/db"
+			"github.com/xiam/gosexy/db/postgresql"
+		)
+
+## Connecting to a database
+
+		sess := postgresql.Session(db.DataSource{Host: "127.0.0.1"})
+
+		err := sess.Open()
+		defer sess.Close()
+
+Read full documentation and examples on the [gosexy/db](/xiam/gosexy/tree/master/db) manual.
diff --git a/db/sqlite/dumps/gotest.sqlite3.db b/db/sqlite/dumps/gotest.sqlite3.db
index c0aca4901735ef6aa1dfaef310e3a6f928eb940e..ca9d13e8bbac02b5a7ef62946a1424ab5192be0e 100644
GIT binary patch
delta 17
YcmZqBXwaA-&3J#Jj5Fi?jR^~c0XKXGZ~y=R

delta 17
YcmZqBXwaA-%{Y0Yj5FipjR^~c0W$~%*Z=?k

diff --git a/db/sqlite/sqlite.go b/db/sqlite/sqlite.go
index dd912926..da457b97 100644
--- a/db/sqlite/sqlite.go
+++ b/db/sqlite/sqlite.go
@@ -365,9 +365,9 @@ func (t *SqliteTable) compileConditions(term interface{}) (string, db.SqlArgs) {
 				return "(" + strings.Join(sql, " AND ") + ")", args
 			}
 		}
-	case db.Where:
+	case db.Cond:
 		{
-			return t.marshal(term.(db.Where))
+			return t.marshal(term.(db.Cond))
 
 		}
 	}
@@ -375,7 +375,7 @@ func (t *SqliteTable) compileConditions(term interface{}) (string, db.SqlArgs) {
 	return "", args
 }
 
-func (t *SqliteTable) marshal(where db.Where) (string, []string) {
+func (t *SqliteTable) marshal(where db.Cond) (string, []string) {
 
 	for key, val := range where {
 		key = strings.Trim(key, " ")
@@ -591,10 +591,10 @@ func (t *SqliteTable) FindAll(terms ...interface{}) []db.Item {
 				term = relation["terms"].(db.On)[k]
 
 				switch term.(type) {
-				// Just waiting for db.Where statements.
-				case db.Where:
+				// Just waiting for db.Cond statements.
+				case db.Cond:
 					{
-						for wkey, wval := range term.(db.Where) {
+						for wkey, wval := range term.(db.Cond) {
 							//if reflect.TypeOf(wval).Kind() == reflect.String { // does not always work.
 							if reflect.TypeOf(wval).Name() == "string" {
 								// Matching dynamic values.
@@ -602,7 +602,7 @@ func (t *SqliteTable) FindAll(terms ...interface{}) []db.Item {
 								if matched {
 									// Replacing dynamic values.
 									kname := strings.Trim(wval.(string), "{}")
-									term = db.Where{wkey: item[kname]}
+									term = db.Cond{wkey: item[kname]}
 								}
 							}
 						}
diff --git a/db/sqlite/sqlite_test.go b/db/sqlite/sqlite_test.go
index 528a83ac..1b52a05b 100644
--- a/db/sqlite/sqlite_test.go
+++ b/db/sqlite/sqlite_test.go
@@ -73,7 +73,7 @@ func TestSqFind(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	result := col.Find(db.Where{"name": "José"})
+	result := col.Find(db.Cond{"name": "José"})
 
 	if result["name"] != "José" {
 		t.Error("Could not find a recently appended item.")
@@ -93,9 +93,9 @@ func TestSqDelete(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Remove(db.Where{"name": "Juan"})
+	col.Remove(db.Cond{"name": "Juan"})
 
-	result := col.Find(db.Where{"name": "Juan"})
+	result := col.Find(db.Cond{"name": "Juan"})
 
 	if len(result) > 0 {
 		t.Error("Could not remove a recently appended item.")
@@ -114,9 +114,9 @@ func TestSqUpdate(t *testing.T) {
 
 	col := sess.Collection("people")
 
-	col.Update(db.Where{"name": "José"}, db.Set{"name": "Joseph"})
+	col.Update(db.Cond{"name": "José"}, db.Set{"name": "Joseph"})
 
-	result := col.Find(db.Where{"name": "Joseph"})
+	result := col.Find(db.Cond{"name": "Joseph"})
 
 	if len(result) == 0 {
 		t.Error("Could not update a recently appended item.")
@@ -163,13 +163,13 @@ func TestSqPopulate(t *testing.T) {
 
 		// Lives in
 		sess.Collection("people").Update(
-			db.Where{"id": person["id"]},
+			db.Cond{"id": person["id"]},
 			db.Set{"place_code_id": int(rand.Float32() * float32(len(places)))},
 		)
 
 		// Has visited
 		for k := 0; k < 3; k++ {
-			place := sess.Collection("places").Find(db.Where{
+			place := sess.Collection("places").Find(db.Cond{
 				"code_id": int(rand.Float32() * float32(len(places))),
 			})
 			sess.Collection("visits").Append(db.Item{
@@ -197,21 +197,21 @@ func TestSqRelation(t *testing.T) {
 		db.Relate{
 			"lives_in": db.On{
 				sess.Collection("places"),
-				db.Where{"code_id": "{place_code_id}"},
+				db.Cond{"code_id": "{place_code_id}"},
 			},
 		},
 		db.RelateAll{
 			"has_children": db.On{
 				sess.Collection("children"),
-				db.Where{"parent_id": "{id}"},
+				db.Cond{"parent_id": "{id}"},
 			},
 			"has_visited": db.On{
 				sess.Collection("visits"),
-				db.Where{"person_id": "{id}"},
+				db.Cond{"person_id": "{id}"},
 				db.Relate{
 					"place": db.On{
 						sess.Collection("places"),
-						db.Where{"id": "{place_id}"},
+						db.Cond{"id": "{place_id}"},
 					},
 				},
 			},
-- 
GitLab