Skip to content

Commit 1dc95c1

Browse files
authored
Merge pull request #293 from rashtao/bugfix/arangodb-id
ArangoDB: use _key instead of _id
2 parents 2004c05 + 20815b7 commit 1dc95c1

File tree

13 files changed

+203
-159
lines changed

13 files changed

+203
-159
lines changed

jnosql-arangodb/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<description>The Eclipse JNoSQL layer to ArangoDB</description>
2929

3030
<properties>
31-
<arango.driver>7.7.1</arango.driver>
31+
<arango.driver>7.11.0</arango.driver>
3232
</properties>
3333
<dependencies>
3434
<dependency>
@@ -46,7 +46,7 @@
4646
</dependency>
4747
<dependency>
4848
<groupId>com.arangodb</groupId>
49-
<artifactId>arangodb-java-driver</artifactId>
49+
<artifactId>arangodb-java-driver-shaded</artifactId>
5050
<version>${arango.driver}</version>
5151
</dependency>
5252
</dependencies>

jnosql-arangodb/src/main/java/org/eclipse/jnosql/databases/arangodb/communication/ArangoDBBucketManager.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
* Contributors:
1212
*
1313
* Otavio Santana
14+
* Michele Rastelli
1415
*/
1516
package org.eclipse.jnosql.databases.arangodb.communication;
1617

1718

1819
import com.arangodb.ArangoDB;
19-
import com.arangodb.entity.BaseDocument;
20+
import jakarta.json.Json;
21+
import jakarta.json.JsonObject;
2022
import jakarta.json.bind.Jsonb;
2123
import org.eclipse.jnosql.communication.Value;
2224
import org.eclipse.jnosql.communication.driver.JsonbSupplier;
@@ -41,8 +43,9 @@
4143
public class ArangoDBBucketManager implements BucketManager {
4244

4345

46+
private static final String KEY = "_key";
4447
private static final String VALUE = "_value";
45-
private static final Function<BaseDocument, String> TO_JSON = e -> e.getAttribute(VALUE).toString();
48+
private static final Function<JsonObject, String> TO_JSON = e -> e.getString(VALUE);
4649
private static final Jsonb JSONB = JsonbSupplier.getInstance().get();
4750

4851
private final ArangoDB arangoDB;
@@ -66,14 +69,15 @@ public String name() {
6669
public <K, V> void put(K key, V value) throws NullPointerException {
6770
Objects.requireNonNull(key, "Key is required");
6871
Objects.requireNonNull(value, "value is required");
69-
BaseDocument baseDocument = new BaseDocument();
70-
baseDocument.setKey(key.toString());
71-
baseDocument.addAttribute(VALUE, JSONB.toJson(value));
72+
JsonObject jsonObject = Json.createObjectBuilder()
73+
.add(KEY, key.toString())
74+
.add(VALUE, JSONB.toJson(value))
75+
.build();
7276
if (arangoDB.db(bucketName).collection(namespace).documentExists(key.toString())) {
7377
arangoDB.db(bucketName).collection(namespace).deleteDocument(key.toString());
7478
}
7579
arangoDB.db(bucketName).collection(namespace)
76-
.insertDocument(baseDocument);
80+
.insertDocument(jsonObject);
7781
}
7882

7983
@Override
@@ -91,8 +95,8 @@ public void put(Iterable<KeyValueEntity> keyValueEntities) throws NullPointerEx
9195
@Override
9296
public <K> Optional<Value> get(K key) throws NullPointerException {
9397
Objects.requireNonNull(key, "Key is required");
94-
BaseDocument entity = arangoDB.db(bucketName).collection(namespace)
95-
.getDocument(key.toString(), BaseDocument.class);
98+
JsonObject entity = arangoDB.db(bucketName).collection(namespace)
99+
.getDocument(key.toString(), JsonObject.class);
96100

97101
return ofNullable(entity)
98102
.map(TO_JSON)
@@ -105,7 +109,7 @@ public <K> Iterable<Value> get(Iterable<K> keys) throws NullPointerException {
105109
return stream(keys.spliterator(), false)
106110
.map(Object::toString)
107111
.map(k -> arangoDB.db(bucketName).collection(namespace)
108-
.getDocument(k, BaseDocument.class))
112+
.getDocument(k, JsonObject.class))
109113
.filter(Objects::nonNull)
110114
.map(TO_JSON)
111115
.map(ValueJSON::of)

jnosql-arangodb/src/main/java/org/eclipse/jnosql/databases/arangodb/communication/ArangoDBConfiguration.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,27 @@
1111
* Contributors:
1212
*
1313
* Otavio Santana
14+
* Michele Rastelli
1415
*/
1516
package org.eclipse.jnosql.databases.arangodb.communication;
1617

1718

1819
import com.arangodb.ArangoDB;
1920
import com.arangodb.entity.LoadBalancingStrategy;
21+
import com.arangodb.serde.ArangoSerde;
2022
import org.eclipse.jnosql.communication.Settings;
2123

2224
import static java.util.Objects.requireNonNull;
2325

2426
/**
25-
* The base to configuration both key-value and document on mongoDB.
27+
* The base to configuration both key-value and document on ArangoDB.
2628
* To each configuration set, it will change both builder
2729
* {@link ArangoDB.Builder}
2830
*/
2931
public abstract class ArangoDBConfiguration {
3032

31-
32-
protected ArangoDB.Builder builder = new ArangoDB.Builder();
33+
protected ArangoDB.Builder builder = new ArangoDB.Builder()
34+
.serde(new JsonbSerde());
3335

3436
/**
3537
* Adds a host in the arangodb builder
@@ -54,7 +56,6 @@ public void setLoadBalancingStrategy(LoadBalancingStrategy loadBalancingStrategy
5456
builder.loadBalancingStrategy(loadBalancingStrategy);
5557
}
5658

57-
5859
/**
5960
* set the setTimeout
6061
*
@@ -91,6 +92,21 @@ public void setUseSSL(boolean value) {
9192
builder.useSsl(value);
9293
}
9394

95+
/**
96+
* Set the ArangoDB serde for the user data. Note that the provided
97+
* serde must support serializing and deserializing JsonP types,
98+
* i.e. {@link jakarta.json.JsonValue} and its children.
99+
* By default, the builder is configured to use {@link JsonbSerde};
100+
* this setter allows overriding it, i.e. providing an instance of
101+
* {@link JsonbSerde} that uses a specific {@link jakarta.json.bind.Jsonb}
102+
* instance.
103+
*
104+
* @param serde the serde
105+
*/
106+
public void setSerde(ArangoSerde serde) {
107+
builder.serde(serde);
108+
}
109+
94110
/**
95111
* Defines a new builder to sync ArangoDB
96112
*
@@ -102,12 +118,10 @@ public void syncBuilder(ArangoDB.Builder builder) throws NullPointerException {
102118
this.builder = builder;
103119
}
104120

105-
106121
protected ArangoDB getArangoDB(Settings settings) {
107122
ArangoDBBuilderSync aragonDB = new ArangoDBBuilderSync(builder);
108123
ArangoDBBuilders.load(settings, aragonDB);
109124
return aragonDB.build();
110125
}
111126

112-
113127
}

jnosql-arangodb/src/main/java/org/eclipse/jnosql/databases/arangodb/communication/ArangoDBUtil.java

Lines changed: 82 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,33 @@
1111
* Contributors:
1212
*
1313
* Otavio Santana
14+
* Michele Rastelli
1415
*/
1516
package org.eclipse.jnosql.databases.arangodb.communication;
1617

1718

1819
import com.arangodb.ArangoDB;
19-
import com.arangodb.entity.BaseDocument;
2020
import com.arangodb.entity.CollectionEntity;
21-
import org.eclipse.jnosql.communication.Value;
21+
import jakarta.json.Json;
22+
import jakarta.json.JsonArray;
23+
import jakarta.json.JsonArrayBuilder;
24+
import jakarta.json.JsonNumber;
25+
import jakarta.json.JsonObject;
26+
import jakarta.json.JsonObjectBuilder;
27+
import jakarta.json.JsonString;
28+
import jakarta.json.JsonValue;
2229
import org.eclipse.jnosql.communication.ValueUtil;
2330
import org.eclipse.jnosql.communication.semistructured.CommunicationEntity;
2431
import org.eclipse.jnosql.communication.semistructured.Element;
2532

26-
import java.util.ArrayList;
2733
import java.util.Collection;
28-
import java.util.HashMap;
34+
import java.util.Collections;
2935
import java.util.List;
3036
import java.util.Map;
3137
import java.util.Objects;
32-
import java.util.function.Function;
3338
import java.util.logging.Level;
3439
import java.util.logging.Logger;
3540

36-
import static java.util.Collections.singletonMap;
3741
import static java.util.stream.Collectors.toList;
3842
import static java.util.stream.StreamSupport.stream;
3943

@@ -47,9 +51,6 @@ public final class ArangoDBUtil {
4751
public static final String REV = "_rev";
4852
private static final Logger LOGGER = Logger.getLogger(ArangoDBUtil.class.getName());
4953

50-
private static final Function<Map.Entry<?, ?>, Element> ENTRY_DOCUMENT = entry ->
51-
Element.of(entry.getKey().toString(), entry.getValue());
52-
5354
private ArangoDBUtil() {
5455
}
5556

@@ -71,101 +72,100 @@ public static void checkCollection(String bucketName, ArangoDB arangoDB, String
7172
List<String> collections = arangoDB.db(bucketName)
7273
.getCollections().stream()
7374
.map(CollectionEntity::getName)
74-
.collect(toList());
75+
.toList();
7576
if (!collections.contains(namespace)) {
7677
arangoDB.db(bucketName).createCollection(namespace);
7778
}
7879
}
7980

81+
static CommunicationEntity toEntity(JsonObject jsonObject) {
82+
List<Element> documents = toDocuments(jsonObject);
8083

81-
static CommunicationEntity toEntity(BaseDocument document) {
82-
Map<String, Object> properties = document.getProperties();
83-
List<Element> documents = properties.keySet().stream()
84-
.map(k -> toDocument(k, properties))
85-
.collect(toList());
86-
87-
documents.add(Element.of(KEY, document.getKey()));
88-
documents.add(Element.of(ID, document.getId()));
89-
documents.add(Element.of(REV, document.getRevision()));
90-
String collection = document.getId().split("/")[0];
84+
String id = jsonObject.getString(ID);
85+
documents.add(Element.of(KEY, jsonObject.getString(KEY)));
86+
documents.add(Element.of(ID, id));
87+
documents.add(Element.of(REV, jsonObject.getString(REV)));
88+
String collection = id.split("/")[0];
9189
return CommunicationEntity.of(collection, documents);
9290
}
9391

94-
static BaseDocument getBaseDocument(CommunicationEntity entity) {
95-
Map<String, Object> map = new HashMap<>();
96-
for (Element document : entity.elements()) {
97-
if(KEY.equals(document.name()) && Objects.isNull(document.get())) {
98-
continue;
99-
}
100-
map.put(document.name(), convert(document.value()));
101-
}
102-
return new BaseDocument(map);
92+
static JsonObject toJsonObject(CommunicationEntity entity) {
93+
return toJsonObject(entity.elements());
10394
}
10495

105-
private static Element toDocument(String key, Map<String, Object> properties) {
106-
Object value = properties.get(key);
107-
if (value instanceof Map map) {
108-
return Element.of(key, map.keySet()
109-
.stream().map(k -> toDocument(k.toString(), map))
110-
.collect(toList()));
111-
}
112-
if (isADocumentIterable(value)) {
113-
List<List<Element>> documents = new ArrayList<>();
114-
for (Object object : Iterable.class.cast(value)) {
115-
Map<?, ?> map = Map.class.cast(object);
116-
documents.add(map.entrySet().stream().map(ENTRY_DOCUMENT).collect(toList()));
117-
}
118-
return Element.of(key, documents);
119-
120-
}
121-
return Element.of(key, value);
96+
private static List<Element> toDocuments(JsonObject object) {
97+
return object.entrySet().stream()
98+
.map(it -> Element.of(it.getKey(), toDocuments(it.getValue())))
99+
.collect(toList());
122100
}
123101

124-
private static boolean isADocumentIterable(Object value) {
125-
return Iterable.class.isInstance(value) &&
126-
stream(Iterable.class.cast(value).spliterator(), false)
127-
.allMatch(Map.class::isInstance);
102+
private static List<?> toDocuments(JsonArray array) {
103+
return array.stream()
104+
.map(ArangoDBUtil::toDocuments)
105+
.toList();
128106
}
129107

130-
private static Object convert(Value value) {
131-
Object val = ValueUtil.convert(value);
132-
133-
if (Element.class.isInstance(val)) {
134-
Element document = Element.class.cast(val);
135-
return singletonMap(document.name(), convert(document.value()));
136-
}
137-
if (isSudDocument(val)) {
138-
return getMap(val);
139-
}
140-
if (isSudDocumentList(val)) {
141-
return stream(Iterable.class.cast(val).spliterator(), false)
142-
.map(ArangoDBUtil::getMap).collect(toList());
143-
}
144-
return val;
108+
private static Object toDocuments(JsonValue value) {
109+
return switch (value.getValueType()) {
110+
case OBJECT -> toDocuments(value.asJsonObject());
111+
case ARRAY -> toDocuments(value.asJsonArray());
112+
case STRING -> ((JsonString) value).getString();
113+
case NUMBER -> ((JsonNumber) value).numberValue();
114+
case TRUE -> true;
115+
case FALSE -> false;
116+
case NULL -> null;
117+
};
145118
}
146119

147-
private static Object getMap(Object val) {
148-
Iterable<?> iterable = Iterable.class.cast(val);
149-
Map<Object, Object> map = new HashMap<>();
150-
for (Object item : iterable) {
151-
var document = cast(item);
152-
map.put(document.name(), document.get());
120+
private static JsonObject toJsonObject(Iterable<Element> elements) {
121+
JsonObjectBuilder builder = Json.createObjectBuilder();
122+
for (Element document : elements) {
123+
if (KEY.equals(document.name()) && Objects.isNull(document.get())) {
124+
continue;
125+
}
126+
Object value = ValueUtil.convert(document.value());
127+
builder.add(document.name(), toJsonValue(value));
153128
}
154-
return map;
129+
return builder.build();
155130
}
156131

157-
private static boolean isSudDocumentList(Object value) {
158-
return value instanceof Iterable && stream(Iterable.class.cast(value).spliterator(), false).
159-
allMatch(d -> d instanceof Iterable && isSudDocument(d));
160-
}
161-
162-
private static boolean isSudDocument(Object value) {
163-
return value instanceof Iterable && stream(Iterable.class.cast(value).spliterator(), false).
164-
allMatch(Element.class::isInstance);
132+
@SuppressWarnings("unchecked")
133+
private static JsonValue toJsonValue(Object value) {
134+
if (value instanceof Element document) {
135+
return toJsonObject(Collections.singletonList(document));
136+
} else if (value instanceof Iterable<?> iterable) {
137+
if (isSubDocument(iterable)) {
138+
return toJsonObject((Iterable<Element>) iterable);
139+
} else {
140+
JsonArrayBuilder builder = Json.createArrayBuilder();
141+
for (Object it : iterable) {
142+
builder.add(toJsonValue(it));
143+
}
144+
return builder.build();
145+
}
146+
} else if (value instanceof Map<?, ?> map) {
147+
JsonObjectBuilder builder = Json.createObjectBuilder();
148+
for (Map.Entry<?, ?> e : map.entrySet()) {
149+
builder.add((String) e.getKey(), toJsonValue(e.getValue()));
150+
}
151+
return builder.build();
152+
} else if (Objects.isNull(value)) {
153+
return JsonValue.NULL;
154+
} else if (value instanceof Number number) {
155+
return Json.createValue(number);
156+
} else if (value instanceof String string) {
157+
return Json.createValue(string);
158+
} else if (Boolean.TRUE.equals(value)) {
159+
return JsonValue.TRUE;
160+
} else if (Boolean.FALSE.equals(value)) {
161+
return JsonValue.FALSE;
162+
} else {
163+
throw new IllegalArgumentException("Unsupported type: " + value.getClass());
164+
}
165165
}
166166

167-
private static Element cast(Object document) {
168-
return Element.class.cast(document);
167+
private static boolean isSubDocument(Iterable<?> iterable) {
168+
return stream(iterable.spliterator(), false).allMatch(Element.class::isInstance);
169169
}
170170

171171
}

0 commit comments

Comments
 (0)