Skip to content

Commit 1ffb9a3

Browse files
Merge branch '268-new-externalpropertytype-jsontonative' into 'dev'
Support new external type JsonToNative #268 See merge request objectbox/objectbox-java!157
2 parents a304b8c + 49b3b2b commit 1ffb9a3

File tree

8 files changed

+63
-11
lines changed

8 files changed

+63
-11
lines changed

objectbox-java-api/src/main/java/io/objectbox/annotation/ExternalPropertyType.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ public enum ExternalPropertyType {
112112
* Representing type: String
113113
*/
114114
JAVASCRIPT,
115+
/**
116+
* A JSON string that is converted to a native "complex" representation in the external system.
117+
* <p>
118+
* For example in MongoDB, embedded/nested documents are converted to a JSON string in ObjectBox and vice versa.
119+
* This allows a quick and simple way to work with non-normalized data from MongoDB in ObjectBox. Alternatively, you
120+
* can use {@link #FLEX_MAP} and {@link #FLEX_VECTOR} to map to language primitives (e.g. maps with string keys; not
121+
* supported by all ObjectBox languages yet).
122+
* <p>
123+
* For MongoDB, (nested) documents and arrays are supported.
124+
* <p>
125+
* Note that this is very close to the internal representation, e.g. the key order is preserved (unlike Flex).
126+
* <p>
127+
* Representing type: String
128+
*/
129+
JSON_TO_NATIVE,
115130
/**
116131
* A vector (array) of Int128 values.
117132
*/

objectbox-java/src/main/java/io/objectbox/model/ExternalPropertyType.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,17 @@ private ExternalPropertyType() { }
100100
* Representing type: String
101101
*/
102102
public static final short JavaScript = 111;
103-
public static final short Reserved5 = 112;
103+
/**
104+
* A JSON string that is converted to a native "complex" representation in the external system.
105+
* For example in MongoDB, embedded/nested documents are converted to a JSON string in ObjectBox and vice versa.
106+
* This allows a quick and simple way to work with non-normalized data from MongoDB in ObjectBox.
107+
* Alternatively, you can use FlexMap and FlexVector to map to language primitives (e.g. maps with string keys;
108+
* not supported by all ObjectBox languages yet).
109+
* For MongoDB, (nested) documents and arrays are supported.
110+
* Note that this is very close to the internal representation, e.g. the key order is preserved (unlike Flex).
111+
* Representing type: String
112+
*/
113+
public static final short JsonToNative = 112;
104114
public static final short Reserved6 = 113;
105115
public static final short Reserved7 = 114;
106116
public static final short Reserved8 = 115;
@@ -110,7 +120,7 @@ private ExternalPropertyType() { }
110120
public static final short Int128Vector = 116;
111121
public static final short Reserved9 = 117;
112122
/**
113-
* A vector (array) of Int128 values
123+
* A vector (array) of UUID values
114124
*/
115125
public static final short UuidVector = 118;
116126
public static final short Reserved10 = 119;
@@ -144,7 +154,7 @@ private ExternalPropertyType() { }
144154
*/
145155
public static final short MongoRegex = 127;
146156

147-
public static final String[] names = { "Unknown", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Int128", "Reserved1", "Uuid", "Decimal128", "UuidString", "UuidV4", "UuidV4String", "FlexMap", "FlexVector", "Json", "Bson", "JavaScript", "Reserved5", "Reserved6", "Reserved7", "Reserved8", "Int128Vector", "Reserved9", "UuidVector", "Reserved10", "Reserved11", "Reserved12", "Reserved13", "MongoId", "MongoIdVector", "MongoTimestamp", "MongoBinary", "MongoRegex", };
157+
public static final String[] names = { "Unknown", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Int128", "Reserved1", "Uuid", "Decimal128", "UuidString", "UuidV4", "UuidV4String", "FlexMap", "FlexVector", "Json", "Bson", "JavaScript", "JsonToNative", "Reserved6", "Reserved7", "Reserved8", "Int128Vector", "Reserved9", "UuidVector", "Reserved10", "Reserved11", "Reserved12", "Reserved13", "MongoId", "MongoIdVector", "MongoTimestamp", "MongoBinary", "MongoRegex", };
148158

149159
public static String name(int e) { return names[e]; }
150160
}

tests/objectbox-java-test/src/main/java/io/objectbox/TestEntity.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,13 @@ public class TestEntity {
7676
private float[] floatArray;
7777
private double[] doubleArray;
7878
private Date date;
79-
// Just smoke testing, also use UUID instead of the default Mongo ID
79+
// Just smoke testing this property type (tests do not use Sync).
80+
// Also use UUID instead of the default MONGO_ID.
8081
@ExternalType(ExternalPropertyType.UUID)
8182
private byte[] externalId;
83+
// Just smoke testing this property type (tests do not use Sync).
84+
@ExternalType(ExternalPropertyType.JSON_TO_NATIVE)
85+
private String externalJsonToNative;
8286

8387
transient boolean noArgsConstructorCalled;
8488

@@ -115,7 +119,8 @@ public TestEntity(long id,
115119
float[] floatArray,
116120
double[] doubleArray,
117121
Date date,
118-
byte[] externalId
122+
byte[] externalId,
123+
String externalJsonToNative
119124
) {
120125
this.id = id;
121126
this.simpleBoolean = simpleBoolean;
@@ -143,6 +148,7 @@ public TestEntity(long id,
143148
this.doubleArray = doubleArray;
144149
this.date = date;
145150
this.externalId = externalId;
151+
this.externalJsonToNative = externalJsonToNative;
146152
if (STRING_VALUE_THROW_IN_CONSTRUCTOR.equals(simpleString)) {
147153
throw new RuntimeException(EXCEPTION_IN_CONSTRUCTOR_MESSAGE);
148154
}
@@ -370,6 +376,15 @@ public void setExternalId(@Nullable byte[] externalId) {
370376
this.externalId = externalId;
371377
}
372378

379+
@Nullable
380+
public String getExternalJsonToNative() {
381+
return externalJsonToNative;
382+
}
383+
384+
public void setExternalJsonToNative(@Nullable String externalJsonToNative) {
385+
this.externalJsonToNative = externalJsonToNative;
386+
}
387+
373388
@Override
374389
public String toString() {
375390
return "TestEntity{" +
@@ -399,6 +414,7 @@ public String toString() {
399414
", doubleArray=" + Arrays.toString(doubleArray) +
400415
", date=" + date +
401416
", externalId=" + Arrays.toString(externalId) +
417+
", externalJsonToString='" + externalJsonToNative + '\'' +
402418
", noArgsConstructorCalled=" + noArgsConstructorCalled +
403419
'}';
404420
}

tests/objectbox-java-test/src/main/java/io/objectbox/TestEntityCursor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public Cursor<TestEntity> createCursor(io.objectbox.Transaction tx, long cursorH
7575
private final static int __ID_doubleArray = TestEntity_.doubleArray.id;
7676
private final static int __ID_date = TestEntity_.date.id;
7777
private final static int __ID_externalId = TestEntity_.externalId.id;
78+
private final static int __ID_externalJsonToNative = TestEntity_.externalJsonToNative.id;
7879

7980
public TestEntityCursor(io.objectbox.Transaction tx, long cursor, BoxStore boxStore) {
8081
super(tx, cursor, TestEntity_.__INSTANCE, boxStore);
@@ -149,6 +150,8 @@ public long put(TestEntity entity) {
149150

150151
String simpleString = entity.getSimpleString();
151152
int __id8 = simpleString != null ? __ID_simpleString : 0;
153+
String externalJsonToNative = entity.getExternalJsonToNative();
154+
int __id26 = externalJsonToNative != null ? __ID_externalJsonToNative : 0;
152155
byte[] simpleByteArray = entity.getSimpleByteArray();
153156
int __id9 = simpleByteArray != null ? __ID_simpleByteArray : 0;
154157
byte[] externalId = entity.getExternalId();
@@ -157,7 +160,7 @@ public long put(TestEntity entity) {
157160
int __id15 = stringObjectMap != null ? __ID_stringObjectMap : 0;
158161

159162
collect430000(cursor, 0, 0,
160-
__id8, simpleString, 0, null,
163+
__id8, simpleString, __id26, externalJsonToNative,
161164
0, null, 0, null,
162165
__id9, simpleByteArray, __id25, externalId,
163166
__id15, __id15 != 0 ? stringObjectMapConverter.convertToDatabaseValue(stringObjectMap) : null);

tests/objectbox-java-test/src/main/java/io/objectbox/TestEntity_.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ public final class TestEntity_ implements EntityInfo<TestEntity> {
130130
public final static io.objectbox.Property<TestEntity> externalId =
131131
new io.objectbox.Property<>(__INSTANCE, 25, 25, byte[].class, "externalId");
132132

133+
public final static io.objectbox.Property<TestEntity> externalJsonToNative =
134+
new io.objectbox.Property<>(__INSTANCE, 26, 27, String.class, "externalJsonToNative");
135+
133136
@SuppressWarnings("unchecked")
134137
public final static io.objectbox.Property<TestEntity>[] __ALL_PROPERTIES = new io.objectbox.Property[]{
135138
id,
@@ -157,7 +160,8 @@ public final class TestEntity_ implements EntityInfo<TestEntity> {
157160
floatArray,
158161
doubleArray,
159162
date,
160-
externalId
163+
externalId,
164+
externalJsonToNative
161165
};
162166

163167
public final static io.objectbox.Property<TestEntity> __ID_PROPERTY = id;

tests/objectbox-java-test/src/test/java/io/objectbox/AbstractObjectBoxTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,14 @@ private void addTestEntity(ModelBuilder modelBuilder, @Nullable IndexType simple
305305
// Date property
306306
entityBuilder.property("date", PropertyType.Date).id(TestEntity_.date.id, ++lastUid);
307307

308-
int lastId = TestEntity_.externalId.id;
309-
310308
// External type property
311309
// Note: there is no way to test external type mapping works here. Instead, verify passing a model with
312310
// externalType(int) works.
313-
entityBuilder.property("externalId", PropertyType.ByteVector).id(lastId, ++lastUid)
311+
entityBuilder.property("externalId", PropertyType.ByteVector).id(TestEntity_.externalId.id, ++lastUid)
314312
.externalType(ExternalPropertyType.Uuid);
313+
int lastId = TestEntity_.externalJsonToNative.id;
314+
entityBuilder.property("externalJsonToNative", PropertyType.String).id(lastId, ++lastUid)
315+
.externalType(ExternalPropertyType.JsonToNative);
315316

316317
entityBuilder.lastPropertyId(lastId, lastUid);
317318
addOptionalFlagsToTestEntity(entityBuilder);
@@ -377,6 +378,7 @@ protected TestEntity createTestEntity(@Nullable String simpleString, int nr) {
377378
// Note: there is no way to test external type mapping works here. Instead, verify that
378379
// there are no side effects for put and get.
379380
entity.setExternalId(simpleByteArray);
381+
entity.setExternalJsonToNative("{\"simpleString\":\"" + simpleString + "\"}");
380382
return entity;
381383
}
382384

tests/objectbox-java-test/src/test/java/io/objectbox/BoxStoreBuilderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ public void maxDataSize() {
302302
DbMaxDataSizeExceededException.class,
303303
() -> getTestEntityBox().put(testEntity2)
304304
);
305-
assertEquals("Exceeded user-set maximum by [bytes]: 592", maxDataExc.getMessage());
305+
assertEquals("Exceeded user-set maximum by [bytes]: 768", maxDataExc.getMessage());
306306

307307
// Remove to get below max data size, then put again.
308308
getTestEntityBox().remove(testEntity1);

tests/objectbox-java-test/src/test/java/io/objectbox/BoxTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public void testPutAndGet() {
9090
assertArrayEquals(new double[]{-valDouble, valDouble}, entity.getDoubleArray(), 0);
9191
assertEquals(new Date(1000 + simpleInt), entity.getDate());
9292
assertArrayEquals(valByteArray, entity.getExternalId());
93+
assertEquals("{\"simpleString\":\"" + simpleString + "\"}", entity.getExternalJsonToNative());
9394
}
9495

9596
@Test
@@ -122,6 +123,7 @@ public void testPutAndGet_defaultOrNullValues() {
122123
assertNull(defaultEntity.getDoubleArray());
123124
assertNull(defaultEntity.getDate());
124125
assertNull(defaultEntity.getExternalId());
126+
assertNull(defaultEntity.getExternalJsonToNative());
125127
}
126128

127129
// Note: There is a similar test using the Cursor API directly (which is deprecated) in CursorTest.

0 commit comments

Comments
 (0)