good morning!!!!

Skip to content
Snippets Groups Projects
db.go 8.32 KiB
Newer Older
  Copyright (c) 2012-2013 José Carlos Nieto, http://xiam.menteslibres.org/

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

José Carlos Nieto's avatar
José Carlos Nieto committed
/*
	menteslibres.net/db wraps third party database drivers in an attempt to make
	permanent storage with Go as easy as possible. The package features a common,
	consistent layer that allows executing operations against different kinds of
	databases using Go expressions, without the need for explicit database-specific
	instructions.
José Carlos Nieto's avatar
José Carlos Nieto committed
*/
	The db.Cond{} expression is used to filter results in a query, it can be
	viewed as a replacement for the SQL "WHERE" clause.
	db.Cond { "age": 18 }				// Where age equals 18.
	db.Cond { "age >=": 18 }		// Where age is greater than or equal to 18.
	db.Cond { "age $lt": 18 }		// Where age is lower than 18 (MongoDB specific).
José Carlos Nieto's avatar
José Carlos Nieto committed
type Cond map[string]interface{}
	The db.And() expression is used to glue two or more expressions under logical
	conjunction, it accepts db.Cond{}, db.Or() and other db.And() expressions.

	db.And (
		db.Cond { "name": "Peter" },
		db.Cond { "last_name": "Parker "},
	)

	db.And (
			db.Cond{ "name": "Peter" },
			db.Cond{ "name": "Mickey" },
		db.Cond{ "last_name": "Mouse" },
	)
*/
	The db.Or() expression is used to glue two or more expressions under logical
	disjunction, it accepts db.Cond{}, db.And() and other db.Or() expressions.

	Example:

	db.Or (
		db.Cond { "year": 2012 },
		db.Cond { "year": 1987 },
	)
*/
	The db.Sort expression determines how results will be sorted.
	db.Sort { "age": -1 }				// Order by age, descendent.
	db.Sort { "age": 1 }				// Order by age, ascendent.
type Sort map[string]interface{}
	The db.Limit() expression sets the maximum number of rows to be returned in a
	query.
	If no db.Limit() is specified, all rows will be returned.

	Example:

		db.Limit(10)
*/
	The db.Offset() expression sets the number of rows to be skipped from a
	result.
	If no db.Offset() is specified, no rows will be skipped.

	Example:

		db.Offset(7)
*/
	The db.Set{} expression is used in *db.Collection.Update()*, it defines new
	values for the given fields.

	Example:

	db.Set {
		"name": "New Name",
	}
*/
type Set map[string]interface{}
// A query result.
type Item map[string]interface{}
// Connection and authentication data.
	// Host to connect to. Cannot be used if Socket is specified.
	Host string
	// Port to connect to. Cannot be used if Socket is specified.
	Port int
	// Name of the database to use.
	Database string
	// Authentication user name.
	User string
	// Authentication password.
	Password string
	// A path of a UNIX socket. Cannot be user if Host is specified.
	Socket string
	// Charset of the database.
	Charset string
// Database methods.
type Database interface {
	// Returns the underlying driver the wrapper uses as an interface{}, so you
	// can still use database-specific features when you need it.
	// Attempts to open a connection using the current settings.
	// Closes the currently active connection to the database.
	// Returns a db.Collection struct by name.
	Collection(string) (Collection, error)
	// Returns the names of all the collections within the active database.
	Collections() ([]string, error)

	// Changes the active database.
	Use(string) error
	Drop() error
	// Sets database connection settings.
	Setup(Settings) error
	// Returns the string name of the active database.
José Carlos Nieto's avatar
José Carlos Nieto committed
	Name() string
	// Starts a transaction block (if the database supports transactions).
	// Ends a transaction block (if the database supports transactions).
// Collection methods.
	// Inserts a new item into the collection. Can work with maps or structs.
	Append(interface{}) (Id, error)
	// Returns true if the collection exists.
	Exists() bool
	// Creates a filter with the given conditions and returns a result set.
	Filter(...interface{}) (Result, error)
	// Returns the string name of the collection.
José Carlos Nieto's avatar
José Carlos Nieto committed
	Name() string
	// Removes all items within the result set.
	// Updates all items within the result set.
	Update(interface{}) error
	// Counts all items within the result set.
	Count() (uint64, error)
	// Fetches all the results of the query into the given pointer.
	//
	// Accepts a pointer to slice of maps or structs.
	All(interface{}) error
	// Fetches the first result of the query into the given pointer and discards
	// the rest.
	//
	// Accepts a pointer to map or struct.
	One(interface{}) error
	// Fetches the next result of the query into the given pointer. Returns error if
	// there are no more results.
	// Warning: If you're only using part of these results you must manually Close()
	// the result.
	//
	// Accepts a pointer to map or struct.
// Specifies which fields will be returned in a query.
type Fields []string
// These are internal variables.
//type MultiFlag bool
//type SqlValues []string
//type SqlArgs []string
// Error messages
var (
	ErrExpectingPointer        = errors.New(`Expecting a pointer destination (dst interface{}).`)
	ErrExpectingSlicePointer   = errors.New(`Expecting a pointer to an slice (dst interface{}).`)
	ErrExpectingSliceMapStruct = errors.New(`Expecting a pointer to an slice of maps or structs (dst interface{}).`)
	ErrExpectingMapOrStruct    = errors.New(`Expecting either a pointer to a map or a pointer to a struct.`)
	ErrNoMoreRows              = errors.New(`There are no more rows in this result set.`)
	ErrNotConnected            = errors.New(`You're currently not connected.`)
	ErrMissingDatabaseName     = errors.New(`Missing a database name.`)
	ErrCollectionDoesNotExists = errors.New(`Collection does not exists.`)
	ErrSockerOrHost            = errors.New(`You can connect either to a socket or a host but not both.`)
	ErrQueryLimitParam         = errors.New(`A query can accept only one db.Limit() parameter.`)
	ErrQuerySortParam          = errors.New(`A query can accept only one db.Sort{} parameter.`)
	ErrQueryOffsetParam        = errors.New(`A query can accept only one db.Offset() parameter.`)
	ErrMissingConditions       = errors.New(`Missing selector conditions.`)
)

// Registered wrappers.
var wrappers = make(map[string]Database)

// Registers a database wrapper with a unique name.
func Register(name string, driver Database) {
		panic("Missing wrapper name.")
	if _, ok := wrappers[name]; ok != false {
		panic("Register called twice for driver " + name)
// Configures a connection to a database using the named wrapper and the given
// settings.
func Open(name string, settings Settings) (Database, error) {
		panic(fmt.Sprintf("Unknown wrapper: %s.", name))

	// Creating a new connection everytime Open() is called.
	t := reflect.ValueOf(driver).Elem().Type()

	conn := reflect.New(t).Interface().(Database)
	// Setting up the connection with the given source.
	if err != nil {
		return nil, err
	}