Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upDiscussion: Fluent builder api #1004
Comments
|
Downside:
|
|
@gitmotte how do you feel about:
Where we make the builder accessible through a static method, it can have not the 'set' methods , maybe we get rid of |
|
The effect would be using a static construction method "builder" instead of "new". Static constructors are ok for me, but i would prefer a common util class (i.e. JSQL.select() { return new Select() ;} ) providing static construction methods for this. i.e:
But i'm ok with the new operator too! The utility class may contain more complex shortcut-methods for building sql. |
|
I'm ok with methods without prefix "set" and "with"-methods are good option too, not breaking javabean spec. What is your preference? |
|
The fluent api should operate directly on a mutable object. If you think of the usecase of manipulate a query after parsing, a real builder does not fit the needs. |
|
This sort of feels like
Isn't anything outside |
I see nothing wrong with that.
But leave the empty constructor public because of the javabean-spec !
Yes, For all Collection - fields i'd like to add elements without the need to create an empty list.
|
I reverted this change, because it makes the api incompatible with users of older versions. As an alternative we are able to overwrite fluent setter methods within the concrete type returning the specific concrete type casting the super-result. i.e.
and
|
* create(...) methods * chaining - methods returning "this" * overwrite chaining - methods of abstract parents/interfaces for returning concrete type * add<Name> methods on collection-fields with varargs-parameter * add public T get<Name>(Class<T>) - casting and returning an inner interface-type
|
Check out new branch master.fluent to get a picture of all api addons i'd like to add:
@AnEmortalKid @wumpz how do you feel about the proposed changes? Whould you merge them into your lib? |
* add<Name> methods on collection-fields with collection-parameter JSQLParser#1004
|
Comparison link: master...gitmotte:master.fluent |
Those seem fine to me, it's @wumpz 's call. Is the expectation here that future enhancements also include chained methods like these? I think if you were to PR this, you'd probably have to do it in chunks just cause 100+ files is harder to parse through mentally |
Yes, i'd expect this, but it's not that critical if it is missed in some cases.
Well, i'm committing currently chunks. Those committed changes are generated with javaparser, manually reviewed and reverted format-changes, that there are only adds on top of the current api. |
* add<Name> methods on collection-fields with varargs-parameter * add<Name> methods on collection-fields with collection-parameter JSQLParser#1004
|
Sorry. Was out of Jsqlparser business for some days now. I will look into the proposed changes. Without looking into the last changes here another comment. Since this would drive JSqlParser more in a SQL builder library the change should somehow try to make it hard to construct invalid SQLs. E.g. a lot of setters accept Expression instances because this is the common interface of the instances that should go in there. But in fact you could put in any Expression implementing instance into it. Using the library as a parser this restriction is maintained by the grammar. Using it as a builder it's not restricted. |
|
A pragmatic approach would be using the deparser to build sql and validate it by parsing it again. Enforcing this by intruducing more subinterfaces to expression would be a good step, but it may be a second or parallel step to clean those things. Btw. sometimes the generator does not find a setter-/getter-method because of naming-issues. i.e. the field is named using a abbreviation. Personally, i would prefer to add @deprecated annotations to methods which will removed at next Release |
type JSQLParser#1004
type (swap Class<? extends E> for Class<E>) JSQLParser#1004
|
Sure a very pragmatic approach. Regarding performance this would be the last try I think. What about some kind of annotation stuff like @Allow( Column.class, Function.class, ...)
public void setMyExpr(Expression expr)Writing this I surely know, that this is a step in your validation stuff. But using this we would be able to constrain it while building it. |
|
No, i don't think that annotations are the best approach for this, but on other side the standard bean-validation api in java using this pattern. The difference is, that it validates the content, but does not check the type itself. (i.e. javax.validation.NotNull, org.hibernate.validator.constraints.ISBN) Why can't we split Column into Column and ColumnExpression ? |
|
I looked into your changes:
In fact I am no fan of this. I see no value in doing
instead of
|
returning concrete type JSQLParser#1004
|
@gitmotte .. and sorry if I got you wrong. :) We want to allow only specific extensions of Expression in a method. What should this ColumnExpression be for? In fact, we need an IMHO using the interface stuff in this way it is a no go. |
|
@gitmotte So this one could be checked through some kind of validation visitor, like you proposed in your other issue. |
the advantage is, that you save a lot of brackets, if you want to chain the getter-methods.
but I'm not sure I'm convinced of that. we now have nice methods for chaining - there are no constructors needed at all.
instead of
|
yes, that's a different subject, which fits more to validation. |
|
except for the create methods all changes are committed.
Now the coverage decreased from 83.6% to 80.1% - if we use the chaining api within the parser, we can push it up again. |
Agreed. The fluent usage is much more concise. You are creating a second way of addressing parse tree objects. Since the visitor stuff is sometimes daunting. But this would be a massive change / addition, right?
So the last both have to be implemented for all methods, to be complete. |
|
So I assume you somehow limit the scope of where the changes should happen. |
The casting getter is implemented for all methods returning interfaces or abstract types, the last method (chaining setter) is implemented for all setters (but i'ts named without prefix "with" at the moment)
The "with" prefix i would add if you prefer it, but next week ... |
|
The get instead of getExpr was simply a typo. :) If I didn't overlooked something the changes should be backward compatible. The performance shouldn't be touched. So we don't even make a new major version. So this will be a huge improvement due to the useability of this tool. Nice. I would indeed prefer the with prefix. |
not break current api) JSQLParser#1004
not break current api) JSQLParser#1004
|
@wumpz @AnEmortalKid i put a merge request for this issue some days ago, have you seen it? |
|
negative @gitmotte , lost track of it since your other PR was merged :) thx for the reminder, i'll take a look tonight! |
|
@gitmotte thx for reminding me. I got into another issue. |
* #1004 * create(...) methods * chaining - methods returning "this" * overwrite chaining - methods of abstract parents/interfaces for returning concrete type * add<Name> methods on collection-fields with varargs-parameter * add public T get<Name>(Class<T>) - casting and returning an inner interface-type * 1004 add chaining - methods returning "this" * #1004 add chaining - methods returning "this" * * add<Name> methods on collection-fields with varargs-parameter * add<Name> methods on collection-fields with collection-parameter #1004 * * add chaining - methods returning "this" * add<Name> methods on collection-fields with varargs-parameter * add<Name> methods on collection-fields with collection-parameter #1004 * * add public T get<Name>(Class<T>) - casting and returning the concrete type #1004 * * add public T get<Name>(Class<T>) - casting and returning the concrete type (swap Class<? extends E> for Class<E>) #1004 * * overwrite chaining - methods of abstract parents/interfaces for returning concrete type #1004 * * add with prefix for fluent setters. #1004 * add getters * * add with prefix for fluent setters. (revert to chaining setters, do not break current api) #1004 * * add with prefix for fluent setters. (revert to chaining setters, do not break current api) #1004 * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * remove create() methods - they do not add enough value to be justified * * use new methods within testcases * add some constructors * fix and add "with" / "add" methods * * use new methods within testcases * * use new methods within testcases * add some constructors * * renamed constant * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * * use new methods within testcases * add some with-methods * add getter/setter named after the field without abbrivation * * use new methods within testcases * remove empty implicit constructor * return the deparsed Statement - object * compare object tree * compare object tree * * fix ObjectTreeToStringStyle * compare object tree * remove casts not needed * * use new methods within testcases * add some "set" "with" "add" methods missing * * use new methods within testcases * add empty constructors and override with-/add-methods returning concrete type * * add ReflectionModelTest * * use new methods within testcases * fix checkstyle errors * license header * remove test-classes from ReflectionModelTest * remove visitoradapter-classes from ReflectionModelTest * remove duplicate import declaration (checkstyle error) * * fix RandomUtils to support used java.sql.* types * fix RandomUtils to support enums * fix RandomUtils to map objects by its interfaces and super-classes * filter method "setASTNode" - do not test setters (cannot randomly create a SimpleNode) * add javadoc, stating that this is a marker interface #1014 (comment) * revert formatting change #1014 (comment) * change to EXEC_TYPE.EXECUTE just so the assertion didn't change #1014 (comment) * try to revert format changes #1014 (comment) * try to revert format changes #1014 (comment) * remove brackets on @override() -> @override * add with-methods to new fields
|
Since the corresponding pull request was merged, I close this issue. |
* JSQLParser#1004 * create(...) methods * chaining - methods returning "this" * overwrite chaining - methods of abstract parents/interfaces for returning concrete type * add<Name> methods on collection-fields with varargs-parameter * add public T get<Name>(Class<T>) - casting and returning an inner interface-type * 1004 add chaining - methods returning "this" * JSQLParser#1004 add chaining - methods returning "this" * * add<Name> methods on collection-fields with varargs-parameter * add<Name> methods on collection-fields with collection-parameter JSQLParser#1004 * * add chaining - methods returning "this" * add<Name> methods on collection-fields with varargs-parameter * add<Name> methods on collection-fields with collection-parameter JSQLParser#1004 * * add public T get<Name>(Class<T>) - casting and returning the concrete type JSQLParser#1004 * * add public T get<Name>(Class<T>) - casting and returning the concrete type (swap Class<? extends E> for Class<E>) JSQLParser#1004 * * overwrite chaining - methods of abstract parents/interfaces for returning concrete type JSQLParser#1004 * * add with prefix for fluent setters. JSQLParser#1004 * add getters * * add with prefix for fluent setters. (revert to chaining setters, do not break current api) JSQLParser#1004 * * add with prefix for fluent setters. (revert to chaining setters, do not break current api) JSQLParser#1004 * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * remove create() methods - they do not add enough value to be justified * * use new methods within testcases * add some constructors * fix and add "with" / "add" methods * * use new methods within testcases * * use new methods within testcases * add some constructors * * renamed constant * use new methods within testcases * use new methods within testcases * use new methods within testcases * use new methods within testcases * * use new methods within testcases * add some with-methods * add getter/setter named after the field without abbrivation * * use new methods within testcases * remove empty implicit constructor * return the deparsed Statement - object * compare object tree * compare object tree * * fix ObjectTreeToStringStyle * compare object tree * remove casts not needed * * use new methods within testcases * add some "set" "with" "add" methods missing * * use new methods within testcases * add empty constructors and override with-/add-methods returning concrete type * * add ReflectionModelTest * * use new methods within testcases * fix checkstyle errors * license header * remove test-classes from ReflectionModelTest * remove visitoradapter-classes from ReflectionModelTest * remove duplicate import declaration (checkstyle error) * * fix RandomUtils to support used java.sql.* types * fix RandomUtils to support enums * fix RandomUtils to map objects by its interfaces and super-classes * filter method "setASTNode" - do not test setters (cannot randomly create a SimpleNode) * add javadoc, stating that this is a marker interface JSQLParser#1014 (comment) * revert formatting change JSQLParser#1014 (comment) * change to EXEC_TYPE.EXECUTE just so the assertion didn't change JSQLParser#1014 (comment) * try to revert format changes JSQLParser#1014 (comment) * try to revert format changes JSQLParser#1014 (comment) * remove brackets on @override() -> @override * add with-methods to new fields
Is it desirable that the model also supports the builder pattern?
If we change setters and add* methods returning "this" building sql will be very easy ... i.e.
I did a fork starting the change to get a picture of it.
See https://github.com/gitmotte/JSqlParser