mirror of
https://github.com/Start9Labs/patch-db.git
synced 2026-03-31 04:13:39 +00:00
utility fns
This commit is contained in:
@@ -247,7 +247,7 @@ fn build_model_struct(
|
|||||||
}
|
}
|
||||||
impl #model_name {
|
impl #model_name {
|
||||||
#(
|
#(
|
||||||
pub fn #child_fn_name(&self) -> #child_model {
|
pub fn #child_fn_name(self) -> #child_model {
|
||||||
self.0.child(#child_path).into()
|
self.0.child(#child_path).into()
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "patch-db"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Aiden McClelland <aiden@start9labs.com>"]
|
authors = ["Aiden McClelland <aiden@start9labs.com>"]
|
||||||
edition = "2018"
|
|
||||||
categories = ["database-implementations"]
|
categories = ["database-implementations"]
|
||||||
keywords = ["json", "json-pointer", "json-patch"]
|
|
||||||
description = "A database that tracks state updates as RFC 6902 JSON Patches"
|
description = "A database that tracks state updates as RFC 6902 JSON Patches"
|
||||||
repository = "https://github.com/Start9Labs/patch-db"
|
edition = "2018"
|
||||||
|
keywords = ["json", "json-pointer", "json-patch"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
name = "patch-db"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/Start9Labs/patch-db"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
@@ -16,17 +16,18 @@ readme = "README.md"
|
|||||||
async-trait = "0.1.42"
|
async-trait = "0.1.42"
|
||||||
fd-lock-rs = "0.1.3"
|
fd-lock-rs = "0.1.3"
|
||||||
futures = "0.3.8"
|
futures = "0.3.8"
|
||||||
|
hashlink = "0.6.0"
|
||||||
json-patch = { path = "../json-patch" }
|
json-patch = { path = "../json-patch" }
|
||||||
json-ptr = { path = "../json-ptr" }
|
json-ptr = { path = "../json-ptr" }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
nix = "0.20.0"
|
nix = "0.20.0"
|
||||||
|
patch-db-macro = { path = "../patch-db-macro" }
|
||||||
qutex-2 = { path = "../qutex" }
|
qutex-2 = { path = "../qutex" }
|
||||||
serde = { version = "1.0.118", features = ["rc"] }
|
serde = { version = "1.0.118", features = ["rc"] }
|
||||||
serde_json = "1.0.61"
|
|
||||||
serde_cbor = { path = "../cbor" }
|
serde_cbor = { path = "../cbor" }
|
||||||
|
serde_json = "1.0.61"
|
||||||
thiserror = "1.0.23"
|
thiserror = "1.0.23"
|
||||||
tokio = { version = "1.0.1", features = ["sync", "fs", "rt", "io-util", "macros"] }
|
tokio = { version = "1.0.1", features = ["sync", "fs", "rt", "io-util", "macros"] }
|
||||||
patch-db-macro = { path = "../patch-db-macro" }
|
|
||||||
lazy_static = "1.4.0"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
proptest = "1.0.0"
|
proptest = "1.0.0"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use hashlink::LinkedHashSet;
|
||||||
use json_ptr::{JsonPointer, SegList};
|
use json_ptr::{JsonPointer, SegList};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@@ -24,6 +25,11 @@ pub trait DbHandle: Sized + Send + Sync {
|
|||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
store_read_lock: Option<RwLockReadGuard<'_, Store>>,
|
store_read_lock: Option<RwLockReadGuard<'_, Store>>,
|
||||||
) -> Result<bool, Error>;
|
) -> Result<bool, Error>;
|
||||||
|
async fn keys<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
ptr: &JsonPointer<S, V>,
|
||||||
|
store_read_lock: Option<RwLockReadGuard<'_, Store>>,
|
||||||
|
) -> Result<LinkedHashSet<String>, Error>;
|
||||||
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
@@ -93,6 +99,13 @@ impl<Handle: DbHandle + Send + Sync> DbHandle for &mut Handle {
|
|||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
(*self).exists(ptr, store_read_lock).await
|
(*self).exists(ptr, store_read_lock).await
|
||||||
}
|
}
|
||||||
|
async fn keys<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
ptr: &JsonPointer<S, V>,
|
||||||
|
store_read_lock: Option<RwLockReadGuard<'_, Store>>,
|
||||||
|
) -> Result<LinkedHashSet<String>, Error> {
|
||||||
|
(*self).keys(ptr, store_read_lock).await
|
||||||
|
}
|
||||||
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
@@ -178,6 +191,17 @@ impl DbHandle for PatchDbHandle {
|
|||||||
self.db.exists(ptr).await
|
self.db.exists(ptr).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async fn keys<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
ptr: &JsonPointer<S, V>,
|
||||||
|
store_read_lock: Option<RwLockReadGuard<'_, Store>>,
|
||||||
|
) -> Result<LinkedHashSet<String>, Error> {
|
||||||
|
if let Some(lock) = store_read_lock {
|
||||||
|
lock.keys(ptr)
|
||||||
|
} else {
|
||||||
|
self.db.keys(ptr).await
|
||||||
|
}
|
||||||
|
}
|
||||||
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::io::Error as IOError;
|
use std::io::Error as IOError;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use json_ptr::JsonPointer;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::sync::broadcast::error::TryRecvError;
|
use tokio::sync::broadcast::error::TryRecvError;
|
||||||
|
|
||||||
@@ -47,4 +48,6 @@ pub enum Error {
|
|||||||
CacheCorrupted(Arc<IOError>),
|
CacheCorrupted(Arc<IOError>),
|
||||||
#[error("Subscriber Error: {0}")]
|
#[error("Subscriber Error: {0}")]
|
||||||
Subscriber(#[from] TryRecvError),
|
Subscriber(#[from] TryRecvError),
|
||||||
|
#[error("Node Does Not Exist: {0}")]
|
||||||
|
NodeDoesNotExist(JsonPointer),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::hash::Hash;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
use hashlink::LinkedHashSet;
|
||||||
use json_ptr::JsonPointer;
|
use json_ptr::JsonPointer;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@@ -75,8 +76,8 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn child<C: Serialize + for<'de> Deserialize<'de>>(&self, index: &str) -> Model<C> {
|
pub fn child<C: Serialize + for<'de> Deserialize<'de>>(self, index: &str) -> Model<C> {
|
||||||
let mut ptr = self.ptr.clone();
|
let mut ptr = self.ptr;
|
||||||
ptr.push_end(index);
|
ptr.push_end(index);
|
||||||
Model {
|
Model {
|
||||||
ptr,
|
ptr,
|
||||||
@@ -133,11 +134,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasModel: Serialize + for<'de> Deserialize<'de> {
|
pub trait HasModel: Serialize + for<'de> Deserialize<'de> {
|
||||||
type Model: From<JsonPointer>
|
type Model: ModelFor<Self>;
|
||||||
+ AsRef<JsonPointer>
|
}
|
||||||
+ Into<JsonPointer>
|
|
||||||
+ From<Model<Self>>
|
pub trait ModelFor<T: Serialize + for<'de> Deserialize<'de>>:
|
||||||
+ Clone;
|
From<JsonPointer> + AsRef<JsonPointer> + Into<JsonPointer> + From<Model<T>> + Clone
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl<
|
||||||
|
T: Serialize + for<'de> Deserialize<'de>,
|
||||||
|
U: From<JsonPointer> + AsRef<JsonPointer> + Into<JsonPointer> + From<Model<T>> + Clone,
|
||||||
|
> ModelFor<T> for U
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -186,11 +194,53 @@ impl<T: HasModel + Serialize + for<'de> Deserialize<'de>> HasModel for Box<T> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OptionModel<T: HasModel + Serialize + for<'de> Deserialize<'de>>(T::Model);
|
pub struct OptionModel<T: HasModel + Serialize + for<'de> Deserialize<'de>>(T::Model);
|
||||||
impl<T: HasModel + Serialize + for<'de> Deserialize<'de>> OptionModel<T> {
|
impl<T: HasModel + Serialize + for<'de> Deserialize<'de>> OptionModel<T> {
|
||||||
|
pub async fn lock<Db: DbHandle>(&self, db: &mut Db, lock: LockType) {
|
||||||
|
db.lock(self.0.as_ref(), lock).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get<Db: DbHandle>(&self, db: &mut Db) -> Result<ModelData<Option<T>>, Error> {
|
||||||
|
self.lock(db, LockType::Read).await;
|
||||||
|
Ok(ModelData(db.get(self.0.as_ref()).await?))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_mut<Db: DbHandle>(&self, db: &mut Db) -> Result<ModelDataMut<T>, Error> {
|
||||||
|
self.lock(db, LockType::Write).await;
|
||||||
|
let original = db.get_value(self.0.as_ref(), None).await?;
|
||||||
|
let current = serde_json::from_value(original.clone())?;
|
||||||
|
Ok(ModelDataMut {
|
||||||
|
original,
|
||||||
|
current,
|
||||||
|
ptr: self.0.clone().into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn exists<Db: DbHandle>(&self, db: &mut Db) -> Result<bool, Error> {
|
pub async fn exists<Db: DbHandle>(&self, db: &mut Db) -> Result<bool, Error> {
|
||||||
db.lock(self.as_ref(), LockType::Read).await;
|
self.lock(db, LockType::Read).await;
|
||||||
Ok(db.exists(&self.as_ref(), None).await?)
|
Ok(db.exists(&self.as_ref(), None).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn map<
|
||||||
|
F: FnOnce(T::Model) -> V,
|
||||||
|
U: Serialize + for<'de> Deserialize<'de>,
|
||||||
|
V: ModelFor<U>,
|
||||||
|
>(
|
||||||
|
self,
|
||||||
|
f: F,
|
||||||
|
) -> Model<Option<U>> {
|
||||||
|
Into::<JsonPointer>::into(f(self.0)).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn and_then<
|
||||||
|
F: FnOnce(T::Model) -> V,
|
||||||
|
U: Serialize + for<'de> Deserialize<'de>,
|
||||||
|
V: ModelFor<Option<U>>,
|
||||||
|
>(
|
||||||
|
self,
|
||||||
|
f: F,
|
||||||
|
) -> V {
|
||||||
|
Into::<JsonPointer>::into(f(self.0)).into()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn check<Db: DbHandle>(self, db: &mut Db) -> Result<Option<T::Model>, Error> {
|
pub async fn check<Db: DbHandle>(self, db: &mut Db) -> Result<Option<T::Model>, Error> {
|
||||||
Ok(if self.exists(db).await? {
|
Ok(if self.exists(db).await? {
|
||||||
Some(self.0)
|
Some(self.0)
|
||||||
@@ -199,6 +249,14 @@ impl<T: HasModel + Serialize + for<'de> Deserialize<'de>> OptionModel<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn expect<Db: DbHandle>(self, db: &mut Db) -> Result<T::Model, Error> {
|
||||||
|
if self.exists(db).await? {
|
||||||
|
Ok(self.0)
|
||||||
|
} else {
|
||||||
|
Err(Error::NodeDoesNotExist(self.0.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn delete<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
pub async fn delete<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||||
db.lock(self.as_ref(), LockType::Write).await;
|
db.lock(self.as_ref(), LockType::Write).await;
|
||||||
db.put(self.as_ref(), &Value::Null).await
|
db.put(self.as_ref(), &Value::Null).await
|
||||||
@@ -256,13 +314,13 @@ impl<T: Serialize + for<'de> Deserialize<'de>> Deref for VecModel<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: Serialize + for<'de> Deserialize<'de>> VecModel<T> {
|
impl<T: Serialize + for<'de> Deserialize<'de>> VecModel<T> {
|
||||||
pub fn idx(&self, idx: usize) -> Model<Option<T>> {
|
pub fn idx(self, idx: usize) -> Model<Option<T>> {
|
||||||
self.child(&format!("{}", idx))
|
self.0.child(&format!("{}", idx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: HasModel + Serialize + for<'de> Deserialize<'de>> VecModel<T> {
|
impl<T: HasModel + Serialize + for<'de> Deserialize<'de>> VecModel<T> {
|
||||||
pub fn idx_model(&self, idx: usize) -> OptionModel<T> {
|
pub fn idx_model(self, idx: usize) -> OptionModel<T> {
|
||||||
self.child(&format!("{}", idx)).into()
|
self.0.child(&format!("{}", idx)).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: Serialize + for<'de> Deserialize<'de>> From<Model<Vec<T>>> for VecModel<T> {
|
impl<T: Serialize + for<'de> Deserialize<'de>> From<Model<Vec<T>>> for VecModel<T> {
|
||||||
@@ -350,8 +408,23 @@ where
|
|||||||
T: Serialize + for<'de> Deserialize<'de> + Map,
|
T: Serialize + for<'de> Deserialize<'de> + Map,
|
||||||
T::Value: Serialize + for<'de> Deserialize<'de>,
|
T::Value: Serialize + for<'de> Deserialize<'de>,
|
||||||
{
|
{
|
||||||
pub fn idx(&self, idx: &<T as Map>::Key) -> Model<Option<<T as Map>::Value>> {
|
pub fn idx(self, idx: &<T as Map>::Key) -> Model<Option<<T as Map>::Value>> {
|
||||||
self.child(idx.as_ref())
|
self.0.child(idx.as_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> MapModel<T>
|
||||||
|
where
|
||||||
|
T: Serialize + for<'de> Deserialize<'de> + Map,
|
||||||
|
T::Key: Hash + Eq + for<'de> Deserialize<'de>,
|
||||||
|
T::Value: Serialize + for<'de> Deserialize<'de>,
|
||||||
|
{
|
||||||
|
pub async fn keys<Db: DbHandle>(&self, db: &mut Db) -> Result<LinkedHashSet<T::Key>, Error> {
|
||||||
|
db.lock(self.as_ref(), LockType::Read).await;
|
||||||
|
let set = db.keys(self.as_ref(), None).await?;
|
||||||
|
Ok(set
|
||||||
|
.into_iter()
|
||||||
|
.map(|s| serde_json::from_value(Value::String(s)))
|
||||||
|
.collect::<Result<_, _>>()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> MapModel<T>
|
impl<T> MapModel<T>
|
||||||
@@ -359,8 +432,8 @@ where
|
|||||||
T: Serialize + for<'de> Deserialize<'de> + Map,
|
T: Serialize + for<'de> Deserialize<'de> + Map,
|
||||||
T::Value: Serialize + for<'de> Deserialize<'de> + HasModel,
|
T::Value: Serialize + for<'de> Deserialize<'de> + HasModel,
|
||||||
{
|
{
|
||||||
pub fn idx_model(&self, idx: &<T as Map>::Key) -> OptionModel<<T as Map>::Value> {
|
pub fn idx_model(self, idx: &<T as Map>::Key) -> OptionModel<<T as Map>::Value> {
|
||||||
self.child(idx.as_ref()).into()
|
self.0.child(idx.as_ref()).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> From<Model<T>> for MapModel<T>
|
impl<T> From<Model<T>> for MapModel<T>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use hashlink::LinkedHashSet;
|
||||||
use json_patch::{AddOperation, Patch, PatchOperation, RemoveOperation, ReplaceOperation};
|
use json_patch::{AddOperation, Patch, PatchOperation, RemoveOperation, ReplaceOperation};
|
||||||
use json_ptr::{JsonPointer, SegList};
|
use json_ptr::{JsonPointer, SegList};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -176,6 +177,26 @@ impl DiffPatch {
|
|||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn keys(&self, mut keys: LinkedHashSet<String>) -> LinkedHashSet<String> {
|
||||||
|
for op in &(self.0).0 {
|
||||||
|
match op {
|
||||||
|
PatchOperation::Add(a) => {
|
||||||
|
if a.path.len() == 1 {
|
||||||
|
keys.insert(a.path.get_segment(0).unwrap().to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PatchOperation::Replace(_) => (),
|
||||||
|
PatchOperation::Remove(a) => {
|
||||||
|
if a.path.len() == 1 {
|
||||||
|
keys.remove(a.path.get_segment(0).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl Default for DiffPatch {
|
impl Default for DiffPatch {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use fd_lock_rs::FdLock;
|
use fd_lock_rs::FdLock;
|
||||||
|
use hashlink::LinkedHashSet;
|
||||||
use json_ptr::{JsonPointer, SegList};
|
use json_ptr::{JsonPointer, SegList};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use qutex_2::{Guard, Qutex};
|
use qutex_2::{Guard, Qutex};
|
||||||
@@ -128,6 +129,15 @@ impl Store {
|
|||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
Ok(ptr.get(self.get_data()?).unwrap_or(&Value::Null) != &Value::Null)
|
Ok(ptr.get(self.get_data()?).unwrap_or(&Value::Null) != &Value::Null)
|
||||||
}
|
}
|
||||||
|
pub(crate) fn keys<S: AsRef<str>, V: SegList>(
|
||||||
|
&self,
|
||||||
|
ptr: &JsonPointer<S, V>,
|
||||||
|
) -> Result<LinkedHashSet<String>, Error> {
|
||||||
|
Ok(match ptr.get(self.get_data()?).unwrap_or(&Value::Null) {
|
||||||
|
Value::Object(o) => o.keys().cloned().collect(),
|
||||||
|
_ => LinkedHashSet::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
pub(crate) fn get<T: for<'de> Deserialize<'de>, S: AsRef<str>, V: SegList>(
|
pub(crate) fn get<T: for<'de> Deserialize<'de>, S: AsRef<str>, V: SegList>(
|
||||||
&self,
|
&self,
|
||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
@@ -213,6 +223,12 @@ impl PatchDb {
|
|||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
self.store.read().await.exists(ptr)
|
self.store.read().await.exists(ptr)
|
||||||
}
|
}
|
||||||
|
pub async fn keys<S: AsRef<str>, V: SegList>(
|
||||||
|
&self,
|
||||||
|
ptr: &JsonPointer<S, V>,
|
||||||
|
) -> Result<LinkedHashSet<String>, Error> {
|
||||||
|
self.store.read().await.keys(ptr)
|
||||||
|
}
|
||||||
pub async fn get<T: for<'de> Deserialize<'de>, S: AsRef<str>, V: SegList>(
|
pub async fn get<T: for<'de> Deserialize<'de>, S: AsRef<str>, V: SegList>(
|
||||||
&self,
|
&self,
|
||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use hashlink::LinkedHashSet;
|
||||||
use json_ptr::{JsonPointer, SegList};
|
use json_ptr::{JsonPointer, SegList};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@@ -99,6 +100,23 @@ impl<Parent: DbHandle + Send + Sync> DbHandle for Transaction<Parent> {
|
|||||||
};
|
};
|
||||||
Ok(self.updates.for_path(ptr).exists().unwrap_or(exists))
|
Ok(self.updates.for_path(ptr).exists().unwrap_or(exists))
|
||||||
}
|
}
|
||||||
|
async fn keys<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
ptr: &JsonPointer<S, V>,
|
||||||
|
store_read_lock: Option<RwLockReadGuard<'_, Store>>,
|
||||||
|
) -> Result<LinkedHashSet<String>, Error> {
|
||||||
|
let keys = {
|
||||||
|
let store_lock = self.parent.store();
|
||||||
|
let store = if let Some(store_read_lock) = store_read_lock {
|
||||||
|
store_read_lock
|
||||||
|
} else {
|
||||||
|
store_lock.read().await
|
||||||
|
};
|
||||||
|
self.rebase()?;
|
||||||
|
self.parent.keys(ptr, Some(store)).await?
|
||||||
|
};
|
||||||
|
Ok(self.updates.for_path(ptr).keys(keys))
|
||||||
|
}
|
||||||
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
async fn get_value<S: AsRef<str> + Send + Sync, V: SegList + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ptr: &JsonPointer<S, V>,
|
ptr: &JsonPointer<S, V>,
|
||||||
|
|||||||
Reference in New Issue
Block a user