khonsulabs / bonsaidb

A developer-friendly document database that grows with you, written in Rust
https://bonsaidb.io/
Apache License 2.0
1.02k stars 37 forks source link

Split ViewSchema/MapReduce, add derive(ViewSchema) #289

Closed ecton closed 1 year ago

ecton commented 1 year ago

This PR aims at reducing the complexity introduced in #284. By moving map/reduce to their own trait, it made it easier to provide a derive macro for ViewSchema.

The derive macro is able to substitute in the correct values when no lifetimes are involved, and when the 'doc associated lifetime is used, everything just works as intended.

This also has another nice side effect of simplifying where the magic happens for CollectionDocument-based map/reduce. Now all the shared ViewSchema functionality lives on the shared trait, and CollectionMapReduce is a simplified version of MapReduce when working with SerializedCollections.

Tasks remaining:

Most code will be able to be easily updated. For example, here's the "before"UniqueView definition from core::test_util:

#[derive(View, Debug, Clone)]
#[view(collection = Unique, key = String)]
struct UniqueView;

impl CollectionViewSchema for UniqueView {
    type View = UniqueView;

    fn unique(&self) -> bool {
        true
    }

    fn map(
        &self,
        document: CollectionDocument<<Self::View as View>::Collection>,
    ) -> bonsaidb_core::schema::ViewMapResult<'static, Self> {
        document.header.emit_key(document.contents.name)
    }

And the updated changes:

#[derive(View, Debug, Clone, ViewSchema)]
#[view(collection = Unique, key = String)]
#[view_schema(unique = true)]
struct UniqueView;

impl CollectionMapReduce for UniqueView {
    fn map<'doc>(
        &self,
        document: CollectionDocument<<Self::View as View>::Collection>,
    ) -> bonsaidb_core::schema::ViewMapResult<'doc, Self> {
        document.header.emit_key(document.contents.name)
    }
}

This also brings us a little closer to allowing CollectionDocument to use borrowed data, but that will be a bit more of an involved change, maybe involving updates to transmog.