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

Discussion: abstract syntax tree #202

Closed
stalniy opened this issue Jun 11, 2020 · 2 comments · Fixed by #204
Closed

Discussion: abstract syntax tree #202

stalniy opened this issue Jun 11, 2020 · 2 comments · Fixed by #204

Comments

@stalniy
Copy link
Contributor

stalniy commented Jun 11, 2020

Hi Craig,

Currently, I’m working on SQL integration in CASL and I need to transform Mongo query into sql query. The standard way to do something like this is through AST. There are 2 steps:

  1. Transform language into AST
  2. Using Iterator or Visitor pattern walk over AST and transform it to whatever language or result you want

So, having AST of Mongo query in casl, I’ll be able to use the same pattern for 2 cases:

  1. Check permissions in runtime
  2. Transform permissions to any database query (other than mongo query)

To do this I need to implement just 2 separate implementations: RuntimeQueryIterator and SQLIterator

So, what do you thing?

Theoretically it should help with Async operators support as well. Your current design is quite similar to what I need the difference is that your objects currently encapsulate data (about operator) and behavior (how to apply this operator).

I know that you refactored the whole package recently and understand that you may have own vision on siftjs future. So, feel free to decline and close this discussion.

@crcn
Copy link
Owner

crcn commented Jun 16, 2020

Would exposing the operator factory solve your problem? For example:

import {createQueryOperation} from "sift";
const operation = createQueryOperation({ age: { $gt: 1 }});

☝🏻 this is from https://github.com/crcn/sift.js/blob/master/src/core.ts#L398

Operators are basically ASTs - I may need to do some work to expose their raw query values, but that shouldn't be hard. From there, you can just roll your own translator:

import {createQueryOperation} from "sift";
const operation = createQueryOperation({ age: { $gt: 1, $lt: 10 }});
const searchQuery = mongodbQueryToSqlSearch(operation); // age > 1 AND age < 10

@stalniy
Copy link
Contributor Author

stalniy commented Jun 18, 2020

Looks fine, but to make sure that we are on the same page, the end result I expect should be this:

import { createQueryOperation, test } from "sift";
const operation = createQueryOperation({ age: { $gt: 1, $lt: 10 }});
const searchQuery = mongodbQueryToSqlSearch(operation); // age > 1 AND age < 10

const matches  = test(operation, { age: 2 }) // true

Update: the last line is equivalent to sift({ age: { $gt: 1, $lt: 10 } })({ age: 2 })

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

Successfully merging a pull request may close this issue.

2 participants