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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement GROUP BY ... HAVING #69
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR!
I think the approach you chose here is the best option. We could try to break out some of the re-usability into a type like SQLBinaryExpressionsBuilder
, but that would only reduce code dupe by a tiny bit. Most of the problem is needing all the various having
overloads and as you mention I don't see any way around that.
Re: dynamic callable, unless I'm mistaken, I think the key path variant only works w/ members at the moment. I don't think there is a type safe version of dynamic callable yet. So that would mean making db.select().asdf()
valid code that doesn't fail until runtime.
Re: Re: dynamic callable, I could indeed not find any confirmation if there was a way to insure type safety for dynamic callables, so I already was afraid of that. Anyway, tomorrow I'll properly document the functions I added, and then I'll undraft! |
Looks like some small conflicts were introduced from merging #68 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks!
I started working on fixing #58, but ran into the issue that reusing code by inheriting
SQLPredicateBuilder
is really possible, for two reasons:SQLPredicateBuilder
defines functionswhere
andorWhere
, while we want them to be calledhaving
andorHaving
, and Swift generics don't seem to be able to rename functions at will (it's not C++ after all 馃槈)SQLSelectBuilder
already inheritsSQLPredicateBuilder
, so that really makes it impossible.To quickly recap the issue, we basically want this:
to translate to
SELECT * FROM `planets` WHERE ... GROUP BY `color` HAVING ...
I can see 4 possible solutions for this:
The simplest: Just copying over the
where
/orWhere
functions fromSQLPredicateBuilder
, renaming them tohaving
/orHaving
and calling it a day (as I have done in this draft PR, for now)Duplicating
SQLPredicateBuilder.swift
, calling itSQLHavingBuilder.swift
(or something), changing the necessary references and again calling it a day (not much unlike option 1)Making
groupBy
return aSQLGroupByBuilder
instead ofSelf
, which then inheritsSQLPredicateBuilder
itself too, which results in this syntax:I really don't like it...
Using
dynamicCallable
s, new in Swift 5! I have never used them, and I only know them from a few blog posts, but looking this one I have a good feeling it's possible to solve our problem.But... Doing this will make the code base much more complex, perhaps unnecessarily so. I imagine there are plenty of footguns that come for free with this solution, and perhaps just taking the easy way out (option 1) is the best solution.
SELECT
is, as far as I know, the only statement that even supportsGROUP BY
, and by extensionHAVING
, so should we be worried so much? If you agree, I'll just add documentation to the PR and we'll be good.