Approach to construct queries

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Approach to construct queries

jtuchel
Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

Benoit St-Jean
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

jtuchel
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim



Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: <a href="http://endormitoire.wordpress.com" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;">endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="j51oe679AgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jtu...@...> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" rel="nofollow" target="_blank" gdf-obfuscated-mailto="j51oe679AgAJ" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp-group...@googlegroups.com.
To post to this group, send email to <a href="javascript:" rel="nofollow" target="_blank" gdf-obfuscated-mailto="j51oe679AgAJ" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp...@....
Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

Alan Knight
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <[hidden email]> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

jtuchel
Alan,

do you happen to know if there are samples or some documentation on virtual collections or the AND:/OR:.
From looking at teh implementors of AND: it seems like everything is right in front of me, I just couldn't see it...

I will try playing with the AND: stuff. Starting point will be somethind along the lines of:

|query products|
query := SimpleQuery returningManyOf: Product.
query where: [:prod| prod color = 'blue'].
query AND: [:prod| prod price <= 1.00].
products := self session execute: query.

If this is the way to go, the rest is easy: just let the filter objects generate these blocks and visit each of them for the query building.

That would be great. I'll keep you updated ;-)


Joachim






Am Dienstag, 30. Januar 2018 18:04:55 UTC+1 schrieb alan.knight:
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="0nJRnvsFAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jtu...@...> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: <a href="http://endormitoire.wordpress.com" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;">endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].

Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="0nJRnvsFAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp-group...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="0nJRnvsFAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp...@....
Visit this group at <a href="https://groups.google.com/group/glorp-group" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

jtuchel
Okay, this is FANTASTIC!

thanks Alan. This AND: / OR: thingie works perfectly. Why didn't I see this?

Joachim



Am Mittwoch, 31. Januar 2018 09:17:35 UTC+1 schrieb jtuchel:
Alan,

do you happen to know if there are samples or some documentation on virtual collections or the AND:/OR:.
From looking at teh implementors of AND: it seems like everything is right in front of me, I just couldn't see it...

I will try playing with the AND: stuff. Starting point will be somethind along the lines of:

|query products|
query := SimpleQuery returningManyOf: Product.
query where: [:prod| prod color = 'blue'].
query AND: [:prod| prod price <= 1.00].
products := self session execute: query.

If this is the way to go, the rest is easy: just let the filter objects generate these blocks and visit each of them for the query building.

That would be great. I'll keep you updated ;-)


Joachim






Am Dienstag, 30. Januar 2018 18:04:55 UTC+1 schrieb alan.knight:
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <[hidden email]> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: <a href="http://endormitoire.wordpress.com" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;">endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].

Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

jtuchel
In reply to this post by Alan Knight
I'm coming back to this topic because I'm having problems getting my head around something here....

Let's say I have a EqualitiyFilter which tests for equality and can be configured to hold an attribute  along with a user-provided value to compare to name which will be used to construct an SQL query.
I'd like to configure it for use in our application doing something like:

self possibleFilters add: ((EqualityFilter for attributeNamed: #birthday) .
The user can then select the filter and enter a value for comparison (like today's date).

Later, when the user presses the "search" button, I want to do something like:

query := SimpleQuery read: Person.
query where: [:person| person isAlive].
self selectedFilters do: [:filter| query AND: filter selectBlock].

Sounds great, doesn't it?
Not yet, because I see a problem I cannot solve on my own: how do I use the attribute name to put it into the query block....?

How do I implement #selectBlock?

selectBlock

   ^[:eachRow| eachRow whatDoIPutHere??? = self valueToCompare]

Any ideas? I guess #perform: doesn't really work in this context...


Joachim












Am Dienstag, 30. Januar 2018 18:04:55 UTC+1 schrieb alan.knight:
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="0nJRnvsFAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jtu...@...> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: <a href="http://endormitoire.wordpress.com" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;">endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].

Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="0nJRnvsFAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp-group...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="0nJRnvsFAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp...@....
Visit this group at <a href="https://groups.google.com/group/glorp-group" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

jtuchel
Sorry, I edited this too fast:

>Let's say I have a EqualitiyFilter which tests for equality and can be configured to hold an attribute  along with a user-provided value to compare to name which will be used to >construct an SQL query.

Should be

Let's say I have a EqualitiyFilter which tests for equality and can be configured to hold an attribute name along with a user-provided value to compare to which will be used to construct an SQL query.






Am Mittwoch, 7. Februar 2018 13:43:54 UTC+1 schrieb jtuchel:
I'm coming back to this topic because I'm having problems getting my head around something here....

Let's say I have a EqualitiyFilter which tests for equality and can be configured to hold an attribute  along with a user-provided value to compare to name which will be used to construct an SQL query.
I'd like to configure it for use in our application doing something like:

self possibleFilters add: ((EqualityFilter for attributeNamed: #birthday) .
The user can then select the filter and enter a value for comparison (like today's date).

Later, when the user presses the "search" button, I want to do something like:

query := SimpleQuery read: Person.
query where: [:person| person isAlive].
self selectedFilters do: [:filter| query AND: filter selectBlock].

Sounds great, doesn't it?
Not yet, because I see a problem I cannot solve on my own: how do I use the attribute name to put it into the query block....?

How do I implement #selectBlock?

selectBlock

   ^[:eachRow| eachRow whatDoIPutHere??? = self valueToCompare]

Any ideas? I guess #perform: doesn't really work in this context...


Joachim












Am Dienstag, 30. Januar 2018 18:04:55 UTC+1 schrieb alan.knight:
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <[hidden email]> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: <a href="http://endormitoire.wordpress.com" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;">endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].

Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

Alan Knight
In reply to this post by jtuchel
Actually I think perform: might well work. What's happening is that there's a proxy passed into the block and it just notes what messages were sent, essentially constructing a tree of the expression. If the proxy understands perform: normally then I think it would work. Alternatively, you could provide a block that just fetched the attribute and evaluate it passing in the proxy. Sorry, mobile keyboard that won't let me type square brackets easily. I also think you could construct a BaseExpression and sent a query to it, but that's probably more complicated.

On Wed, Feb 7, 2018, 04:43 jtuchel <[hidden email]> wrote:
I'm coming back to this topic because I'm having problems getting my head around something here....

Let's say I have a EqualitiyFilter which tests for equality and can be configured to hold an attribute  along with a user-provided value to compare to name which will be used to construct an SQL query.
I'd like to configure it for use in our application doing something like:

self possibleFilters add: ((EqualityFilter for attributeNamed: #birthday) .
The user can then select the filter and enter a value for comparison (like today's date).

Later, when the user presses the "search" button, I want to do something like:

query := SimpleQuery read: Person.
query where: [:person| person isAlive].
self selectedFilters do: [:filter| query AND: filter selectBlock].

Sounds great, doesn't it?
Not yet, because I see a problem I cannot solve on my own: how do I use the attribute name to put it into the query block....?

How do I implement #selectBlock?

selectBlock

   ^[:eachRow| eachRow whatDoIPutHere??? = self valueToCompare]

Any ideas? I guess #perform: doesn't really work in this context...


Joachim












Am Dienstag, 30. Januar 2018 18:04:55 UTC+1 schrieb alan.knight:
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <[hidden email]> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Approach to construct queries

jtuchel
This is so incredibly fantastic!
The follwong expression actually really works and thus absolutely blows my mind ;-)

session read: Person where: [:ea| (ea perform: #id)   = 1017 ].

I was so sure this can't possibly work I even didn't dare to try ;-)))) Of course, once you think about it, there is no magic involved. Both sending #id and doing a #perform: #id send the message #id to the receiver. So I am hopping around the room celebrating something lame and boring. It's Smalltalk, so what...? (Eat this, static fanboys!)

So all I need is right there in front of me ;-) Thanks a lot, Alan!

Now we need a solution for the #refresh: anomaly I described on this group a few days ago and we're back in full steam with Glorp on our production web server.

Joachim



 

Am Mittwoch, 7. Februar 2018 16:50:33 UTC+1 schrieb alan.knight:
Actually I think perform: might well work. What's happening is that there's a proxy passed into the block and it just notes what messages were sent, essentially constructing a tree of the expression. If the proxy understands perform: normally then I think it would work. Alternatively, you could provide a block that just fetched the attribute and evaluate it passing in the proxy. Sorry, mobile keyboard that won't let me type square brackets easily. I also think you could construct a BaseExpression and sent a query to it, but that's probably more complicated.

On Wed, Feb 7, 2018, 04:43 jtuchel <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="od4Yg1f0AwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jtu...@...> wrote:
I'm coming back to this topic because I'm having problems getting my head around something here....

Let's say I have a EqualitiyFilter which tests for equality and can be configured to hold an attribute  along with a user-provided value to compare to name which will be used to construct an SQL query.
I'd like to configure it for use in our application doing something like:

self possibleFilters add: ((EqualityFilter for attributeNamed: #birthday) .
The user can then select the filter and enter a value for comparison (like today's date).

Later, when the user presses the "search" button, I want to do something like:

query := SimpleQuery read: Person.
query where: [:person| person isAlive].
self selectedFilters do: [:filter| query AND: filter selectBlock].

Sounds great, doesn't it?
Not yet, because I see a problem I cannot solve on my own: how do I use the attribute name to put it into the query block....?

How do I implement #selectBlock?

selectBlock

   ^[:eachRow| eachRow whatDoIPutHere??? = self valueToCompare]

Any ideas? I guess #perform: doesn't really work in this context...


Joachim












Am Dienstag, 30. Januar 2018 18:04:55 UTC+1 schrieb alan.knight:
This is a very common usage, and one that's definitely supported, though apparently not as easy to find as it might be.

Filtered reads are something different. What you want is probably either virtual collection, or just that AND: and OR: are implemented on query.

The former lets you get a collection to which you can send reject:/select: and it just returns a new virtual collection which adds the new query criteria. It doesn't actually issue the query until you start iterating over the result. And the way this is implemented is just that you can send AND: to a query (with a where clause, not another query) and it gives you another query whose where clause is the AND of the two where clauses.


On Tue, Jan 30, 2018 at 7:57 AM jtuchel <[hidden email]> wrote:
Benoît,


sounds like what I am looking for.
I took another tour of the Query subclasses.

I found Query subclass FilteringQuery. Its class comment says:

This is a query that expects all the objects it might return to already be in memory, and in a collection from which it can pick them out by evaluating a block. This is used to implement filtered reads on a mapping. When one of the mappings fires, it reads all the relevant results, and so each instance  using that mapping can get the results out of memory without going to the database again.

So this is not what I am looking for.
Just to be sure I am not overlooking the obvious I checked for implementors of #where: and only found one. It directly sets an instance variable, so the feature you mention seems not to have made its way into "normal" Queries ;-)

So any more ideas?

Joachim




Am Dienstag, 30. Januar 2018 15:32:48 UTC+1 schrieb bstjean:
I remember that in TOPLink (Glorp's ancestor), we had filtered reads (or something named similarly)...  Basically, we could stack WHERE conditions and the final query would be built at the very last moment before execution.  Perhaps, Glorp needs this (it was a useful feature as I remember it).  Alan, are you listening?  ;)


-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
Blogue: <a href="http://endormitoire.wordpress.com" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fendormitoire.wordpress.com\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVTrJOgWx4wljrvY17-qXr_fvEPw&#39;;return true;">endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


On Tuesday, January 30, 2018, 2:26:01 AM EST, jtuchel <[hidden email]> wrote:


Dear Glorp Community,

I am wondering about an approach to construct Glorp Queries from Filter objects. Let me tell you a bit what I mean by that...

In many web shops and sites you find things like sliders for a price range, a few clickable options like "on stock", "blue/red/greed", "rated higher that x stars" and whatever. And there are nice GUIs for combining these, like using a slider, date pickers, input fields etc. You can add these filters and remove them and then start a search.

We need to build these and the result should end up as a Glorp Query returning objects. We currently only have a few such places in our app and use code like this (from my head, not actual code) to construct queries:

self session read: Product where: [:p| p active = true AND: (self onlyOnStock = false OR: (p onStock=true))].

This work quite well for, say, up to 5 filters, but it doesn't really scale up to 10 or more. The code becomes extremely hard to maintain.

I'd rather like to use something like a visitor pattern, where each filter knows how to add its condition(s) to a query. Somthing like:

|query|
query := Query returningManyOf: Product.
self filters do: [:f|

  query addToWhereCondition: f condition.

].
products := self session execute: query.


Glorp is such a nice framework, but I cannot find a way to do this. Has anybody solved this or found something that could help me on my journey? The idea is that I define Filter objects for concrete values, NULL, ranges (between and) etc. and each of them constructs its little part of the query.

Any ideas? Any code samples?

Joachim

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].

Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/glorp-group" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="od4Yg1f0AwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp-group...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="od4Yg1f0AwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">glorp...@....
Visit this group at <a href="https://groups.google.com/group/glorp-group" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/glorp-group&#39;;return true;">https://groups.google.com/group/glorp-group.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/d/optout.