Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class DataPreviewResponse {
private int limit;
private int offset;
private boolean hasMore;
private List<String> warnings;

/** Default constructor for JSON deserialization. */
public DataPreviewResponse() {}
Expand All @@ -55,6 +56,21 @@ public DataPreviewResponse(
this.hasMore = hasMore;
}

public DataPreviewResponse(
List<DataRow> data,
int total,
int limit,
int offset,
boolean hasMore,
List<String> warnings) {
this.data = data;
this.total = total;
this.limit = limit;
this.offset = offset;
this.hasMore = hasMore;
this.warnings = warnings;
}

public List<DataRow> getData() {
return data;
}
Expand Down Expand Up @@ -95,13 +111,22 @@ public void setHasMore(boolean hasMore) {
this.hasMore = hasMore;
}

public List<String> getWarnings() {
return warnings;
}

public void setWarnings(List<String> warnings) {
this.warnings = warnings;
}

/** Builder class for creating DataPreviewResponse instances. */
public static class Builder {
private List<DataRow> data;
private int total;
private int limit;
private int offset;
private boolean hasMore;
private List<String> warnings;

public Builder data(List<DataRow> data) {
this.data = data;
Expand All @@ -128,8 +153,13 @@ public Builder hasMore(boolean hasMore) {
return this;
}

public Builder warnings(List<String> warnings) {
this.warnings = warnings;
return this;
}

public DataPreviewResponse build() {
return new DataPreviewResponse(data, total, limit, offset, hasMore);
return new DataPreviewResponse(data, total, limit, offset, hasMore, warnings);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@
import java.util.Map;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import org.apache.tsfile.viewer.config.TsFileProperties;
import org.apache.tsfile.viewer.dto.AdvancedCondition;
import org.apache.tsfile.viewer.dto.AggregationType;
Expand All @@ -46,6 +42,9 @@
import org.apache.tsfile.viewer.exception.QueryTimeoutException;
import org.apache.tsfile.viewer.exception.TsFileNotFoundException;
import org.apache.tsfile.viewer.tsfile.TsFileDataReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
* Service for data query operations.
Expand Down Expand Up @@ -155,6 +154,7 @@ public DataPreviewResponse previewData(DataPreviewRequest request)
.limit(limit)
.offset(offset)
.hasMore(hasMore)
.warnings(readResult.getWarnings())
.build();

} catch (java.util.concurrent.TimeoutException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,30 @@ public static class DataReadResult {
private final boolean hasMore;
private final List<String> columnNames;
private final List<String> columnTypes;
private final List<String> warnings;

public DataReadResult(
List<DataRow> data,
int totalRowsRead,
boolean hasMore,
List<String> columnNames,
List<String> columnTypes) {
this(data, totalRowsRead, hasMore, columnNames, columnTypes, new ArrayList<>());
}

public DataReadResult(
List<DataRow> data,
int totalRowsRead,
boolean hasMore,
List<String> columnNames,
List<String> columnTypes,
List<String> warnings) {
this.data = data;
this.totalRowsRead = totalRowsRead;
this.hasMore = hasMore;
this.columnNames = columnNames;
this.columnTypes = columnTypes;
this.warnings = warnings != null ? warnings : new ArrayList<>();
}

public List<DataRow> getData() {
Expand All @@ -130,6 +142,10 @@ public List<String> getColumnNames() {
public List<String> getColumnTypes() {
return columnTypes;
}

public List<String> getWarnings() {
return warnings;
}
}

/** Filter conditions for data reading. */
Expand Down Expand Up @@ -206,6 +222,7 @@ public DataReadResult readDataByTimeRange(
List<DataRow> results = new ArrayList<>();
List<String> colNames = new ArrayList<>();
List<String> colTypes = new ArrayList<>();
List<String> warnings = new ArrayList<>();
int skipped = 0, collected = 0;
boolean hasMore = false;

Expand Down Expand Up @@ -301,10 +318,23 @@ public DataReadResult readDataByTimeRange(
}
} catch (NoTableException | NoMeasurementException | ReadProcessException e) {
logger.warn("Error querying {}: {}", tblName, e.getMessage());
warnings.add("Error querying table '" + tblName + "': " + e.getMessage());
} catch (java.nio.BufferUnderflowException | java.nio.BufferOverflowException e) {
logger.warn(
"Buffer error reading table {}, possibly incompatible file version: {}",
tblName,
e.getMessage());
warnings.add(
"Failed to decode data in table '"
+ tblName
+ "': file may have been created with an incompatible TsFile SDK version");
} catch (RuntimeException e) {
logger.warn("Unexpected error reading table {}: {}", tblName, e.getMessage());
warnings.add("Unexpected error reading table '" + tblName + "': " + e.getMessage());
}
}
}
return new DataReadResult(results, collected, hasMore, colNames, colTypes);
return new DataReadResult(results, collected, hasMore, colNames, colTypes, warnings);
}

/** Reads data using an existing reader with time range filtering and pagination. */
Expand Down Expand Up @@ -390,6 +420,13 @@ public DataReadResult readDataByTimeRange(
}
} catch (NoTableException | NoMeasurementException | ReadProcessException e) {
logger.warn("Error querying {}: {}", tblName, e.getMessage());
} catch (java.nio.BufferUnderflowException | java.nio.BufferOverflowException e) {
logger.warn(
"Buffer error reading table {}, possibly incompatible file version: {}",
tblName,
e.getMessage());
} catch (RuntimeException e) {
logger.warn("Unexpected error reading table {}: {}", tblName, e.getMessage());
}
}
return new DataReadResult(results, collected, hasMore, colNames, colTypes);
Expand Down Expand Up @@ -507,6 +544,13 @@ public DataReadResult readDataWithFilter(File filePath, ReadFilter filter, int l
}
} catch (NoTableException | NoMeasurementException | ReadProcessException e) {
logger.warn("Error querying {}: {}", tblName, e.getMessage());
} catch (java.nio.BufferUnderflowException | java.nio.BufferOverflowException e) {
logger.warn(
"Buffer error reading table {}, possibly incompatible file version: {}",
tblName,
e.getMessage());
} catch (RuntimeException e) {
logger.warn("Unexpected error reading table {}: {}", tblName, e.getMessage());
}
}
}
Expand Down Expand Up @@ -590,6 +634,13 @@ public int streamData(File filePath, ReadFilter filter, Consumer<DataRow> consum
}
} catch (NoTableException | NoMeasurementException | ReadProcessException e) {
logger.warn("Error querying {}: {}", tblName, e.getMessage());
} catch (java.nio.BufferUnderflowException | java.nio.BufferOverflowException e) {
logger.warn(
"Buffer error reading table {}, possibly incompatible file version: {}",
tblName,
e.getMessage());
} catch (RuntimeException e) {
logger.warn("Unexpected error reading table {}: {}", tblName, e.getMessage());
}
}
}
Expand Down Expand Up @@ -669,6 +720,13 @@ public DataReadResult readDataByTimestamps(File filePath, List<Long> timestamps)
}
} catch (NoTableException | NoMeasurementException | ReadProcessException e) {
logger.warn("Error querying {}: {}", tblName, e.getMessage());
} catch (java.nio.BufferUnderflowException | java.nio.BufferOverflowException e) {
logger.warn(
"Buffer error reading table {}, possibly incompatible file version: {}",
tblName,
e.getMessage());
} catch (RuntimeException e) {
logger.warn("Unexpected error reading table {}: {}", tblName, e.getMessage());
}
}
}
Expand Down Expand Up @@ -716,6 +774,12 @@ public long countRows(File filePath, Long startTime, Long endTime) throws IOExce
while (rs.next()) total++;
} catch (NoTableException | NoMeasurementException | ReadProcessException e) {
logger.warn("Error counting: {}", e.getMessage());
} catch (java.nio.BufferUnderflowException | java.nio.BufferOverflowException e) {
logger.warn(
"Buffer error counting rows in table {}: {}", ts.getTableName(), e.getMessage());
} catch (RuntimeException e) {
logger.warn(
"Unexpected error counting rows in table {}: {}", ts.getTableName(), e.getMessage());
}
}
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/api/tsfile/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export interface DataPreviewResponse {
limit: number;
offset: number;
hasMore: boolean;
warnings?: string[];
}

// Table Model Query Types
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
"pages": "pages",
"moreAvailable": "More data available",
"noDataFound": "No data found",
"dataReadWarning": "Some data could not be read",
"enterDevices": "Enter device names (comma-separated)",
"enterMeasurements": "Enter measurement names (comma-separated)",
"advancedFilter": "Advanced Filter",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
"pages": "页",
"moreAvailable": "还有更多数据",
"noDataFound": "未找到数据",
"dataReadWarning": "部分数据无法读取",
"enterDevices": "输入设备名称(逗号分隔)",
"enterMeasurements": "输入测点名称(逗号分隔)",
"advancedFilter": "高级筛选",
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/views/tsfile/data-preview/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const currentLimit = ref(100);
const hasMore = ref(false);
const loading = ref(false);
const error = ref<string | null>(null);
const warnings = ref<string[]>([]);
const currentFilters = ref<Record<string, unknown>>({});
const metadata = ref<TSFileMetadata | null>(null);
const metaError = ref<string | null>(null);
Expand Down Expand Up @@ -115,6 +116,7 @@ async function loadData(filters: Record<string, unknown>) {
currentOffset.value = response.offset;
currentLimit.value = response.limit;
hasMore.value = response.hasMore;
warnings.value = response.warnings ?? [];
} catch (e: unknown) {
error.value = e instanceof Error ? e.message : "Failed to load data";
} finally {
Expand Down Expand Up @@ -217,6 +219,19 @@ function goToQuickScan() {
@change="handleFilterChange"
/>
</div>
<Alert
v-if="warnings.length > 0"
type="warning"
show-icon
:message="t('tsfile.data.dataReadWarning')"
class="mt-3 flex-shrink-0"
>
<template #description>
<ul class="m-0 pl-4">
<li v-for="(w, i) in warnings" :key="i">{{ w }}</li>
</ul>
</template>
</Alert>
<div class="flex-1 mt-3 min-h-0">
<DataTable
:data="dataRows"
Expand Down