Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The Role model is not backed by a dedicated table, but a dataset that is a UNION of eight individual roles tables. When filtering for roles, this was done by adding WHERE conditions to the overall dataset, which resulted in slow query executions. A more efficient approach is to move the WHERE conditions into the individual datasets per role. This commit customizes the Role model/dataset. The creation of the UNIONed dataset is moved into a dedicated class (RoleDataset) that supports building a dataset with filters (i.e. WHERE conditions) per role (i.e. individual table). The 'where' method of the Role dataset is overridden and uses Dataset.from ([1]) to change the dataset's source. It replaces the source with a new dataset built with filters per role. As 'where' calls can be chained, the filters need to be kept in the dataset instance (cache) and the source dataset needs to be built again on each 'where' invocation with all the filters, i.e. previous and new WHERE conditions. Furthermore fully qualified identifiers (table name and column name) have to be adapted; as the WHERE conditions are applied on the individual roles tables, no table name prefix is required and thus removed from the identifiers. Some filters can now be handled in a more efficient way. When filtering for a specific role type, the corresponding dataset gets a 'WHERE 1 = 1', whereas all the other datasets get a 'WHERE 1 = 0', meaning they never return any rows. Something similar is done when filtering for organizations or spaces; the opposite role types get a 'WHERE 1 = 0' as they don't have the requested 'id' field. As there might be filters that still should be applied to the overall dataset, 'where' invocations with a block (aka. virtual row block) are treated as before, i.e. applied at the end. Drawbacks: - The current implementation of the custom Role model/dataset is rather strict with regards to allowed filter expressions. This means that if some functionality is added (e.g. new or different filter), the custom Role model/dataset needs to be adapted. This was done by intention to ensure that every code path is tested. - To limit the number of different filter expressions, invocations of 'first(cond)' and 'find(cond)' on the custom Role model/dataset have been replaced with 'where(cond).first' which is semantically identical. [1] https://sequel.jeremyevans.net/rdoc/classes/Sequel/Dataset.html#method-i-from
- Loading branch information