做完rust全链路

This commit is contained in:
LIm1tZz7 committed 2026-09-24 21:28:49 +08:00
1 parent e428265357
commit 2a4b446252
34 files changed
+1756 -1031

No files matched your search

+77 -11
View File
@@ -1,5 +1,3 @@
//! 数据字典:记录每张表有哪些列、什么类型。
//! 存在 data/catalog.json。insert 时自动补列,describe 时读回。
use std::collections::BTreeMap;
use std::io;
@@ -9,20 +7,27 @@ use serde::{Deserialize, Serialize};
use crate::protocol::{ColumnType, Row, SchemaColumn};
/// 一张表的 schema。
// 数据字典:记每张表有哪些列、什么类型、多少行。
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
/// 一张表的 schema
pub struct TableSchema {
pub columns: Vec<SchemaColumn>,
#[serde(default)]
pub row_count: u64,
}
/// 整个数据字典。
#[derive(Debug, Default, Serialize, Deserialize)]
/// 数据字典:表名到 schema
pub struct Catalog {
tables: BTreeMap<String, TableSchema>,
}
impl Catalog {
/// 从文件读;文件不存在返回空字典。
// 读取与保存
/// 从文件读;不存在给空字典
pub fn load<P: AsRef<Path>>(path: P) -> io::Result<Self> {
if !path.as_ref().exists() {
return Ok(Catalog::default());
@@ -34,23 +39,25 @@ impl Catalog {
serde_json::from_slice(&bytes).map_err(io::Error::other)
}
/// 写回文件。
/// 写回文件
pub fn save<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
let bytes = serde_json::to_vec_pretty(self).map_err(io::Error::other)?;
std::fs::write(path, bytes)
}
/// 一张表的 schema;没有就返回 None。
// 查询
/// 一张表的 schema
pub fn describe(&self, table: &str) -> Option<&TableSchema> {
self.tables.get(table)
}
/// catalog 里记录的所有表名。
/// 记录过的所有表名
pub fn table_names(&self) -> Vec<String> {
self.tables.keys().cloned().collect()
}
/// 按一行数据补列;已有的列不动。
// 更新
/// 按一行数据补列
pub fn ensure_columns(&mut self, table: &str, row: &Row) {
let entry = self.tables.entry(table.to_string()).or_default();
for (k, v) in row {
@@ -66,15 +73,74 @@ impl Catalog {
}
}
/// 按多行数据补列;replace_all 用。
/// 建表;已存在报错
pub fn create_table(&mut self, table: &str, columns: Vec<SchemaColumn>) -> io::Result<()> {
if self.tables.contains_key(table) {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!("table already exists: {}", table),
));
}
self.tables.insert(
table.to_string(),
TableSchema {
columns,
row_count: 0,
},
);
Ok(())
}
/// 按多行数据补列
pub fn ensure_columns_from_rows(&mut self, table: &str, rows: &[Row]) {
for r in rows {
self.ensure_columns(table, r);
}
}
/// 记一次插入:补列 + 行数 +1
pub fn record_insert(&mut self, table: &str, row: &Row) {
let entry = self.tables.entry(table.to_string()).or_default();
for (k, v) in row {
if entry.columns.iter().any(|c| &c.name == k) {
continue;
}
if let Some(ty) = infer_type(v) {
entry.columns.push(SchemaColumn { name: k.clone(), ty });
}
}
entry.row_count += 1;
}
/// 记一次整表替换:列照补,行数重置
pub fn record_replace_all(&mut self, table: &str, rows: &[Row]) {
let entry = self.tables.entry(table.to_string()).or_default();
for r in rows {
for (k, v) in r {
if entry.columns.iter().any(|c| &c.name == k) {
continue;
}
if let Some(ty) = infer_type(v) {
entry.columns.push(SchemaColumn { name: k.clone(), ty });
}
}
}
entry.row_count = rows.len() as u64;
}
/// 删表
pub fn drop_table(&mut self, table: &str) -> io::Result<()> {
if self.tables.remove(table).is_none() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("unknown table: {}", table),
));
}
Ok(())
}
}
/// 从 JSON 值推断列类型;不支持的类型返回 None。
// 推断
/// 由 JSON 值猜列类型
fn infer_type(v: &serde_json::Value) -> Option<ColumnType> {
match v {
serde_json::Value::Number(_) => Some(ColumnType::Int),