Newer
Older
José Carlos Nieto
committed
// Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
//
// 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
committed
// The `upper.io/db` package for Go provides a single interface for interacting
// with different data sources through the use of adapters that wrap well-known
// database drivers.
//
// As of today, `upper.io/db` fully supports MySQL, PostgreSQL and SQLite (CRUD
// + Transactions) and provides partial support for MongoDB and QL (CRUD only).
José Carlos Nieto
committed
//
// Usage:
//
// import(
// // Main package.
// "upper.io/db"
// // PostgreSQL adapter.
// "upper.io/db/postgresql"
// )
José Carlos Nieto
committed
//
// `upper.io/db` is not an ORM and thus does not impose any hard restrictions
// on data structures:
//
// // This code works the same for all supported databases.
// var people []Person
// res = col.Find(db.Cond{"name": "Max"}).Limit(2).Sort("-input")
// err = res.All(&people)
José Carlos Nieto
committed
package db
José Carlos Nieto
committed
// The `db.Cond{}` expression is used to define conditions used as arguments to
// `db.Collection.Find()` and `db.Result.Where()`.
José Carlos Nieto
committed
//
// Examples:
//
// // Where age equals 18.
// db.Cond { "age": 18 }
//
// Where age is greater than or equal to 18.
// db.Cond { "age >=": 18 }
//
// Where age is lower than 18 (On MongoDB context).
// db.Cond { "age $lt": 18 }
José Carlos Nieto
committed
// The `db.Func{}` expression is used to represent database functions.
//
// Examples:
//
// // MOD(29, 9)
// db.Func{"MOD", []int{29, 9}}
//
// // CONCAT("foo", "bar")
// db.Func{"CONCAT", []string{"foo", "bar"}}
//
// // NOW()
// db.Func{"NOW"}
//
// // RTRIM("Hello ")
// db.Func{"RTRIM", "Hello "}
type Func struct {
Name string
Args interface{}
}
José Carlos Nieto
committed
// The `db.And{}` expression is used to join two or more expressions under
// logical conjunction, it accepts `db.Cond{}`, `db.Or{}`, `db.Raw{}` and other
// `db.And{}` expressions.
//
// Examples:
//
// // SQL: name = "Peter" AND last_name = "Parker"
// db.And (
// db.Cond { "name": "Peter" },
// db.Cond { "last_name": "Parker "},
// )
//
// // SQL: (name = "Peter" OR name = "Mickey") AND last_name = "Mouse"
// db.And {
// db.Or {
// db.Cond{ "name": "Peter" },
// db.Cond{ "name": "Mickey" },
// },
// db.Cond{ "last_name": "Mouse" },
// }
José Carlos Nieto
committed
type And []interface{}
José Carlos Nieto
committed
// The `db.Or{}` expression is used to glue two or more expressions under
// logical disjunction, it accepts `db.Cond{}`, `db.And{}`, `db.Raw{}` and
// other `db.Or{}` expressions.
//
// Example:
//
// // SQL: year = 2012 OR year = 1987
// db.Or {
// db.Cond{"year": 2012},
// db.Cond{"year": 1987},
// }
José Carlos Nieto
committed
type Or []interface{}
José Carlos Nieto
committed
// The `db.Raw{}` expression is mean to hold chunks of data to be passed to the
// database without any filtering.
//
// When using `db.Raw{}`, the developer is responsible of providing a sanitized
// instruction to the database.
//
// The `db.Raw{}` expression is allowed as element on `db.Cond{}`, `db.And{}`,
// `db.Or{}` expressions and as argument on `db.Result.Select()` and
// `db.Collection.Find()` methods.
//
// Example:
//
// // SQL: SOUNDEX('Hello')
// Raw{"SOUNDEX('Hello')"}
type Raw struct {
Value interface{}
}
José Carlos Nieto
committed
// The `db.Settings{}` struct holds database connection and authentication
// data. Not all fields must be supplied, is any field is skipped, the database
// adapter will either try to use database defaults or return an error. Refer
// to the specific adapter to see which fields are required.
//
// Example:
//
// db.Settings{
// Host: "127.0.0.1",
// Database: "tests",
// User: "john",
// Password: "doe",
// }
Carlos Nieto
committed
type Settings struct {
José Carlos Nieto
committed
// Database server hostname or IP. This field is ignored if using unix
// sockets or if the database does not require a connection to any host
// (SQLite, QL).
José Carlos Nieto
committed
// Database server port. This field is ignored if using unix sockets or if
// the database does not require a connection to any host (SQLite, QL). If
// not provided, the default database port is tried.
José Carlos Nieto
committed
// Name of the database. You can also use a filename if the database supports
// opening a raw file (SQLite, QL).
José Carlos Nieto
committed
// Username for authentication, if required.
José Carlos Nieto
committed
// Password for authentication, if required.
José Carlos Nieto
committed
// A path to a UNIX socket file. Leave blank if you rather use host and port.
José Carlos Nieto
committed
// Database charset. You can leave this field blank to use the default
// database charset.
José Carlos Nieto
committed
}
José Carlos Nieto
committed
// The `db.Database` interface defines methods that all adapters must provide.
José Carlos Nieto
committed
// Returns the underlying driver the wrapper uses. As an `interface{}`.
//
// In order to actually use the `interface{}` you must cast it to the known
// database driver type.
//
// Example:
// internalSQLDriver := sess.Driver().(*sql.DB)
José Carlos Nieto
committed
Driver() interface{}
José Carlos Nieto
committed
// Attempts to stablish a connection with the database server, a previous
// call to Setup() is required.
José Carlos Nieto
committed
Open() error
José Carlos Nieto
committed
// Clones the current database session. Returns an error if the clone could
// not be carried out.
Clone() (Database, error)
// Returns error if the database server cannot be reached.
Carlos Nieto
committed
// Closes the currently active connection to the database.
José Carlos Nieto
committed
Close() error
José Carlos Nieto
committed
// Returns a `db.Collection{}` struct by name. Some databases support
// collections of more than one source or table, refer to the documentation
// of the specific database adapter to see if using multiple sources is
// supported.
Collection(...string) (Collection, error)
José Carlos Nieto
committed
// Returns the names of all non-system sources or tables within the active
Carlos Nieto
committed
Collections() ([]string, error)
José Carlos Nieto
committed
// Attempts to connect to another database using the same connection
// settings. Similar to MySQL's `USE` instruction.
Carlos Nieto
committed
// Drops the active database.
José Carlos Nieto
committed
// Sets the database connection settings. In order to connect, a call to
// `db.Database.Open()` is required.
Carlos Nieto
committed
Setup(Settings) error
// Returns the name of the active database.
José Carlos Nieto
committed
// Starts a transaction block. Some databases do not support transactions,
// refer to the documentation of the specific database adapter to see the
// current status on transactions.
Transaction() (Tx, error)
}
José Carlos Nieto
committed
// The `db.Tx` interface provides the same methods that the `db.Database` does,
// plus some other that help the user deal with database transactions. In order
// to get a proper `db.Tx` interface the `db.Database.Transaction()` method
// must be called on an already opened database session.
José Carlos Nieto
committed
//
// Example:
// ...
// if sess, err = db.Open(postgresql.Adapter, settings); err != nil {
// log.Fatal(err)
// }
//
// var tx db.Tx
// if tx, err = sess.Transaction(); err != nil {
// log.Fatal(err)
// }
//
// var artist db.Collection
// if artist, err = tx.Collection("artist"); err != nil {
// log.Fatal(err)
// }
// ...
type Tx interface {
Database
José Carlos Nieto
committed
// Discards all the instructions issued during the transaction.
José Carlos Nieto
committed
// Verifies that all the instructions isssued during the transaction were
// executed.
José Carlos Nieto
committed
// The `db.Collection` interface defines methods for handling data sources or
// tables.
José Carlos Nieto
committed
type Collection interface {
José Carlos Nieto
committed
// Inserts a new item into the collection. Accepts a map or a struct as
// argument.
Append(interface{}) (interface{}, error)
Carlos Nieto
committed
// Returns true if the collection exists.
Exists() bool
José Carlos Nieto
committed
José Carlos Nieto
committed
// Sets a filter on the collection with the given conditions and returns a
// result set.
Find(...interface{}) Result
José Carlos Nieto
committed
José Carlos Nieto
committed
// Removes all elements on the collection and resets the IDs.
Truncate() error
José Carlos Nieto
committed
}
José Carlos Nieto
committed
// The `db.Result` interface defines methods for working with result sets.
José Carlos Nieto
committed
type Result interface {
José Carlos Nieto
committed
// Defines the maximum number of results in this set.
Limit(uint) Result
José Carlos Nieto
committed
// Skips over the *n* initial results.
Skip(uint) Result
José Carlos Nieto
committed
// Receives fields that define the order in which elements will be returned
// in a query, field names may be prefixed with a minus sign (-) indicating
// descending order; ascending order would be used by default.
Sort(...string) Result
José Carlos Nieto
committed
// Defines specific fields to be fulfilled on results in this result set.
José Carlos Nieto
committed
// Discards the initial filtering conditions and sets new ones.
José Carlos Nieto
committed
Where(...interface{}) Result
Carlos Nieto
committed
// Removes all items within the result set.
// Updates all items within the result set. Receives an struct or an interface{}.
// Counts all the items on the result set.
// Fetches the next result within the result set and dumps it into the given
// pointer to struct or pointer to map. You must manually call Close() after
// finishing using Next().
José Carlos Nieto
committed
Next(interface{}) error
// Fetches the first result within the result set and dumps it into the given
// pointer to struct or pointer to map. Then it calls Close() to free the
// result set.
// Fetches all results within the result set and dumps them into the given
// pointer to slice of maps or structs. Then it calls Close() to free the
// result set.
All(interface{}) error
José Carlos Nieto
committed
Close() error
}
José Carlos Nieto
committed
// If the user sets the `UPPERIO_DB_DEBUG` environment variable to a
// non-empty value, all generated statements will be printed at runtime to
// the standard logger.
//
// Example:
//
// UPPERIO_DB_DEBUG=1 go test
//
// UPPERIO_DB_DEBUG=1 ./go-program
var EnvEnableDebug = `UPPERIO_DB_DEBUG`