Go
Examples on GitHub: sample_db, go
go-tarantool is the official Go connector for Tarantool. It is not supplied as part of the Tarantool repository and should be installed separately.
This tutorial shows how to use the go-tarantool 2.x library to create a Go application that connects to a remote Tarantool instance, performs CRUD operations, and executes a stored procedure. You can find the full package documentation here: Client in Go for Tarantool.
Before creating and starting a client Go application, you need to run the sample_db application using tt start:
$ tt start sample_db
Now you can create a client Go application that makes requests to this database.
Before you start, make sure you have Go installed on your computer.
-
Create the
hellodirectory for your application and go to this directory:$ mkdir hello$ cd hello -
Initialize a new Go module:
$ go mod init example/hello -
Inside the
hellodirectory, create thehello.gofile for application code.
In the hello.go file, declare a main package and import the
following packages:
package mainimport ("context""fmt""github.com/tarantool/go-tarantool/v2"_ "github.com/tarantool/go-tarantool/v2/datetime"_ "github.com/tarantool/go-tarantool/v2/decimal"_ "github.com/tarantool/go-tarantool/v2/uuid""time")
The packages for external MsgPack types, such as datetime, decimal,
or uuid, are required to parse these types in a response.
-
Declare the
main()function:func main() {} -
Inside the
main()function, add the following code:
// Connect to the databasectx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()dialer := tarantool.NetDialer{Address: "127.0.0.1:3301",User: "sampleuser",Password: "123456",}opts := tarantool.Opts{Timeout: time.Second,}conn, err := tarantool.Connect(ctx, dialer, opts)if err != nil {fmt.Println("Connection refused:", err)return}// Interact with the database// ...
This code establishes a connection to a running Tarantool instanceon behalf of `sampleuser`. The `conn` object can be used to makeCRUD requests and execute stored procedures.
Add the following code to insert four tuples into the bands space:
// Insert datatuples := [][]interface{}{{1, "Roxette", 1986},{2, "Scorpions", 1965},{3, "Ace of Base", 1987},{4, "The Beatles", 1960},}var futures []*tarantool.Futurefor _, tuple := range tuples {request := tarantool.NewInsertRequest("bands").Tuple(tuple)futures = append(futures, conn.Do(request))}fmt.Println("Inserted tuples:")for _, future := range futures {result, err := future.Get()if err != nil {fmt.Println("Got an error:", err)} else {fmt.Println(result)}}
This code makes insert requests asynchronously:
- The
Futurestructure is used as a handle for asynchronous requests. - The
NewInsertRequest()method creates an insert request object that is executed by the connection.
To get a tuple by the specified primary key value, use
NewSelectRequest() to create an insert request object:
// Select by primary keydata, err := conn.Do(tarantool.NewSelectRequest("bands").Limit(10).Iterator(tarantool.IterEq).Key([]interface{}{uint(1)}),).Get()if err != nil {fmt.Println("Got an error:", err)}fmt.Println("Tuple selected by the primary key value:", data)
You can also get a tuple by the value of the specified index by using
Index():
// Select by secondary keydata, err = conn.Do(tarantool.NewSelectRequest("bands").Index("band").Limit(10).Iterator(tarantool.IterEq).Key([]interface{}{"The Beatles"}),).Get()if err != nil {fmt.Println("Got an error:", err)}fmt.Println("Tuple selected by the secondary key value:", data)
NewUpdateRequest() can be used to update a tuple identified by the
primary key as follows:
// Updatedata, err = conn.Do(tarantool.NewUpdateRequest("bands").Key(tarantool.IntKey{2}).Operations(tarantool.NewOperations().Assign(1, "Pink Floyd")),).Get()if err != nil {fmt.Println("Got an error:", err)}fmt.Println("Updated tuple:", data)
NewUpsertRequest() can be used to update an existing tuple or insert a
new one. In the example below, a new tuple is inserted:
// Upsertdata, err = conn.Do(tarantool.NewUpsertRequest("bands").Tuple([]interface{}{uint(5), "The Rolling Stones", 1962}).Operations(tarantool.NewOperations().Assign(1, "The Doors")),).Get()if err != nil {fmt.Println("Got an error:", err)}
In this example, NewReplaceRequest() is used to delete the existing
tuple and insert a new one:
// Replacedata, err = conn.Do(tarantool.NewReplaceRequest("bands").Tuple([]interface{}{1, "Queen", 1970}),).Get()if err != nil {fmt.Println("Got an error:", err)}fmt.Println("Replaced tuple:", data)
NewDeleteRequest() in the example below is used to delete a tuple
whose primary key value is 5:
// Deletedata, err = conn.Do(tarantool.NewDeleteRequest("bands").Key([]interface{}{uint(5)}),).Get()if err != nil {fmt.Println("Got an error:", err)}fmt.Println("Deleted tuple:", data)
To execute a stored procedure, use NewCallRequest():
// Calldata, err = conn.Do(tarantool.NewCallRequest("get_bands_older_than").Args([]interface{}{1966}),).Get()if err != nil {fmt.Println("Got an error:", err)}fmt.Println("Stored procedure result:", data)
The CloseGraceful() method can be used to close the connection when it
is no longer needed:
// Close connectionconn.CloseGraceful()fmt.Println("Connection is closed")
-
Execute the following
go getcommands to update dependencies in thego.modfile:$ go get github.com/tarantool/go-tarantool/v2$ go get github.com/tarantool/go-tarantool/v2/decimal$ go get github.com/tarantool/go-tarantool/v2/uuid -
To run the resulting application, execute the
go runcommand in the application directory:$ go run .Inserted tuples:[[1 Roxette 1986]][[2 Scorpions 1965]][[3 Ace of Base 1987]][[4 The Beatles 1960]]Tuple selected by the primary key value: [[1 Roxette 1986]]Tuple selected by the secondary key value: [[4 The Beatles 1960]]Updated tuple: [[2 Pink Floyd 1965]]Replaced tuple: [[1 Queen 1970]]Deleted tuple: [[5 The Rolling Stones 1962]]Stored procedure result: [[[2 Pink Floyd 1965] [4 The Beatles 1960]]]Connection is closed
Last update: January 2023
There are also the following community-driven Go connectors:
The table below contains a feature comparison for the connectors mentioned above.
[tarantool/go-tarantool](https://github.com/tarantool/go-tarantool) [viciious/go-tarantool](https://github.com/viciious/go-tarantool) [FZambia/tarantool](https://github.com/FZambia/tarantool)
License BSD 2-Clause MIT BSD 2-Clause Last update 2023 2022 2022 Documentation README with examples and up-to-date GoDoc README with examples, code comments README with examples Testing / CI / CD GitHub Actions Travis CI GitHub Actions GitHub Stars 147 45 14 Static analysis golangci-lint, luacheck golint golangci-lint Packaging go get go get go get Code coverage Yes No No msgpack driver vmihailenco/msgpack/v2 or vmihailenco/msgpack/v5 tinylib/msgp vmihailenco/msgpack/v5 Async work Yes Yes Yes Schema reload Yes (manual pull) Yes (manual pull) Yes (manual pull) Space / index names Yes Yes Yes Tuples as structures Yes (structure and marshall functions must be predefined in Go code) No Yes (structure and marshall functions must be predefined in Go code) Access tuple fields by names Only if marshalled to structure No Only if marshalled to structure SQL support Yes No (#18, closed) No Interactive transactions Yes No No Varbinary support Yes (with in-built language tools) Yes (with in-built language tools) Yes (decodes to string by default, see #6) UUID support Yes No No Decimal support Yes No No EXT_ERROR support Yes No No Datetime support Yes No No box.session.push() responses Yes No (#21) Yes Session settings Yes No No Graceful shutdown Yes No No IPROTO_ID (feature discovering) Yes No No tarantool/crud support No No No Connection pool Yes (round-robin failover, no balancing) No No Transparent reconnecting Yes (see comments in #129) No (handle reconnects explicitly, refer to #11) Yes (see comments in #7) Transparent request retrying No No No Watchers Yes No No Pagination Yes No No Language features context context context Miscellaneous Supports tarantool/queue API Can mimic a Tarantool instance (also as replica). Provides instrumentation for reading snapshot and xlog files via snapio module. Implements unpacking of query structs if you want to implement your own iproto proxy API is experimental and breaking changes may happen