sd-core-sync documentation (#2511)

* sd-core-sync api documentation

* use spaces
This commit is contained in:
Brendan Allan 2024-05-29 11:30:24 +08:00 committed by GitHub
parent a76aca7d3c
commit b7c3eb6f5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 139 additions and 54 deletions

View file

@ -195,18 +195,9 @@ impl Task<Error> for SaveTask {
size_in_bytes_bytes
),
sync_db_entry!(inode_to_db(entry.metadata.inode), inode),
{
let v = entry.metadata.created_at.into();
sync_db_entry!(v, date_created)
},
{
let v = entry.metadata.modified_at.into();
sync_db_entry!(v, date_modified)
},
{
let v = Utc::now().into();
sync_db_entry!(v, date_indexed)
},
sync_db_entry!(entry.metadata.created_at.into(), date_created),
sync_db_entry!(entry.metadata.modified_at.into(), date_modified),
sync_db_entry!(Utc::now().into(), date_indexed),
sync_db_entry!(entry.metadata.hidden, hidden),
]
.into_iter()

103
core/crates/sync/README.md Normal file
View file

@ -0,0 +1,103 @@
# `sd-core-sync`
Spacedrive's sync system. Consumes types and helpers from `sd-sync`.
## Using Sync
### Creating Records
Prepare a sync id by creating or obtaining its value,
and then wrapping it in the model's `SyncId` struct,
available at `prisma_sync::{model}::SyncId`.
Next, prepare the sync operations using some varaints of the `sync_entry` macros.
`sync_entry` and `option_sync_entry` take the value first, and then the path to the field's prisma module.
`sync_db_entry` and `option_sync_db_entry` take the same inputs, but additionally produce a prisma operation in a tuple with the sync operation, intended to be put into a `Vec` and unzipped.
Finally, use `sync.shared/relation_create` depending on if you're creating a standalone record or a relation between two records, and then write it to the database with `write_ops`.
```rs
let (sync_params, db_params): (Vec<_>, Vec<_>) = [
sync_db_entry!(self.name, tag::name),
sync_db_entry!(self.color, tag::color),
sync_db_entry!(false, tag::is_hidden),
sync_db_entry!(date_created, tag::date_created),
]
.into_iter()
.unzip();
sync.write_ops(
db,
(
sync.shared_create(
prisma_sync::tag::SyncId { pub_id },
sync_params,
),
db.tag().create(pub_id, db_params),
),
)
```
### Updating Records
This follows a similar process to creation, but with `sync.shared/relation_create`.
```rs
let (sync_params, db_params): (Vec<_>, Vec<_>) = [
sync_db_entry!(name, tag::name),
sync_db_entry!(color, tag::color),
]
.into_iter()
.unzip();
sync.write_ops(
db,
(
sync.shared_update(prisma_sync::tag::SyncId { pub_id }, k, v),
db.tag().update(tag::id::equals(id), db_params);
)
)
```
### Deleting Records
This only requires a sync ID.
```rs
sync.write_op(
db,
sync.shared_delete(prisma_sync::tag::SyncId { pub_id }),
db.tag().delete(tag::id::equals(id));
)
```
### Relation Records
Relations require sync IDs for both the item and the group being related together.
Apart from that they're basically the same as shared operations.
```rs
let (sync_params, db_params): (Vec<_>, Vec<_>) = [
sync_db_entry!(date_created, tag_on_object::date_created)
]
.into_iter()
.unzip();
sync.write_ops(
db,
(
sync.relation_create(
prisma_sync::tag_on_object::SyncId {
tag: prisma_sync::tag::SyncId { pub_id: tag_pub_id },
object: prisma_sync::object::SyncId { pub_id: object_pub_id },
},
sync_params
),
db.tag_on_object().create(
object::id::equals(object_id),
tag::id::equals(tag_id),
db_params
)
)
)
```

View file

@ -4,7 +4,7 @@ use sd_prisma::{
prisma::{file_path, object, tag, tag_on_object},
prisma_sync,
};
use sd_sync::OperationFactory;
use sd_sync::{option_sync_db_entry, option_sync_entry, sync_entry, OperationFactory};
use sd_utils::{msgpack, uuid_to_bytes};
use std::collections::BTreeMap;
@ -324,29 +324,30 @@ pub(crate) fn mount() -> AlphaRouter<Ctx> {
.exec()
.await?;
let (sync_params, db_params): (Vec<_>, Vec<_>) = [
option_sync_db_entry!(args.name, tag::name),
option_sync_db_entry!(args.color, tag::color),
]
.into_iter()
.flatten()
.unzip();
sync.write_ops(
db,
(
[
args.name.as_ref().map(|v| (tag::name::NAME, msgpack!(v))),
args.color.as_ref().map(|v| (tag::color::NAME, msgpack!(v))),
]
.into_iter()
.flatten()
.map(|(k, v)| {
sync.shared_update(
prisma_sync::tag::SyncId {
pub_id: tag.pub_id.clone(),
},
k,
v,
)
})
.collect(),
db.tag().update(
tag::id::equals(args.id),
vec![tag::name::set(args.name), tag::color::set(args.color)],
),
sync_params
.into_iter()
.map(|(k, v)| {
sync.shared_update(
prisma_sync::tag::SyncId {
pub_id: tag.pub_id.clone(),
},
k,
v,
)
})
.collect(),
db.tag().update(tag::id::equals(args.id), db_params),
),
)
.await?;

View file

@ -26,6 +26,15 @@ impl TagCreateArgs {
let pub_id = Uuid::new_v4().as_bytes().to_vec();
let date_created: DateTime<FixedOffset> = Utc::now().into();
let (sync_params, db_params): (Vec<_>, Vec<_>) = [
sync_db_entry!(self.name, tag::name),
sync_db_entry!(self.color, tag::color),
sync_db_entry!(false, tag::is_hidden),
sync_db_entry!(date_created, tag::date_created),
]
.into_iter()
.unzip();
sync.write_ops(
db,
(
@ -33,25 +42,9 @@ impl TagCreateArgs {
prisma_sync::tag::SyncId {
pub_id: pub_id.clone(),
},
[
(tag::name::NAME, msgpack!(&self.name)),
(tag::color::NAME, msgpack!(&self.color)),
(tag::is_hidden::NAME, msgpack!(false)),
(
tag::date_created::NAME,
msgpack!(&date_created.to_rfc3339()),
),
],
),
db.tag().create(
pub_id,
vec![
tag::name::set(Some(self.name)),
tag::color::set(Some(self.color)),
tag::is_hidden::set(Some(false)),
tag::date_created::set(Some(date_created)),
],
sync_params,
),
db.tag().create(pub_id, db_params),
),
)
.await

View file

@ -1,3 +0,0 @@
# crdt-rs
Just @brendonovich experimenting with CRDT stuff.