Skip to content

Commit 67aec2b

Browse files
committed
JsonTypeInfo annotation
1 parent a6fac68 commit 67aec2b

4 files changed

Lines changed: 309 additions & 2 deletions

File tree

data/semantickernel-data-oracle/src/main/java/com/microsoft/semantickernel/data/jdbc/oracle/OracleVectorStoreQueryProvider.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.util.ArrayList;
5252
import java.util.Collections;
5353
import java.util.List;
54+
import java.util.Map;
5455
import java.util.UUID;
5556
import java.util.logging.Logger;
5657
import java.util.stream.Collectors;
@@ -67,6 +68,8 @@ public class OracleVectorStoreQueryProvider extends JDBCVectorStoreQueryProvider
6768
// This could be common to all query providers
6869
private final ObjectMapper objectMapper;
6970

71+
private final Map<Class<?>, String> annotatedTypeMapping;
72+
7073
private static final Object dbCreationLock = new Object();
7174

7275
private static final Logger logger = Logger.getLogger(OracleVectorStoreQueryProvider.class.getName());
@@ -97,7 +100,8 @@ private OracleVectorStoreQueryProvider(
97100
@Nonnull String prefixForCollectionTables,
98101
int defaultVarcharSize,
99102
@Nonnull StringTypeMapping stringTypeMapping,
100-
ObjectMapper objectMapper) {
103+
ObjectMapper objectMapper,
104+
Map<Class<?>, String> annotatedTypeMapping) {
101105
super(
102106
dataSource,
103107
collectionsTable,
@@ -108,6 +112,7 @@ private OracleVectorStoreQueryProvider(
108112
this.collectionsTable = collectionsTable;
109113
this.objectMapper = objectMapper;
110114
this.objectMapper.registerModule(new JavaTimeModule());
115+
this.annotatedTypeMapping = annotatedTypeMapping;
111116
}
112117

113118
@Override
@@ -569,6 +574,7 @@ public <Record> VectorStoreRecordMapper<Record, ResultSet> getVectorStoreRecordM
569574
.withRecordClass(recordClass)
570575
.withVectorStoreRecordDefinition(vectorStoreRecordDefinition)
571576
.withSupportedDataTypesMapping(getSupportedDataTypes())
577+
.withAnnotatedTypeMapping(annotatedTypeMapping)
572578
.build();
573579
}
574580

@@ -586,6 +592,8 @@ public static class Builder
586592
private StringTypeMapping stringTypeMapping = StringTypeMapping.USE_VARCHAR;
587593
private int defaultVarcharSize = 2000;
588594

595+
private Map<Class<?>, String> annotatedTypeMapping = null;
596+
589597

590598
@SuppressFBWarnings("EI_EXPOSE_REP2")
591599
public Builder withDataSource(DataSource dataSource) {
@@ -619,6 +627,11 @@ public Builder withObjectMapper(
619627
return this;
620628
}
621629

630+
public Builder withAnnotatedTypeMapping(Map<Class<?>, String> annotatedTypeMapping) {
631+
this.annotatedTypeMapping = annotatedTypeMapping;
632+
return this;
633+
}
634+
622635
/**
623636
* Sets the desired String type mapping.
624637
* @param stringTypeMapping the desired String type mapping. The default value is
@@ -644,7 +657,8 @@ public Builder withDefaultVarcharSize (int defaultVarcharSize) {
644657
@Override
645658
public OracleVectorStoreQueryProvider build() {
646659
return new OracleVectorStoreQueryProvider(dataSource, collectionsTable,
647-
prefixForCollectionTables, defaultVarcharSize, stringTypeMapping, objectMapper);
660+
prefixForCollectionTables, defaultVarcharSize, stringTypeMapping, objectMapper,
661+
annotatedTypeMapping);
648662
}
649663
}
650664
}

data/semantickernel-data-oracle/src/main/java/com/microsoft/semantickernel/data/jdbc/oracle/OracleVectorStoreRecordMapper.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
package com.microsoft.semantickernel.data.jdbc.oracle;
33

4+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
45
import com.fasterxml.jackson.databind.JsonNode;
56
import com.fasterxml.jackson.databind.ObjectMapper;
67
import com.fasterxml.jackson.databind.node.ObjectNode;
8+
import com.fasterxml.jackson.databind.node.TextNode;
79
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
810
import com.microsoft.semantickernel.data.vectorstorage.VectorStoreRecordMapper;
911
import com.microsoft.semantickernel.data.vectorstorage.definition.VectorStoreRecordDefinition;
@@ -69,6 +71,7 @@ public static class Builder<Record>
6971
private VectorStoreRecordDefinition vectorStoreRecordDefinition;
7072
private Map<Class<?>, String> supportedDataTypesMapping;
7173
private ObjectMapper objectMapper = new ObjectMapper();
74+
private Map<Class<?>, String> annotatedTypeMapping;
7275

7376
/**
7477
* Sets the record class.
@@ -118,6 +121,11 @@ public Builder<Record> withSupportedDataTypesMapping(
118121
return this;
119122
}
120123

124+
public Builder<Record> withAnnotatedTypeMapping(Map<Class<?>, String> annotatedTypeMapping) {
125+
this.annotatedTypeMapping = annotatedTypeMapping;
126+
return this;
127+
}
128+
121129
/**
122130
* Builds the {@link OracleVectorStoreRecordMapper}.
123131
*
@@ -142,6 +150,14 @@ public OracleVectorStoreRecordMapper<Record> build() {
142150
for (VectorStoreRecordField field : vectorStoreRecordDefinition.getNonVectorFields()) {
143151
Class<?> fieldType = field.getFieldType();
144152

153+
boolean isAnnotated = false;
154+
try {
155+
isAnnotated = recordClass.getDeclaredField(field.getName())
156+
.isAnnotationPresent(JsonTypeInfo.class);
157+
} catch (NoSuchFieldException e) {
158+
// ignore exception, assume the field is not annotated
159+
}
160+
145161
Object value;
146162
switch (supportedDataTypesMapping.get(fieldType)) {
147163
case OracleDataTypesMapping.STRING_CLOB:
@@ -204,6 +220,18 @@ public OracleVectorStoreRecordMapper<Record> build() {
204220
JsonNode genericNode = objectMapper.valueToTree(value);
205221

206222
objectNode.set(field.getEffectiveStorageName(), genericNode);
223+
if (isAnnotated) {
224+
if (annotatedTypeMapping != null && annotatedTypeMapping.containsKey(field.getFieldType())) {
225+
objectNode.set(field.getEffectiveStorageName() + "_type",
226+
TextNode.valueOf(
227+
annotatedTypeMapping.get(field.getFieldType())));
228+
} else {
229+
objectNode.set(field.getEffectiveStorageName() + "_type",
230+
TextNode.valueOf(
231+
field.getFieldType().getName()));
232+
233+
}
234+
}
207235
}
208236
if (options != null && options.isIncludeVectors()) {
209237
for (VectorStoreRecordVectorField field : vectorStoreRecordDefinition.getVectorFields()) {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.microsoft.semantickernel.data.jdbc.oracle;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonSubTypes;
5+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
6+
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
7+
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
8+
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordData;
9+
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordKey;
10+
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordVector;
11+
import com.microsoft.semantickernel.data.vectorstorage.definition.DistanceFunction;
12+
import com.microsoft.semantickernel.data.vectorstorage.definition.IndexKind;
13+
14+
import java.math.BigDecimal;
15+
import java.time.OffsetDateTime;
16+
import java.util.List;
17+
import java.util.UUID;
18+
19+
@JsonIgnoreProperties(ignoreUnknown = true)
20+
public class ClassWithAnnotatedTypes {
21+
22+
private final String id;
23+
24+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.EXTERNAL_PROPERTY , property = "value_type")
25+
@JsonSubTypes({
26+
@JsonSubTypes.Type(value = String.class, name="java.lang.String"),
27+
@JsonSubTypes.Type(value = Boolean.class, name="java.lang.Boolean"),
28+
@JsonSubTypes.Type(value = Byte.class, name="java.lang.Byte"),
29+
@JsonSubTypes.Type(value = Short.class, name="java.lang.Short"),
30+
@JsonSubTypes.Type(value = Integer.class, name="java.lang.Integer"),
31+
@JsonSubTypes.Type(value = Long.class, name="java.lang.Long"),
32+
@JsonSubTypes.Type(value = Float.class, name="java.lang.Float"),
33+
@JsonSubTypes.Type(value = Double.class, name="java.lang.Double"),
34+
@JsonSubTypes.Type(value = BigDecimal.class, name="java.math.BigDecimal"),
35+
@JsonSubTypes.Type(value = OffsetDateTime.class, name="java.time.OffsetDateTime"),
36+
@JsonSubTypes.Type(value = UUID.class, name="java.util.UUID"),
37+
@JsonSubTypes.Type(value = byte[].class, name="byte_array"),
38+
@JsonSubTypes.Type(value = List.class, name="listOfStrings")
39+
})
40+
private Object value;
41+
42+
private final Float[] vectorValue;
43+
44+
45+
public ClassWithAnnotatedTypes() {
46+
this(null, null, null);
47+
};
48+
public ClassWithAnnotatedTypes(String id, Object value, Float[] vectorValue) {
49+
this.id = id;
50+
this.value = value;
51+
this.vectorValue = vectorValue;
52+
}
53+
54+
public String getId() {
55+
return id;
56+
}
57+
58+
public Object getValue() {
59+
return value;
60+
}
61+
62+
public Float[] getVectorValue() {
63+
return vectorValue;
64+
}
65+
}

0 commit comments

Comments
 (0)