Files
ChuSQL/chusql-storage/src/protocol.rs
T

138 lines
3.3 KiB
Rust
Raw Normal View History

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
2026-09-24 21:28:49 +08:00
// 协议:Haskell 与 Rust 之间的请求 / 响应类型。
2026-09-24 21:28:49 +08:00
/// 一行:列名到 JSON 值
pub type Row = HashMap<String, serde_json::Value>;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
2026-09-24 21:28:49 +08:00
/// 列类型(对应 Haskell 的 TInt / TStr / TBool)
pub enum ColumnType {
Int,
Str,
Bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2026-09-24 21:28:49 +08:00
/// 一列的 schema
pub struct SchemaColumn {
pub name: String,
pub ty: ColumnType,
}
2026-09-25 14:21:55 +08:00
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
/// 一列的统计(随数据字典一起走)
pub struct ColumnStatWire {
pub name: String,
/// 不同值个数;`capped` 为真时它只是下界
pub distinct: u64,
#[serde(default)]
pub capped: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
/// 一条索引定义
pub struct IndexWire {
pub column: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "method", rename_all = "snake_case")]
2026-09-24 21:28:49 +08:00
/// 请求:method 字段决定类型
pub enum Request {
Ping,
2026-09-25 14:21:55 +08:00
Scan {
table: String,
},
/// 插一行;要不要写索引由表上的索引决定(调用方不用管)
Insert {
table: String,
row: Row,
},
2026-09-25 14:21:55 +08:00
/// 一批行一起插:一次 WAL、一次 fsync
InsertBatch {
table: String,
rows: Vec<Row>,
},
/// 按 id 批量删行
DeleteKeys {
table: String,
keys: Vec<i64>,
},
/// 按某一列的索引取一行(列名默认 "id",兼容老客户端)
LookupByIndex {
table: String,
#[serde(default = "default_id_column")]
column: String,
key: i64,
},
ReplaceAll {
table: String,
rows: Vec<Row>,
},
ListTables,
2026-09-25 14:21:55 +08:00
DescribeTable {
table: String,
},
2026-09-24 21:28:49 +08:00
CreateTable {
table: String,
columns: Vec<SchemaColumn>,
},
2026-09-25 14:21:55 +08:00
DropTable {
table: String,
},
ListCatalog,
/// 给某一列建索引(要求这一列整数取值唯一)
CreateIndex {
table: String,
column: String,
},
/// 去掉某一列的索引
DropIndex {
table: String,
column: String,
},
}
/// 没写 column 时按 `id` 算
fn default_id_column() -> String {
"id".to_string()
}
#[derive(Debug, Serialize, Deserialize)]
2026-09-25 14:21:55 +08:00
#[serde(tag = "status", rename_all = "snake_case")]
2026-09-24 21:28:49 +08:00
/// 响应:status 字段决定类型
pub enum Response {
Pong,
Rows { rows: Vec<Row> },
Tables { tables: Vec<String> },
2026-09-24 21:28:49 +08:00
Schema {
2026-09-25 14:21:55 +08:00
table: String,
2026-09-24 21:28:49 +08:00
columns: Vec<SchemaColumn>,
#[serde(default)]
row_count: u64,
2026-09-25 14:21:55 +08:00
#[serde(default)]
indexes: Vec<IndexWire>,
#[serde(default)]
stats: Vec<ColumnStatWire>,
2026-09-24 21:28:49 +08:00
},
2026-09-25 14:21:55 +08:00
/// 这一列没有索引 —— 调用方应该退回全表扫描
NoIndex,
Ok,
Error { message: String },
2026-09-24 23:56:07 +08:00
Catalog { schemas: Vec<TableSchemaWire> },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableSchemaWire {
pub table: String,
pub columns: Vec<SchemaColumn>,
#[serde(default)]
pub row_count: u64,
2026-09-25 14:21:55 +08:00
#[serde(default)]
pub indexes: Vec<IndexWire>,
#[serde(default)]
pub stats: Vec<ColumnStatWire>,
}