Skip to content

Commit

Permalink
Merge pull request #29 from codenotary/feat_kv_api_improvements
Browse files Browse the repository at this point in the history
feat(src/main): add new kv and index-related apis
  • Loading branch information
jeroiraz committed Jun 2, 2022
2 parents 12b616d + 3ce6f3a commit d1ccece
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 20 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Expand Up @@ -40,13 +40,13 @@ apply plugin: 'signing'

group = 'io.codenotary'
archivesBaseName = 'immudb4j'
version = '0.9.10.1'
version = '0.9.10.2'

sourceCompatibility = 1.8
targetCompatibility = 1.8

def protocVersion = '3.19.4'
def grpcVersion = '1.43.2'
def grpcVersion = '1.44.1'

protobuf {
protoc {
Expand Down
154 changes: 139 additions & 15 deletions src/main/java/io/codenotary/immudb4j/ImmuClient.java
Expand Up @@ -214,17 +214,17 @@ public Entry get(String key) throws KeyNotFoundException {
}

public Entry get(byte[] key) throws KeyNotFoundException {
return get(key, 0);
return getAtTx(key, 0);
}

public Entry get(String key, long atTx) throws KeyNotFoundException {
return get(Utils.toByteArray(key), atTx);
public Entry getAtTx(String key, long tx) throws KeyNotFoundException {
return getAtTx(Utils.toByteArray(key), tx);
}

public Entry get(byte[] key, long atTx) throws KeyNotFoundException {
public Entry getAtTx(byte[] key, long tx) throws KeyNotFoundException {
final ImmudbProto.KeyRequest req =ImmudbProto.KeyRequest.newBuilder()
.setKey(Utils.toByteString(key))
.setAtTx(atTx)
.setAtTx(tx)
.build();

try {
Expand All @@ -238,6 +238,48 @@ public Entry get(byte[] key, long atTx) throws KeyNotFoundException {
}
}

public Entry getSinceTx(String key, long tx) throws KeyNotFoundException {
return getSinceTx(Utils.toByteArray(key), tx);
}

public Entry getSinceTx(byte[] key, long tx) throws KeyNotFoundException {
final ImmudbProto.KeyRequest req =ImmudbProto.KeyRequest.newBuilder()
.setKey(Utils.toByteString(key))
.setSinceTx(tx)
.build();

try {
return Entry.valueOf(getStub().get(req));
} catch (StatusRuntimeException e) {
if (e.getMessage().contains("key not found")) {
throw new KeyNotFoundException();
}

throw e;
}
}

public Entry getAtRevision(String key, long rev) throws KeyNotFoundException {
return getAtRevision(Utils.toByteArray(key), rev);
}

public Entry getAtRevision(byte[] key, long rev) throws KeyNotFoundException {
final ImmudbProto.KeyRequest req =ImmudbProto.KeyRequest.newBuilder()
.setKey(Utils.toByteString(key))
.setAtRevision(rev)
.build();

try {
return Entry.valueOf(getStub().get(req));
} catch (StatusRuntimeException e) {
if (e.getMessage().contains("key not found")) {
throw new KeyNotFoundException();
}

throw e;
}
}

public List<Entry> getAll(List<String> keys) {
final List<ByteString> keysBS = new ArrayList<>(keys.size());

Expand All @@ -258,27 +300,53 @@ public List<Entry> getAll(List<String> keys) {
}

public Entry verifiedGet(String key) throws KeyNotFoundException, VerificationException {
return verifiedGet(key, 0);
return verifiedGetAtTx(key, 0);
}

public Entry verifiedGet(byte[] key) throws KeyNotFoundException, VerificationException {
return verifiedGet(key, 0);
return verifiedGetAtTx(key, 0);
}

public Entry verifiedGetAtTx(String key, long tx) throws KeyNotFoundException, VerificationException {
return verifiedGetAtTx(Utils.toByteArray(key), tx);
}

public Entry verifiedGet(String key, long atTx) throws KeyNotFoundException, VerificationException {
return verifiedGet(Utils.toByteArray(key), atTx);
public Entry verifiedGetAtTx(byte[] key, long tx) throws KeyNotFoundException, VerificationException {
final ImmudbProto.KeyRequest keyReq = ImmudbProto.KeyRequest.newBuilder()
.setKey(Utils.toByteString(key))
.setAtTx(tx)
.build();

return verifiedGet(keyReq, state());
}

public Entry verifiedGet(byte[] key, long atTx) throws KeyNotFoundException, VerificationException {
return verifiedGet(key, atTx, state());
public Entry verifiedGetSinceTx(String key, long tx) throws KeyNotFoundException, VerificationException {
return verifiedGetSinceTx(Utils.toByteArray(key), tx);
}

public Entry verifiedGet(byte[] key, long atTx, ImmuState state) throws KeyNotFoundException, VerificationException {
public Entry verifiedGetSinceTx(byte[] key, long tx) throws KeyNotFoundException, VerificationException {
final ImmudbProto.KeyRequest keyReq = ImmudbProto.KeyRequest.newBuilder()
.setKey(Utils.toByteString(key))
.setAtTx(atTx)
.setSinceTx(tx)
.build();

return verifiedGet(keyReq, state());
}

public Entry verifiedGetAtRevision(String key, long rev) throws KeyNotFoundException, VerificationException {
return verifiedGetAtRevision(Utils.toByteArray(key), rev);
}

public Entry verifiedGetAtRevision(byte[] key, long rev) throws KeyNotFoundException, VerificationException {
final ImmudbProto.KeyRequest keyReq = ImmudbProto.KeyRequest.newBuilder()
.setKey(Utils.toByteString(key))
.setAtRevision(rev)
.build();

return verifiedGet(keyReq, state());
}

private Entry verifiedGet(ImmudbProto.KeyRequest keyReq, ImmuState state) throws KeyNotFoundException, VerificationException {
final ImmudbProto.VerifiableGetRequest vGetReq = ImmudbProto.VerifiableGetRequest.newBuilder()
.setKeyRequest(keyReq)
.setProveSinceTx(state.txId)
Expand All @@ -296,6 +364,14 @@ public Entry verifiedGet(byte[] key, long atTx, ImmuState state) throws KeyNotFo

final Entry entry = Entry.valueOf(vEntry.getEntry());

if (entry.getReferenceBy() == null && !Arrays.equals(keyReq.getKey().toByteArray(), entry.getKey())) {
throw new RuntimeException("Data is corrupted: entry does not belong to specified key");
}

if (entry.getReferenceBy() != null && !Arrays.equals(keyReq.getKey().toByteArray(), entry.getReferenceBy().getKey())) {
throw new RuntimeException("Data is corrupted: entry does not belong to specified key");
}

if (entry.getMetadata() != null && entry.getMetadata().deleted()) {
throw new RuntimeException("Data is corrupted: entry is marked as deleted");
}
Expand Down Expand Up @@ -355,6 +431,30 @@ public Entry verifiedGet(byte[] key, long atTx, ImmuState state) throws KeyNotFo
return Entry.valueOf(vEntry.getEntry());
}

//
// ========== DELETE ==========
//

public TxHeader delete(String key) throws KeyNotFoundException {
return delete(Utils.toByteArray(key));
}

public TxHeader delete(byte[] key) throws KeyNotFoundException {
try {
final ImmudbProto.DeleteKeysRequest req = ImmudbProto.DeleteKeysRequest.newBuilder()
.addKeys(Utils.toByteString(key))
.build();

return TxHeader.valueOf(getStub().delete(req));
} catch (StatusRuntimeException e) {
if (e.getMessage().contains("key not found")) {
throw new KeyNotFoundException();
}

throw e;
}
}

//
// ========== HISTORY ==========
//
Expand Down Expand Up @@ -407,10 +507,26 @@ public List<Entry> scan(String prefix, String seekKey, long limit, boolean desc)
return scan(Utils.toByteArray(prefix), Utils.toByteArray(seekKey), limit, desc);
}

public List<Entry> scan(String prefix, String seekKey, String endKey, long limit, boolean desc) {
return scan(Utils.toByteArray(prefix), Utils.toByteArray(seekKey), Utils.toByteArray(endKey), limit, desc);
}

public List<Entry> scan(byte[] prefix, byte[] seekKey, long limit, boolean desc) {
return scan(prefix, seekKey, null, limit, desc);
}

public List<Entry> scan(byte[] prefix, byte[] seekKey, byte[] endKey, long limit, boolean desc) {
return scan(prefix, seekKey, endKey, false, false, limit, desc);
}

public List<Entry> scan(byte[] prefix, byte[] seekKey, byte[] endKey, boolean inclusiveSeek, boolean inclusiveEnd,
long limit, boolean desc) {
final ImmudbProto.ScanRequest req = ScanRequest.newBuilder()
.setPrefix(Utils.toByteString(prefix))
.setSeekKey(Utils.toByteString(seekKey))
.setEndKey(Utils.toByteString(endKey))
.setInclusiveSeek(inclusiveSeek)
.setInclusiveEnd(inclusiveEnd)
.setLimit(limit)
.setDesc(desc)
.build();
Expand Down Expand Up @@ -928,11 +1044,19 @@ public void changePassword(String user, String oldPassword, String newPassword)
}

//
// ========== USER MGMT ==========
// ========== INDEX MGMT ==========
//

public void flushIndex(float cleanupPercentage, boolean synced) {
ImmudbProto.FlushIndexRequest req = ImmudbProto.FlushIndexRequest.newBuilder()
.setCleanupPercentage(cleanupPercentage)
.setSynced(synced)
.build();

getStub().flushIndex(req);
}

public void compactIndex() {
//noinspection ResultOfMethodCallIgnored
getStub().compactIndex(Empty.getDefaultInstance());
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/proto/schema.proto
Expand Up @@ -159,11 +159,14 @@ message ZEntries {

message ScanRequest {
bytes seekKey = 1;
bytes endKey = 7;
bytes prefix = 2;
bool desc = 3;
uint64 limit = 4;
uint64 sinceTx = 5;
bool noWait = 6;
bool inclusiveSeek = 8;
bool inclusiveEnd = 9;
}

message KeyPrefix {
Expand Down Expand Up @@ -271,6 +274,7 @@ message KeyRequest {
uint64 atTx = 2;
uint64 sinceTx = 3;
bool noWait = 4;
int64 atRevision = 5;
}

message KeyListRequest {
Expand Down
25 changes: 23 additions & 2 deletions src/test/java/io/codenotary/immudb4j/SetAndGetTest.java
Expand Up @@ -16,6 +16,7 @@
package io.codenotary.immudb4j;

import io.codenotary.immudb4j.exceptions.CorruptedDataException;
import io.codenotary.immudb4j.exceptions.KeyNotFoundException;
import org.testng.Assert;
import org.testng.annotations.Test;

Expand All @@ -29,7 +30,7 @@ public void t1() {
immuClient.login("immudb", "immudb");
immuClient.useDatabase("defaultdb");

byte[] key = "key1".getBytes(StandardCharsets.UTF_8);
String key = "key1";
byte[] val = new byte[]{1, 2, 3, 4, 5};

TxHeader txHdr = null;
Expand All @@ -44,10 +45,30 @@ public void t1() {
Assert.assertNotNull(entry1);
Assert.assertEquals(entry1.getValue(), val);

Entry entry1At = immuClient.get(key, txHdr.id);
Entry entry1At = immuClient.getAtTx(key, txHdr.id);
Assert.assertNotNull(entry1At);
Assert.assertEquals(entry1At.getValue(), val);

immuClient.delete(key);

try {
immuClient.get(key);
Assert.fail("key not found exception expected");
} catch (KeyNotFoundException _) {
// expected
} catch (Exception _) {
Assert.fail("key not found exception expected");
}

try {
immuClient.delete(key);
Assert.fail("key not found exception expected");
} catch (KeyNotFoundException _) {
// expected
} catch (Exception _) {
Assert.fail("key not found exception expected");
}

immuClient.logout();
}

Expand Down
Expand Up @@ -79,7 +79,7 @@ public void t2() {

// verifiedGetAt
try {
vEntry = immuClient.verifiedGet(key, vEntry.getTx());
vEntry = immuClient.verifiedGetAtTx(key, vEntry.getTx());
} catch (VerificationException e) {
Assert.fail("Failed at verifiedGetAt. Cause: " + e.getMessage(), e);
}
Expand Down

0 comments on commit d1ccece

Please sign in to comment.