Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading relationships with get()? #19

Open
nybblr opened this issue Apr 17, 2017 · 3 comments
Open

Loading relationships with get()? #19

nybblr opened this issue Apr 17, 2017 · 3 comments

Comments

@nybblr
Copy link
Contributor

nybblr commented Apr 17, 2017

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 💯 to write a PR!

@dfahlander
Copy link
Owner

dfahlander commented Apr 17, 2017

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.

@nybblr
Copy link
Contributor Author

nybblr commented Apr 17, 2017

Oh, nice (re. rewrite)! Hmm, so this sounds like two action items:

  1. 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.
  2. 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.
  3. 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?

@dfahlander
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants