Home

Awesome

ignite-go-client

GoDoc GitHub release GitHub issues GitHub issues closed Go Report Card license

Apache Ignite (GridGain) v2.5+ client for Go programming language

This library is production ready.

Version is less than v1.0 because not all functionality is implemented yet (see Road map for details). But the implemented functionality is production ready.

Requirements

Road map

Project status:

  1. Develop "Cache Configuration" methods (Completed)
  2. Develop "Key-Value Queries" methods (Completed*)
  3. Develop "SQL and Scan Queries" methods (Completed)
  4. Develop SQL driver (Completed)
  5. Develop "Binary Types" methods (Not started)

*Not all types are supported. See type mapping for detail.

How to install

go get -u github.com/amsokol/ignite-go-client/...

How to use client

Import client package:

import (
    "github.com/amsokol/ignite-go-client/binary/v1"
)

Connect to server:

ctx := context.Background()

// connect
c, err := ignite.Connect(ctx, ignite.ConnInfo{
    Network: "tcp",
    Host:    "localhost",
    Port:    10800,
    Major:   1,
    Minor:   1,
    Patch:   0,
    // Credentials are only needed if they're configured in your Ignite server.
    Username: "ignite",
    Password: "ignite",
    Dialer: net.Dialer{
        Timeout: 10 * time.Second,
    },
    // Don't set the TLSConfig if your Ignite server
    // isn't configured with any TLS certificates.
    TLSConfig: &tls.Config{
        // You should only set this to true for testing purposes.
        InsecureSkipVerify: true,
    },
})
if err != nil {
    t.Fatalf("failed connect to server: %v", err)
}
defer c.Close()

See example of Key-Value Queries for more.

See example of SQL Queries for more.

See "_test.go" files for other examples.

How to use SQL driver

Import SQL driver:

import (
    "database/sql"

    _ "github.com/amsokol/ignite-go-client/sql"
)

Connect to server:

ctx := context.Background()

// open connection
db, err := sql.Open("ignite", "tcp://localhost:10800/ExampleDB?version=1.1.0&username=ignite&password=ignite"+
    "&tls=yes&tls-insecure-skip-verify=yes&page-size=10000&timeout=5000")
if err != nil {
    t.Fatalf("failed to open connection: %v", err)
}
defer db.Close()

See example for more.

Connection URL format:

protocol://host:port/cache?param1=value1&param2=value2&paramN=valueN

URL parts:

NameMandatoryDescriptionDefault value
protocolnoConnection protocoltcp
hostnoApache Ignite Cluster host name or IP address127.0.0.1
portnoMax rows to return by query10800
cacheyesCache name

URL parameters (param1,...paramN):

NameMandatoryDescriptionDefault value
schemanoDatabase schema"" (PUBLIC schema is used)
versionnoBinary protocol version in Semantic Version format1.0.0
usernamenoUsernameno
passwordnoPasswordno
tlsnoConnect using TLSno
tls-insecure-skip-verifynoControls whether a client verifies the server's certificate chain and host nameno
page-sizenoQuery cursor page size10000
max-rowsnoMax rows to return by query0 (looks like it means unlimited)
timeoutnoTimeout in milliseconds to execute query0 (disable timeout)
distributed-joinsnoDistributed joins (yes/no)no
local-querynoLocal query (yes/no)no
replicated-onlynoWhether query contains only replicated tables or not (yes/no)no
enforce-join-ordernoEnforce join order (yes/no)no
collocatednoWhether your data is co-located or not (yes/no)no
lazy-querynoLazy query execution (yes/no)no

How to run tests

  1. Download Apache Ignite 2.7 from official site
  2. Extract distributive to any folder
  3. Persistance mode is enabled to run tests. So you need to remove <path_with_ignite>\work folder each time to clean up test data before run tests.
  4. cd to testdata folder with configuration-for-tests.xml file
  5. Start Ignite server with configuration-for-tests.xml configuration file:
# For Windows:
<path_with_ignite>\bin\ignite.bat .\configuration-for-tests.xml

# For Linux:
<path_with_ignite>/bin/ignite.sh ./configuration-for-tests.xml
  1. Activate cluster:
# For Windows:
<path_with_ignite>\bin\control.bat --activate --user ignite --password ignite

# For Linux:
<path_with_ignite>/bin/control.bat --activate --user ignite --password ignite
  1. Run tests into the root folder of this project:
go test ./...

Type mapping

Apache Ignite TypeGo language type
bytebyte
shortint16
intint32
longint64, int
floatfloat32
doublefloat64
charignite.Char
boolbool
Stringstring
UUID (Guid)uuid.UUID (UUID library from Google)
Date*ignite.Date / time.Time
byte array[]byte
short array[]int16
int array[]int32
long array[]int64
float array[]float32
double array[]float64
char array[]ignite.Char
bool array[]bool
String array[]string
UUID (Guid) array[]uuid.UUID
Date array*[]ignite.Date / []time.Time
Object arrayNot supported. Need help.
CollectionNot supported. Need help.
MapNot supported. Need help.
EnumNot supported. Need help.
Enum arrayNot supported. Need help.
DecimalNot supported. Need help.
Decimal arrayNot supported. Need help.
Timestamptime.Time
Timestamp array[]time.Time
Time**ignite.Time / time.Time
Time array**[]ignite.Time / []time.Time
NULLnil
Complex Objectignite.ComplexObject

Note: pointers (*byte, *int32, *string, *uuid.UUID, *[]time.Time, etc.) are supported also.

*Date is outdated type. It's recommended to use Timestamp type. If you still need Date type use ignite.ToDate() function when you put date:

t := time.Date(2018, 4, 3, 14, 25, 32, int(time.Millisecond*123), time.UTC)
err := c.CachePut("CacheGet", false, "Date", ignite.ToDate(t)) // ToDate() converts time.Time to ignite.Date
...

t, err = c.CacheGet("CacheGet", false, "Date") // 't' is time.Time, you don't need any converting

**Time is outdated type. It's recommended to use Timestamp type. If you still need Time type use ignite.ToTime() function when you put time:

t := time.Date(1, 1, 1, 14, 25, 32, int(time.Millisecond*123), time.UTC)
err := c.CachePut("CacheGet", false, "Time", ignite.ToTime(t)) // ToTime() converts time.Time to ignite.Time (year, month and day are ignored)
...

t, err = c.CacheGet("CacheGet", false, "Time") // 't' is time.Time (where year=1, month=1 and day=1), you don't need any converting

Example how to use Complex Object type

// put complex object
c1 := ignite.NewComplexObject("ComplexObject1")
c1.Set("field1", "value 1")
c1.Set("field2", int32(2))
c1.Set("field3", true)
c2 := ignite.NewComplexObject("ComplexObject2")
c2.Set("complexField1", c1)
if err := c.CachePut(cache, false, "key", c2); err != nil {
    return err
}
...

// get complex object
v, err := c.CacheGet(cache, false, "key")
if err != nil {
    return err
}
c2 = v.(ignite.ComplexObject)
log.Printf("key=\"%s\", value=\"%#v\"", "key", c2)
v, _ = c2.Get("complexField1")
c1 = v.(ignite.ComplexObject)
log.Printf("key=\"%s\", value=\"%#v\"", "complexField1", c1)
v, _ = c1.Get("field1")
log.Printf("key=\"%s\", value=\"%s\"", "field1", v)
v, _ = c1.Get("field2")
log.Printf("key=\"%s\", value=%d", "field2", v)
v, _ = c1.Get("field3")
log.Printf("key=\"%s\", value=%t", "field3", v)

SQL and Scan Queries supported operations

OperationStatus of implementation
OP_QUERY_SQLDone.
OP_QUERY_SQL_CURSOR_GET_PAGEDone.
OP_QUERY_SQL_FIELDSDone.
OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGEDone.
OP_QUERY_SCANDone (without filter object support).
OP_QUERY_SCAN_CURSOR_GET_PAGEDone (without filter object support).
OP_RESOURCE_CLOSEDone.

Error handling

In case of operation execution error you can get original status and error message from Apache Ignite server.
Example:

if err := client.CachePut("TestCache", false, "key", "value"); err != nil {
    // try to cast to *IgniteError type
    original, ok := err.(*IgniteError)
    if ok {
        // log Apache Ignite status and message
        log.Printf("[%d] %s", original.IgniteStatus, original.IgniteMessage)
    }
    return err
}