Skip to content

Commit 9d7f1bd

Browse files
authored
feat: Resolve CQId, add CQIds to MemDB plugin (#95)
Fixes #92
1 parent b2dfcd8 commit 9d7f1bd

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

Diff for: lib/src/main/java/io/cloudquery/helper/ArrowHelper.java

+4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ public class ArrowHelper {
5959

6060
private static void setVectorData(FieldVector vector, Object data) {
6161
vector.allocateNew();
62+
if (data == null) {
63+
vector.setNull(0);
64+
return;
65+
}
6266
if (vector instanceof BigIntVector bigIntVector) {
6367
bigIntVector.set(0, (long) data);
6468
return;

Diff for: lib/src/main/java/io/cloudquery/memdb/MemDB.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,10 @@ public void close() {
142142
public ClientMeta newClient(String spec, NewClientOptions options) throws Exception {
143143
this.spec = Spec.fromJSON(spec);
144144
this.allTables = getTables();
145-
Tables.transformTables(allTables);
145+
Tables.transformTables(this.allTables);
146+
for (Table table : this.allTables) {
147+
table.addCQIDs();
148+
}
146149
return new MemDBClient();
147150
}
148151
}

Diff for: lib/src/main/java/io/cloudquery/scheduler/Scheduler.java

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public void run() {
5454
table.getResolver().get().resolve(client, parent, schedulerTableOutputStream);
5555

5656
for (Resource resource : schedulerTableOutputStream.getResources()) {
57+
resource.resolveCQId(deterministicCqId);
5758
ByteString record = resource.encode();
5859
Sync.MessageInsert insert =
5960
Sync.MessageInsert.newBuilder().setRecord(record).build();

Diff for: lib/src/main/java/io/cloudquery/schema/Resource.java

+47
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
package io.cloudquery.schema;
22

3+
import com.google.common.base.Objects;
34
import com.google.protobuf.ByteString;
45
import io.cloudquery.helper.ArrowHelper;
56
import io.cloudquery.scalar.Scalar;
67
import io.cloudquery.scalar.ValidationException;
78
import java.io.IOException;
9+
import java.nio.ByteBuffer;
10+
import java.nio.charset.StandardCharsets;
11+
import java.security.MessageDigest;
12+
import java.security.NoSuchAlgorithmException;
813
import java.util.ArrayList;
14+
import java.util.Collections;
915
import java.util.List;
16+
import java.util.UUID;
1017
import lombok.Builder;
1118
import lombok.Getter;
1219
import lombok.NonNull;
@@ -44,4 +51,44 @@ public Scalar<?> get(String columnName) {
4451
public ByteString encode() throws IOException {
4552
return ArrowHelper.encode(this);
4653
}
54+
55+
public void setCqId(UUID value) throws ValidationException {
56+
int index = table.indexOfColumn(Column.CQ_ID_COLUMN.getName());
57+
if (index == -1) {
58+
return;
59+
}
60+
this.data.get(index).set(value);
61+
}
62+
63+
public void resolveCQId(boolean deterministicCqId)
64+
throws ValidationException, NoSuchAlgorithmException {
65+
UUID randomUUID = UUID.randomUUID();
66+
if (!deterministicCqId) {
67+
this.setCqId(randomUUID);
68+
return;
69+
}
70+
71+
// Use an array list to support sorting
72+
ArrayList<String> pks = new ArrayList<>(this.table.primaryKeys());
73+
boolean cqOnlyPK =
74+
pks.stream().allMatch((pk) -> Objects.equal(pk, Column.CQ_ID_COLUMN.getName()));
75+
if (cqOnlyPK) {
76+
this.setCqId(randomUUID);
77+
return;
78+
}
79+
80+
Collections.sort(pks);
81+
// Generate uuid v5 (same as sha-1)
82+
MessageDigest digest = MessageDigest.getInstance("SHA-1");
83+
for (String pk : pks) {
84+
digest.update(pk.getBytes(StandardCharsets.UTF_8));
85+
digest.update(this.get(pk).toString().getBytes(StandardCharsets.UTF_8));
86+
}
87+
88+
ByteBuffer byteBuffer = ByteBuffer.wrap(digest.digest());
89+
long mostSig = byteBuffer.getLong();
90+
long leastSig = byteBuffer.getLong();
91+
this.setCqId(new UUID(mostSig, leastSig));
92+
return;
93+
}
4794
}

Diff for: lib/src/test/java/io/cloudquery/schema/ResourceTest.java

+42
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package io.cloudquery.schema;
22

3+
import static org.junit.Assert.assertNotNull;
34
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
45
import static org.junit.jupiter.api.Assertions.assertEquals;
56
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
67

78
import io.cloudquery.scalar.ValidationException;
89
import io.cloudquery.types.UUIDType;
10+
import java.security.NoSuchAlgorithmException;
11+
import java.util.ArrayList;
12+
import java.util.Arrays;
913
import java.util.List;
1014
import java.util.UUID;
1115
import org.apache.arrow.vector.types.pojo.ArrowType;
@@ -41,4 +45,42 @@ public void shouldSetAndGetDataTypes() throws ValidationException {
4145
resource.set(column1.getName(), UUID);
4246
assertEquals(UUID, resource.get(column1.getName()).get());
4347
}
48+
49+
@Test
50+
public void shouldResolveRandomCQId() throws ValidationException, NoSuchAlgorithmException {
51+
Table table = Table.builder().name("test").build();
52+
table.addCQIDs();
53+
54+
Resource resource = Resource.builder().table(table).build();
55+
resource.resolveCQId(false);
56+
57+
assertNotNull(resource.get(Column.CQ_ID_COLUMN.getName()).get());
58+
assertEquals(
59+
UUID.getClass().getName(),
60+
resource.get(Column.CQ_ID_COLUMN.getName()).get().getClass().getName());
61+
}
62+
63+
@Test
64+
public void shouldResolveDeterministicCqId()
65+
throws ValidationException, NoSuchAlgorithmException {
66+
Column column1 =
67+
Column.builder().name("name").primaryKey(true).type(ArrowType.Utf8.INSTANCE).build();
68+
Column column2 =
69+
Column.builder().primaryKey(true).name("id").type(new ArrowType.Int(64, true)).build();
70+
Table table =
71+
Table.builder()
72+
.name("test")
73+
.columns(new ArrayList<Column>(Arrays.asList(column1, column2)))
74+
.build();
75+
table.addCQIDs();
76+
77+
Resource resource = Resource.builder().table(table).build();
78+
resource.set(column1.getName(), "test");
79+
resource.set(column2.getName(), 1000);
80+
resource.resolveCQId(true);
81+
82+
assertEquals(
83+
"a63a6152-e1d8-470f-f118-e5fa4874cb2d",
84+
resource.get(Column.CQ_ID_COLUMN.getName()).toString());
85+
}
4486
}

0 commit comments

Comments
 (0)