Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(src/main): add new kv and index-related apis #29

Merged
merged 1 commit into from Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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