Documentation
¶
Overview ¶
Package client provides clients for accessing the various externally-facing Cockroach database endpoints.
DB Client ¶
The DB client is a fully-featured client of Cockroach's key-value database. It provides a simple, synchronous interface well-suited to parallel updates and queries.
The simplest way to use the client is through the Run method. Run synchronously invokes the call, fills in the reply and returns an error. The example below shows a get and a put.
db, err := client.Open("rpcs://root@localhost:26257") if err != nil { log.Fatal(err) } if err := db.Put("a", "hello"); err != nil { log.Fatal(err) } if gr, err := db.Get("a"); err != nil { log.Fatal(err) } else { log.Printf("%s", gr.ValueBytes()) // "hello" }
The API is synchronous, but accommodates efficient parallel updates and queries using Batch objects. An arbitrary number of calls may be added to a Batch which is executed using DB.Run. Note however that the individual calls within a batch are not guaranteed to have atomic semantics. A transaction must be used to guarantee atomicity. A simple example of using a Batch which does two scans in parallel and then sends a sequence of puts in parallel:
db, err := client.Open("rpcs://root@localhost:26257") if err != nil { log.Fatal(err) } b1 := &client.Batch{} b1.Scan("a", "c\x00", 1000) b1.Scan("x", "z\x00", 1000) // Run sends both scans in parallel and returns the first error or nil. if err := db.Run(b1); err != nil { log.Fatal(err) } acResult := b1.Results[0] xzResult := b1.Results[1] // Append maximum value from "a"-"c" to all values from "x"-"z". max := []byte(nil) for _, row := range acResult.Rows { if bytes.Compare(max, row.ValueBytes()) < 0 { max = row.ValueBytes() } } b2 := &client.Batch{} for _, row := range xzResult.Rows { b2.Put(row.Key, bytes.Join([][]byte{row.ValueBytes(), max}, []byte(nil))) } // Run all puts for parallel execution. if err := db.Run(b2); err != nil { log.Fatal(err) }
Transactions are supported through the DB.Txn() method, which takes a retryable function, itself composed of the same simple mix of API calls typical of a non-transactional operation. Within the context of the Txn() call, all method invocations are transparently given necessary transactional details, and conflicts are handled with backoff/retry loops and transaction restarts as necessary. An example of using transactions with parallel writes:
db, err := client.Open("rpcs://root@localhost:26257") if err != nil { log.Fatal(err) } err := db.Txn(func(txn *client.Txn) error { b := &client.Batch{} for i := 0; i < 100; i++ { key := fmt.Sprintf("testkey-%02d", i) b.Put(key, "test value") } // Note that the Txn client is flushed automatically when this function // returns success (i.e. nil). Calling CommitInBatch explicitly can // sometimes reduce the number of RPCs. return txn.CommitInBatch(b) }) if err != nil { log.Fatal(err) }
Note that with Cockroach's lock-free transactions, clients should expect retries as a matter of course. This is why the transaction functionality is exposed through a retryable function. The retryable function should have no side effects which are not idempotent.
Transactions should endeavor to use batches to perform multiple operations in a single RPC. In addition to the reduced number of RPCs to the server, this allows writes to the same range to be batched together. In cases where the entire transaction affects only a single range, transactions can commit in a single round trip.
Index ¶
- Constants
- Variables
- func RegisterSender(scheme string, f newSenderFunc)
- func SendWrapped(sender Sender, ctx context.Context, args roachpb.Request) (roachpb.Response, *roachpb.Error)
- func SendWrappedWith(sender Sender, ctx context.Context, h roachpb.Header, args roachpb.Request) (roachpb.Response, *roachpb.Error)
- type AdminClient
- func (a *AdminClient) Delete(key string) error
- func (a *AdminClient) Get() (string, error)
- func (a *AdminClient) GetJSON(key string) (string, error)
- func (a *AdminClient) GetYAML(key string) (string, error)
- func (a *AdminClient) List() ([]string, error)
- func (a *AdminClient) SetJSON(key, body string) error
- func (a *AdminClient) SetYAML(key, body string) error
- type Batch
- func (b *Batch) CPut(key, value, expValue interface{})
- func (b *Batch) Del(keys ...interface{})
- func (b *Batch) DelRange(s, e interface{})
- func (b *Batch) Get(key interface{})
- func (b *Batch) Inc(key interface{}, value int64)
- func (b *Batch) InternalAddRequest(reqs ...roachpb.Request)
- func (b *Batch) Put(key, value interface{})
- func (b *Batch) ReverseScan(s, e interface{}, maxRows int64)
- func (b *Batch) Scan(s, e interface{}, maxRows int64)
- type DB
- func (db *DB) AdminMerge(key interface{}) *roachpb.Error
- func (db *DB) AdminSplit(splitKey interface{}) *roachpb.Error
- func (db *DB) CPut(key, value, expValue interface{}) *roachpb.Error
- func (db *DB) Del(keys ...interface{}) *roachpb.Error
- func (db *DB) DelRange(begin, end interface{}) *roachpb.Error
- func (db *DB) Get(key interface{}) (KeyValue, *roachpb.Error)
- func (db *DB) GetProto(key interface{}, msg proto.Message) *roachpb.Error
- func (db *DB) GetSender() Sender
- func (db *DB) Inc(key interface{}, value int64) (KeyValue, *roachpb.Error)
- func (db *DB) NewBatch() *Batch
- func (db *DB) Put(key, value interface{}) *roachpb.Error
- func (db *DB) ReverseScan(begin, end interface{}, maxRows int64) ([]KeyValue, *roachpb.Error)
- func (db *DB) Run(b *Batch) *roachpb.Error
- func (db *DB) RunWithResponse(b *Batch) (*roachpb.BatchResponse, *roachpb.Error)
- func (db *DB) Scan(begin, end interface{}, maxRows int64) ([]KeyValue, *roachpb.Error)
- func (db *DB) Txn(retryable func(txn *Txn) *roachpb.Error) *roachpb.Error
- type KeyValue
- type Result
- type Runner
- type Sender
- type SenderFunc
- type Txn
- func (txn *Txn) CPut(key, value, expValue interface{}) *roachpb.Error
- func (txn *Txn) Cleanup(pErr *roachpb.Error)
- func (txn *Txn) Commit() *roachpb.Error
- func (txn *Txn) CommitBy(deadline roachpb.Timestamp) *roachpb.Error
- func (txn *Txn) CommitInBatch(b *Batch) *roachpb.Error
- func (txn *Txn) CommitInBatchWithResponse(b *Batch) (*roachpb.BatchResponse, *roachpb.Error)
- func (txn *Txn) CommitNoCleanup() *roachpb.Error
- func (txn *Txn) DebugName() string
- func (txn *Txn) Del(keys ...interface{}) *roachpb.Error
- func (txn *Txn) DelRange(begin, end interface{}) *roachpb.Error
- func (txn *Txn) Get(key interface{}) (KeyValue, *roachpb.Error)
- func (txn *Txn) GetProto(key interface{}, msg proto.Message) *roachpb.Error
- func (txn *Txn) Inc(key interface{}, value int64) (KeyValue, *roachpb.Error)
- func (txn *Txn) InternalSetPriority(priority int32)
- func (txn *Txn) NewBatch() *Batch
- func (txn *Txn) Put(key, value interface{}) *roachpb.Error
- func (txn *Txn) ReverseScan(begin, end interface{}, maxRows int64) ([]KeyValue, *roachpb.Error)
- func (txn *Txn) Rollback() *roachpb.Error
- func (txn *Txn) Run(b *Batch) *roachpb.Error
- func (txn *Txn) RunWithResponse(b *Batch) (*roachpb.BatchResponse, *roachpb.Error)
- func (txn *Txn) Scan(begin, end interface{}, maxRows int64) ([]KeyValue, *roachpb.Error)
- func (txn *Txn) SetDebugName(name string, depth int)
- func (txn *Txn) SetIsolation(isolation roachpb.IsolationType) *roachpb.Error
- func (txn *Txn) SetSystemConfigTrigger()
- func (txn *Txn) SetUserPriority(userPriority roachpb.UserPriority) *roachpb.Error
- func (txn *Txn) SystemConfigTrigger() bool
Examples ¶
Constants ¶
const (
// Quit only handles Get requests.
Quit = "quit"
)
Variables ¶
var DefaultTxnRetryOptions = retry.Options{ InitialBackoff: 50 * time.Millisecond, MaxBackoff: 5 * time.Second, Multiplier: 2, }
DefaultTxnRetryOptions are the standard retry options used for transactions. This is exported for testing purposes only.
Functions ¶
func RegisterSender ¶
func RegisterSender(scheme string, f newSenderFunc)
RegisterSender registers the specified function to be used for creation of a new sender when the specified scheme is encountered.
func SendWrapped ¶
func SendWrapped(sender Sender, ctx context.Context, args roachpb.Request) (roachpb.Response, *roachpb.Error)
SendWrapped is identical to SendWrappedAt with a zero header.
func SendWrappedWith ¶
func SendWrappedWith(sender Sender, ctx context.Context, h roachpb.Header, args roachpb.Request) (roachpb.Response, *roachpb.Error)
SendWrappedWith is a convenience function which wraps the request in a batch and sends it via the provided Sender at the given timestamp. It returns the unwrapped response or an error. It's valid to pass a `nil` context; context.Background() is used in that case.
Types ¶
type AdminClient ¶
type AdminClient struct {
// contains filtered or unexported fields
}
AdminClient issues http requests to admin endpoints. TODO(marc): unify the way we handle addresses in clients.
func NewAdminClient ¶
func NewAdminClient(ctx *base.Context, address, configType string) AdminClient
NewAdminClient returns a new 'configType' admin client, talking to 'address'.
func (*AdminClient) Delete ¶
func (a *AdminClient) Delete(key string) error
Delete issues a DELETE request for the given key.
func (*AdminClient) Get ¶
func (a *AdminClient) Get() (string, error)
Get issues a GET and returns the plain-text body. It cannot take a key.
func (*AdminClient) GetJSON ¶
func (a *AdminClient) GetJSON(key string) (string, error)
GetJSON issues a GET request and returns a json-encoded response.
func (*AdminClient) GetYAML ¶
func (a *AdminClient) GetYAML(key string) (string, error)
GetYAML issues a GET request and returns a yaml-encoded response.
func (*AdminClient) List ¶
func (a *AdminClient) List() ([]string, error)
List issues a GET request to list all configs. Returns a list of keys.
func (*AdminClient) SetJSON ¶
func (a *AdminClient) SetJSON(key, body string) error
SetJSON issues a POST request for the given key using the json-encoded body.
func (*AdminClient) SetYAML ¶
func (a *AdminClient) SetYAML(key, body string) error
SetYAML issues a POST request for the given key using the yaml-encoded body.
type Batch ¶
type Batch struct { // The DB the batch is associated with. This field may be nil if the batch // was not created via DB.NewBatch or Txn.NewBatch. DB *DB // Results contains an entry for each operation added to the batch. The order // of the results matches the order the operations were added to the // batch. For example: // // b := db.NewBatch() // b.Put("a", "1") // b.Put("b", "2") // _ = db.Run(b) // // string(b.Results[0].Rows[0].Key) == "a" // // string(b.Results[1].Rows[0].Key) == "b" Results []Result // contains filtered or unexported fields }
Batch provides for the parallel execution of a number of database operations. Operations are added to the Batch and then the Batch is executed via either DB.Run, Txn.Run or Txn.Commit.
TODO(pmattis): Allow a timestamp to be specified which is applied to all operations within the batch.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() b := &client.Batch{} b.Get("aa") b.Put("bb", "2") if pErr := db.Run(b); pErr != nil { panic(pErr) } for _, result := range b.Results { for _, row := range result.Rows { fmt.Printf("%s=%s\n", row.Key, row.ValueBytes()) } } }
Output: "aa"= "bb"=2
func (*Batch) CPut ¶
func (b *Batch) CPut(key, value, expValue interface{})
CPut conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string. value can be any key type, a proto.Message or any Go primitive type (bool, int, etc).
func (*Batch) Del ¶
func (b *Batch) Del(keys ...interface{})
Del deletes one or more keys.
A new result will be appended to the batch and each key will have a corresponding row in the returned Result.
key can be either a byte slice or a string.
func (*Batch) DelRange ¶
func (b *Batch) DelRange(s, e interface{})
DelRange deletes the rows between begin (inclusive) and end (exclusive).
A new result will be appended to the batch which will contain 0 rows and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
func (*Batch) Get ¶
func (b *Batch) Get(key interface{})
Get retrieves the value for a key. A new result will be appended to the batch which will contain a single row.
r, err := db.Get("a") // string(r.Rows[0].Key) == "a"
key can be either a byte slice or a string.
func (*Batch) Inc ¶
Inc increments the integer value at key. If the key does not exist it will be created with an initial value of 0 which will then be incremented. If the key exists but was set using Put or CPut an error will be returned.
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
func (*Batch) InternalAddRequest ¶
InternalAddRequest adds the specified requests to the batch. It is intended for internal use only.
func (*Batch) Put ¶
func (b *Batch) Put(key, value interface{})
Put sets the value for a key.
A new result will be appended to the batch which will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string. value can be any key type, a proto.Message or any Go primitive type (bool, int, etc).
func (*Batch) ReverseScan ¶
ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) in descending order.
A new result will be appended to the batch which will contain up to maxRows rows and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB is a database handle to a single cockroach cluster. A DB is safe for concurrent use by multiple goroutines.
func NewDBWithPriority ¶
func NewDBWithPriority(sender Sender, userPriority roachpb.UserPriority) *DB
NewDBWithPriority returns a new DB.
func Open ¶
Open creates a new database handle to the cockroach cluster specified by addr. The cluster is identified by a URL with the format:
[<sender>:]//[<user>@]<host>:<port>[?certs=<dir>,priority=<val>]
The URL scheme (<sender>) specifies which transport to use for talking to the cockroach cluster. Currently allowable values are: http, https, rpc, rpcs. The rpc and rpcs senders use a variant of Go's builtin rpc library for communication with the cluster. This protocol is lower overhead and more efficient than http. The decision between the encrypted (https, rpcs) and unencrypted senders (http, rpc) depends on the settings of the cluster. A given cluster supports either encrypted or unencrypted traffic, but not both.
If not specified, the <user> field defaults to "root".
The certs parameter can be used to override the default directory to use for client certificates. In tests, the directory "test_certs" uses the embedded test certificates.
The priority parameter can be used to override the default priority for operations.
func (*DB) AdminMerge ¶
AdminMerge merges the range containing key and the subsequent range. After the merge operation is complete, the range containing key will contain all of the key/value pairs of the subsequent range and the subsequent range will no longer exist.
key can be either a byte slice or a string.
func (*DB) AdminSplit ¶
AdminSplit splits the range at splitkey.
key can be either a byte slice or a string.
func (*DB) CPut ¶
CPut conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
key can be either a byte slice or a string. value can be any key type, a proto.Message or any Go primitive type (bool, int, etc).
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() if pErr := db.Put("aa", "1"); pErr != nil { panic(pErr) } if pErr := db.CPut("aa", "2", "1"); pErr != nil { panic(pErr) } result, pErr := db.Get("aa") if pErr != nil { panic(pErr) } fmt.Printf("aa=%s\n", result.ValueBytes()) if pErr = db.CPut("aa", "3", "1"); pErr == nil { panic("expected pError from conditional put") } result, pErr = db.Get("aa") if pErr != nil { panic(pErr) } fmt.Printf("aa=%s\n", result.ValueBytes()) if pErr = db.CPut("bb", "4", "1"); pErr == nil { panic("expected error from conditional put") } result, pErr = db.Get("bb") if pErr != nil { panic(pErr) } fmt.Printf("bb=%s\n", result.ValueBytes()) if pErr = db.CPut("bb", "4", nil); pErr != nil { panic(pErr) } result, pErr = db.Get("bb") if pErr != nil { panic(pErr) } fmt.Printf("bb=%s\n", result.ValueBytes()) }
Output: aa=2 aa=2 bb= bb=4
func (*DB) Del ¶
Del deletes one or more keys.
key can be either a byte slice or a string.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() b := &client.Batch{} b.Put("aa", "1") b.Put("ab", "2") b.Put("ac", "3") if pErr := db.Run(b); pErr != nil { panic(pErr) } if pErr := db.Del("ab"); pErr != nil { panic(pErr) } rows, pErr := db.Scan("a", "b", 100) if pErr != nil { panic(pErr) } for i, row := range rows { fmt.Printf("%d: %s=%s\n", i, row.Key, row.ValueBytes()) } }
Output: 0: "aa"=1 1: "ac"=3
func (*DB) DelRange ¶
DelRange deletes the rows between begin (inclusive) and end (exclusive).
TODO(pmattis): Perhaps the result should return which rows were deleted.
key can be either a byte slice or a string.
func (*DB) Get ¶
Get retrieves the value for a key, returning the retrieved key/value or an error.
r, err := db.Get("a") // string(r.Key) == "a"
key can be either a byte slice or a string.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() result, pErr := db.Get("aa") if pErr != nil { panic(pErr) } fmt.Printf("aa=%s\n", result.ValueBytes()) }
Output: aa=
func (*DB) GetProto ¶
GetProto retrieves the value for a key and decodes the result as a proto message.
key can be either a byte slice or a string.
func (*DB) Inc ¶
Inc increments the integer value at key. If the key does not exist it will be created with an initial value of 0 which will then be incremented. If the key exists but was set using Put or CPut an error will be returned.
key can be either a byte slice or a string.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() if _, pErr := db.Inc("aa", 100); pErr != nil { panic(pErr) } result, pErr := db.Get("aa") if pErr != nil { panic(pErr) } fmt.Printf("aa=%d\n", result.ValueInt()) }
Output: aa=100
func (*DB) NewBatch ¶
NewBatch creates and returns a new empty batch object for use with the DB. TODO(tschottdorf): it appears this can be unexported.
func (*DB) Put ¶
Put sets the value for a key.
key can be either a byte slice or a string. value can be any key type, a proto.Message or any Go primitive type (bool, int, etc).
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() if pErr := db.Put("aa", "1"); pErr != nil { panic(pErr) } result, pErr := db.Get("aa") if pErr != nil { panic(pErr) } fmt.Printf("aa=%s\n", result.ValueBytes()) }
Output: aa=1
Example (Insecure) ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func main() { s := &server.TestServer{} s.Ctx = server.NewTestContext() s.Ctx.Insecure = true if pErr := s.Start(); pErr != nil { log.Fatalf("Could not start server: %v", pErr) } defer s.Stop() db, err := client.Open(s.Stopper(), "rpc://foo@"+s.ServingAddr()) if err != nil { log.Fatal(err) } if pErr := db.Put("aa", "1"); pErr != nil { panic(pErr) } result, pErr := db.Get("aa") if pErr != nil { panic(pErr) } fmt.Printf("aa=%s\n", result.ValueBytes()) }
Output: aa=1
func (*DB) ReverseScan ¶
ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) in descending order.
The returned []KeyValue will contain up to maxRows elements.
key can be either a byte slice or a string.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() b := &client.Batch{} b.Put("aa", "1") b.Put("ab", "2") b.Put("bb", "3") if pErr := db.Run(b); pErr != nil { panic(pErr) } rows, pErr := db.ReverseScan("ab", "c", 100) if pErr != nil { panic(pErr) } for i, row := range rows { fmt.Printf("%d: %s=%s\n", i, row.Key, row.ValueBytes()) } }
Output: 0: "bb"=3 1: "ab"=2
func (*DB) Run ¶
Run executes the operations queued up within a batch. Before executing any of the operations the batch is first checked to see if there were any errors during its construction (e.g. failure to marshal a proto message).
The operations within a batch are run in parallel and the order is non-deterministic. It is an unspecified behavior to modify and retrieve the same key within a batch.
Upon completion, Batch.Results will contain the results for each operation. The order of the results matches the order the operations were added to the batch.
func (*DB) RunWithResponse ¶
RunWithResponse is a version of Run that returns the BatchResponse.
func (*DB) Scan ¶
Scan retrieves the rows between begin (inclusive) and end (exclusive) in ascending order.
The returned []KeyValue will contain up to maxRows elements.
key can be either a byte slice or a string.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() b := &client.Batch{} b.Put("aa", "1") b.Put("ab", "2") b.Put("bb", "3") if pErr := db.Run(b); pErr != nil { panic(pErr) } rows, pErr := db.Scan("a", "b", 100) if pErr != nil { panic(pErr) } for i, row := range rows { fmt.Printf("%d: %s=%s\n", i, row.Key, row.ValueBytes()) } }
Output: 0: "aa"=1 1: "ab"=2
func (*DB) Txn ¶
Txn executes retryable in the context of a distributed transaction. The transaction is automatically aborted if retryable returns any error aside from recoverable internal errors, and is automatically committed otherwise. The retryable function should have no side effects which could cause problems in the event it must be run more than once.
TODO(pmattis): Allow transaction options to be specified.
type KeyValue ¶
KeyValue represents a single key/value pair and corresponding timestamp. This is similar to roachpb.KeyValue except that the value may be nil.
func (*KeyValue) PrettyValue ¶
PrettyValue returns a human-readable version of the value as a string.
func (*KeyValue) ValueBytes ¶
ValueBytes returns the value as a byte slice. This method will panic if the value's type is not a byte slice.
type Result ¶
type Result struct { // Err contains any error encountered when performing the operation. PErr *roachpb.Error // Rows contains the key/value pairs for the operation. The number of rows // returned varies by operation. For Get, Put, CPut, Inc and Del the number // of rows returned is the number of keys operated on. For Scan the number of // rows returned is the number or rows matching the scan capped by the // maxRows parameter. For DelRange Rows is nil. Rows []KeyValue // contains filtered or unexported fields }
Result holds the result for a single DB or Txn operation (e.g. Get, Put, etc).
type Sender ¶
type Sender interface {
Send(context.Context, roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error)
}
Sender is the interface used to call into a Cockroach instance. If the returned *roachpb.Error is not nil, no response should be returned.
func Wrap ¶
func Wrap(sender Sender, f func(roachpb.BatchRequest) roachpb.BatchRequest) Sender
Wrap returns a Sender which applies the given function before delegating to the supplied Sender.
type SenderFunc ¶
type SenderFunc func(context.Context, roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error)
SenderFunc is an adapter to allow the use of ordinary functions as Senders.
func (SenderFunc) Send ¶
func (f SenderFunc) Send(ctx context.Context, ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error)
Send calls f(ctx, c).
type Txn ¶
type Txn struct { Proto roachpb.Transaction UserPriority roachpb.UserPriority // contains filtered or unexported fields }
Txn is an in-progress distributed database transaction. A Txn is not safe for concurrent use by multiple goroutines.
func (*Txn) CPut ¶
CPut conditionally sets the value for a key if the existing value is equal to expValue. To conditionally set a value only if there is no existing entry pass nil for expValue. Note that this must be an interface{}(nil), not a typed nil value (e.g. []byte(nil)).
key can be either a byte slice or a string. value can be any key type, a proto.Message or any Go primitive type (bool, int, etc).
func (*Txn) Commit ¶
Commit sends an EndTransactionRequest with Commit=true.
Example ¶
package main import ( "fmt" "github.com/cockroachdb/cockroach/client" "github.com/cockroachdb/cockroach/roachpb" "github.com/cockroachdb/cockroach/security" "github.com/cockroachdb/cockroach/server" "github.com/cockroachdb/cockroach/util/log" ) func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=%s", security.NodeUser, s.ServingAddr(), security.EmbeddedCertsDir)) if err != nil { log.Fatal(err) } return s, db } func main() { s, db := setup() defer s.Stop() pErr := db.Txn(func(txn *client.Txn) *roachpb.Error { b := txn.NewBatch() b.Put("aa", "1") b.Put("ab", "2") return txn.CommitInBatch(b) }) if pErr != nil { panic(pErr) } b := &client.Batch{} b.Get("aa") b.Get("ab") if pErr := db.Run(b); pErr != nil { panic(pErr) } for i, result := range b.Results { for j, row := range result.Rows { fmt.Printf("%d/%d: %s=%s\n", i, j, row.Key, row.ValueBytes()) } } }
Output: 0/0: "aa"=1 1/0: "ab"=2
func (*Txn) CommitBy ¶
CommitBy sends an EndTransactionRequest with Commit=true and Deadline=deadline.
func (*Txn) CommitInBatch ¶
CommitInBatch executes the operations queued up within a batch and commits the transaction. Explicitly committing a transaction is optional, but more efficient than relying on the implicit commit performed when the transaction function returns without error. The batch must be created by this transaction.
func (*Txn) CommitInBatchWithResponse ¶
CommitInBatchWithResponse is a version of CommitInBatch that returns the BatchResponse.
func (*Txn) CommitNoCleanup ¶
CommitNoCleanup is the same as Commit but will not attempt to clean up on failure. It is exposed only for use in txn_correctness_test.go because those tests manipulate transaction state at a low level.
func (*Txn) DelRange ¶
DelRange deletes the rows between begin (inclusive) and end (exclusive).
The returned Result will contain 0 rows and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
func (*Txn) Get ¶
Get retrieves the value for a key, returning the retrieved key/value or an error.
r, err := db.Get("a") // string(r.Key) == "a"
key can be either a byte slice or a string.
func (*Txn) GetProto ¶
GetProto retrieves the value for a key and decodes the result as a proto message.
key can be either a byte slice or a string.
func (*Txn) Inc ¶
Inc increments the integer value at key. If the key does not exist it will be created with an initial value of 0 which will then be incremented. If the key exists but was set using Put or CPut an error will be returned.
The returned Result will contain a single row and Result.Err will indicate success or failure.
key can be either a byte slice or a string.
func (*Txn) InternalSetPriority ¶
InternalSetPriority sets the transaction priority. It is intended for internal (testing) use only.
func (*Txn) Put ¶
Put sets the value for a key
key can be either a byte slice or a string. value can be any key type, a proto.Message or any Go primitive type (bool, int, etc).
func (*Txn) ReverseScan ¶
ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) in descending order.
The returned []KeyValue will contain up to maxRows elements.
key can be either a byte slice or a string.
func (*Txn) Run ¶
Run executes the operations queued up within a batch. Before executing any of the operations the batch is first checked to see if there were any errors during its construction (e.g. failure to marshal a proto message).
The operations within a batch are run in parallel and the order is non-deterministic. It is an unspecified behavior to modify and retrieve the same key within a batch.
Upon completion, Batch.Results will contain the results for each operation. The order of the results matches the order the operations were added to the batch.
func (*Txn) RunWithResponse ¶
RunWithResponse is a version of Run that returns the BatchResponse.
func (*Txn) Scan ¶
Scan retrieves the rows between begin (inclusive) and end (exclusive) in ascending order.
The returned []KeyValue will contain up to maxRows elements.
key can be either a byte slice or a string.
func (*Txn) SetDebugName ¶
SetDebugName sets the debug name associated with the transaction which will appear in log files and the web UI. Each transaction starts out with an automatically assigned debug name composed of the file and line number where the transaction was created.
func (*Txn) SetIsolation ¶
func (txn *Txn) SetIsolation(isolation roachpb.IsolationType) *roachpb.Error
SetIsolation sets the transaction's isolation type. Transactions default to serializable isolation. The isolation must be set before any operations are performed on the transaction.
func (*Txn) SetSystemConfigTrigger ¶
func (txn *Txn) SetSystemConfigTrigger()
SetSystemConfigTrigger sets the system db trigger to true on this transaction. This will impact the EndTransactionRequest.
func (*Txn) SetUserPriority ¶
func (txn *Txn) SetUserPriority(userPriority roachpb.UserPriority) *roachpb.Error
SetUserPriority sets the transaction's user priority. Transactions default to normal user priority. The user priority must be set before any operations are performed on the transaction.
func (*Txn) SystemConfigTrigger ¶
SystemConfigTrigger returns the systemConfigTrigger flag.