import json import os from typing import List, Dict, Any class SimpleNoSQL: def __init__(self, db_path: str= "db.json"): self.db_path = db_path if os.path.exists(self.db_path): with open(self.db_path, "r") as f: self.data = json.load(f) else: self.data = [] def save(self): with open(self.db_path, "w") as f: json.dump(self.data, f, indent=2) def insert(self, document: Dict[str, Any]): self.data.append(document) self.save() def find(self, query: Dict[str, Any]) -> List[Dict[str, Any]]: def match(doc): return all(doc.get(k) == v for k, v in query.items()) return [doc for doc in self.data if match(doc)] def update(self, query: Dict [str, Any], update_fields: Dict[str, Any]): for doc in self.data: if all(doc.get(k) == v for k, v in query.items()): doc.update(update_fields) self.save() def delete(self, query: Dict[str, Any]): self.data = [doc for doc in self.data if not all(doc.get(k) == v for k, v in query.items())] self.save db = SimpleNoSQL() db.insert({ "session_id": "abc123", "code": "fn main() { println!(\"Hello\"); }", "output": "Hello", "status": "success" }) results = db.find({"session_id": "abc123"}) print("検索結果:", results) db.update({"session_id": "abc123"}, {"status": "reviewed"})
[
{
“session_id”: “abc123”,
“code”: “fn main() { println!(\”Hello\”); }”,
“output”: “Hello”,
“status”: “reviewed”
}
]
これをRustでやりたい
### Rustでのjsonの保存
use std::collections::HashMap; use std::fs::File; use std::io::Write; use serde::{Serialize, Deserialize}; fn json_w() -> std::io::Result<()> { let mut map = HashMap::new(); map.insert("name", "Alice"); map.insert("city", "Tokyo"); map.insert("language", "Rust"); let json = serde_json::to_string_pretty(&map).expect("Failed to serialize"); let mut file = File::create("output.json")?; file.write_all(json.as_bytes())?; println!("{:?}", json); Ok(()) } fn main() { let _ = json_w(); }
### jsonの読み取り
fn json_r() { let data = fs::read_to_string("output.json").expect("Failed to read file"); let map: HashMap<String, String> = serde_json::from_str(&data).expect("Failed to deserialize"); println!("{:#?}", map); }
{
“name”: “Alice”,
“language”: “Rust”,
“city”: “Tokyo”,
}
### 改修
レコードごとに保存する必要があるので HashMap
fn json_w() -> std::io::Result<()> { let mut data: Vec<HashMap<String, String>> = match File::open("output.json") { Ok(mut file) => { let mut contents = String::new(); file.read_to_string(&mut contents)?; serde_json::from_str(&contents).unwrap_or_else(|_| Vec::new()) }, Err(_) => Vec::new(), }; let mut map = HashMap::new(); // map.insert("name".to_string(), "Alice".to_string()); // map.insert("city".to_string(), "Tokyo".to_string()); // map.insert("language".to_string(), "Rust".to_string()); map.insert("name".to_string(), "Bob".to_string()); map.insert("city".to_string(), "Osaka".to_string()); map.insert("language".to_string(), "Go".to_string()); data.push(map); let json = serde_json::to_string_pretty(&data).expect("Failed to serialize"); let mut file = File::create("output.json")?; file.write_all(json.as_bytes())?; println!("{:?}", json); Ok(()) } fn json_r() { let data = fs::read_to_string("output.json").expect("Failed to read file"); let v: Vec<HashMap<String, String>> = serde_json::from_str(&data).expect("Failed to deserialize"); println!("{:#?}", v); } fn main() { // // let _ = json_w(); let _ = json_r(); }
[
{
“language”: “Rust”,
“name”: “Alice”,
“city”: “Tokyo”,
},
{
“city”: “Osaka”,
“language”: “Go”,
“name”: “Bob”,
},
]
### implで表現する
関数をinsert, selectとする
use std::collections::HashMap; use std::fs; use std::fs::{File}; use std::io::{Read, Write}; use serde::{Serialize, Deserialize}; pub static FILE_NAME : &'static str = "output.json"; struct NoSQL { data: Vec<HashMap<String, String>>, } impl NoSQL { fn insert(&mut self, map: HashMap<String, String>) -> std::io::Result<()> { self.data = match File::open(FILE_NAME) { Ok(mut file) => { let mut contents = String::new(); file.read_to_string(&mut contents)?; serde_json::from_str(&contents).unwrap_or_else(|_| Vec::new()) }, Err(_) => Vec::new(), }; self.data.push(map); let json = serde_json::to_string_pretty(&self.data).expect("Failed to serialize"); let mut file = File::create(FILE_NAME)?; file.write_all(json.as_bytes())?; println!("{:?}", json); Ok(()) } fn select(&self) { let data = fs::read_to_string(FILE_NAME).expect("Failed to read file"); let v: Vec<HashMap<String, String>> = serde_json::from_str(&data).expect("Failed to deserialize"); println!("{:#?}", v); } } fn main() { let mut sql = NoSQL{ data: Vec::new() }; let mut map = HashMap::new(); map.insert("name".to_string(), "Bob".to_string()); map.insert("city".to_string(), "Osaka".to_string()); map.insert("language".to_string(), "Go".to_string()); sql.insert(map); sql.select(); }
こうすると、nosqlは単純にVec
インメモリデータベースの場合は、メモリに保存するので、jsonではなく、単純にデータとして持っておくだけになる。その場合、サイズが動的なので、スタックではなく、ヒープに保存される。