fix: add --meta filtering support to client/server list mode
Plumb metadata filter from client CLI through the HTTP API to the server's data_service.list_items(). The server accepts a JSON-encoded meta query parameter where null values mean 'key exists' and string values mean 'exact match'. Also fix LZ4 compression round-trip for client mode: - Explicit flush FrameEncoder before drop to avoid sending only the frame header when compress=false - Send _client_compression metadata so client knows actual compression on retrieval (server records compression=None when compress=false) - Use FrameDecoder (frame format) instead of decompress_size_prepended (size-prepended format) to match server storage format
This commit is contained in:
@@ -23,14 +23,14 @@ pub fn mode(
|
||||
ids[0]
|
||||
} else if !tags.is_empty() {
|
||||
// Find item by tags
|
||||
let items = client.list_items(tags, "newest", 0, 1)?;
|
||||
let items = client.list_items(tags, "newest", 0, 1, &std::collections::HashMap::new())?;
|
||||
if items.is_empty() {
|
||||
return Err(anyhow::anyhow!("No items found matching tags: {:?}", tags));
|
||||
}
|
||||
items[0].id
|
||||
} else {
|
||||
// Get latest item
|
||||
let items = client.list_items(&[], "newest", 0, 1)?;
|
||||
let items = client.list_items(&[], "newest", 0, 1, &std::collections::HashMap::new())?;
|
||||
if items.is_empty() {
|
||||
return Err(anyhow::anyhow!("No items found"));
|
||||
}
|
||||
@@ -60,8 +60,17 @@ pub fn mode(
|
||||
}
|
||||
}
|
||||
|
||||
// Decompress locally
|
||||
let compression_type = CompressionType::from_str(&compression).unwrap_or(CompressionType::None);
|
||||
// Decompress locally.
|
||||
// Prefer _client_compression metadata (set by client save) over the server-reported
|
||||
// compression header, because when compress=false the server stores compressed bytes
|
||||
// but records compression=None.
|
||||
let effective_compression = item_info
|
||||
.metadata
|
||||
.get("_client_compression")
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or(&compression);
|
||||
let compression_type =
|
||||
CompressionType::from_str(effective_compression).unwrap_or(CompressionType::None);
|
||||
|
||||
let decompressed = match compression_type {
|
||||
CompressionType::GZip => {
|
||||
@@ -71,8 +80,13 @@ pub fn mode(
|
||||
decoder.read_to_end(&mut content)?;
|
||||
content
|
||||
}
|
||||
CompressionType::LZ4 => lz4_flex::decompress_size_prepended(&raw_bytes)
|
||||
.map_err(|e| anyhow::anyhow!("LZ4 decompression failed: {}", e))?,
|
||||
CompressionType::LZ4 => {
|
||||
use lz4_flex::frame::FrameDecoder;
|
||||
let mut decoder = FrameDecoder::new(&raw_bytes[..]);
|
||||
let mut content = Vec::new();
|
||||
decoder.read_to_end(&mut content)?;
|
||||
content
|
||||
}
|
||||
_ => raw_bytes,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user