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

---
 db/README.md | 120 ++++++++++++++++++++++++++++++++++++---------------
 db/mongo.go  |  88 +++----------------------------------
 2 files changed, 91 insertions(+), 117 deletions(-)

diff --git a/db/README.md b/db/README.md
index abe3c677..c4d6876e 100644
--- a/db/README.md
+++ b/db/README.md
@@ -8,24 +8,28 @@ This package is a wrapper of [mgo](http://launchpad.net/mgo), [database/sql](htt
 
 ## Available interfaces
 
-* MongoDB with [mgo](http://launchpad.net/mgo)
-* MySQL with [go-mysql-driver](http://code.google.com/p/go-mysql-driver/)
-* PostgreSQL with (a fork of) [pq](https://github.com/bmizerany/pq)
-* SQLite3 with (a fork of) [sqlite3](https://github.com/mattn/go-sqlite3)
+* 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)
 
-## Usage
+## Recommended usage
 
-Import ``github.com/xiam/gosexy/db`` into your project.
+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``.
 
-A handful of methods will be available, each database has its specific ways of doing the same task but this will be handled by the drivers, the interface is the same for all of them.
+    import . "github.com/xiam/gosexy/db"
+
+Each database has its very specific way of doing the same task, the interface and methods are the same for any of them.
+
+Be aware that all the examples in this page are shown without prefixes.
 
 ### Setting up a database
 
 The first step is to choose a driver and set up the connection, this is how it would be done using ``MysqlSession``
 
-    sess := db.MysqlSession(db.DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
+    sess := MysqlSession(DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
 
-The ``db.DataSource`` is a generic structure than can store connection values in a consistent way.
+The ``DataSource`` is a generic structure than can store connection values in a consistent way.
 
     // Connection and authentication data.
     type DataSource struct {
@@ -36,14 +40,14 @@ The ``db.DataSource`` is a generic structure than can store connection values in
       Password string
     }
 
-You may use other drivers to setup a connection, available drivers are ``db.MysqlSession``, ``db.MongodbSession``, ``db.PostgresqlSession`` and ``db.SqliteSession`` each one of them receives a ``db.DataSource`` and returns a ``db.Database``.
+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
 
-Use your recently configured ``db.Database`` to request the driver to actually connect to the selected database.
+Use your recently configured ``Database`` to request the driver to actually connect to the selected database.
 
     // Setting up database.
-    sess := db.MysqlSession(db.DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
+    sess := MysqlSession(DataSource{Host: "localhost", Database: "test", User: "myuser", Password: "mypass"})
     sess.Open()
 
     // Don't forget to close the connection when it's not required anymore.
@@ -51,7 +55,7 @@ Use your recently configured ``db.Database`` to request the driver to actually c
 
 ### Database methods.
 
-The ``db.Database`` interface exposes the very same methods for all databases.
+The ``Database`` interface exposes the very same methods for all databases.
 
     // Database methods.
     type Database interface {
@@ -67,31 +71,31 @@ The ``db.Database`` interface exposes the very same methods for all databases.
       Drop() error
     }
 
-#### db.Database.Driver() interface{}
+#### 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.
 
-#### db.Database.Open() error
+#### Database.Open() error
 
 Requests a connection to the database session. Returns an error if it fails.
 
-#### db.Database.Close() error
+#### Database.Close() error
 
 Disconnects from the database session. Returns an error if it fails.
 
-#### db.Database.Collection(name string) Collection
+#### Database.Collection(name string) Collection
 
-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.
+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.
 
-#### db.Database.Collections() []string
+#### Database.Collections() []string
 
 Returns the names of all the collections in the current database.
 
-#### db.Database.Use(name string) error
+#### Database.Use(name string) error
 
 Makes the session switch between databases given the name. Returns an error if it fails.
 
-#### db.Database.Drop() error
+#### Database.Drop() error
 
 Erases the entire database and all the collections. Returns an error if it fails.
 
@@ -99,7 +103,7 @@ Erases the entire database and all the collections. Returns an error if it fails
 
 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 ``Find()`` or ``FindAll()``, a special structure named ``Item`` will be returned.
+When you request data from a Collection with ``Collection.Find()`` or ``Collection.FindAll()``, a special object with structure ``Item`` will be returned.
 
     // Collection methods.
     type Collection interface {
@@ -120,19 +124,19 @@ When you request data from a Collection with ``Find()`` or ``FindAll()``, a spec
     // Rows from a result.
     type Item map[string]interface{}
 
-#### db.Collection.Append(...interface{}) bool
+#### Collection.Append(...interface{}) bool
 
 Appends one or more items to the collection.
 
     collection.Append(Item { "name": "Peter" })
 
-#### db.Collection.Count(...interface{}) int
+#### Collection.Count(...interface{}) int
 
 Returns the number of total items matching the provided conditions.
 
     total := collection.Count(Where { "name": "Peter" })
 
-#### db.Collection.Find(...interface{}) Item
+#### Collection.Find(...interface{}) 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.
 
@@ -146,11 +150,47 @@ Return the first Item of the collection that matches all the provided conditions
      },
     )
 
-#### db.Collection.FindAll(...interface{}) []Item
-
-Returns all the Items ([]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 FindAll() but not to Find(), like db.Limit(n) or db.Offset(n).
+You can use relations in your definition
+
+  collection.FindAll(
+    // One-to-one relation with the table "places".
+    Relate{
+      "lives_in": On{
+        session.Collection("places"),
+        // Relates rows of the table "places" where place.code_id = collection.place_code_id.
+        Where{"code_id": "{place_code_id}"},
+      },
+    },
+    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}"},
+      },
+      // One-to-many relation with the table "visits".
+      "has_visited": On{
+        session.Collection("visits"),
+        // Relates rows of the table "visits" where visits.person_id = collection.id
+        Where{"person_id": "{id}"},
+        // A nested relation
+        Relate{
+          // Relates rows of the table "places" with the "visits" table.
+          "place": On{
+            session.Collection("places"),
+            // Where places.id = visits.place_id
+            Where{"id": "{place_id}"},
+          },
+        },
+      },
+    },
+  )
+
+#### Collection.FindAll(...interface{}) []Item
+
+Returns all the Items (``[]Item``) of the collection that match all the provided conditions. See ``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)``.
 
     // Just give me the the first 10 rows with last_name = "Smith"
     collection.Find(
@@ -158,9 +198,9 @@ Be aware that there are some extra parameters that you can pass to FindAll() but
       Limit(10),
     )
 
-#### db.Collection.Update(...interface{}) bool
+#### 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 ``Set``, ``Modify`` or ``Upsert``. At the time of this writing ``Modify`` and ``Upsert`` are only available for MongoSession.
 
     // Example of assigning field values with Set:
     collection.Update(
@@ -180,7 +220,7 @@ Updates all the items of the collection that match all the provided conditions.
       Upsert { "name": "Robert"},
     )
 
-#### db.Collection.Remove(...interface{}) bool
+#### Collection.Remove(...interface{}) bool
 
 Deletes all the items of the collection that match the provided conditions.
 
@@ -189,7 +229,7 @@ Deletes all the items of the collection that match the provided conditions.
       Where { "last_name": "Parker" },
     )
 
-#### db.Collection.Truncate() bool
+#### Collection.Truncate() bool
 
 Deletes the whole collection.
 
@@ -202,3 +242,15 @@ You can read ``gosexy/db`` documentation from a terminal
     $ go doc github.com/xiam/gosexy/db
 
 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 Go time datatype.
+* Improve datatype guessing.
+* Improve error handling.
+* Add CouchDB support.
+
+## Changelog
+
+2012/07/09 - First public beta with MySQL, MongoDB, PostgreSQL and SQLite3.
diff --git a/db/mongo.go b/db/mongo.go
index 5cd7fd8a..cc137ce7 100644
--- a/db/mongo.go
+++ b/db/mongo.go
@@ -78,11 +78,7 @@ func (c *MongoDataSourceCollection) Truncate() bool {
 	return true
 }
 
-// Inserts items into the collection. You can use one or many Item values as arguments.
-//
-// Example:
-//
-// collection.Append(Item { "name": "Peter" })
+// Inserts items into the collection.
 func (c *MongoDataSourceCollection) Append(items ...interface{}) bool {
 
 	parent := reflect.TypeOf(c.collection)
@@ -170,14 +166,7 @@ func (c *MongoDataSourceCollection) compileQuery(terms []interface{}) interface{
 	return query
 }
 
-// Removes the first item that matches the provided conditions.
-//
-// Example:
-//
-// collection.Remove(
-//   Where { "name": "Peter" },
-//   Where { "last_name": "Parker" },
-// )
+// Removes all the items that match the provided conditions.
 func (c *MongoDataSourceCollection) Remove(terms ...interface{}) bool {
 
 	query := c.compileQuery(terms)
@@ -187,28 +176,7 @@ func (c *MongoDataSourceCollection) Remove(terms ...interface{}) bool {
 	return true
 }
 
-// Updates a single document matching the provided conditions. You can specify the modification type by using Set, Modify or Upsert.
-//
-// Example of assigning field values with Set:
-//
-// collection.Update(
-//   Where { "name": "José" },
-//   Set { "name": "Joseph"},
-// )
-//
-// Example of custom modification with Modify:
-//
-// collection.Update(
-//   Where { "times <": "10" },
-//   Modify { "$inc": { "times": 1 } },
-// )
-//
-// Example of inserting if none matches with Upsert:
-//
-// collection.Update(
-//   Where { "name": "Roberto" },
-//   Upsert { "name": "Robert"},
-// )
+// Updates all the items that match the provided conditions. You can specify the modification type by using Set, Modify or Upsert.
 func (c *MongoDataSourceCollection) Update(terms ...interface{}) bool {
 
 	var set interface{}
@@ -297,18 +265,6 @@ func (c *MongoDataSourceCollection) Count(terms ...interface{}) int {
 
 // Returns a document that matches all the provided conditions. Ordering of the terms doesn't matter but you must take in
 // account that conditions are generally evaluated from left to right (or from top to bottom).
-//
-// Example:
-//
-// This 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 },
-//   },
-// )
 func (c *MongoDataSourceCollection) Find(terms ...interface{}) Item {
 
 	var item Item
@@ -328,8 +284,6 @@ func (c *MongoDataSourceCollection) Find(terms ...interface{}) Item {
 }
 
 // Returns a mgo.Query that matches the provided terms.
-//
-// This is actually a function that is only public because of the implementation of mongo.go but you should not use or rely on it.
 func (c *MongoDataSourceCollection) BuildQuery(terms ...interface{}) *mgo.Query {
 
 	var sort interface{}
@@ -382,16 +336,6 @@ func (c *MongoDataSourceCollection) BuildQuery(terms ...interface{}) *mgo.Query
 }
 
 // Returns all the results that match the provided conditions. See Find().
-//
-// Be aware that there are some extra parameters that you can pass to FindAll() but not to Find(), like
-// Limit(n).
-//
-// Example:
-//
-// collection.Find(
-//   Where { "last_name": "Smith" },
-//   Limit(10),
-// )
 func (c *MongoDataSourceCollection) FindAll(terms ...interface{}) []Item {
 	var items []Item
 	var result []interface{}
@@ -536,29 +480,7 @@ func (c *MongoDataSourceCollection) FindAll(terms ...interface{}) []Item {
 	return items
 }
 
-// Returns a new MongoDataSource object, this object can be then used to Connect() to the database and operate on Collections.
-// See db.DataSource{}.
-//
-// Example:
-//
-// source := MongoSession(&DataSource {
-//   Host: "localhost",
-//   Database: "test",
-//   User: "charly",
-//   Password: "sn00py"
-// })
-//
-// err := source.Connect()
-//
-// if err != nil {
-//   panic(err)
-// }
-//
-// source.Use("test")
-//
-// people := db.Collection("people")
-//
-// result := people.Find(Where { "name": "José" })
+// Returns a new MongoDataSource object.
 func MongoSession(config DataSource) Database {
 	m := &MongoDataSource{}
 	m.config = config
@@ -631,7 +553,7 @@ func (m *MongoDataSource) Close() error {
 	return nil
 }
 
-// Returns all the collection names on the active database.
+// Returns all the collection names in the active database.
 func (m *MongoDataSource) Collections() []string {
 	names, _ := m.database.CollectionNames()
 	return names
-- 
GitLab