diff --git a/src/main/java/picoded/dstack/jsql_json/JsonbUtils.java b/src/main/java/picoded/dstack/jsql_json/JsonbUtils.java index 44266792..f6fca2c5 100644 --- a/src/main/java/picoded/dstack/jsql_json/JsonbUtils.java +++ b/src/main/java/picoded/dstack/jsql_json/JsonbUtils.java @@ -103,8 +103,7 @@ public static MutablePair serializeDataMap(Map i continue; } } else if (v instanceof byte[]) { - // Handling of binary data - binMap.put(k, v); + // Skip binary data in keySet loop; processed below from fullSet } else { // In all other cases, treat it as JSON data // we add it to the jsonMap, if its within the keyset @@ -114,6 +113,17 @@ public static MutablePair serializeDataMap(Map i } } + // Build complete binary map from fullSet to prevent losing existing binary properties during partial updates + for (String k : fullSet) { + if (k.equalsIgnoreCase("_otm") || k.length() > 64) { + continue; + } + Object v = inMap.get(k); + if (v instanceof byte[] && v != null && v != ObjectToken.NULL) { + binMap.put(k, v); + } + } + // Lets do the required conversions String json = ConvertJSON.fromMap(jsonMap); byte[] bin = null; diff --git a/src/main/java/picoded/dstack/jsql_json/PostgresJsonb_DataObjectMap.java b/src/main/java/picoded/dstack/jsql_json/PostgresJsonb_DataObjectMap.java index 38f60c40..41e17837 100755 --- a/src/main/java/picoded/dstack/jsql_json/PostgresJsonb_DataObjectMap.java +++ b/src/main/java/picoded/dstack/jsql_json/PostgresJsonb_DataObjectMap.java @@ -214,17 +214,32 @@ public void DataObjectRemoteDataMap_update(String _oid, Map full // Curent timestamp long now = JSql_DataObjectMapUtil.getCurrentTimestamp(); - // // Ensure GUID is registered - // sqlObj.upsert( // - // dataStorageTable, // - // new String[] { "oID" }, // - // new Object[] { _oid }, // - // new String[] { "uTm", "data", "bData" }, // - // new Object[] { now, dataPair.getLeft(), dataPair.getRight() }, // - // new String[] { "cTm", "eTm" }, // - // new Object[] { now, 0 }, // - // null // The only misc col, is pKy, which is being handled by DB - // ); + // Determine which keys are being deleted/removed (explicitly null or ObjectToken.NULL) + String updateDataSql = dataStorageTable + ".data||EXCLUDED.data"; + Set keysToProcess = keys; + if (keysToProcess == null) { + keysToProcess = fullMap.keySet(); + } + + java.util.List deletedKeys = new java.util.ArrayList<>(); + for (String k : keysToProcess) { + if (k.equalsIgnoreCase("oid") || k.equalsIgnoreCase("_oid") || k.equalsIgnoreCase("_otm")) { + continue; + } + Object v = fullMap.get(k); + if (v == null || v == picoded.core.common.ObjectToken.NULL) { + deletedKeys.add(k); + } + } + + if (!deletedKeys.isEmpty()) { + StringBuilder sb = new StringBuilder(); + sb.append("(").append(updateDataSql).append(")"); + for (String dk : deletedKeys) { + sb.append(" - '").append(dk.replace("'", "''")).append("'"); + } + updateDataSql = sb.toString(); + } // Perform the upsert command sqlObj.update_raw( // @@ -233,7 +248,7 @@ public void DataObjectRemoteDataMap_update(String _oid, Map full "VALUES ( ?, ?, ?, ?, ?::jsonb, ? ) " + // "ON CONFLICT ( oID ) DO UPDATE SET " + // "uTm=EXCLUDED.uTm, " + // - "data=" + dataStorageTable + ".data||EXCLUDED.data, " + // + "data=" + updateDataSql + ", " + // "bData=EXCLUDED.bData", new Object[] { // _oid, now, now, 0, dataPair.getLeft(), dataPair.getRight() // });