dexie-relationships
dexie-relationships copied to clipboard
Loading relationships with `get()`?
The current use case (AFAICT) for with()
is to use it where you would call .toArray()
.
However, I'd like to use it on .get()
queries and in places where I don't want to invoke .toArray()
. Implicitly invoking toArray()
limits query building scenarios.
Rail's ActiveRecord handles this by "queueing up" query filters, then having an evaluate method (similar to toArray()
). Is there a similar way to do this, so with()
will work with get()
, plus enable some more complex query builders such as the following use cases:
Use Case 1: Executing a scalar query
let song = await db.songs.with({ album: 'albumId' }).get(3);
Use Case 2: Composing a collection query
let findSongs = (albumId) => {
let query = db.songs
.where('albumId')
.equals(albumId)
.with({ album: 'albumId' });
return query;
};
let page = (query, number, limit) => {
return query.offset(number*limit).limit(limit);
};
let songs = await page(findSongs(3), 2, 10)).toArray();
Use Case 3: Composing queries that are "doubly" async
let intersect = async (table, queries) => {
let results = await Promise.all(
queries.map(q => q.primaryKeys()));
let reduced = results
.reduce((a, b) => {
let set = new Set(b);
return a.filter(k => set.has(k));
});
return table.where(':id').anyOf(reduced);
};
let query1 = db.songs
.where('albumId')
.equals(3)
.with({ album: 'albumId' });
let query2 = db.songs
.where('genreId')
.equals(5)
.with({ album: 'albumId' });
let aggregateQuery = await intersect(query1, query2);
let songs = await aggregateQuery.toArray();
If the answer is "yes" or @dfahlander has some pointers on how to do this, I'm :100: to write a PR!
I agree fully. Problem right now is that Dexie needs to change it's core loop to handle this. I've started a rewrite in typescript at https://github.com/dfahlander/Dexie.js/tree/next-expression-engine/src/dexie-next. This new branch is a rewrite of quite much. It will support chained where clauses in combination with orderBy() and support lazy mapping like what you are requesting. It will also support asynchronous hooks. Many of the features mentioned here will be supported.
I would very much appreciate any help with completing this branch later on when it comes to a stage where it is functional and testable. I find myself with too little time this spring to work on it right now. But hope to get it going again later this year (August and forth). Probably too undocumented to jump into right away though. (does not even compile right now)
If you find an easier way to accomplish it based on current Dexie master branch, feel free to implement it and PR it. You will then need PRs for both Dexie and dexie-relationships. As long as all the unit tests pass, I'm fine with it.
Oh, nice (re. rewrite)! Hmm, so this sounds like two action items:
- For now, I'll try to crunch out a very specific solution for the
.get()
use case which works with the current Dexie version; I'm working on some bootcamp code so I'd love to have something I can use now. - I use Dexie a fair bit, so definitely ping me when it would help to have help! Tests/refactors/code review, just let me know.
- Would it be a safe guess to say "relationships" could become first class in Dexie, or would it continue to live on as an addon?
Thanks! I'll ping you as I move forward. Just the knowledge of that there are people wanting to help further on is good.
Relationships addon is already part of the CI tests of Dexie, as other addons may be too, too verify a new Dexie version never will break first class addons. It may continue as an addon to save the library size though.