Comments (14)
How about this?
sumo:find_by(doc_name, [{first_name, "John"}, {last_name, "Doe"}] -> John AND Doe
sumo:find_by(doc_name, [{first_name, ["John", "Jane"]}] -> John OR Jane
sumo:find_by(doc_name, [{first_name, ["John", "Jane"]}, {last_name, "Doe"}] -> (John OR Jane) AND Doe
sumo:find_by(doc_name, [[{first_name, "John"]}, {last_name, "Doe"}]] -> John OR Doe
Rule being terms inside a list are ORed. Everything else is ANDed. Guess putting the atom 'or' inside the list might be superfluous.
from sumo_db.
It might be superflous, but it makes it clearer for the reader. In your example, I would rather turn {first_name, ["John", "Jane"]}
into first_name IN ("John", "Jane")
but I think that's out of the scope of this particular issue. Maybe it's something good to add in a subsequent issue once this one is implemented.
from sumo_db.
I want to be a little more detailed on your examples and compare them with the original proposal… Let's see…
John AND Doe
Expected query
SELECT * FROM doc_name WHERE first_name = "John" AND last_name = "Doe"
Code
% Original
sumo:find_by(doc_name, [{first_name, "John"}, {last_name, "Doe"}])
% New Proposal
sumo:find_by(doc_name, [{first_name, "John"}, {last_name, "Doe"}])
John OR Jane
Expected query
SELECT * FROM doc_name WHERE first_name = "John" OR first_name = "Jane"
Code
% Original
sumo:find_by(doc_name, [{{first_name, "John"}, 'or', {first_name, "Jane"}}]).
% New
sumo:find_by(doc_name, [{first_name, ["John", "Jane"]}]).
(John OR Jane) AND Doe
Expected query
SELECT *
FROM doc_name
WHERE (first_name = "John" OR first_name = "Jane")
AND last_name = "Doe"
Code
% Original
sumo:find_by(doc_name, [{{first_name, "John"}, 'or', {first_name, "Jane"}}, {last_name, "Doe"}]).
% New
sumo:find_by(doc_name, [{first_name, ["John", "Jane"]}, {last_name, "Doe"}])
John OR Doe
Expected query
SELECT * FROM doc_name WHERE first_name = "John" OR last_name = "Doe"
Code
% Original
sumo:find_by(doc_name, [{{first_name, "John"}, 'or', {last_name, "Doe"}}]).
% New
sumo:find_by(doc_name, [[{first_name, "John"]}, {last_name, "Doe"}]]).
((John OR Jane) AND Doe) OR (Jack AND Smith)
Expected query
SELECT *
FROM doc_name
WHERE ((first_name = "John" OR first_name = "Jane") AND last_name = "Doe")
OR (first_name = "Jack" AND last_name = "Smith")
Code
% Original
sumo:find_by(
doc_name,
[ { [ {{first_name, "John"}, 'or', {first_name, "Jane"}}, {last_name, "Doe"}]
, 'or'
, [ {fist_name, "Jack"}, {last_name, "Smith"}]
}
]).
% New
… ??? …
I'm not sure how you would write the code for my new example above.
And we're not even adding a key component here: {'not', …}
In the end, I don't know about you, but I find the original way clearer to read. Not to mention that differentiating ["John", "Jane"]
from "John"
can be tricky (specially when you want stuff like day = 12 OR day = 15
that would end up in some sort of [{day, [12, 15]}]
.
I would not mind too much to make the 'or' atom optional (so that, if you use a tuple it's an or and if you use a list it's an and) and then we will need to figure out how to implement not
logic.
from sumo_db.
Oh yes it does. :) I missed that all of the conditional logic is required.
Maybe not now, but later.
Just for thinking aloud, how about using prefix notation in a tuple? Like
that we can incorporate representation of all logic, including IN and NOT
using the same syntax...
from sumo_db.
You mean like {'or', […]}
or {'not', […]}
.
I don't hate it, but I like it better when the atom(s) is/are in the place where they should be read.
from sumo_db.
I'm open for opinions, of course… maybe @marcelog, @igaray, @jfacorro, @Euen or somebody else have something to say about it.
from sumo_db.
The reason I mentioned pre-fix is because it is easier to parse. One head operation and bam - you immediately know what has to be done with the rest of the arguments and build the query. In other methods (including in fix) you'll have to scan for tokens.
Well, yes the readability is low, but one gets used to it. And by experience one doesn't change SQL queries or such finders too frequently anyway.
Also a much better option is to use some kind of language integrated query. More here. The good news? Ecto, an Elixir project similar to sumo_db already has it implemented. Maybe we can just use that instead... More on ecto's query syntax here.
from sumo_db.
oh, no… I escaped from that .NET world a long time ago 😨
In Erlang, parsing is a matter of pattern-matching and these 2 patterns are, well, equally easy to match:
parse_query({First, 'or', Second}) -> [parse_query(First), " OR ", parse_query(Second)];
parse_query({'or', First, Second}) -> [parse_query(First), " OR ", parse_query(Second)];
…
So we can include both with no real effort. We can also include a third one, if we want:
parse_query({'or', Queries}) ->
string:join([parse_query(Query) || Query <- Queries], " OR ");
from sumo_db.
👍 Sounds like a plan to me :)
from sumo_db.
Hey, by scanning for tokens I actually meant positional pattern matching isn't always easy to infer when there's varying arguments. For example, what does one do when when has to OR three terms... Won't the function signature of parse_query change?
from sumo_db.
The initial recomendation would've been to use something like:
{{Query1, 'or', Query2}, 'or', Query3}
But I understand why that can be ugly… so much that everybody starts wishing for {'or', […]}
to exist 😉
from sumo_db.
LOL! So your plan is to force people to think of only two things at the same time... Very sinister!
from sumo_db.
Based on the current discussion here's the definition of the syntax that sumo_db will support for the find_by/2
function.
-type operator() :: '<' | '>' | '==' | '=<' | '>=' | '/=' | 'like'.
-type field_name() :: atom().
-type value() :: binary() | string() | number() | 'null' | 'not_null'.
-type expression() ::
[expression()]
| {'and', [expression()]}
| {'or', [expression()]}
| {'not', expression()}
| terminal().
-type terminal() ::
{field_name(), operator(), field_name()}
| {field_name(), operator(), value()}
| {field_name(), value()}.
The expression [expression()]
is equivalent to {and, [expression()]}
for backwards compatibility. The following is an example of how a query expression would look like using this syntax:
{or, [{and, [{count, '<', 100},
{category, '=', "shoes"}]},
{category, 'null'}
]
}.
from sumo_db.
👍
from sumo_db.
Related Issues (20)
- Allow flexible key/primary-key attribute name and also enable composed keys
- Implement a rebar3 plugin in order to automate models skeleton generation
- Move src/adapter_test_helpers folder out from test folder, let sumo src agnostic to test helpers
- Upgrade sumo/example to latests sumo version.
- Improve `sumo:find_by` to make it more flexible – pagination/sorting params as options
- Add clause for maps on sumo_utils:to_bin/1
- Add log function
- Version Bump to 0.7.2
- How to create your own sumo_store?
- Add sumo:count_by function HOT 10
- Version Bump to 0.7.3
- Unify `sumo_backend` and `sumo_store` in a single behaviour
- In `sumo_store` add `handle_info` and `terminate` as optional callbacks
- Identify optional_callbacks and treat them as such
- Update sumo_store to use wpool:call/4 HOT 1
- Upgrade sumo_db dependencies
- docs sys.config HOT 2
- sumo_pgsql gen_server <0.905.0> terminated with reason: sock_closed HOT 2
- Doc links are broken HOT 1
- Modernize this Project
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sumo_db.