|
1 | 1 | package org.hypertrace.core.documentstore.postgres; |
2 | 2 |
|
3 | | -import com.fasterxml.jackson.databind.JsonNode; |
4 | | -import com.fasterxml.jackson.databind.ObjectMapper; |
5 | 3 | import java.io.IOException; |
6 | | -import java.sql.PreparedStatement; |
7 | | -import java.sql.ResultSet; |
8 | | -import java.sql.SQLException; |
9 | | -import java.util.ArrayList; |
10 | | -import java.util.Iterator; |
11 | 4 | import java.util.List; |
12 | 5 | import java.util.Map; |
13 | 6 | import java.util.Optional; |
14 | 7 | import java.util.Set; |
15 | | -import java.util.stream.Collectors; |
16 | 8 | import org.hypertrace.core.documentstore.BulkArrayValueUpdateRequest; |
17 | 9 | import org.hypertrace.core.documentstore.BulkDeleteResult; |
18 | 10 | import org.hypertrace.core.documentstore.BulkUpdateRequest; |
|
26 | 18 | import org.hypertrace.core.documentstore.model.options.QueryOptions; |
27 | 19 | import org.hypertrace.core.documentstore.model.options.UpdateOptions; |
28 | 20 | import org.hypertrace.core.documentstore.model.subdoc.SubDocumentUpdate; |
29 | | -import org.hypertrace.core.documentstore.postgres.model.PostgresColumnMetadata; |
30 | 21 | import org.hypertrace.core.documentstore.postgres.query.v1.PostgresQueryParser; |
31 | 22 | import org.hypertrace.core.documentstore.postgres.query.v1.transformer.FlatPostgresFieldTransformer; |
32 | 23 | import org.hypertrace.core.documentstore.query.Query; |
|
43 | 34 | public class FlatPostgresCollection extends PostgresCollection { |
44 | 35 |
|
45 | 36 | private static final Logger LOGGER = LoggerFactory.getLogger(FlatPostgresCollection.class); |
46 | | - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); |
47 | 37 | private static final String WRITE_NOT_SUPPORTED = |
48 | 38 | "Write operations are not supported for flat collections yet!"; |
49 | 39 |
|
@@ -97,105 +87,7 @@ public boolean upsert(Key key, Document document) throws IOException { |
97 | 87 |
|
98 | 88 | @Override |
99 | 89 | public Document upsertAndReturn(Key key, Document document) throws IOException { |
100 | | - String tableName = tableIdentifier.getTableName(); |
101 | | - Map<String, PostgresColumnMetadata> schema = schemaRegistry.getSchema(tableName); |
102 | | - |
103 | | - if (schema.isEmpty()) { |
104 | | - throw new IOException("No schema found for table: " + tableName); |
105 | | - } |
106 | | - |
107 | | - try { |
108 | | - JsonNode docJson = OBJECT_MAPPER.readTree(document.toJson()); |
109 | | - List<String> columns = new ArrayList<>(); |
110 | | - List<Object> values = new ArrayList<>(); |
111 | | - |
112 | | - // Extract fields from document that exist in schema |
113 | | - Iterator<Map.Entry<String, JsonNode>> fields = docJson.fields(); |
114 | | - while (fields.hasNext()) { |
115 | | - Map.Entry<String, JsonNode> field = fields.next(); |
116 | | - String colName = field.getKey(); |
117 | | - if (schemaRegistry.getColumnOrRefresh(tableName, colName).isPresent()) { |
118 | | - columns.add(colName); |
119 | | - values.add(extractValue(field.getValue())); |
120 | | - } |
121 | | - } |
122 | | - |
123 | | - if (columns.isEmpty()) { |
124 | | - throw new IOException("No matching columns found in schema for document"); |
125 | | - } |
126 | | - |
127 | | - // Build UPSERT SQL: INSERT ... ON CONFLICT DO UPDATE |
128 | | - String columnList = String.join(", ", columns); |
129 | | - String placeholders = columns.stream().map(c -> "?").collect(Collectors.joining(", ")); |
130 | | - String updateSet = |
131 | | - columns.stream().map(c -> c + " = EXCLUDED." + c).collect(Collectors.joining(", ")); |
132 | | - |
133 | | - // Determine primary key column (assume first column or 'id') |
134 | | - String pkColumn = schema.containsKey("id") ? "id" : columns.get(0); |
135 | | - |
136 | | - String sql = |
137 | | - String.format( |
138 | | - "INSERT INTO %s (%s) VALUES (%s) ON CONFLICT (%s) DO UPDATE SET %s RETURNING *", |
139 | | - tableIdentifier, columnList, placeholders, pkColumn, updateSet); |
140 | | - |
141 | | - try (PreparedStatement ps = client.getConnection().prepareStatement(sql)) { |
142 | | - for (int i = 0; i < values.size(); i++) { |
143 | | - ps.setObject(i + 1, values.get(i)); |
144 | | - } |
145 | | - |
146 | | - try (ResultSet rs = ps.executeQuery()) { |
147 | | - if (rs.next()) { |
148 | | - return resultSetToDocument(rs, columns); |
149 | | - } |
150 | | - } |
151 | | - } |
152 | | - return document; |
153 | | - } catch (SQLException e) { |
154 | | - LOGGER.error("SQLException in upsertAndReturn. key: {} document: {}", key, document, e); |
155 | | - throw new IOException(e); |
156 | | - } |
157 | | - } |
158 | | - |
159 | | - private Object extractValue(JsonNode node) { |
160 | | - if (node.isNull()) { |
161 | | - return null; |
162 | | - } else if (node.isBoolean()) { |
163 | | - return node.booleanValue(); |
164 | | - } else if (node.isInt()) { |
165 | | - return node.intValue(); |
166 | | - } else if (node.isLong()) { |
167 | | - return node.longValue(); |
168 | | - } else if (node.isDouble() || node.isFloat()) { |
169 | | - return node.doubleValue(); |
170 | | - } else if (node.isTextual()) { |
171 | | - return node.textValue(); |
172 | | - } else { |
173 | | - return node.toString(); |
174 | | - } |
175 | | - } |
176 | | - |
177 | | - private Document resultSetToDocument(ResultSet rs, List<String> columns) |
178 | | - throws SQLException, IOException { |
179 | | - StringBuilder json = new StringBuilder("{"); |
180 | | - for (int i = 0; i < columns.size(); i++) { |
181 | | - if (i > 0) { |
182 | | - json.append(","); |
183 | | - } |
184 | | - String col = columns.get(i); |
185 | | - Object value = rs.getObject(col); |
186 | | - json.append("\"").append(col).append("\":"); |
187 | | - if (value == null) { |
188 | | - json.append("null"); |
189 | | - } else if (value instanceof String) { |
190 | | - json.append("\"").append(value).append("\""); |
191 | | - } else if (value instanceof Boolean) { |
192 | | - json.append(value); |
193 | | - } else { |
194 | | - json.append(value); |
195 | | - } |
196 | | - } |
197 | | - json.append("}"); |
198 | | - return new org.hypertrace.core.documentstore.JSONDocument(json.toString()); |
| 90 | + throw new UnsupportedOperationException(WRITE_NOT_SUPPORTED); |
199 | 91 | } |
200 | 92 |
|
201 | 93 | @Override |
|
0 commit comments