Warning, /pim/sink/docs/queries.md is written in an unsupported language. File is not indexed.

0001 ## Query System
0002 The query system should allow for efficient retrieval for just the amount of data required by the client. Efficient querying is supported by the indexes provided by the resources.
0003 
0004 The query always retrieves a set of entities matching the query, while not necessarily all properties of the entity need to be populated.
0005 
0006 Queries are declarative to keep the specification simple and to allow the implementation to choose the most efficient execution.
0007 
0008 Queries can be kept open (live) to receive updates as the store changes.
0009 
0010 ### Query
0011 The query consists of:
0012 
0013 * a set of filters to match the wanted entities
0014 * the set of properties to retrieve for each entity
0015 
0016 Queryable properties are defined by the [[Domain Types]] above.
0017 
0018 ### Query Result
0019 The result is returned directly after running the query in form of a QAbstractItemModel. Each row in the model represents a matching entity.
0020 
0021 The model allows to access the domain object directly, or to access individual properties directly via the rows columns.
0022 
0023 The model is always populated asynchronously. It is therefore initially empty and will then populate itself gradually, through the regular update mechanisms (rowsInserted).
0024 
0025 Tree Queries allow the application to query for i.e. a folder hierarchy in a single query. This is necessary for performance reasons to avoid recursive querying in large hierarchies. To avoid on the other hand loading large hierchies directly into memory, the model only populates the toplevel rows automatically, all other rows need to be populated by calling `QAbstractItemModel::fetchMore(QModelIndex);`. This way the resource can deal efficiently with the query (i.e. by avoiding the many roundtrips that would be necessary with recursive queries), while keeping the amount of data in memory to a minimum (i.e. if the majority of the folder tree is collapsed in the view anyways). A tree result set can therefore be seen as a set of sets, where every subset corresponds to the children of one parent.
0026 
0027 If the query is live, the model updates itself if the update applies to one of the already loaded subsets (otherwise it's currently irrelevant and will load once the subset is loaded).
0028 
0029 #### Enhancements
0030 * Asynchronous loading of entities/properties can be achieved by returning an invalid QVariant initially, and emitting dataChanged once the value is loaded.
0031 * To avoid loading a large list when not all data is necessary, a batch size could be defined to guarantee for instance that there is sufficient data to fill the screen, and the fetchMore mechanism can be used to gradually load more data as required when scrolling in the application.
0032 
0033 #### Filter
0034 A filter consists of:
0035 
0036 * a property to filter on as defined by the [[Domain Types]]
0037 * a comparator to use
0038 * a value
0039 
0040 The available comparators are:
0041 
0042 * equal
0043 * greater than
0044 * less than
0045 * inclusive range
0046 
0047 Value types include:
0048 
0049 * Null
0050 * Bool
0051 * Regular Expression
0052 * Substring
0053 * A type-specific literal value (e.g. string, number, date, ..)
0054 
0055 Filters can be combined using AND, OR, NOT.
0056 
0057 #### Example
0058 ```
0059 query =  {
0060     offset: int
0061     limit: int
0062     filter = {
0063         and {
0064             collection = foo
0065             or {
0066                 resource = res1
0067                 resource = res2
0068             }
0069         }
0070     }
0071 }
0072 ```
0073 
0074 possible API:
0075 
0076 ```
0077 query.filter().and().property("collection") = "foo"
0078 query.filter().and().or().property("resource") = "res1"
0079 query.filter().and().or().property("resource") = "res2"
0080 query.filter().and().property("start-date") = InclusiveRange(QDateTime, QDateTime)
0081 ```
0082 
0083 The problem is that it is difficult to adjust an individual resource property like that.
0084 
0085 ### Usecases ###
0086 Mail:
0087 
0088 * All mails in folder X within date-range Y that are unread.
0089 * All mails (in all folders) that contain the string X in property Y.
0090 
0091 Todos:
0092 
0093 * Give me all the todos in that collection where their RELATED-TO field maps to no other todo UID field in the collection
0094 * Give me all the todos in that collection where their RELATED-TO field has a given value
0095 * Give me all the collections which have a given collection as parent and which have a descendant matching a criteria on its attributes;
0096 
0097 Events:
0098 
0099 * All events of calendar X within date-range Y.
0100 
0101 Generic:
0102 * entity with identifier X
0103 * all entities of resource X
0104