(cmd: &RespCommand, session: &RespSession, state: &SharedState)
| 347 | } |
| 348 | |
| 349 | async fn handle_keys(cmd: &RespCommand, session: &RespSession, state: &SharedState) -> RespValue { |
| 350 | let pattern = cmd.arg_str(0).unwrap_or("*"); |
| 351 | |
| 352 | let plan = PhysicalPlan::Kv(KvOp::Scan { |
| 353 | collection: session.collection.clone(), |
| 354 | cursor: Vec::new(), |
| 355 | count: 100_000, |
| 356 | filters: Vec::new(), |
| 357 | match_pattern: Some(pattern.to_string()), |
| 358 | sort_keys: Vec::new(), |
| 359 | surrogate_ceiling: None, |
| 360 | }); |
| 361 | |
| 362 | match dispatch_kv(state, session, plan).await { |
| 363 | Ok(resp) if resp.status == Status::Ok => { |
| 364 | let json: serde_json::Value = match sonic_rs::from_slice(&resp.payload) { |
| 365 | Ok(v) => v, |
| 366 | Err(e) => { |
| 367 | tracing::warn!(error = %e, "RESP KEYS: failed to decode KV scan payload"); |
| 368 | return RespValue::err(format!("ERR keys decode failed: {e}")); |
| 369 | } |
| 370 | }; |
| 371 | let entries = match json { |
| 372 | serde_json::Value::Array(arr) => arr, |
| 373 | _ => Vec::new(), |
| 374 | }; |
| 375 | |
| 376 | let keys: Vec<RespValue> = entries |
| 377 | .iter() |
| 378 | .filter_map(|e| { |
| 379 | e.get("key").and_then(|k| k.as_str()).and_then(|b64| { |
| 380 | base64::Engine::decode(&base64::engine::general_purpose::STANDARD, b64) |
| 381 | .ok() |
| 382 | .map(RespValue::bulk) |
| 383 | }) |
| 384 | }) |
| 385 | .collect(); |
| 386 | |
| 387 | RespValue::array(keys) |
| 388 | } |
| 389 | Ok(_) => RespValue::array(vec![]), |
| 390 | Err(e) => RespValue::err(format!("ERR {e}")), |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | // --------------------------------------------------------------------------- |
| 395 | // Info / stats |
no test coverage detected