Skip to main content

StorageAdapter

Trait StorageAdapter 

Source
pub trait StorageAdapter: Send + Sync {
    // Required methods
    fn all_schemas(
        &self,
    ) -> impl Future<Output = Result<Vec<ClassSchema>, ParseError>> + Send;
    fn upsert_schema(
        &self,
        schema: &ClassSchema,
    ) -> impl Future<Output = Result<(), ParseError>> + Send;
    fn create(
        &self,
        schema: &ClassSchema,
        row: &Row,
    ) -> impl Future<Output = Result<WriteResult, ParseError>> + Send;
    fn find(
        &self,
        schema: &ClassSchema,
        constraints: &[Constraint],
        options: &QueryOptions,
    ) -> impl Future<Output = Result<Vec<Row>, ParseError>> + Send;
    fn count(
        &self,
        schema: &ClassSchema,
        constraints: &[Constraint],
    ) -> impl Future<Output = Result<u64, ParseError>> + Send;
    fn update(
        &self,
        schema: &ClassSchema,
        constraints: &[Constraint],
        values: &Row,
    ) -> impl Future<Output = Result<u64, ParseError>> + Send;
    fn delete(
        &self,
        schema: &ClassSchema,
        constraints: &[Constraint],
    ) -> impl Future<Output = Result<u64, ParseError>> + Send;
    fn ensure_unique_index(
        &self,
        class_name: &str,
        fields: &[&str],
        name: Option<&str>,
    ) -> impl Future<Output = Result<(), ParseError>> + Send;
}
Expand description

Storage operations.

async fn in trait, so this is not object-safe. That is deliberate for now: the server holds one concrete adapter chosen at construction, and boxing every call to support a dyn we do not need would cost allocations on the hot path. If a deployment ever needs to swap adapters at runtime, add a boxed wrapper rather than degrading this.

Required Methods§

Source

fn all_schemas( &self, ) -> impl Future<Output = Result<Vec<ClassSchema>, ParseError>> + Send

Load every class schema. Upstream has no per-class fetch: a miss on any class triggers a full getAllClasses, and reproducing that shape keeps the caching behavior comparable.

Source

fn upsert_schema( &self, schema: &ClassSchema, ) -> impl Future<Output = Result<(), ParseError>> + Send

Persist a class schema, creating the class if it does not exist.

Source

fn create( &self, schema: &ClassSchema, row: &Row, ) -> impl Future<Output = Result<WriteResult, ParseError>> + Send

Insert one row. object_id is generated by the caller, not the adapter, because it is part of the Parse contract rather than a storage detail.

Source

fn find( &self, schema: &ClassSchema, constraints: &[Constraint], options: &QueryOptions, ) -> impl Future<Output = Result<Vec<Row>, ParseError>> + Send

Find rows matching every constraint.

Source

fn count( &self, schema: &ClassSchema, constraints: &[Constraint], ) -> impl Future<Output = Result<u64, ParseError>> + Send

Count rows matching every constraint.

Source

fn update( &self, schema: &ClassSchema, constraints: &[Constraint], values: &Row, ) -> impl Future<Output = Result<u64, ParseError>> + Send

Update matching rows with the given field values.

Returns how many rows matched, so a caller can distinguish “updated nothing because the object does not exist” from “updated nothing because the ACL excluded it”. Upstream conflates those into OBJECT_NOT_FOUND, which is the behavior to reproduce at the REST layer, but the adapter should not throw the information away before then.

Source

fn delete( &self, schema: &ClassSchema, constraints: &[Constraint], ) -> impl Future<Output = Result<u64, ParseError>> + Send

Delete matching rows. Returns how many, for the same reason as update.

Source

fn ensure_unique_index( &self, class_name: &str, fields: &[&str], name: Option<&str>, ) -> impl Future<Output = Result<(), ParseError>> + Send

Create a unique index.

Index names are part of the contract. Both adapters recover duplicated_field by regex over the index name, and the Mongo regex matches only auto-generated <field>_1 names, so a differently-named index changes the error a client sees. name: None means “let the backend auto-name it”, which is what produces username_1.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§