rethinkgo

package module
v0.0.0-...-64fcd6e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2013 License: BSD-3-Clause Imports: 14 Imported by: 0

README

rethinkgo

Go language driver for RethinkDB made by Christopher Hesse

Installation

go get -u github.com/christopherhesse/rethinkgo

If you do not have goprotobuf runtime installed, it is required:

brew install mercurial  # if you do not have mercurial installed
go get code.google.com/p/goprotobuf/{proto,protoc-gen-go}

Example

package main

import (
    "fmt"
    r "github.com/christopherhesse/rethinkgo"
)

func main() {
    session, _ := r.Connect("localhost:28015", "test")

    err := r.TableCreate("characters").Run(session).Exec()
    err = r.Table("characters").Insert(
        r.List{r.Map{ "name": "Worf", "show": "Star Trek TNG" },
        r.Map{ "name": "Data", "show": "Star Trek TNG" },
        r.Map{ "name": "William Adama", "show": "Battlestar Galactica" },
        r.Map{ "name": "Homer Simpson", "show": "The Simpsons" }},
    ).Run(session).Exec()

    rows := r.Table("characters").Run(session)
    defer rows.Close()

    for rows.Next() {
        var result map[string]string
        rows.Scan(&result)
        fmt.Println("result:", result)
    }

    err = rows.Err()
    if err != nil {
        fmt.Println("error:", err)
    }
}

Overview

The Go driver is most similar to the official Javascript driver.

Most of the functions have the same names as in the Javascript driver, only with the first letter capitalized. See Go Driver Documentation for examples and documentation for each function.

To use RethinkDB with this driver, you build a query using r.Table(), for example, and then call query.Run(session) to execute the query on the server and return an iterator for the results.

There are 3 convenience functions on the iterator if you don't want to iterate over the results, .One(&result) for a query that returns a single result, .All(&results) for multiple results, and .Exec() for a query that returns an empty response (for instance, r.TableCreate(string)).

The important types are r.Exp (for RethinkDB expressions), r.Query (interface for all queries, including expressions), r.List (used for Arrays, an alias for []interface{}), and r.Map (used for Objects, an alias for map[string]interface{}).

The function r.Expr() can take arbitrary structs and uses the "json" module to serialize them. This means that structs can use the json.Marshaler interface (define a method MarshalJSON() on the struct). Also, struct fields can also be annotated to specify their JSON equivalents:

type MyStruct struct {
    MyField int `json:"my_field"`
}

See the json docs for more information.

Differences from official RethinkDB drivers

  • When running queries, getting results is a little different from the more dynamic languages. .Run(*Session) returns a *Rows iterator object with the following methods that put the response into a variable dest, here's when you should use the different methods:

    • You want to iterate through the results of the query individually: rows.Next() and rows.Scan(&dest) (you should defer rows.Close() when using this)
    • The query always returns a single response: .One(&dest)
    • The query returns a list of responses: .All(&dest)
    • The query returns an empty response: .Exec()
  • No errors are generated when creating queries, only when running them, so Table(string) returns only an Exp instance, but sess.Run(Query).Err() will tell you if your query could not be serialized for the server. To check just the serialization of the query before calling .Run(*Session), use .Check(*Session)

  • Go does not have optional args, most optional args are either require or separate methods.

    • .Atomic(bool), .Overwrite(bool), .UseOutdated(bool) are methods on any Table() or other Exp (will apply to all tables, inserts, etc that have already been specified)
    • .TableCreate(string) has a variant called TableCreateSpec(TableSpec) which takes a TableSpec instance specifying the parameters for the table
  • There's no r(attributeName) or row[attributeName] function call / item indexing to get attributes of the "current" row or a specific row respectively. Instead, there is a .Attr() method on the global "Row" object (r.Row) and any row Expressions that can be used to access attributes. Examples:

      r.Table("marvel").OuterJoin(r.Table("dc"),
          func(marvel, dc r.Exp) interface{} {
              return marvel.Attr("strength").Eq(dc.Attr("strength"))
          })
    
      r.Table("marvel").Map(r.Row.Attr("strength").Mul(2))
    

Documentation

Overview

Package rethinkgo implements the RethinkDB API for Go. RethinkDB (http://www.rethinkdb.com/) is an open-source distributed database in the style of MongoDB.

If you haven't tried it out, it takes about a minute to setup and has a sweet web console. Even runs on Mac OS X. (http://www.rethinkdb.com/docs/guides/quickstart/)

If you are familiar with the RethinkDB API, this package should be straightforward to use. If not, the docs for this package contain plenty of examples, but you may want to look through the RethinkDB tutorials (http://www.rethinkdb.com/docs/).

Example usage:

package main

import (
    "fmt"
    r "github.com/christopherhesse/rethinkgo"
)

type Employee struct {
    FirstName string
    LastName  string
    Job       string
}

func main() {
    // To access a RethinkDB database, you connect to it with the Connect function
    session, err := r.Connect("localhost:28015", "company_info")
    if err != nil {
        fmt.Println("error connecting:", err)
        return
    }

    // This creates a database session 'session' that may be used to run
    // queries on the server.  Queries let you read, insert, update, and
    // delete JSON objects ("rows") on the server, as well as manage tables.
    query := r.Table("employees")
    rows := query.Run(session)
    defer rows.Close()

    // 'rows' is an iterator that can be used to iterate over the
    // results.  If there was an error, it is available in rows.Err()
    for rows.Next() {
        var row Employee
        if err = rows.Scan(&row); err != nil {
            fmt.Println("err:", err)
            break
        }
        fmt.Println("row:", row)
    }
    if err = rows.Err(); err != nil {
        fmt.Println("err:", err)
    }
}

Besides this simple read query, you can run almost arbitrary expressions on the server, even Javascript code. See the rest of these docs for more details.

Index

Constants

This section is empty.

Variables

View Source
var Row = Exp{/* contains filtered or unexported fields */}

Row supplies access to the current row in any query, even if there's no go func with a reference to it.

Example without Row:

var response []interface{}
// Get the real names of all the villains
err := r.Table("villains").Map(func(row r.Exp) r.Exp {
    return row.Attr("real_name")
}).Run(session).All(&response)

Example with Row:

var response []interface{}
// Get the real names of all the villains
err := r.Table("employees").Map(Row.Attr("real_name")).Run(session).All(&response)

Example response:

["En Sabah Nur", "Victor von Doom", ...]

Functions

func SetDebug

func SetDebug(debug bool)

SetDebug causes all queries sent to the server and responses received to be printed to stdout in raw form.

Example usage:

r.SetDebug(true)

Types

type ErrBadQuery

type ErrBadQuery struct {
	// contains filtered or unexported fields
}

ErrBadQuery indicates that the server has told us we have constructed an invalid query.

Example usage:

err := r.Table("heroes").ArrayToStream().ArrayToStream().Run(session).Err()

func (ErrBadQuery) Error

func (e ErrBadQuery) Error() string

type ErrBrokenClient

type ErrBrokenClient struct {
	// contains filtered or unexported fields
}

ErrBrokenClient means the server believes there's a bug in the client library, for instance a malformed protocol buffer.

func (ErrBrokenClient) Error

func (e ErrBrokenClient) Error() string

type ErrNoSuchRow

type ErrNoSuchRow struct {
	// contains filtered or unexported fields
}

ErrNoSuchRow is returned when there is an empty response from the server and .One() is being used.

Example usage:

var row interface{}
err := r.Table("heroes").Get("Apocalypse", "name").Run(session).One(&row)

func (ErrNoSuchRow) Error

func (e ErrNoSuchRow) Error() string

type ErrRuntime

type ErrRuntime struct {
	// contains filtered or unexported fields
}

ErrRuntime indicates that the server has encountered an error while trying to execute our query.

Example usage:

err := r.Table("table_that_doesnt_exist").Run(session).Err()
err := r.RuntimeError("error time!").Run(session).Err()

func (ErrRuntime) Error

func (e ErrRuntime) Error() string

type ErrWrongResponseType

type ErrWrongResponseType struct {
	// contains filtered or unexported fields
}

ErrWrongResponseType is returned when .Exec(), .One(). or .All() have been used, but the expected response type does not match the type we got from the server.

Example usage:

var row []interface{}
err := r.Table("heroes").Get("Archangel", "name").Run(session).All(&row)

func (ErrWrongResponseType) Error

func (e ErrWrongResponseType) Error() string

type Exp

type Exp struct {
	// contains filtered or unexported fields
}

Exp represents an RQL expression, such as the return value of r.Expr(). Exp has all the RQL methods on it, such as .Add(), .Attr(), .Filter() etc.

To create an Exp from a native or user-defined type, or function, use r.Expr().

Example usage:

r.Expr(2).Mul(2) => 4

Exp is the type used for the arguments to any functions that are used in RQL.

Example usage:

var response []interface{}
// Get the intelligence rating for each of our heroes
getIntelligence := func(row r.Exp) r.Exp {
    return row.Attr("intelligence")
}
err := r.Table("heroes").Map(getIntelligence).Run(session).All(&response)

Example response:

[7, 5, 4, 6, 2, 2, 6, 4, ...]

Literal Expressions can be used directly for queries.

Example usage:

var squares []int
// Square a series of numbers
square := func(row r.Exp) r.Exp { return row.Mul(row) }
err := r.Expr(1,2,3).Map(square).Run(session).One(&squares)

Example response:

[1, 2, 3]

func Asc

func Asc(attr string) Exp

Asc tells OrderBy to sort a particular attribute in ascending order. This is the default sort.

Example usage:

var response []interface{}
// Retrieve villains in order of increasing fighting ability (worst fighters first)
err := r.Table("villains").OrderBy(r.Asc("fighting")).Run(session).All(&response)

func Avg

func Avg(attribute string) Exp

Avg computes the average value of an attribute for a group, for use with the .GroupBy() method.

Example usage:

var response []interface{}
err := r.Table("heroes").GroupBy("strength", r.Avg("intelligence")).Run(session).One(&response)

Example response:

[
  {
    // this is the strength attribute for every member of this group
    "group": 1,
    // this is the average value of the intelligence attribute of all members of the group
    "reduction": 1
  },
  {
    "group": 2,
    "reduction": 3
  },
  ...
]

func Branch

func Branch(test, trueBranch, falseBranch interface{}) Exp

Branch checks a test expression, evaluating the trueBranch expression if it's true and falseBranch otherwise.

Example usage:

// Roughly equivalent RQL expression
r.Branch(r.Row.Attr("first_name").Eq("Marc"), "is probably marc", "who cares")

func Count

func Count() Exp

Count counts the number of rows in a group, for use with the .GroupBy() method.

Example usage:

var response []interface{}
// Count all heroes in each superhero group
err := r.Table("heroes").GroupBy("affiliation", r.Count()).Run(session).One(&response)

Example response:

[
  {
    "group": "Avengers", // this is the affiliation attribute for every member of this group
    "reduction": 9  // this is the number of members in this group
  },
  {
    "group": "X-Men",
    "reduction": 12
  },
  ...
]

func Db

func Db(name string) Exp

Db lets you perform operations within a specific database (this will override the database specified on the session). This can be used to access or create/list/delete tables within any database available on the server.

Example usage:

var response []interface{}
// this query will use the default database of the last created session
r.Table("test").Run(session).All(&response)
// this query will use database "marvel" regardless of what database the session has set
r.Db("marvel").Table("heroes").Run(session).All(&response)

func DbCreate

func DbCreate(name string) Exp

DbCreate creates a database with the supplied name.

Example usage:

err := r.DbCreate("marvel").Run(session).Exec()

func DbDrop

func DbDrop(name string) Exp

DbDrop deletes the specified database

Example usage:

err := r.DbDrop("marvel").Run(session).Exec()

func DbList

func DbList() Exp

DbList lists all databases on the server

Example usage:

var databases []string
err := r.DbList().Run(session).All(&databases)

Example response:

["test", "marvel"]

func Desc

func Desc(attr string) Exp

Desc tells OrderBy to sort a particular attribute in descending order.

Example usage:

var response []interface{}
// Retrieve villains in order of decreasing speed (fastest villains first)
err := r.Table("villains").OrderBy(r.Desc("speed")).Run(session).All(&response)

func Do

func Do(operands ...interface{}) Exp

Do evalutes the last argument (a function) using all previous arguments as the arguments to the function.

For instance, Do(a, b, c, f) will be run as f(a, b, c).

Example usage:

 var response interface{}
 err := r.Do(1, 2, 3, func(a, b, c r.Exp) interface{} {
	    return r.List{a, b, c}
 }).Run(session).One(&response)

Example response:

[1,2,3]

func Expr

func Expr(value interface{}) Exp

Expr converts any value to an expression. Internally it uses the `json` module to convert any literals, so any type annotations or methods understood by that module can be used. If the value cannot be converted, an error is returned at query .Run(session) time.

If you want to call expression methods on an object that is not yet an expression, this is the function you want.

Example usage:

var response interface{}
rows := r.Expr(r.Map{"go": "awesome", "rethinkdb": "awesomer"}).Run(session).One(&response)

Example response:

{"go": "awesome", "rethinkdb": "awesomer"}

func Js

func Js(body string) Exp

Js creates an expression using Javascript code. The code is executed on the server (using eval() https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval) and can be used in a couple of roles, as value or as a function. When used as a function, it receives two named arguments, 'row' and/or 'acc' (used for reductions).

The value of the 'this' object inside Javascript code is the current row.

Example usages:

// (same effect as r.Expr(1,2,3))
r.Js(`[1,2,3]`).Run(session)
// Parens are required here, otherwise eval() thinks it's a block.
r.Js(`({name: 2})`).Run(session)
// String concatenation is possible using r.Js
r.Table("employees").Map(r.Js(`this.first_name[0] + ' Fucking ' + this.last_name[0]`)).Run(session)

Example without Js:

var response []interface{}
// Combine each hero's strength and durability
err := r.Table("heroes").Map(func(row r.Exp) r.Exp {
    return row.Attr("strength").Add(row.Attr("durability"))
}).Run(session).All(&response)

Example with Js:

var response []interface{}
// Combine each hero's strength and durability
err := r.Table("heroes").Map(
	r.Js(`(function (row) { return row.strength + row.durability; })`),
).Run(session).All(&response)

Example response:

[11, 6, 9, 11, ...]

func RuntimeError

func RuntimeError(message string) Exp

RuntimeError tells the server to respond with a ErrRuntime, useful for testing.

Example usage:

err := r.RuntimeError("hi there").Run(session).Err()

func Sum

func Sum(attribute string) Exp

Sum computes the sum of an attribute for a group, for use with the .GroupBy() method.

Example usage:

var response []interface{}
// Get the total intelligence of all heroes who have the same strength
err := r.Table("heroes").GroupBy("strength", r.Sum("intelligence")).Run(session).One(&response)

Example response:

[
  {
    // this is the strength attribute for every member of this group
    "group": 1,
    // this is the sum of the intelligence attribute of all members of the group
    "reduction": 2
  },
  {
    "group": 2,
    "reduction": 15
  },
  ...
]

func Table

func Table(name string) Exp

Table references all rows in a specific table, using the database that this method was called on.

Example usage:

var response []map[string]interface{}
err := r.Db("marvel").Table("heroes").Run(session).All(&response)

Example response:

[
  {
    "strength": 3,
    "name": "Doctor Strange",
    "durability": 6,
    "intelligence": 4,
    "energy": 7,
    "fighting": 7,
    "real_name": "Stephen Vincent Strange",
    "speed": 5,
    "id": "edc3a46b-95a0-4f64-9d1c-0dd7d83c4bcd"
  },
  ...
]

func TableCreate

func TableCreate(name string) Exp

TableCreate creates a table with the specified name.

Example usage:

err := r.TableCreate("heroes").Run(session).Exec()

func TableCreateSpec

func TableCreateSpec(spec TableSpec) Exp

TableCreateSpec creates a table with the specified attributes.

Example usage:

spec := TableSpec{Name: "heroes", PrimaryKey: "name"}
err := r.TableCreateSpec(spec).Run(session).Exec()

func TableDrop

func TableDrop(name string) Exp

TableDrop removes a table from the database.

Example usage:

err := r.Db("marvel").TableDrop("heroes").Run(session).Exec()

func TableList

func TableList() Exp

TableList lists all tables in the database.

Example usage:

var tables []string
err := r.TableList().Run(session).All(&tables)

Example response:

["heroes", "villains"]

func (Exp) Add

func (e Exp) Add(operand interface{}) Exp

Add sums two numbers or concatenates two arrays.

Example usage:

r.Expr(1,2,3).Add(r.Expr(4,5,6)) => [1,2,3,4,5,6]
r.Expr(2).Add(2) => 4

func (Exp) And

func (e Exp) And(operand interface{}) Exp

And performs a logical and on two values.

Example usage:

r.Expr(true).And(true) => true

func (Exp) Append

func (e Exp) Append(operand interface{}) Exp

Append appends a value to an array.

Example usage:

var response []interface{}
err := r.Expr(r.List{1, 2, 3, 4}).Append(5).Run(session).One(&response)

Example response:

[1, 2, 3, 4, 5]

func (Exp) Atomic

func (e Exp) Atomic(atomic bool) Exp

Atomic changes the required atomic-ness of a query. By default queries will only be run if they can be executed atomically, that is, all at once. If a query may not be executed atomically, the server will return an error. To disable the atomic requirement, use .Atomic(false).

Example usage:

var response r.WriteResponse
id := "05679c96-9a05-4f42-a2f6-a9e47c45a5ae"
replacement := r.Map{"name": r.Js("Thing")}
// The following will return an error, because of the use of r.Js
err := r.Table("heroes").GetById(id).Update(replacement).Run(session).One(&response)
// This will work
err := r.Table("heroes").GetById(id).Update(replacement).Atomic(false).Run(session).One(&response)

func (Exp) Attr

func (e Exp) Attr(name string) Exp

Attr gets an attribute's value from the row.

Example usage:

r.Expr(r.Map{"key": "value"}).Attr("key") => "value"

func (Exp) Between

func (e Exp) Between(lowerbound, upperbound interface{}) Exp

Between gets all rows where the primary key attribute's value falls between the lowerbound and upperbound (inclusive).

Example usage:

var response []interface{}
// Retrieve all heroes with names between "E" and "F" ("name" is the primary key)
err := r.Table("heroes").Between("E", "F").Run(session).All(&response)

Example response:

{
  "strength": 4,
  "name": "Elektra",
  "durability": 2,
  "intelligence": 4,
  "energy": 3,
  "fighting": 7,
  "real_name": "Elektra Natchios",
  "speed": 6,
}

func (Exp) Check

func (e Exp) Check(s *Session) error

Check compiles a query for sending to the server, but does not send it. There is one .Check() method for each query type.

func (Exp) CoerceTo

func (e Exp) CoerceTo(typename string) Exp

CoerceTo converts a value of one type to another type.

You can convert: a selection, sequence, or object into an ARRAY, an array of pairs into an OBJECT, and any DATUM into a STRING.

Example usage:

var response string
err := Expr(1).CoerceTo("string").Run(session).One(&response)

Example response:

"1"

func (Exp) ConcatMap

func (e Exp) ConcatMap(operand interface{}) Exp

ConcatMap constructs a sequence by running the provided function on each row, then concatenating all the results.

Example usage:

var flattened []int
// Flatten some nested lists
flatten := func(row r.Exp) r.Exp { return row }
err := r.Expr(r.List{1,2}, r.List{3,4}).ConcatMap(flatten).Run(session).One(&flattened)

Example response:

[1, 2, 3, 4]

Example usage:

var names []string
// Get all hero real names and aliases in a list
getNames := func(row r.Exp) interface{} {
    return r.List{row.Attr("name"), row.Attr("real_name")}
}
err := r.Table("heroes").ConcatMap(getNames).Run(session).All(&names)

Example response:

["Captain Britain", "Brian Braddock", "Iceman", "Robert \"Bobby\" Louis Drake", ...]

func (Exp) Contains

func (e Exp) Contains(keys ...string) Exp

Contains returns true if an object has all the given attributes.

Example usage:

hero := r.Map{"name": "Iron Man", "energy": 6, "speed": 5}
r.Expr(hero).Contains("energy", "speed") => true
r.Expr(hero).Contains("energy", "guns") => false

func (Exp) Count

func (e Exp) Count() Exp

Count returns the number of elements in the response.

Example usage:

var response int
err := r.Table("heroes").Count().Run(session).One(&response)

Example response:

42

func (Exp) Delete

func (e Exp) Delete() Exp

Delete removes one or more rows from the database.

Example usage:

var response r.WriteResponse

// Delete a single row by id
id := "5d93edbb-2882-4594-8163-f64d8695e575"
err := r.Table("heroes").GetById(id).Delete().Run(session).One(&response)

// Delete all rows in a table
err := r.Table("heroes").Delete().Run(session).One(&response)

// Find a row, then delete it
row := r.Map{"real_name": "Peter Benjamin Parker"}
err := r.Table("heroes").Filter(row).Delete().Run(session).One(&response)

func (Exp) Distinct

func (e Exp) Distinct() Exp

Distinct removes duplicate elements from a sequence.

Example usage:

var response []interface{}
// Get a list of all possible strength values for our heroes
err := r.Table("heroes").Map(r.Row.Attr("strength")).Distinct().Run(session).All(&response)

Example response:

[7, 1, 6, 4, 2, 5, 3]

func (Exp) Div

func (e Exp) Div(operand interface{}) Exp

Div divides two numbers.

Example usage:

r.Expr(3).Div(2) => 1.5

func (Exp) Eq

func (e Exp) Eq(operand interface{}) Exp

Eq returns true if two values are equal.

Example usage:

r.Expr(1).Eq(1) => true

func (Exp) EqJoin

func (leftExpr Exp) EqJoin(leftAttribute string, rightExpr Exp) Exp

EqJoin performs a join on two expressions, it is more efficient than .InnerJoin() and .OuterJoin() because it looks up elements in the right table by primary key. See also .InnerJoin() and .OuterJoin().

Example usage:

var response []interface{}
// Get each hero and their associated lair, in this case, "villain_id" is
// the primary key for the "lairs" table
query := r.Table("villains").EqJoin("id", r.Table("lairs"))
err := query.Run(session).All(&response)

Example response:

[
  {
    "left": {
      "durability": 6,
      "energy": 6,
      "fighting": 3,
      "id": "c0d1b94f-b07e-40c3-a1db-448e645daedc",
      "intelligence": 6,
      "name": "Magneto",
      "real_name": "Max Eisenhardt",
      "speed": 4,
      "strength": 2
    },
    "right": {
      "lair": "Asteroid M",
      "villain_id": "c0d1b94f-b07e-40c3-a1db-448e645daedc"
    }
  },
  ...
]

func (Exp) Filter

func (e Exp) Filter(operand interface{}) Exp

Filter removes all objects from a sequence that do not match the given condition. The condition can be an RQL expression, an r.Map, or a function that returns true or false.

Example with an RQL expression:

var response []interface{}
// Get all heroes with durability 6
err := r.Table("heroes").Filter(r.Row.Attr("durability").Eq(6)).Run(session).All(&response)

Example with r.Map:

err := r.Table("heroes").Filter(r.Map{"durability": 6}).Run(session).All(&response)

Example with function:

filterFunc := func (row r.Exp) r.Exp { return row.Attr("durability").Eq(6) }
err := r.Table("heroes").Filter(filterFunc).Run(session).All(&response)

Example response:

[
  {
    "durability": 6,
    "energy": 6,
    "fighting": 3,
    "id": "1a760d0b-57ef-42a8-9fec-c3a1f34930aa",
    "intelligence": 6,
    "name": "Iron Man",
    "real_name": "Anthony Edward \"Tony\" Stark",
    "speed": 5,
    "strength": 6
  }
  ...
]

func (Exp) ForEach

func (e Exp) ForEach(queryFunc interface{}) Exp

ForEach runs a given write query for each row of a sequence.

Example usage:

// Delete all rows with the given ids
var response r.WriteResponse
// Delete multiple rows by primary key
heroNames := []string{"Iron Man", "Colossus"}
deleteHero := func (name r.Exp) r.Query {
    return r.Table("heroes").Get(name, "name").Delete()
}
err := r.Expr(heroNames).ForEach(deleteHero).Run(session).One(&response)

Example response:

{
  "deleted": 2
}

func (Exp) Ge

func (e Exp) Ge(operand interface{}) Exp

Gt returns true if the first value is greater than or equal to the second.

Example usage:

r.Expr(2).Gt(2) => true

func (Exp) Get

func (e Exp) Get(key interface{}) Exp

Get retrieves a single row by primary key (secondary key indexes are not supported yet by RethinkDB).

Example usage:

var response map[string]interface{}
err := r.Table("heroes").Get("Doctor Strange").Run(session).One(&response)

Example response:

{
  "strength": 3,
  "name": "Doctor Strange",
  "durability": 6,
  "intelligence": 4,
  "energy": 7,
  "fighting": 7,
  "real_name": "Stephen Vincent Strange",
  "speed": 5,
  "id": "edc3a46b-95a0-4f64-9d1c-0dd7d83c4bcd"
}

func (Exp) GroupBy

func (e Exp) GroupBy(attribute, groupedMapReduce interface{}) Exp

GroupBy does a sort of grouped map reduce. First the server groups all rows that have the same value for `attribute`, then it applys the map reduce to each group. It takes one of the following reductions: r.Count(), r.Sum(string), r.Avg(string)

`attribute` must be a single attribute (string) or a list of attributes ([]string)

Example usage:

var response []interface{}
// Find all heroes with the same durability, calculate their average speed
// to see if more durable heroes are slower.
err := r.Table("heroes").GroupBy("durability", r.Avg("speed")).Run(session).One(&response)

Example response:

[
  {
    "group": 1,  // this is the strength attribute for every member of this group
    "reduction": 1.5  // this is the sum of the intelligence attribute of all members of the group
  },
  {
    "group": 2,
    "reduction": 3.5
  },
  ...
]

Example with multiple attributes:

// Find all heroes with the same strength and speed, sum their intelligence
rows := r.Table("heroes").GroupBy([]string{"strength", "speed"}, r.Count()).Run(session)

func (Exp) GroupedMapReduce

func (e Exp) GroupedMapReduce(grouping, mapping, reduction, base interface{}) Exp

GroupedMapReduce partitions a sequence into groups, then performs a map and a reduction on each group. See also .Map() and .GroupBy().

Example usage:

// Find the sum of the even and odd numbers separately
grouping := func(row r.Exp) r.Exp { return r.Branch(row.Mod(2).Eq(0), "even", "odd") }
mapping := func(row r.Exp) r.Exp { return row }
base := 0
reduction := func(acc, row r.Exp) r.Exp {
	return acc.Add(row)
}

var response []interface{}
query := r.Expr(1,2,3,4,5).GroupedMapReduce(grouping, mapping, reduction, base)
err := query.Run(session).One(&response)

Example response:

[
  {
    "group": "even",
    "reduction": 6
  },
  {
    "group": "odd",
    "reduction": 9
  }
]

Example usage:

// Group all heroes by intelligence, then find the fastest one in each group
grouping := func(row r.Exp) r.Exp { return row.Attr("intelligence") }
mapping := func(row r.Exp) r.Exp { return row.Pluck("name", "speed") }
base := r.Map{"name": nil, "speed": 0}
reduction := func(acc, row r.Exp) r.Exp {
	return r.Branch(acc.Attr("speed").Lt(row.Attr("speed")), row, acc)
}

var response []interface{}
query := r.Table("heroes").GroupedMapReduce(grouping, mapping, reduction, base)
err := query.Run(session).One(&response)

Example response:

[
  {
    "group": 1,
    "reduction": {
      "name": "Northstar",
      "speed": 2
    }
  },
  {
    "group": 2,
    "reduction": {
      "name": "Thor",
      "speed": 6
    }
  },
  ...
]

func (Exp) Gt

func (e Exp) Gt(operand interface{}) Exp

Gt returns true if the first value is greater than the second.

Example usage:

r.Expr(2).Gt(1) => true

func (Exp) InnerJoin

func (leftExpr Exp) InnerJoin(rightExpr Exp, predicate interface{}) Exp

InnerJoin performs an inner join on two sequences, using the provided function to compare the rows from each sequence. See also .EqJoin() and .OuterJoin().

Each row from the left sequence is compared to every row from the right sequence using the provided predicate function. If the function returns true for a pair of rows, that pair will appear in the resulting sequence.

Example usage:

var response []interface{}
// Get each hero and their associated lair, in this case, "villain_id" is
// the primary key for the "lairs" table
compareRows := func (left, right r.Exp) r.Exp {
    return left.Attr("id").Eq(right.Attr("villain_id"))
}
err := r.Table("villains").InnerJoin(r.Table("lairs"), compareRows).Run(session).All(&response)

Example response:

[
  {
    "left": {
      "durability": 6,
      "energy": 6,
      "fighting": 3,
      "id": "c0d1b94f-b07e-40c3-a1db-448e645daedc",
      "intelligence": 6,
      "name": "Magneto",
      "real_name": "Max Eisenhardt",
      "speed": 4,
      "strength": 2
    },
    "right": {
      "lair": "Asteroid M",
      "villain_id": "c0d1b94f-b07e-40c3-a1db-448e645daedc"
    }
  }
]

func (Exp) Insert

func (e Exp) Insert(rows ...interface{}) Exp

Insert inserts rows into the database. If no value is specified for the primary key (by default "id"), a value will be generated by the server, e.g. "05679c96-9a05-4f42-a2f6-a9e47c45a5ae".

Example usage:

var response r.WriteResponse
row := r.Map{"name": "Thing"}
err := r.Table("heroes").Insert(row).Run(session).One(&response)

func (Exp) Le

func (e Exp) Le(operand interface{}) Exp

Le returns true if the first value is less than or equal to the second.

Example usage:

r.Expr(2).Lt(2) => true

func (Exp) Limit

func (e Exp) Limit(limit interface{}) Exp

Limit returns only the first `limit` results from the query.

Example usage:

var response []int
err := r.Expr(1,2,3,4,5).Limit(3).Run(session).One(&response)

Example response:

[1, 2, 3]

func (Exp) Lt

func (e Exp) Lt(operand interface{}) Exp

Lt returns true if the first value is less than the second.

Example usage:

r.Expr(1).Lt(2) => true

func (Exp) Map

func (e Exp) Map(operand interface{}) Exp

Map transforms a sequence by applying the given function to each row.

Example usage:

var squares []int
// Square a series of numbers
square := func(row r.Exp) r.Exp { return row.Mul(row) }
err := r.Expr(1,2,3).Map(square).Run(session).One(&squares)

Example response:

[1, 2, 3]

Example usage:

var heroes []interface{}
// Fetch multiple rows by primary key
heroNames := []string{"Iron Man", "Colossus"}
getHero := func (name r.Exp) r.Exp { return r.Table("heroes").Get(name, "name") }
err := r.Expr(heroNames).Map(getHero).Run(session).One(&heroes)

Example response:

[
  {
    "durability": 6,
    "energy": 6,
    "fighting": 3,
    "intelligence": 6,
    "name": "Iron Man",
    "real_name": "Anthony Edward \"Tony\" Stark",
    "speed": 5,
    "strength": 6
  },
  ...
]

func (Exp) Merge

func (e Exp) Merge(operand interface{}) Exp

Merge combines an object with another object, overwriting properties from the first with properties from the second.

Example usage:

var response interface{}
firstMap := r.Map{"name": "HAL9000", "role": "Support System"}
secondMap := r.Map{"color": "Red", "role": "Betrayal System"}
err := r.Expr(firstMap).Merge(secondMap).Run(session).One(&response)

Example response:

{
  "color": "Red",
  "name": "HAL9000",
  "role": "Betrayal System"
}

func (Exp) Mod

func (e Exp) Mod(operand interface{}) Exp

Mod divides two numbers and returns the remainder.

Example usage:

r.Expr(23).Mod(10) => 3

func (Exp) Mul

func (e Exp) Mul(operand interface{}) Exp

Mul multiplies two numbers.

Example usage:

r.Expr(2).Mul(3) => 6

func (Exp) Ne

func (e Exp) Ne(operand interface{}) Exp

Ne returns true if two values are not equal.

Example usage:

r.Expr(1).Ne(-1) => true

func (Exp) Not

func (e Exp) Not() Exp

Not performs a logical not on a value.

Example usage:

r.Expr(true).Not() => false

func (Exp) Nth

func (e Exp) Nth(operand interface{}) Exp

Nth returns the nth element in sequence, zero-indexed.

Example usage:

var response int
// Get the second element of an array
err := r.Expr(4,3,2,1).Nth(1).Run(session).One(&response)

Example response:

3

func (Exp) Or

func (e Exp) Or(operand interface{}) Exp

Or performs a logical or on two values.

Example usage:

r.Expr(true).Or(false) => true

func (Exp) OrderBy

func (e Exp) OrderBy(orderings ...interface{}) Exp

OrderBy sort the sequence by the values of the given key(s) in each row. The default sort is increasing.

Example usage:

var response []interface{}
// Retrieve villains in order of increasing strength
err := r.Table("villains").OrderBy("strength").Run(session).All(&response)

// Retrieve villains in order of decreasing strength, then increasing intelligence
query := r.Table("villains").OrderBy(r.Desc("strength"), "intelligence")
err := query.Run(session).All(&response)

func (Exp) OuterJoin

func (leftExpr Exp) OuterJoin(rightExpr Exp, predicate interface{}) Exp

OuterJoin performs a left outer join on two sequences, using the provided function to compare the rows from each sequence. See also .EqJoin() and .InnerJoin().

Each row from the left sequence is compared to every row from the right sequence using the provided predicate function. If the function returns true for a pair of rows, that pair will appear in the resulting sequence.

If the predicate is false for every pairing for a specific left row, the left row will appear in the sequence with no right row present.

Example usage:

var response []interface{}
// Get each hero and their associated lair, in this case, "villain_id" is
// the primary key for the "lairs" table
compareRows := func (left, right r.Exp) r.Exp {
    return left.Attr("id").Eq(right.Attr("villain_id"))
}
err := r.Table("villains").OuterJoin(r.Table("lairs"), compareRows).Run(session).All(&response)

Example response:

[
  {
    "left": {
      "durability": 6,
      "energy": 6,
      "fighting": 3,
      "id": "c0d1b94f-b07e-40c3-a1db-448e645daedc",
      "intelligence": 6,
      "name": "Magneto",
      "real_name": "Max Eisenhardt",
      "speed": 4,
      "strength": 2
    },
    "right": {
      "lair": "Asteroid M",
      "villain_id": "c0d1b94f-b07e-40c3-a1db-448e645daedc"
    }
  },
  {
    "left": {
      "durability": 4,
      "energy": 1,
      "fighting": 7,
      "id": "ab140a9c-63d1-455e-862e-045ad7f57ae3",
      "intelligence": 2,
      "name": "Sabretooth",
      "real_name": "Victor Creed",
      "speed": 2,
      "strength": 4
    }
  }
  ...
]

func (Exp) Overwrite

func (e Exp) Overwrite(overwrite bool) Exp

Overwrite tells an Insert query to overwrite existing rows instead of returning an error.

Example usage:

var response r.WriteResponse
row := r.Map{"name": "Thing"}
err := r.Table("heroes").Insert(row).Overwrite(true).Run(session).One(&response)

func (Exp) Pluck

func (e Exp) Pluck(attributes ...string) Exp

Pluck takes only the given attributes from an object, discarding all others. See also .Without().

Example usage:

var heroes []interface{}
err := r.Table("heroes").Pluck("real_name", "id").Run(session).All(&heroes)

Example response:

[
  {
    "real_name": "Peter Benjamin Parker",
    "id": "1227f639-38f0-4cbb-a7b1-9c49f13fe89d",
  },
  ...
]

func (Exp) Reduce

func (e Exp) Reduce(reduction, base interface{}) Exp

Reduce iterates over a sequence, starting with a base value and applying a reduction function to the value so far and the next row of the sequence.

Example usage:

var sum int
// Add the numbers 1-4 together
reduction := func(acc, val r.Exp) r.Exp { return acc.Add(val) }
err := r.Expr(1,2,3,4).Reduce(reduction, 0).Run(session).One(&sum)

Example response:

10

Example usage:

var totalSpeed int
// Compute the total speed for all heroes, the types of acc and val should
// be the same, so we extract the speed first with a .Map()
mapping := func(row r.Exp) r.Exp { return row.Attr("speed") }
reduction := func(acc, val r.Exp) r.Exp { return acc.Add(val) }
err := r.Table("heroes").Map(mapping).Reduce(reduction, 0).Run(session).One(&totalSpeed)

Example response:

232

func (Exp) Replace

func (e Exp) Replace(mapping interface{}) Exp

Replace replaces rows in the database. Accepts a JSON document or a RQL expression, and replaces the original document with the new one. The new row must have the same primary key as the original document.

Example usage:

var response r.WriteResponse

// Replace a single row by id
id := "05679c96-9a05-4f42-a2f6-a9e47c45a5ae"
replacement := r.Map{"id": r.Row.Attr("id"), "name": "Thing"}
err := r.Table("heroes").GetById(id).Replace(replacement).Run(session).One(&response)

// Replace all rows in a table
err := r.Table("heroes").Replace(replacement).Run(session).One(&response)

func (Exp) Run

func (e Exp) Run(session *Session) *Rows

Run runs a query using the given session, there is one Run() method for each type of query.

func (Exp) Skip

func (e Exp) Skip(start interface{}) Exp

Skip returns all results after the first `start` results. Basically it's the opposite of .Limit().

Example usage:

var response []int
err := r.Expr(1,2,3,4,5).Skip(3).Run(session).One(&response)

Example response:

[4, 5]

func (Exp) Slice

func (e Exp) Slice(lower, upper interface{}) Exp

Slice returns a section of a sequence, with bounds [lower, upper), where lower bound is inclusive and upper bound is exclusive.

Example usage:

var response []int
err := r.Expr(1,2,3,4,5).Slice(2,4).Run(session).One(&response)

Example response:

[3, 4]

func (Exp) Sub

func (e Exp) Sub(operand interface{}) Exp

Sub subtracts two numbers.

Example usage:

r.Expr(2).Sub(2) => 0

func (Exp) Table

func (e Exp) Table(name string) Exp

func (Exp) TableCreate

func (e Exp) TableCreate(name string) Exp

func (Exp) TableCreateSpec

func (e Exp) TableCreateSpec(spec TableSpec) Exp

func (Exp) TableDrop

func (e Exp) TableDrop(name string) Exp

func (Exp) TableList

func (e Exp) TableList() Exp

func (Exp) TypeOf

func (e Exp) TypeOf() Exp

TypeOf returns the type of the expression.

Example usage:

var response string
err := r.Expr(1).TypeOf().Run(session).One(&response)

Example response:

"NUMBER"

func (Exp) Union

func (e Exp) Union(operands ...interface{}) Exp

Union concatenates two sequences.

Example usage:

var response []interface{}
// Retrieve all heroes and villains
r.Table("heroes").Union(r.Table("villains")).Run(session).All(&response)

Example response:

[
  {
    "durability": 6,
    "energy": 6,
    "fighting": 3,
    "id": "1a760d0b-57ef-42a8-9fec-c3a1f34930aa",
    "intelligence": 6,
    "name": "Iron Man",
    "real_name": "Anthony Edward \"Tony\" Stark",
    "speed": 5,
    "strength": 6
  },
  ...
]

func (Exp) Update

func (e Exp) Update(mapping interface{}) Exp

Update updates rows in the database. Accepts a JSON document, a RQL expression, or a combination of the two.

Example usage:

var response r.WriteResponse
replacement := r.Map{"name": "Thing"}
// Update a single row by id
id := "05679c96-9a05-4f42-a2f6-a9e47c45a5ae"
err := r.Table("heroes").GetById(id).Update(replacement).Run(session).One(&response)
// Update all rows in the database
err := r.Table("heroes").Update(replacement).Run(session).One(&response)

func (Exp) UseOutdated

func (e Exp) UseOutdated(useOutdated bool) Exp

UseOutdated tells the server to use potentially out-of-date data from all tables already specified in this query. The advantage is that read queries may be faster if this is set.

Example with single table:

rows := r.Table("heroes").UseOutdated(true).Run(session)

Example with multiple tables (all tables would be allowed to use outdated data):

villain_strength := r.Table("villains").Get("Doctor Doom", "name").Attr("strength")
compareFunc := r.Row.Attr("strength").Eq(villain_strength)
rows := r.Table("heroes").Filter(compareFunc).UseOutdated(true).Run(session)

func (Exp) Without

func (e Exp) Without(attributes ...string) Exp

Without removes the given attributes from an object. See also .Pluck().

Example usage:

var heroes []interface{}
err := r.Table("heroes").Without("real_name", "id").Run(session).All(&heroes)

Example response:

[
  {
    "durability": 4,
    "energy": 7,
    "fighting": 4,
    "intelligence": 7,
    "name": "Professor X",
    "speed": 2,
    "strength": 4
  },
  ...
]

func (Exp) Zip

func (e Exp) Zip() Exp

Zip flattens the results of a join by merging the "left" and "right" fields of each row together. If any keys conflict, the "right" field takes precedence.

Example without .Zip():

var response []interface{}
// Find each hero-villain pair with the same strength
equalStrength := func(hero, villain r.Exp) r.Exp {
    return hero.Attr("strength").Eq(villain.Attr("strength"))
}
query := r.Table("heroes").InnerJoin(r.Table("villains"), equalStrength)
err := query.Run(session).All(&response)

Example response:

[
  {
    "left":
    {
      "durability": 5,
      "energy": 7,
      "fighting": 7,
      "id": "f915d9a7-6cfa-4151-b5f6-6aded7da595f",
      "intelligence": 5,
      "name": "Nightcrawler",
      "real_name": "Kurt Wagner",
      "speed": 7,
      "strength": 4
    },
    "right":
    {
      "durability": 4,
      "energy": 1,
      "fighting": 7,
      "id": "12e58b11-93b3-4e89-987d-efb345001dfe",
      "intelligence": 2,
      "name": "Sabretooth",
      "real_name": "Victor Creed",
      "speed": 2,
      "strength": 4
    }
  },
  ...
]

Example with .Zip():

var response []interface{}
// Find each hero-villain pair with the same strength
equalStrength := func(hero, villain r.Exp) r.Exp {
    return hero.Attr("strength").Eq(villain.Attr("strength"))
}
query := r.Table("heroes").InnerJoin(r.Table("villains"), equalStrength).Zip()
err := query.Run(session).All(&response)

Example response:

[
  {
    "durability": 4,
    "energy": 1,
    "fighting": 7,
    "id": "12e58b11-93b3-4e89-987d-efb345001dfe",
    "intelligence": 2,
    "name": "Sabretooth",
    "real_name": "Victor Creed",
    "speed": 2,
    "strength": 4
  },
  ...
]

type List

type List []interface{}

List is a shorter name for an array of arbitrary objects

type Map

type Map map[string]interface{}

Map is a shorter name for a mapping from strings to arbitrary objects

type Rows

type Rows struct {
	// contains filtered or unexported fields
}

Rows is an interator to move through the rows returned by the database, call rows.Scan(&dest) in a loop to scan a row into the variable `dest`, rows.Next() returns false when there is an error or no more rows left.

There are three methods on the rows object that can be used to avoid iterating in this manner. These three methods correspond to the return types of a query:

.Exec() for an empty response:

err := r.Db("marvel").TableCreate("heroes").Exec()

.One(&dest) for a response that always returns a single result:

var response string
err := r.Table("heroes").Get("Omega Red", "name").Run(session).One(&response)

.All(&dest) for a list of results:

var response []string
err := r.Db("marvel").TableList().Run(session).All(&response)

.All() may perform multiple network requests to get all of the results of the query. Use .Limit() if you only need a certain number.

All three of these methods will return errors if used on a query response that does not match the expected type (ErrWrongResponseType).

func (*Rows) All

func (rows *Rows) All(slice interface{}) error

All gets all results from the iterator into a reference to a slice. It may perform multiple network requests to the server until it has retrieved all results.

Example usage:

var result []interface{}
err := r.Table("heroes").Run(session).All(&result)

func (*Rows) Close

func (rows *Rows) Close() (err error)

Close frees up the connection associated with this iterator, if any. Just use defer rows.Close() after retrieving a Rows iterator. Not required with .Exec(), .One(), or .All().

Only stream responses will have an associated connection.

Example usage:

rows := r.Table("villains").Run(session)
defer rows.Close()

for rows.Next() {
    var result interface{}
    rows.Scan(&result)
    fmt.Println("result:", result)
}

func (*Rows) Err

func (rows *Rows) Err() error

Err returns the last error encountered, for example, a network error while contacting the database server, or while parsing.

Example usage:

err := r.Table("heroes").Run(session).Err()

func (*Rows) Exec

func (rows *Rows) Exec() error

Exec is for queries for which you wish to ignore the result. For instance, creating a table.

Example usage:

err := r.TableCreate("villains").Run(session).Exec()

func (*Rows) Next

func (rows *Rows) Next() bool

Next moves the iterator forward by one document, returns false if there are no more rows or some sort of error has occurred (use .Err() to get the last error). `dest` must be passed by reference.

Example usage:

rows := r.Table("heroes").Run(session)
for rows.Next() {
    var hero interface{}
    rows.Scan(&hero)
    fmt.Println("hero:", hero)
}
if rows.Err() != nil {
    ...
}

func (*Rows) One

func (rows *Rows) One(row interface{}) error

One gets the first result from a query response.

Example usage:

var result interface{}
err := r.Table("villains").Get("Galactus", "name").Run(session).One(&result)

func (*Rows) Scan

func (rows *Rows) Scan(dest interface{}) error

Scan writes the current row into the provided variable, which must be passed by reference.

NOTE: Scan uses json.Unmarshal internally and will not clear the destination before writing the next row. Make sure to create a new destination or clear it before calling .Scan(&dest).

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session represents a connection to a server, use it to run queries against a database, with either sess.Run(query) or query.Run(session). It is safe to use from multiple goroutines.

func Connect

func Connect(address, database string) (*Session, error)

Connect creates a new database session.

Example usage:

sess, err := r.Connect("localhost:28015", "test")

func (*Session) Close

func (s *Session) Close() error

Close closes the session, freeing any associated resources.

Example usage:

err := sess.Close()

func (*Session) Reconnect

func (s *Session) Reconnect() error

Reconnect closes and re-opens a session. [ Example usage:

err := sess.Reconnect()

func (*Session) Run

func (s *Session) Run(query Exp) *Rows

Run executes a query directly on a specific session and returns an iterator that moves through the resulting JSON rows with rows.Next() and rows.Scan(&dest). See the documentation for the Rows object for other options.

Example usage:

rows := session.Run(query)
for rows.Next() {
    var row map[string]interface{}
    rows.Scan(&row)
    fmt.Println("row:", row)
}
if rows.Err() {
    ...
}

func (*Session) SetTimeout

func (s *Session) SetTimeout(timeout time.Duration)

SetTimeout causes any future queries that are run on this session to timeout after the given duration, returning a timeout error. Set to zero to disable.

The timeout is global to all queries run on a single Session and does not apply to queries currently in progress. The timeout does not cover the time taken to connect to the server in the case that there is no idle connection available.

If a timeout occurs, the individual connection handling that query will be closed instead of being returned to the connection pool.

func (*Session) Use

func (s *Session) Use(database string)

Use changes the default database for a connection. This is the database that will be used when a query is created without an explicit database. This should not be used if the session is shared between goroutines, confusion would result.

Example usage:

sess.Use("dave")
rows := r.Table("employees").Run(session) // uses database "dave"

type TableSpec

type TableSpec struct {
	Name       string
	PrimaryKey string
	Datacenter string
	CacheSize  int64
}

TableSpec lets you specify the various parameters for a table, then create it with TableCreateSpec(). See that function for documentation.

type WriteResponse

type WriteResponse struct {
	Inserted      int
	Errors        int
	Updated       int
	Unchanged     int
	Replaced      int
	Deleted       int
	GeneratedKeys []string `json:"generated_keys"`
	FirstError    string   `json:"first_error"` // populated if Errors > 0
}

WriteResponse is a type that can be used to read responses to write queries, such as .Insert()

Example usage:

var response r.WriteResponse
err := r.Table("heroes").Insert(r.Map{"name": "Professor X"}).Run(session).One(&response)
fmt.Println("inserted", response.Inserted, "rows")

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL