OpenSlides/docs/interfaces/datastore-service.txt

304 lines
8.6 KiB
Plaintext
Raw Normal View History

2020-01-20 07:43:25 +01:00
# Datastore Interface
Enum EventType {
Create,
Update,
Delete,
Restore,
}
Exception ModelDoesNotExist(model: Fqid);
Exception ModelExist(model: Fqid);
Exception ModelNotDeleted(model: Fqid);
2020-01-22 11:39:51 +01:00
Exception ModelLocked(key: Fqid | Fqfield | CollectionField);
Exception InvalidFormat(msg: string);
Exception InvalidRequest(msg: string);
# Note: Error returns via HTTP 400:
Interface ErrorResponse {
error: InvalidFormatData |
InvalidRequestData |
ModelDoesNotExistData |
ModelExistData |
ModelMotDeletedData |
ModelLockedData;
}
Interface InvalidFormatData {
type: 1;
msg: string;
}
Interface InvalidRequestData {
type: 2;
msg: string;
2020-03-19 14:14:45 +01:00
}
2020-01-22 11:39:51 +01:00
Interface ModelDoesNotExistData {
type: 3;
fqid: string;
}
Interface ModelExistData {
type: 4;
fqid: string;
}
Interface ModelNotDeletedData {
type: 5;
fqid: string;
}
Interface ModelLockedData {
type: 6;
key: string;
}
2020-01-20 07:43:25 +01:00
## Writer
2020-01-22 11:39:51 +01:00
# Note: Different host and port than the reader!
2020-01-20 07:43:25 +01:00
/**
2020-01-22 11:39:51 +01:00
* Writes Events into the datastore.
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/writer/write
2020-01-20 07:43:25 +01:00
*
* @throws ModelDoesNotExist
* @throws ModelExists
* @throws ModelLocked
* @throws InvalidFormat
* @throws ModelNotDeleted
*/
2020-01-22 11:39:51 +01:00
write(request: WriteRequest): void publishes ModifiedFieldsEvent
2020-01-20 07:43:25 +01:00
Interface WriteRequest {
events: (CreateEvent | RestoreEvent | UpdateEvent | DeleteEvent)[];
information: {
<fqid>: Object
};
user_id: number;
locked_fields: {
<fqid>: Position;
2020-01-22 11:39:51 +01:00
<fqfield>: Position;
2020-01-20 07:43:25 +01:00
<CollectionField>: Position;
}
}
Interface CreateEvent {
2020-01-22 11:39:51 +01:00
type: 'create';
2020-01-20 07:43:25 +01:00
fqid: Fqid;
2020-01-22 11:39:51 +01:00
fields: {
2020-01-20 07:43:25 +01:00
<field>: Value;
}
}
2020-11-13 13:04:20 +01:00
// Note: For deleting keys, they must be set to `None`. These keys will be removed from
// the model.
// list_fields can be used to partially update list fields: the values in `add` will be
// appended to the given field, the values in `remove` will be removed from the field.
// The case of double adding or removing something invalid will be silently ignored.
// All given list_fields must be flat arrays of strings or ints, else an error is
// thrown.
// Either fields or list_fields must be given or an error will be thrown.
2020-01-20 07:43:25 +01:00
Interface UpdateEvent {
2020-01-22 11:39:51 +01:00
type: 'update';
fqid: Fqid;
fields: {
<field>: Value;
2020-01-20 07:43:25 +01:00
}
2020-11-13 13:04:20 +01:00
list_fields: {
add: {
<field>: Value[];
}
remove: {
<field>: Value[];
}
}
2020-01-20 07:43:25 +01:00
}
Interface RestoreEvent {
2020-01-22 11:39:51 +01:00
type: 'restore';
2020-01-20 07:43:25 +01:00
fqid: Fqid;
}
Interface DeleteEvent {
2020-01-22 11:39:51 +01:00
type: 'delete';
2020-01-20 07:43:25 +01:00
fqid: Fqid;
}
2020-01-22 11:39:51 +01:00
// Note: The modified fqfields include:
// - all updated fqfields
// - all deleted fqfields
// - all fqfields of all deleted models
// - all fqfields of all created models
// - all fqfields of all restored models (logically the same as created)
Event ModifiedFieldsEvent on topic ModifiedFields {
modified: Fqfield[];
2020-01-20 07:43:25 +01:00
}
2020-01-22 11:39:51 +01:00
/**
2020-06-09 12:36:27 +02:00
* Reserves multiple sequential ids for the given collection und returns them.
2020-05-07 10:13:07 +02:00
* Url: POST to /internal/datastore/writer/reserve_ids
2020-01-22 11:39:51 +01:00
*/
2020-06-09 12:36:27 +02:00
reserveIds(collection: Collection, amount: number): Id[]
2020-01-20 07:43:25 +01:00
2020-03-19 14:14:45 +01:00
2020-01-22 11:39:51 +01:00
## Reader
# Note: Different host and port than the writer!
/** Common notes:
* - parameter `position`: Optional, if given reads the data to this position.
2020-03-19 14:14:45 +01:00
* - parameter `mapped_fields`: List of fields that should only be present in the response.
* - parameter `get_deleted_models`: Optional, defines which models to return
* - DeletedModelsBehaviour.NO_DELETED: (Default) only non-deleted models are returned.
* get throws a ModelDoesNotExist error if the given
* model is deleted.
* - DeletedModelsBehaviour.ONLY_DELETED: only deleted models are returned. get throws
* a ModelNotDeleted if the given model is not deleted.
* - DeletedModelsBehaviour.ALL_MODELS: all models are returned
2020-01-22 11:39:51 +01:00
* - All operations adds the fields `meta_position` and `meta_deleted` to the models.
* - The InvalidFormat exception can always be thrown, if the requested formats are
* wrong, including something like empty collections, ...
2020-01-20 07:43:25 +01:00
*/
2020-03-19 14:14:45 +01:00
Enum DeletedModelsBehaviour {
NO_DELETED = 1,
ONLY_DELETED = 2,
ALL_MODELS = 3
}
2020-01-20 07:43:25 +01:00
/**
2020-03-19 14:14:45 +01:00
* Returns a model by fqid.
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/reader/get
2020-01-20 07:43:25 +01:00
*
* @throws ModelDoesNotExist
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
2020-03-19 14:14:45 +01:00
get(fqid: Fqid, mapped_fields?: Field[], position?: Position, get_deleted_models?: DeletedModelsBehaviour): Partial<Model>;
2020-01-20 07:43:25 +01:00
/**
2020-03-19 14:14:45 +01:00
* Returns multiple models.
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/reader/get_many
*
2020-04-28 11:59:28 +02:00
* Can either be called with a list of Fqfields or with a list of specific request
* objects that map a collection to the needed ids and fields. If both the lower and
* the higher level mapped_fields are given, the higher level one is merged into all
* lower level ones. If Fqfields are given, the mapped_fields are ignored.
2020-03-19 14:14:45 +01:00
* If an id is not found, it is not included in the response instead of throwing a
* ModelDoesNotExist.
2020-01-20 07:43:25 +01:00
*
2020-04-28 11:59:28 +02:00
* @returns A mapping of collection to ids to models. Example:
* {
* "collection1": {
* "id1": {
* "field1": "foo",
* "field2": "bar",
* },
* },
* "collection2": {
* "id2": {
* "field3": 42,
* },
* },
* }
*
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
2020-05-05 11:49:17 +02:00
get_many(requests: GetManyRequest[] | Fqfield[], mapped_fields?: Field[], position?: Position, get_deleted_models?: DeletedModelsBehaviour): Map<Collection, Map<Id, Partial<Model>>>;
2020-01-20 07:43:25 +01:00
2020-03-19 14:14:45 +01:00
Interface GetManyRequest {
collection: Collection;
ids: Id[];
mapped_fields?: Field[];
}
2020-01-20 07:43:25 +01:00
/**
2020-05-05 11:49:17 +02:00
* Returns all models of one collection.
* Url: POST to /internal/datastore/reader/get_all
*
* It is not possible to specify a position, so this method cannot be used if the user
* browses the history. It should be noted that it is highly disencouraged to use this
* method because it might return a huge amount of data.
*
* @returns see get_many
2020-05-05 11:49:17 +02:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
get_all(collection: Collection, mapped_fields?: Field[], get_deleted_models?: DeletedModelsBehaviour): Map<Id, Partial<Model>>;
2020-01-20 07:43:25 +01:00
2020-10-16 13:11:00 +02:00
/**
* Returns all models.
* Url: POST to /internal/datastore/reader/get_everything
*
* This is a dev route only!
*
* @returns The example data format: A mapping of a collection to a list of models.
*/
get_everything(get_deleted_models?: DeletedModelsBehaviour): Map<Collection, Model[]>;
2020-01-20 07:43:25 +01:00
/**
2020-05-05 11:49:17 +02:00
* Returns all models of one collection that satisfy the filter condition.
* Url: POST to /internal/datastore/reader/filter
*
* This method does not take a position and can not be used when browsing the history.
2020-01-20 07:43:25 +01:00
*
* @returns see get_many
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
filter(collection: Collection, filter: Filter, mapped_fields?: Field[]): Map<Id, Partial<Model>>
2020-01-20 07:43:25 +01:00
/**
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/reader/exists
*
2020-01-22 11:39:51 +01:00
* See `filter`, returns true, if at least one model was found. The returned position is
* the highest position in the complete datastore.
2020-01-20 07:43:25 +01:00
*
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
2020-01-22 11:39:51 +01:00
exists(collection: Collection, filter: Filter): {exists: boolean; position: Position;}
2020-01-20 07:43:25 +01:00
/**
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/reader/count
*
2020-01-22 11:39:51 +01:00
* See `filter`, returns the amount of found models. The returned position is
* the highest position in the complete datastore.
2020-01-20 07:43:25 +01:00
*
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
2020-01-22 11:39:51 +01:00
count(collection: Collection, filter: Filter): {count: number; position: Position;}
2020-01-20 07:43:25 +01:00
/**
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/reader/min
*
2020-03-19 14:14:45 +01:00
* Executes a min aggregation on all models of one collection on
* the given field that satisfy the filter condition.
2020-04-08 11:20:55 +02:00
* The field is cast to int by default. If aggregation of another field type is needed,
* a valid type can be passed via the type parameter.
2020-01-20 07:43:25 +01:00
*
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
2020-04-08 11:20:55 +02:00
min(collection: Collection, filter: Filter, field: Field, type?: string): {min: Value; position: Position;}
2020-01-20 07:43:25 +01:00
/**
2020-05-05 11:49:17 +02:00
* Url: POST to /internal/datastore/reader/max
2020-04-08 11:20:55 +02:00
* Analogous to min.
2020-01-20 07:43:25 +01:00
*
2020-01-22 11:39:51 +01:00
* @throws InvalidFormat
2020-01-20 07:43:25 +01:00
*/
2020-04-08 11:20:55 +02:00
max(collection: Collection, filter: Filter, field: Field, type?: string): {max: Value; position: Position;}
2020-01-20 07:43:25 +01:00
Type Filter = And | Or | Not | FilterOperator
/**
2020-01-22 11:39:51 +01:00
* The filter predicate. M[field] states the value of the field of a model M.
* For all operations the predicate if true, if `M[field] <op> value` is true.
2020-01-20 07:43:25 +01:00
*/
Interface FilterOperator {
field: Field;
value: Value | null;
2020-04-08 11:20:55 +02:00
operator: '=' | '!=' | '<' | '>' | '>=' | '<=';
2020-01-20 07:43:25 +01:00
}
Interface Not {
2020-03-19 14:14:45 +01:00
not_filter: Filter;
2020-01-20 07:43:25 +01:00
}
Interface And {
2020-03-19 14:14:45 +01:00
and_filter: Filter[];
2020-01-20 07:43:25 +01:00
}
Interface Or {
2020-03-19 14:14:45 +01:00
or_filter: Filter[];
2020-01-20 07:43:25 +01:00
}