Skip to content

Instantly share code, notes, and snippets.

@SaulDoesCode
Last active April 9, 2024 08:24
Show Gist options
  • Save SaulDoesCode/032040fcb2b1e6b282934fd11f352e53 to your computer and use it in GitHub Desktop.
Save SaulDoesCode/032040fcb2b1e6b282934fd11f352e53 to your computer and use it in GitHub Desktop.
proxydb
use dashmap::DashMap;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[derive(Serialize, Deserialize)]
struct Data {
// Your data structure here
}
struct DiskBackedDashMap {
map: DashMap<String, Data>,
dir: String,
}
impl DiskBackedDashMap {
async fn new(dir: &str) -> DiskBackedDashMap {
let map = DashMap::new();
let dir = dir.to_string();
// Load existing data from disk
if let Ok(entries) = fs::read_dir(&dir) {
for entry in entries {
if let Ok(entry) = entry {
let path = entry.path();
if path.is_file() {
if let Ok(mut file) = tokio::fs::File::open(&path).await {
let mut contents = String::new();
if let Ok(_) = file.read_to_string(&mut contents).await {
if let Ok(data) = serde_json::from_str::<Data>(&contents) {
let key = entry.file_name().into_string().unwrap();
map.insert(key, data);
}
}
}
}
}
}
}
DiskBackedDashMap { map, dir }
}
async fn get(&self, key: &str) -> Option<Data> {
self.map.get(key).map(|v| v.clone())
}
async fn set(&self, key: &str, value: Data) {
self.map.insert(key.to_string(), value.clone());
let filepath = format!("{}/{}.json", self.dir, key);
if let Ok(mut file) = tokio::fs::File::create(filepath).await {
let _ = file.write_all(serde_json::to_string(&value).unwrap().as_bytes()).await;
}
}
}
// Usage:
// #[tokio::main]
// async fn main() {
// let dbdm = DiskBackedDashMap::new("./data").await;
// dbdm.set("test", Data { /* your data here */ }).await;
// println!("{:?}", dbdm.get("test").await);
// }
function proxdb(obj, dir) {
let index
const indexPath = `${dir}/index.json`
// Load existing index or create a new one
try {
const data = localStorage.getItem(indexPath)
index = JSON.parse(data)
} catch (error) {
index = {}
}
return new Proxy(obj, {
get: (target, prop) => {
if (target[prop]) return target[prop]
try {
const filename = index[prop]
const data = localStorage.getItem(`${dir}/${filename}.json`)
target[prop] = JSON.parse(data)
if (typeof target[prop] === 'object' && target[prop] !== null)
target[prop] = proxdb(target[prop], dir)
return target[prop]
} catch (error) {
return undefined
}
},
set: (target, prop, value) => {
if (typeof value === 'object' && value !== null) value = proxdb(value, dir)
target[prop] = value
let filename = index[prop] || prop, filepath = `${dir}/${filename}.json`
localStorage.setItem(filepath, JSON.stringify(value))
let oldIndex = { ...index }
index[prop] = filename
// Update index only if it has changed
if (JSON.stringify(oldIndex) !== JSON.stringify(index)) localStorage.setItem(indexPath, JSON.stringify(index))
return true
}
})
}
const fs = require('fs').promises, path = require('path')
async function proxdb(obj, dir) {
try {
await fs.access(dir)
} catch (error) {
await fs.mkdir(dir)
}
let index
const indexPath = path.join(dir, 'index.json')
// Load existing index or create a new one
try {
const data = await fs.readFile(indexPath, 'utf8')
index = JSON.parse(data)
} catch (error) {
index = {}
}
return new Proxy(obj, {
get: async (target, prop) => {
if (target[prop]) return target[prop]
try {
const filename = index[prop], data = await fs.readFile(path.join(dir, `${filename}.json`), 'utf8')
target[prop] = JSON.parse(data)
if (typeof target[prop] === 'object' && target[prop] !== null)
target[prop] = await proxdb(target[prop], dir)
return target[prop]
} catch (error) {
return undefined
}
},
set: async (target, prop, value) => {
if (typeof value === 'object' && value !== null) value = await proxdb(value, dir)
target[prop] = value
let filename = index[prop] || prop, filepath = path.join(dir, `${filename}.json`)
await fs.writeFile(filepath, JSON.stringify(value))
let oldIndex = { ...index }
index[prop] = filename
// Update index only if it has changed
if (JSON.stringify(oldIndex) !== JSON.stringify(index)) await fs.writeFile(indexPath, JSON.stringify(index))
return true
}
})
}
// Usage:
// (async () => {
// const obj = {};
// const proxy = await proxdb(obj, './data');
// proxy.test = { a: 1, b: { c: 2, d: 3 } };
// console.log(await proxy.test);
// })();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment