Queries & History
The fundamental property of immudb is that it’s an append-only database. This means that an update does not change an existing record. Instead, it is a new insert of the same key with a new value. It’s possible to retrieve all the values for a particular key with the history command.
History accepts the following parameters:
Key: a key of an itemOffset: the starting index (excluded from the search). OptionalLimit: maximum returned items. OptionalDesc: items are returned in reverse order. OptionalSinceTx: immudb will wait that the transaction specified by SinceTx is processed. Optional
Go
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7
8 "github.com/codenotary/immudb/pkg/api/schema"
9 immudb "github.com/codenotary/immudb/pkg/client"
10)
11
12func main() {
13 opts := immudb.DefaultOptions().
14 WithAddress("localhost").
15 WithPort(3322)
16
17 client := immudb.NewClient().WithOptions(opts)
18 err := client.OpenSession(
19 context.TODO(),
20 []byte(`immudb`),
21 []byte(`immudb`),
22 "defaultdb",
23 )
24 if err != nil {
25 log.Fatal(err)
26 }
27
28 defer client.CloseSession(context.TODO())
29
30 _, err = client.Set(
31 context.TODO(),
32 []byte(`hello`),
33 []byte(`immutable world`),
34 )
35 if err != nil {
36 log.Fatal(err)
37 }
38 _, err = client.Set(
39 context.TODO(),
40 []byte(`hello`),
41 []byte(`immudb`),
42 )
43 if err != nil {
44 log.Fatal(err)
45 }
46
47 req := &schema.HistoryRequest{
48 Key: []byte(`hello`),
49 }
50
51 ret, err := client.History(context.TODO(), req)
52 if err != nil {
53 log.Fatal(err)
54 }
55
56 fmt.Printf(
57 "Successfully retrieved %d entries for key %s\n",
58 len(ret.GetEntries()),
59 req.Key,
60 )
61}Java
1package io.codenotary.immudb.helloworld;
2
3import java.nio.charset.StandardCharsets;
4import java.util.Arrays;
5import java.util.Iterator;
6
7import io.codenotary.immudb4j.Entry;
8import io.codenotary.immudb4j.FileImmuStateHolder;
9import io.codenotary.immudb4j.ImmuClient;
10
11public class App {
12
13 public static void main(String[] args) {
14
15 ImmuClient client = null;
16
17 try {
18
19 FileImmuStateHolder stateHolder = FileImmuStateHolder.newBuilder()
20 .withStatesFolder("./immudb_states")
21 .build();
22
23 client = ImmuClient.newBuilder()
24 .withServerUrl("127.0.0.1")
25 .withServerPort(3322)
26 .withStateHolder(stateHolder)
27 .build();
28
29 client.openSession("defaultdb", "immudb", "immudb");
30
31 byte[] key1 = "myKey1".getBytes(StandardCharsets.UTF_8);
32 byte[] value1 = new byte[] { 1, 2, 3 };
33 byte[] value2 = new byte[] { 4, 5, 6 };
34
35 client.set(key1, value1);
36 client.set(key1, value2);
37
38 Iterator<Entry> it = client.history(key1, false, 0, 0);
39
40 while (it.hasNext()) {
41 Entry entry = it.next();
42
43 System.out.format("('%s', '%s')\n", new String(entry.getKey()), Arrays.toString(entry.getValue()));
44 }
45
46 client.closeSession();
47
48 } catch (Exception e) {
49 e.printStackTrace();
50 } finally {
51 if (client != null) {
52 try {
53 client.shutdown();
54 } catch (InterruptedException e) {
55 e.printStackTrace();
56 }
57 }
58 }
59
60 }
61
62}Note that, similar with many other methods, history method is overloaded to allow different kinds/set of parameters.
.NET
1
2var client = new ImmuClient();
3await client.Open("immudb", "immudb", "defaultdb");
4
5try
6{
7 await client.Set("history1", value1);
8 await client.Set("history1", value2);
9 await client.Set("history2", value1);
10 await client.Set("history2", value2);
11 await client.Set("history2", value3);
12}
13catch (CorruptedDataException e)
14{
15 Console.WriteLine("Failed at set.", e);
16}
17
18List<Entry> historyResponse1 = await client.History("history1", 10, 0, false);
19
20await client.Close();Note that, similar with many other methods, history method is overloaded to allow different kinds/set of parameters.
Python
Python immudb sdk currently doesn’t support SinceTx parameter
1from immudb import ImmudbClient
2
3URL = "localhost:3322" # immudb running on your machine
4LOGIN = "immudb" # Default username
5PASSWORD = "immudb" # Default password
6DB = b"defaultdb" # Default database name (must be in bytes)
7
8def main():
9 client = ImmudbClient(URL)
10 client.login(LOGIN, PASSWORD, database = DB)
11
12 client.set(b'test', b'1')
13 client.set(b'test', b'2')
14 client.set(b'test', b'3')
15
16 history = client.history(b'test', 0, 100, True) # List[immudb.datatypes.historyResponseItem]
17 responseItemFirst = history[0]
18 print(responseItemFirst.key) # Entry key (b'test')
19 print(responseItemFirst.value) # Entry value (b'3')
20 print(responseItemFirst.tx) # Transaction id
21
22 responseItemThird = history[2]
23 print(responseItemThird.key) # Entry key (b'test')
24 print(responseItemThird.value) # Entry value (b'1')
25 print(responseItemThird.tx) # Transaction id
26
27if __name__ == "__main__":
28 main()Node.js
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 const key = 'hello'
15
16 await cl.set({ key, value: 'immutable world' })
17 await cl.set({ key, value: 'immudb' })
18
19 const historyReq: Parameters.History = {
20 key
21 }
22 const historyRes = cl.history(historyReq)
23 console.log('success: history', historyRes)
24})()Others
If you’re using another development language, please refer to the immugw option.
Counting#
Counting entries is not supported at the moment.
Go
This feature is not yet supported or not documented. Do you want to make a feature request or help out? Open an issue on Go sdk github project
Java
This feature is not yet supported or not documented. Do you want to make a feature request or help out? Open an issue on Java sdk github project
Python
This feature is not yet supported or not documented. Do you want to make a feature request or help out? Open an issue on Python sdk github project
Node.js
This feature is not yet supported or not documented. Do you want to make a feature request or help out? Open an issue on Node.js sdk github project
.NET
This feature is not yet supported or not documented. Do you want to make a feature request or help out? Open an issue on .Net sdk github project
Others
If you’re using another development language, please refer to the immugw option.
Scan#
The scan command is used to iterate over the collection of elements present in the currently selected database.
Scan accepts the following parameters:
Prefix: prefix. If not provided all keys will be involved. OptionalSeekKey: initial key for the first entry in the iteration. OptionalDesc: DESC or ASC sorting order. OptionalLimit: maximum returned items. OptionalSinceTx: immudb will wait that the transaction provided by SinceTx be processed. OptionalNoWait: Default false. When true scan doesn’t wait for the index to be fully generated and returns the last indexed value. Optional
To gain speed it’s possible to specify noWait=true. The control will be returned to the caller immediately, without waiting for the indexing to complete. When noWait is used, keep in mind that the returned data may not be yet up to date with the inserted data, as the indexing might not have completed.
Go
An ordinary scan command and a reversed one.
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7 "math"
8
9 "github.com/codenotary/immudb/pkg/api/schema"
10 immudb "github.com/codenotary/immudb/pkg/client"
11)
12
13func main() {
14 opts := immudb.DefaultOptions().
15 WithAddress("localhost").
16 WithPort(3322)
17
18 client := immudb.NewClient().WithOptions(opts)
19 err := client.OpenSession(
20 context.TODO(),
21 []byte(`immudb`),
22 []byte(`immudb`),
23 "defaultdb",
24 )
25 if err != nil {
26 log.Fatal(err)
27 }
28
29 defer client.CloseSession(context.TODO())
30
31 _, err = client.Set(context.TODO(), []byte(`aaa`), []byte(`item1`))
32 if err != nil {
33 log.Fatal(err)
34 }
35 _, err = client.Set(context.TODO(), []byte(`bbb`), []byte(`item2`))
36 if err != nil {
37 log.Fatal(err)
38 }
39 _, err = client.Set(context.TODO(), []byte(`abc`), []byte(`item3`))
40 if err != nil {
41 log.Fatal(err)
42 }
43
44 scanReq := &schema.ScanRequest{
45 Prefix: []byte(`a`),
46 }
47
48 list, err := client.Scan(context.TODO(), scanReq)
49 if err != nil {
50 log.Fatal(err)
51 }
52 fmt.Printf("%v\n", list)
53 scanReq1 := &schema.ScanRequest{
54 SeekKey: []byte{0xFF},
55 Prefix: []byte(`a`),
56 Desc: true,
57 }
58
59 list, err = client.Scan(context.TODO(), scanReq1)
60 if err != nil {
61 log.Fatal(err)
62 }
63 fmt.Printf("%v\n", list)
64
65 // scan on all key values on the current database,
66 // with a fresh snapshot
67 scanReq2 := &schema.ScanRequest{
68 SeekKey: []byte{0xFF},
69 Desc: true,
70 SinceTx: math.MaxUint64,
71 }
72
73 list, err = client.Scan(context.TODO(), scanReq2)
74 if err != nil {
75 log.Fatal(err)
76 }
77 fmt.Printf("%v\n", list)
78}Java
1package io.codenotary.immudb.helloworld;
2
3import java.nio.charset.StandardCharsets;
4import java.util.Arrays;
5import java.util.Iterator;
6
7import io.codenotary.immudb4j.Entry;
8import io.codenotary.immudb4j.FileImmuStateHolder;
9import io.codenotary.immudb4j.ImmuClient;
10
11public class App {
12
13 public static void main(String[] args) {
14
15 ImmuClient client = null;
16
17 try {
18
19 FileImmuStateHolder stateHolder = FileImmuStateHolder.newBuilder()
20 .withStatesFolder("./immudb_states")
21 .build();
22
23 client = ImmuClient.newBuilder()
24 .withServerUrl("127.0.0.1")
25 .withServerPort(3322)
26 .withStateHolder(stateHolder)
27 .build();
28
29 client.openSession("defaultdb", "immudb", "immudb");
30
31 byte[] key1 = "myKey1".getBytes(StandardCharsets.UTF_8);
32 byte[] value1 = new byte[] { 1, 2, 3 };
33
34 byte[] key2 = "myKey2".getBytes(StandardCharsets.UTF_8);
35 byte[] value2 = new byte[] { 4, 5, 6 };
36
37 client.set(key1, value1);
38 client.set(key2, value2);
39
40 Iterator<Entry> it = client.scan("myKey");
41
42 while (it.hasNext()) {
43 Entry entry = it.next();
44
45 System.out.format("('%s', '%s')\n", new String(entry.getKey()), Arrays.toString(entry.getValue()));
46 }
47
48 client.closeSession();
49
50 } catch (Exception e) {
51 e.printStackTrace();
52 } finally {
53 if (client != null) {
54 try {
55 client.shutdown();
56 } catch (InterruptedException e) {
57 e.printStackTrace();
58 }
59 }
60 }
61
62 }
63
64}scan is an overloaded method, therefore multiple flavours of it with different parameter options exist.
.NET
1var client = new ImmuClient();
2await client.Open("immudb", "immudb", "defaultdb");
3
4byte[] value1 = { 0, 1, 2, 3 };
5byte[] value2 = { 4, 5, 6, 7 };
6
7try
8{
9 await client.Set("scan1", value1);
10 await client.Set("scan2", value2);
11}
12catch (CorruptedDataException e)
13{
14 Assert.Fail("Failed at set.", e);
15}
16
17List<Entry> scanResult = await client.Scan("scan", 5, false);
18Console.WriteLine(scanResult.Count);
19
20await client.Close();scan is an overloaded method, therefore multiple flavours of it with different parameter options exist.
Python
1from immudb import ImmudbClient
2
3URL = "localhost:3322" # immudb running on your machine
4LOGIN = "immudb" # Default username
5PASSWORD = "immudb" # Default password
6DB = b"defaultdb" # Default database name (must be in bytes)
7
8def main():
9 client = ImmudbClient(URL)
10 client.login(LOGIN, PASSWORD, database = DB)
11 toSet = {
12 b"aaa": b'1',
13 b'bbb': b'2',
14 b'ccc': b'3',
15 b'acc': b'1',
16 b'aac': b'2',
17 b'aac:test1': b'3',
18 b'aac:test2': b'1',
19 b'aac:xxx:test': b'2'
20 }
21 client.setAll(toSet)
22
23 result = client.scan(b'', b'', True, 100) # All entries
24 print(result)
25 result = client.scan(b'', b'aac', True, 100) # All entries with prefix 'aac' including 'aac'
26 print(result)
27
28 # Seek key example (allows retrieve entries in proper chunks):
29 result = client.scan(b'', b'', False, 3)
30 while result:
31 for item, value in result.items():
32 print("SEEK", item, value)
33 lastKey = list(result.keys())[-1]
34 result = client.scan(lastKey, b'', False, 3)
35
36if __name__ == "__main__":
37 main()Node.js
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 await cl.set({ key: 'aaa', value: 'item1' })
15 await cl.set({ key: 'bbb', value: 'item2' })
16 await cl.set({ key: 'abc', value: 'item3' })
17
18 const scanReq: Parameters.Scan = {
19 prefix: 'a',
20 desc: false,
21 limit: 0,
22 sincetx: 0
23 }
24 const scanRes = await cl.scan(scanReq)
25 console.log('success: scan', scanRes)
26
27 const scanReq1: Parameters.Scan = {
28 prefix: 'a',
29 desc: true,
30 limit: 0,
31 sincetx: 0
32 }
33 const scanRes1 = await cl.scan(scanReq1)
34 console.log('success: scan', scanRes1)
35})()Example with an offset:
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 await cl.set({ key: 'aaa', value: 'item1' })
15 await cl.set({ key: 'bbb', value: 'item2' })
16 await cl.set({ key: 'abc', value: 'item3' })
17
18 const scanReq: Parameters.Scan = {
19 seekkey: '',
20 prefix: '',
21 desc: true,
22 limit: 0,
23 sincetx: 0
24 }
25 const scanRes = await cl.scan(scanReq)
26 console.log('success: scan', scanRes)
27
28 const scanReq1: Parameters.Scan = {
29 seekkey: 'bbb',
30 prefix: '',
31 desc: true,
32 limit: 0,
33 sincetx: 0
34 }
35 const scanRes1 = await cl.scan(scanReq1)
36 console.log('success: scan', scanRes1)
37
38 const scanReq2: Parameters.Scan = {
39 seekkey: 'b',
40 prefix: 'b',
41 desc: true,
42 limit: 0,
43 sincetx: 0
44 }
45 const scanRes2 = await cl.scan(scanReq2)
46 console.log('success: scan', scanRes2)
47})()Others
If you’re using another development language, please refer to the immugw option.
References#
SetReference is like a “tag” operation. It appends a reference on a key/value element.
As a consequence, when we retrieve that reference with a Get or VerifiedGet the value retrieved will be the original value associated with the original key.
Its VerifiedReference counterpart is the same except that it also produces the inclusion and consistency proofs.
Go
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7
8 immudb "github.com/codenotary/immudb/pkg/client"
9)
10
11func main() {
12 opts := immudb.DefaultOptions().
13 WithAddress("localhost").
14 WithPort(3322)
15
16 client := immudb.NewClient().WithOptions(opts)
17 err := client.OpenSession(
18 context.TODO(),
19 []byte(`immudb`),
20 []byte(`immudb`),
21 "defaultdb",
22 )
23 if err != nil {
24 log.Fatal(err)
25 }
26
27 defer client.CloseSession(context.TODO())
28
29 _, err = client.Set(
30 context.TODO(),
31 []byte(`firstKey`),
32 []byte(`firstValue`),
33 )
34 if err != nil {
35 log.Fatal(err)
36 }
37 reference, err := client.SetReference(
38 context.TODO(),
39 []byte(`myTag`),
40 []byte(`firstKey`),
41 )
42 if err != nil {
43 log.Fatal(err)
44 }
45
46 fmt.Printf("%v\n", reference)
47 firstItem, err := client.Get(
48 context.TODO(),
49 []byte(`myTag`),
50 )
51 if err != nil {
52 log.Fatal(err)
53 }
54 fmt.Printf("%v\n", firstItem)
55}Example with verifications
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7
8 immudb "github.com/codenotary/immudb/pkg/client"
9)
10
11func main() {
12 opts := immudb.DefaultOptions().
13 WithAddress("localhost").
14 WithPort(3322)
15
16 client := immudb.NewClient().WithOptions(opts)
17 err := client.OpenSession(
18 context.TODO(),
19 []byte(`immudb`),
20 []byte(`immudb`),
21 "defaultdb",
22 )
23 if err != nil {
24 log.Fatal(err)
25 }
26
27 defer client.CloseSession(context.TODO())
28
29 _, err = client.Set(
30 context.TODO(),
31 []byte(`secondKey`),
32 []byte(`secondValue`),
33 )
34 if err != nil {
35 log.Fatal(err)
36 }
37 reference, err := client.VerifiedSetReference(
38 context.TODO(),
39 []byte(`mySecondTag`),
40 []byte(`secondKey`),
41 )
42 if err != nil {
43 log.Fatal(err)
44 }
45 fmt.Printf("%v\n", reference)
46
47 secondItem, err := client.Get(
48 context.TODO(),
49 []byte(`mySecondTag`),
50 )
51 if err != nil {
52 log.Fatal(err)
53 }
54 fmt.Printf("%v\n", secondItem)
55}Java
1package io.codenotary.immudb.helloworld;
2
3import java.nio.charset.StandardCharsets;
4import java.util.Arrays;
5
6import io.codenotary.immudb4j.Entry;
7import io.codenotary.immudb4j.FileImmuStateHolder;
8import io.codenotary.immudb4j.ImmuClient;
9
10public class App {
11
12 public static void main(String[] args) {
13
14 ImmuClient client = null;
15
16 try {
17
18 FileImmuStateHolder stateHolder = FileImmuStateHolder.newBuilder()
19 .withStatesFolder("./immudb_states")
20 .build();
21
22 client = ImmuClient.newBuilder()
23 .withServerUrl("127.0.0.1")
24 .withServerPort(3322)
25 .withStateHolder(stateHolder)
26 .build();
27
28 client.openSession("defaultdb", "immudb", "immudb");
29
30 byte[] key = "myKey".getBytes(StandardCharsets.UTF_8);
31 byte[] value = new byte[] { 1, 2, 3 };
32
33 byte[] myRef = "myRef".getBytes(StandardCharsets.UTF_8);
34
35 client.set(key, value);
36
37 client.setReference(myRef, key);
38
39 Entry entry = client.get(myRef);
40
41 System.out.format("('%s', '%s')\n", new String(entry.getKey()), Arrays.toString(entry.getValue()));
42
43 client.closeSession();
44
45 } catch (Exception e) {
46 e.printStackTrace();
47 } finally {
48 if (client != null) {
49 try {
50 client.shutdown();
51 } catch (InterruptedException e) {
52 e.printStackTrace();
53 }
54 }
55 }
56
57 }
58
59}.NET
1var client = new ImmuClient();
2await client.Open("immudb", "immudb", "defaultdb");
3
4byte[] key = Encoding.UTF8.GetBytes("testRef");
5byte[] val = Encoding.UTF8.GetBytes("abc");
6
7TxHeader? setTxHdr = null;
8try
9{
10 setTxHdr = await client.Set(key, val);
11}
12catch (CorruptedDataException e)
13{
14 Console.WriteLine("Failed at set.", e);
15 return;
16}
17
18byte[] ref1Key = Encoding.UTF8.GetBytes("ref1_to_testRef");
19byte[] ref2Key = Encoding.UTF8.GetBytes("ref2_to_testRef");
20
21TxHeader? ref1TxHdr = null;
22try
23{
24 ref1TxHdr = await client.SetReference(ref1Key, key);
25}
26catch (CorruptedDataException e)
27{
28 Console.WriteLine("Failed at setReference", e);
29 return;
30}
31
32TxHeader? ref2TxHdr = null;
33try
34{
35 ref2TxHdr = await client.SetReference(ref2Key, key, setTxHdr.Id);
36}
37catch (CorruptedDataException e)
38{
39 Console.WriteLine("Failed at setReferenceAt.", e);
40}
41
42await client.Close();Python
1from immudb import ImmudbClient
2
3URL = "localhost:3322" # immudb running on your machine
4LOGIN = "immudb" # Default username
5PASSWORD = "immudb" # Default password
6DB = b"defaultdb" # Default database name (must be in bytes)
7
8def main():
9 client = ImmudbClient(URL)
10 client.login(LOGIN, PASSWORD, database = DB)
11 client.verifiedSet(b'x', b'1')
12 client.verifiedSet(b'y', b'1')
13 retrieved = client.verifiedGet(b'x')
14 print(retrieved.refkey) # Entry reference key (None)
15
16 client.verifiedSetReference(b'x', b'reference1')
17 client.setReference(b'x', b'reference2')
18 client.setReference(b'y', b'reference2')
19 client.verifiedSet(b'y', b'2')
20
21 retrieved = client.verifiedGet(b'reference1')
22 print(retrieved.key) # Entry key (b'x')
23 print(retrieved.refkey) # Entry reference key (b'reference1')
24 print(retrieved.verified) # Entry verification status (True)
25
26 retrieved = client.verifiedGet(b'reference2')
27 print(retrieved.key) # Entry key (b'y')
28 print(retrieved.refkey) # Entry reference key (b'reference2')
29 print(retrieved.verified) # Entry verification status (True)
30 print(retrieved.value) # Entry value (b'3')
31
32 retrieved = client.verifiedGet(b'x')
33 print(retrieved.key) # Entry key (b'x')
34 print(retrieved.refkey) # Entry reference key (None)
35 print(retrieved.verified) # Entry verification status (True)
36
37 retrieved = client.get(b'reference2')
38 print(retrieved.key) # Entry key (b'y')
39
40if __name__ == "__main__":
41 main()Node.js
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 const setReq: Parameters.Set = {
15 key: 'firstKey',
16 value: 'firstValue'
17 }
18 await cl.set(setReq)
19
20 const referenceReq: Parameters.SetReference = {
21 key: 'myTag',
22 referencedKey: 'firstKey'
23 }
24 const referenceRes = await cl.setReference(referenceReq)
25 console.log('success: setReference', referenceRes)
26
27 const getReq: Parameters.Get = {
28 key: 'myTag'
29 }
30 const getRes = await cl.get(getReq)
31 console.log('success: get by reference', getRes)
32})()Example with verifications
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 const setReq: Parameters.Set = {
15 key: 'firstKey',
16 value: 'firstValue'
17 }
18 await cl.set(setReq)
19
20 const verifiedReferenceReq: Parameters.SetReference = {
21 key: 'myTag',
22 referencedKey: 'firstKey'
23 }
24 const verifiedReferenceRes = await cl.verifiedSetReference(verifiedReferenceReq)
25 console.log('success: verifiedSetReference', verifiedReferenceRes)
26
27 const getReq: Parameters.Get = {
28 key: 'myTag'
29 }
30 const getRes = await cl.get(getReq)
31 console.log('success: get by reference', getRes)
32})()Others
If you’re using another development language, please refer to the immugw option.
GetReference and VerifiedGetReference#
When reference is resolved with get or verifiedGet in case of multiples equals references the last reference is returned.
Go
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7
8 immudb "github.com/codenotary/immudb/pkg/client"
9)
10
11func main() {
12 opts := immudb.DefaultOptions().
13 WithAddress("localhost").
14 WithPort(3322)
15
16 client := immudb.NewClient().WithOptions(opts)
17 err := client.OpenSession(
18 context.TODO(),
19 []byte(`immudb`),
20 []byte(`immudb`),
21 "defaultdb",
22 )
23 if err != nil {
24 log.Fatal(err)
25 }
26
27 defer client.CloseSession(context.TODO())
28
29 _, err = client.Set(
30 context.TODO(),
31 []byte(`secondKey`),
32 []byte(`secondValue`),
33 )
34 if err != nil {
35 log.Fatal(err)
36 }
37 _, err = client.Set(
38 context.TODO(),
39 []byte(`secondKey`),
40 []byte(`thirdValue`),
41 )
42 if err != nil {
43 log.Fatal(err)
44 }
45 reference, err := client.VerifiedSetReference(
46 context.TODO(),
47 []byte(`myThirdTag`),
48 []byte(`secondKey`),
49 )
50 if err != nil {
51 log.Fatal(err)
52 }
53 fmt.Printf("%v\n", reference)
54
55 thirdItem, err := client.Get(
56 context.TODO(),
57 []byte(`myThirdTag`),
58 )
59 if err != nil {
60 log.Fatal(err)
61 }
62 fmt.Printf("%v\n", thirdItem)
63}Java
1package io.codenotary.immudb.helloworld;
2
3import java.nio.charset.StandardCharsets;
4import java.util.Arrays;
5
6import io.codenotary.immudb4j.Entry;
7import io.codenotary.immudb4j.FileImmuStateHolder;
8import io.codenotary.immudb4j.ImmuClient;
9
10public class App {
11
12 public static void main(String[] args) {
13
14 ImmuClient client = null;
15
16 try {
17
18 FileImmuStateHolder stateHolder = FileImmuStateHolder.newBuilder()
19 .withStatesFolder("./immudb_states")
20 .build();
21
22 client = ImmuClient.newBuilder()
23 .withServerUrl("127.0.0.1")
24 .withServerPort(3322)
25 .withStateHolder(stateHolder)
26 .build();
27
28 client.openSession("defaultdb", "immudb", "immudb");
29
30 byte[] key = "myKey".getBytes(StandardCharsets.UTF_8);
31 byte[] value1 = new byte[] { 1, 2, 3 };
32 byte[] value2 = new byte[] { 4, 5, 6 };
33
34 client.set(key, value1);
35
36 byte[] myRef = "myRef".getBytes(StandardCharsets.UTF_8);
37 client.setReference(myRef, key);
38
39 client.set(key, value2);
40
41 Entry entry = client.get(myRef);
42
43 System.out.format("('%s', '%s')\n", new String(entry.getKey()), Arrays.toString(entry.getValue()));
44
45 client.closeSession();
46
47 } catch (Exception e) {
48 e.printStackTrace();
49 } finally {
50 if (client != null) {
51 try {
52 client.shutdown();
53 } catch (InterruptedException e) {
54 e.printStackTrace();
55 }
56 }
57 }
58
59 }
60
61}Python
1from immudb import ImmudbClient
2
3URL = "localhost:3322" # immudb running on your machine
4LOGIN = "immudb" # Default username
5PASSWORD = "immudb" # Default password
6DB = b"defaultdb" # Default database name (must be in bytes)
7
8def main():
9 client = ImmudbClient(URL)
10 client.login(LOGIN, PASSWORD, database = DB)
11 client.verifiedSet(b'x', b'1')
12 client.verifiedSet(b'y', b'1')
13 retrieved = client.verifiedGet(b'x')
14 print(retrieved.refkey) # Entry reference key (None)
15
16 client.verifiedSetReference(b'x', b'reference1')
17 client.setReference(b'x', b'reference2')
18 client.setReference(b'y', b'reference2')
19 client.verifiedSet(b'y', b'2')
20
21 retrieved = client.verifiedGet(b'reference1')
22 print(retrieved.key) # Entry key (b'x')
23 print(retrieved.refkey) # Entry reference key (b'reference1')
24 print(retrieved.verified) # Entry verification status (True)
25
26 retrieved = client.verifiedGet(b'reference2')
27 print(retrieved.key) # Entry key (b'y')
28 print(retrieved.refkey) # Entry reference key (b'reference2')
29 print(retrieved.verified) # Entry verification status (True)
30 print(retrieved.value) # Entry value (b'3')
31
32 retrieved = client.verifiedGet(b'x')
33 print(retrieved.key) # Entry key (b'x')
34 print(retrieved.refkey) # Entry reference key (None)
35 print(retrieved.verified) # Entry verification status (True)
36
37 retrieved = client.get(b'reference2')
38 print(retrieved.key) # Entry key (b'y')
39
40if __name__ == "__main__":
41 main()Node.js
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 const setReq: Parameters.Set = {
15 key: 'firstKey',
16 value: 'firstValue'
17 }
18 await cl.set(setReq)
19 const setReq1: Parameters.Set = {
20 key: 'secondKey',
21 value: 'secondValue'
22 }
23 await cl.set(setReq1)
24
25 const verifiedReferenceReq: Parameters.SetReference = {
26 key: 'myTag',
27 referencedKey: 'firstKey'
28 }
29 await cl.verifiedSetReference(verifiedReferenceReq)
30 const verifiedReferenceReq1: Parameters.SetReference = {
31 key: 'myTag',
32 referencedKey: 'secondKey'
33 }
34 await cl.verifiedSetReference(verifiedReferenceReq1)
35
36 const getReq: Parameters.Get = {
37 key: 'myTag'
38 }
39 const getSecondItemRes = await cl.get(getReq)
40 console.log('success: get by second reference', getSecondItemRes)
41})().NET
1
2using ImmuDB;
3using ImmuDB.Exceptions;
4using ImmuDB.SQL;
5
6namespace simple_app;
7
8class Program
9{
10 public static async Task Main(string[] args)
11 {
12 var client = new ImmuClient();
13
14 await client.Open("immudb", "immudb","defaultdb");
15 await client.VerifiedSet("mykey", "myvalue");
16 await client.VerifiedSetReference("myreference", "mykey");
17 Entry result = await client.Get("myreference");
18
19 System.Console.WriteLine(result.ToString());
20 }
21}Others
If you’re using another development language, please refer to the immugw option.
Resolving reference with transaction id#
It’s possible to bind a reference to a key on a specific transaction using SetReferenceAt and VerifiedSetReferenceAt
Go
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7
8 immudb "github.com/codenotary/immudb/pkg/client"
9)
10
11func main() {
12 opts := immudb.DefaultOptions().
13 WithAddress("localhost").
14 WithPort(3322)
15
16 client := immudb.NewClient().WithOptions(opts)
17 err := client.OpenSession(
18 context.TODO(),
19 []byte(`immudb`),
20 []byte(`immudb`),
21 "defaultdb",
22 )
23 if err != nil {
24 log.Fatal(err)
25 }
26
27 defer client.CloseSession(context.TODO())
28
29 meta, err := client.Set(
30 context.TODO(),
31 []byte(`secondKey`),
32 []byte(`secondValue`),
33 )
34 if err != nil {
35 log.Fatal(err)
36 }
37 _, err = client.Set(
38 context.TODO(),
39 []byte(`secondKey`),
40 []byte(`thirdValue`),
41 )
42 if err != nil {
43 log.Fatal(err)
44 }
45 reference, err := client.VerifiedSetReferenceAt(
46 context.TODO(),
47 []byte(`myThirdTag`),
48 []byte(`secondKey`),
49 meta.Id,
50 )
51 if err != nil {
52 log.Fatal(err)
53 }
54 fmt.Printf("%v\n", reference)
55
56 thirdItem, err := client.Get(
57 context.TODO(),
58 []byte(`myThirdTag`),
59 )
60 if err != nil {
61 log.Fatal(err)
62 }
63 fmt.Printf("%v\n", thirdItem)
64}Java
1package io.codenotary.immudb.helloworld;
2
3import java.nio.charset.StandardCharsets;
4import java.util.Arrays;
5
6import io.codenotary.immudb4j.Entry;
7import io.codenotary.immudb4j.FileImmuStateHolder;
8import io.codenotary.immudb4j.ImmuClient;
9import io.codenotary.immudb4j.TxHeader;
10
11public class App {
12
13 public static void main(String[] args) {
14
15 ImmuClient client = null;
16
17 try {
18
19 FileImmuStateHolder stateHolder = FileImmuStateHolder.newBuilder()
20 .withStatesFolder("./immudb_states")
21 .build();
22
23 client = ImmuClient.newBuilder()
24 .withServerUrl("127.0.0.1")
25 .withServerPort(3322)
26 .withStateHolder(stateHolder)
27 .build();
28
29 client.openSession("defaultdb", "immudb", "immudb");
30
31 byte[] key = "myKey".getBytes(StandardCharsets.UTF_8);
32 byte[] value1 = new byte[] { 1, 2, 3 };
33 byte[] value2 = new byte[] { 4, 5, 6 };
34
35 TxHeader hdr1 = client.set(key, value1);
36
37 byte[] myRef = "myRef".getBytes(StandardCharsets.UTF_8);
38 client.setReference(myRef, key, hdr1.getId());
39
40 client.set(key, value2);
41
42 Entry entry = client.get(myRef);
43
44 System.out.format("('%s', '%s')\n", new String(entry.getKey()), Arrays.toString(entry.getValue()));
45
46 client.closeSession();
47
48 } catch (Exception e) {
49 e.printStackTrace();
50 } finally {
51 if (client != null) {
52 try {
53 client.shutdown();
54 } catch (InterruptedException e) {
55 e.printStackTrace();
56 }
57 }
58 }
59
60 }
61
62}.NET
1
2var client = new ImmuClient();
3await client.Open("immudb", "immudb", "defaultdb");
4
5byte[] key = Encoding.UTF8.GetBytes("testRef");
6byte[] val = Encoding.UTF8.GetBytes("abc");
7
8TxHeader? setTxHdr = null;
9try
10{
11 setTxHdr = await client.Set(key, val);
12}
13catch (CorruptedDataException e)
14{
15 Console.WriteLine("Failed at set.", e);
16 return;
17}
18
19byte[] ref1Key = Encoding.UTF8.GetBytes("ref1_to_testRef");
20byte[] ref2Key = Encoding.UTF8.GetBytes("ref2_to_testRef");
21
22TxHeader? ref1TxHdr = null;
23try
24{
25 ref1TxHdr = await client.SetReference(ref1Key, key);
26}
27catch (CorruptedDataException e)
28{
29 Console.WriteLine("Failed at SetReference", e);
30 return;
31}
32
33TxHeader? ref2TxHdr = null;
34try
35{
36 ref2TxHdr = await client.SetReference(ref2Key, key, setTxHdr.Id);
37}
38catch (CorruptedDataException e)
39{
40 Console.WriteLine("Failed at SetReference.", e);
41}
42
43await client.Close();Python
This feature is not yet supported or not documented. Do you want to make a feature request or help out? Open an issue on Python sdk github project
Node.js
1import ImmudbClient from 'immudb-node'
2import Parameters from 'immudb-node/types/parameters'
3
4const IMMUDB_HOST = '127.0.0.1'
5const IMMUDB_PORT = '3322'
6const IMMUDB_USER = 'immudb'
7const IMMUDB_PWD = 'immudb'
8
9const cl = new ImmudbClient({ host: IMMUDB_HOST, port: IMMUDB_PORT });
10
11(async () => {
12 await cl.login({ user: IMMUDB_USER, password: IMMUDB_PWD })
13
14 const { id } = await cl.set({ key: 'firstKey', value: 'firstValue' })
15 await cl.set({ key: 'firstKey', value: 'secondValue' })
16
17 const verifiedSetReferenceAtReq: Parameters.VerifiedSetReferenceAt = {
18 key: 'myFirstTag',
19 referencedKey: 'firstKey',
20 attx: id
21 }
22 const verifiedSetReferenceAtRes = await cl.verifiedSetReferenceAt(verifiedSetReferenceAtReq)
23 console.log('success: verifiedSetReferenceAt', verifiedSetReferenceAtRes)
24
25 const getSecondItemRes = await cl.get({ key: 'myFirstTag' })
26 console.log('success: get second item by reference', getSecondItemRes)
27})()Others
If you’re using another development language, please refer to the immugw option.