Go
Примеры на GitHub: sample_db, go
go-tarantool – официальный коннектор Go для Tarantool. Он не входит в состав репозитория Tarantool и должен устанавливаться отдельно.
В этом руководстве показано, как с помощью библиотеки go-tarantool 2.x создать приложение на Go, которое подключается к удаленному экземпляру Tarantool, выполняет CRUD-операции и вызывает хранимую процедуру. Полная документация пакета доступна здесь: Client in Go for Tarantool.
Перед созданием и запуском клиентского приложения на Go необходимо запустить приложение sample_db с помощью команды tt start:
$ tt start sample_db
Теперь можно создать клиентское приложение на Go, которое будет выполнять запросы к этой базе данных.
Перед началом работы убедитесь, что на вашем компьютере установлен Go.
-
Создайте каталог
helloдля приложения и перейдите в него:$ mkdir hello$ cd hello -
Инициализируйте новый модуль Go:
$ go mod init example/hello -
В каталоге
helloсоздайте файлhello.goдля кода приложения.
В файле hello.go объявите пакет main и импортируйте следующие пакеты:
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")
Пакеты для внешних типов MsgPack, такие как datetime, decimal или uuid, необходимы для разбора этих типов в ответе.
-
Объявите функцию
main():func main() {} -
Внутри функции
main()добавьте следующий код:
// 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// ...
Этот код устанавливает подключение к работающему экземпляру Tarantool от имени пользователя sampleuser. Объект conn можно
использовать для выполнения CRUD-запросов и вызова хранимых процедур.
Добавьте следующий код, чтобы вставить четыре кортежа в спейс bands:
// 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)}}
Этот код выполняет запросы на вставку асинхронно:
- Структура
Futureиспользуется как дескриптор для асинхронных запросов. - Метод
NewInsertRequest()создает объект запроса на вставку, который выполняется подключением.
Чтобы получить кортеж по заданному значению первичного ключа, используйте NewSelectRequest() для создания объекта запроса:
// 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)
Также можно получить кортеж по значению заданного индекса с помощью 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() можно использовать для обновления кортежа, идентифицированного первичным ключом, следующим образом:
// 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() можно использовать для обновления существующего кортежа или вставки нового. В примере ниже вставляется
новый кортеж:
// 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)}
В этом примере NewReplaceRequest() используется для удаления существующего кортежа и вставки нового:
// 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() в примере ниже используется для удаления кортежа, значение первичного ключа которого равно 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)
Для вызова хранимой процедуры используйте 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)
Метод CloseGraceful() можно использовать для закрытия подключения, когда оно больше не нужно:
// Close connectionconn.CloseGraceful()fmt.Println("Connection is closed")
-
Выполните следующие команды
go get, чтобы обновить зависимости в файлеgo.mod:$ 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 -
Чтобы запустить получившееся приложение, выполните команду
go runв каталоге приложения:$ 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
Последнее обновление: январь 2023
Также существуют следующие коннекторы Go, разработанные сообществом:
В таблице ниже приведено сравнение возможностей перечисленных коннекторов.
Лицензия | BSD 2-Clause | MIT | BSD 2-Clause |
Последнее обновление | 2023 | 2022 | 2022 |
Документация | README с примерами и актуальным GoDoc | README с примерами и комментариями в коде | README с примерами |
Тестирование / CI / CD | GitHub Actions | Travis CI | GitHub Actions |
Звёзды на GitHub | 147 | 45 | 14 |
Статический анализ | golangci-lint, luacheck | golint | golangci-lint |
Пакетирование | go get | go get | go get |
Покрытие кода | Да | Нет | Нет |
драйвер msgpack | |||
Асинхронная работа | Да | Да | Да |
Перезагрузка схемы | Да (ручная загрузка) | Да (ручная загрузка) | Да (ручная загрузка) |
Имена спейсов / индексов | Да | Да | Да |
Кортежи как структуры | Да (структуры и функции marshall должны быть заранее определены в коде Go) | Нет | Да (структуры и функции marshall должны быть заранее определены в коде Go) |
Доступ к полям кортежа по именам | Только при преобразовании в структуру | Нет | Только при преобразовании в структуру |
Поддержка SQL | Да | Нет (#18, закрыт) | Нет |
Да | Нет | Нет | |
Поддержка Varbinary | Да (встроенными средствами языка) | Да (встроенными средствами языка) | Да (по умолчанию декодирует в строку, см. #6) |
Поддержка UUID | Да | Нет | Нет |
Поддержка Decimal | Да | Нет | Нет |
Поддержка EXT_ERROR | Да | Нет | Нет |
Поддержка Datetime | Да | Нет | Нет |
Да | Нет (#21) | Да | |
Да | Нет | Нет | |
Да | Нет | Нет | |
Да | Нет | Нет | |
Поддержка tarantool/crud | Нет | Нет | Нет |
Пул соединений | Да (циклическое переключение при отказе, без балансировки) | Нет | Нет |
Прозрачное повторное подключение | Да (см. комментарии в #129) | Нет (повторное подключение выполняется явно, см. #11) | Да (см. комментарии в #7) |
Прозрачные повторные попытки запросов | Нет | Нет | Нет |
Да | Нет | Нет | |
Да | Нет | Нет | |
Особенности языка | context | context | context |
Прочее | Поддерживает API tarantool/queue | Может имитировать экземпляр Tarantool (в том числе как реплику). Предоставляет инструменты для чтения файлов снимков и xlog через модуль snapio. Реализует распаковку структур запросов, если нужно реализовать собственный iproto-прокси | API экспериментальный, возможны ломающие изменения |