entry : historicalObjects.entrySet()) {
+ DataspaceObject historical = entry.getValue();
+ DataspaceConnection connection = connections.get(historical.getConnectionId());
+ if (connection == null) {
+ result.put(entry.getKey(), new ObjectResolution(
+ historical, null, "MISSING",
+ DataspaceErrorCode.CONNECTION_NOT_FOUND.code(),
+ DataspaceErrorCode.CONNECTION_NOT_FOUND.defaultMessage()));
+ continue;
+ }
+ if (!"ENABLED".equals(connection.getStatus())) {
+ result.put(entry.getKey(), new ObjectResolution(
+ historical, null, "CONNECTION_DISABLED",
+ DataspaceErrorCode.CONNECTION_DISABLED.code(),
+ DataspaceErrorCode.CONNECTION_DISABLED.defaultMessage()));
+ continue;
+ }
+ DataspaceObject current = currentByConnection
+ .getOrDefault(connection.getId(), Map.of())
+ .get(identity(historical, connection));
+ result.put(entry.getKey(), current == null
+ ? new ObjectResolution(
+ historical, null, "MISSING",
+ DataspaceErrorCode.OBJECT_MISSING.code(),
+ "表或视图 “" + historical.getObjectName()
+ + "” 已不在最新元数据中,请刷新或移除该表")
+ : new ObjectResolution(historical, current, "ACTIVE", null, null));
+ }
+ return Map.copyOf(result);
+ }
+
+ /**
+ * 获取连接当前对应的元数据快照 revision。
+ *
+ * 首期元数据快照随 Federation Definition 一同推进;解析逻辑集中在此处,
+ * 后续拆分独立 metadata revision 时无需修改调用方。
+ *
+ * @param connection 物理连接
+ * @return 当前元数据 revision,缺失时返回 0
+ */
+ public long currentMetadataRevision(DataspaceConnection connection) {
+ return connection == null || connection.getDefinitionRevision() == null
+ ? 0L : connection.getDefinitionRevision();
+ }
+
+ /**
+ * 判断对象字段是否存在。
+ *
+ * @param object 元数据对象
+ * @param columnName 字段名
+ * @param databaseType 数据库类型
+ * @return 是否存在
+ */
+ public boolean hasColumn(
+ DataspaceObject object,
+ String columnName,
+ String databaseType) {
+ if (object == null || columnName == null || columnName.isBlank()) {
+ return false;
+ }
+ return columns(object).stream()
+ .map(column -> String.valueOf(column.get("name")))
+ .anyMatch(name -> sameIdentifier(name, columnName.trim(), databaseType));
+ }
+
+ /**
+ * 返回指定字段的元数据。
+ *
+ * @param object 元数据对象
+ * @param columnName 字段名
+ * @param databaseType 数据库类型
+ * @return 字段元数据,不存在时返回空映射
+ */
+ public Map column(
+ DataspaceObject object,
+ String columnName,
+ String databaseType) {
+ if (object == null || columnName == null || columnName.isBlank()) {
+ return Map.of();
+ }
+ return columns(object).stream()
+ .filter(column -> sameIdentifier(
+ String.valueOf(column.get("name")),
+ columnName.trim(),
+ databaseType))
+ .findFirst()
+ .map(column -> java.util.Collections.unmodifiableMap(
+ new LinkedHashMap<>(column)))
+ .orElseGet(Map::of);
+ }
+
+ /**
+ * 安全读取对象字段,兼容历史异常数据中的空字段集合。
+ *
+ * @param object 元数据对象
+ * @return 非空字段集合
+ */
+ private List