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 から Vec> に変更
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ではなく、単純にデータとして持っておくだけになる。その場合、サイズが動的なので、スタックではなく、ヒープに保存される。