Package -


A few words about Tarantool: Tarantool is a (No)SQL database with in-memory and disk-based storage engines.

Key features:

  • Fast as hell
  • ACID transactions
  • Secondary indices
  • Onboard Lua scripting
  • Asynchronous master-master replication

The package includes three main modules:

  • Tarantool: common protocols to work with schema, spaces and indices.
  • TarantoolModule: an implementation to run your code (stored procedures) inside a tarantool process.
  • TarantoolConnector: an implementation which can run the same code by communicating with a remote instance.

And the one that allows us run the code in different environments:

  • AsyncTarantool: an implementation of our Async protocol to switch over different cooperative multitasking systems.

Follow the examples link below to see how to use it all together.


.package(url: "", from: "0.4.0")


You can find this code and more in examples.

Tarantool Connector

import TarantoolConnector

let iproto = try IProto(host: "")
try iproto.auth(username: "tester", password: "tester")

var schema = try Schema(iproto)

guard let test = schema.spaces["test"] else {
    print("space test not found")

// select by key
let equal = try .eq, keys: [3])
equal.forEach { print($0) }

// select all
let all = try .all)
all.forEach { print($0) }

// replace
try test.replace([42, "Answer to the Ultimate Question of Life, The Universe, and Everything"])
if let answer = try test.get(keys: [42]) {

// eval example
let result = try iproto.eval("return 3 + 0.14")

// create space & index
if schema.spaces["new_space"] == nil {
    try iproto.auth(username: "admin", password: "admin")
    var space = try schema.createSpace(name: "new_space")
    try space.createIndex(name: "new_index", sequence: true)
guard let newSpace = schema.spaces["new_space"] else {
    print("new_space doesn't exist")
// autoincrementing index
try newSpace.insert([nil, "test1"])
try newSpace.insert([nil, "test2"])
let newResult = try .all)
newResult.forEach { print($0) }

Tarantool in-memory module


import MessagePack
import TarantoolModule

struct ModuleError: Error, CustomStringConvertible {
    let description: String

public func helloSwift(context: Box.Context) -> Box.Result {
    return Box.convertCall(context) { output in
        try output.append(["hello"])
        try output.append(["from"])
        try output.append(["swift"])

public func getFoo(context: Box.Context) -> Box.Result {
    return Box.convertCall(context) { output in
        guard let space = schema.spaces["data"] else {
            throw Box.Error(code: .noSuchSpace, message: "space: 'data'")

        try space.replace(["foo", "bar"])

        guard let result = try space.get(keys: ["foo"]) else {
            throw Box.Error(code: .tupleNotFound, message: "keys: foo")
        try output.append(result)

public func getCount(
    context: Box.Context,
    start: UnsafePointer<UInt8>,
    end: UnsafePointer<UInt8>
) -> Box.Result {
    return Box.convertCall(context, start, end) { arguments, output in
        guard let name = String(arguments.first) else {
            throw ModuleError(description: "incorrect space name argument")

        guard let space = schema.spaces[name] else {
            throw Box.Error(code: .noSuchSpace, message: "space: '\(name)'")

        let count = try space.count()
        try output.append([.int(count)])

public func evalLuaScript(context: Box.Context) -> Box.Result {
    return Box.convertCall(context) { output in
        var result = try Lua.eval("return 3 + 0.14")
        result.insert("eval result", at: 0)
        try output.append(result)


import TarantoolConnector

let iproto = try IProto(host: "")

print(try"get_count", arguments: ["test"]))


You can also run the tests with a custom path to tarantool executable by setting TARANTOOL_BIN variable:

TARANTOOL_BIN=/path/to/bin/tarantool swift test