Question about filtering using object methods

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

Question about filtering using object methods

Mariano Martinez Peck
Hi.  I know I can have 2 scenarios when writing queries:

1) Compare instance variables that have been mapped to fields. Example:
session readManyOf: XXX where: [ :object | object xxx = 'ABX'  ].

2) Compare using DOMAIN MODEL METHODS that are NOT mapped to anything:
session readManyOf: XXX where: [ :object | (object isEffectiveOn: Date today)  ]

In the first case 1) the #xxx method is an accessor for an instVar that is mapped to a field. Hence, Glorp can write the SQL in a way to filter the rows in the DB and just bring to memory the one that satisfies. 

Case 2) would need to instantiate each row of the table, send the message #isEffectiveOn: and check if it's true or not.  So, I have 2 questions here:

a) How can I make such a query work? The same query of the scenario 2 does not work for me and I get a MessageNotUnderstood: BaseExpression>>convertedDbValueOf: (I can attach PharoDebug.log if it helps). 

b) do such type of queries (scenario 2) bring only one object at a time and only keep the ones that satisfy the conditions or it brings (instantiates) all rows/objects at the same time in memory and then filter them?  I think this is important because there are some of my tables that won't fit in memory. 

c) if the answer to b) is that you do one by one (which I don't think so), all (or at least several) plain rows will be in memory right? I don't think you will go to the db for each row..

Thanks in advance, 


--
Mariano
http://marianopeck.wordpress.com

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

Re: Question about filtering using object methods

jtuchel
Mariano,

the problem here is that what looks like a Block in fact isn't really. You cannot send messages to each of the resulting objects. The "Block" is used to generate an SQL statement, and there is no way to determine what isEffectiveOn: would look like in SQL by simply analyzing the descriptor.

I wish I could call some nice Smalltalk methods on rows as well, but GLORP does not support this, afaik. And I guess it is not really easy to implement. You'd have to decide for each message send in a Block whether it is something that can be expressed in SQL or has to be executed on a materialized object.

So I am not aware of any other possibility than turning such things into a two-pass select. First a readManyOf:where: for everything that's directly mapped, and a subsequent "pure old Smalltalk" select: on the results for everything else.

It would be great to simply forget about the SQL nature and write normal select:/reject: expressions and have Glorp determine how to convert parts of them into SQL and parts as SQL code.

I am afraid this is a very expensive feature, however.

Joachim
Am Dienstag, 23. Juli 2013 17:44:48 UTC+2 schrieb Mariano Martinez Peck:
Hi.  I know I can have 2 scenarios when writing queries:

1) Compare instance variables that have been mapped to fields. Example:
session readManyOf: XXX where: [ :object | object xxx = 'ABX'  ].

2) Compare using DOMAIN MODEL METHODS that are NOT mapped to anything:
session readManyOf: XXX where: [ :object | (object isEffectiveOn: Date today)  ]

In the first case 1) the #xxx method is an accessor for an instVar that is mapped to a field. Hence, Glorp can write the SQL in a way to filter the rows in the DB and just bring to memory the one that satisfies. 

Case 2) would need to instantiate each row of the table, send the message #isEffectiveOn: and check if it's true or not.  So, I have 2 questions here:

a) How can I make such a query work? The same query of the scenario 2 does not work for me and I get a MessageNotUnderstood: BaseExpression>>convertedDbValueOf: (I can attach PharoDebug.log if it helps). 

b) do such type of queries (scenario 2) bring only one object at a time and only keep the ones that satisfy the conditions or it brings (instantiates) all rows/objects at the same time in memory and then filter them?  I think this is important because there are some of my tables that won't fit in memory. 

c) if the answer to b) is that you do one by one (which I don't think so), all (or at least several) plain rows will be in memory right? I don't think you will go to the db for each row..

Thanks in advance, 


--
Mariano
http://marianopeck.wordpress.com

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

Re: Question about filtering using object methods

jtuchel
In reply to this post by Mariano Martinez Peck
Mariano,

the problem here is that what looks like a Block in fact isn't really. You cannot send messages to each of the resulting objects. The "Block" is used to generate an SQL statement, and there is no way to determine what isEffectiveOn: would look like in SQL by simply analyzing the descriptor.

I wish I could call some nice Smalltalk methods on rows as well, but GLORP does not support this, afaik. And I guess it is not really easy to implement. You'd have to decide for each message send in a Block whether it is something that can be expressed in SQL or has to be executed on a materialized object.

So I am not aware of any other possibility than turning such things into a two-pass select. First a readManyOf:where: for everything that's directly mapped, and a subsequent "pure old Smalltalk" select: on the results for everything else.

It would be great to simply forget about the SQL nature and write normal select:/reject: expressions and have Glorp determine how to convert parts of them into SQL and parts as Smalltalkcode.

I am afraid this is a very expensive feature, however.

Joachim

Am Dienstag, 23. Juli 2013 17:44:48 UTC+2 schrieb Mariano Martinez Peck:
Hi.  I know I can have 2 scenarios when writing queries:

1) Compare instance variables that have been mapped to fields. Example:
session readManyOf: XXX where: [ :object | object xxx = 'ABX'  ].

2) Compare using DOMAIN MODEL METHODS that are NOT mapped to anything:
session readManyOf: XXX where: [ :object | (object isEffectiveOn: Date today)  ]

In the first case 1) the #xxx method is an accessor for an instVar that is mapped to a field. Hence, Glorp can write the SQL in a way to filter the rows in the DB and just bring to memory the one that satisfies. 

Case 2) would need to instantiate each row of the table, send the message #isEffectiveOn: and check if it's true or not.  So, I have 2 questions here:

a) How can I make such a query work? The same query of the scenario 2 does not work for me and I get a MessageNotUnderstood: BaseExpression>>convertedDbValueOf: (I can attach PharoDebug.log if it helps). 

b) do such type of queries (scenario 2) bring only one object at a time and only keep the ones that satisfy the conditions or it brings (instantiates) all rows/objects at the same time in memory and then filter them?  I think this is important because there are some of my tables that won't fit in memory. 

c) if the answer to b) is that you do one by one (which I don't think so), all (or at least several) plain rows will be in memory right? I don't think you will go to the db for each row..

Thanks in advance, 


--
Mariano
http://marianopeck.wordpress.com

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

Re: Question about filtering using object methods

Mariano Martinez Peck



On Mon, Aug 19, 2013 at 10:21 AM, jtuchel <[hidden email]> wrote:
Mariano,



Hi Joachim, thanks for answering.
 
the problem here is that what looks like a Block in fact isn't really. You cannot send messages to each of the resulting objects. The "Block" is used to generate an SQL statement, and there is no way to determine what isEffectiveOn: would look like in SQL by simply analyzing the descriptor.


Totally agree. 

I wish I could call some nice Smalltalk methods on rows as well, but GLORP does not support this, afaik. And I guess it is not really easy to implement. You'd have to decide for each message send in a Block whether it is something that can be expressed in SQL or has to be executed on a materialized object.

So I am not aware of any other possibility than turning such things into a two-pass select. First a readManyOf:where: for everything that's directly mapped, and a subsequent "pure old Smalltalk" select: on the results for everything else.

It would be great to simply forget about the SQL nature and write normal select:/reject: expressions and have Glorp determine how to convert parts of them into SQL and parts as Smalltalkcode.


I thought Glorp provided these 2 last paragraphs (what I call scenario 2 in my email). I thought Glorp could realized that it was not possible to generate a SQL from the block closure and hence, that it was going to fall back to materialize objects from DB and send them such a message. I am disappointed :(

Anyway, I agree with you that the only possibility is then to do the readManyOf:where: (making sure the SQL will work) and then the #select: in memory. 

 

I am afraid this is a very expensive feature, however.

Joachim

Am Dienstag, 23. Juli 2013 17:44:48 UTC+2 schrieb Mariano Martinez Peck:
Hi.  I know I can have 2 scenarios when writing queries:

1) Compare instance variables that have been mapped to fields. Example:
session readManyOf: XXX where: [ :object | object xxx = 'ABX'  ].

2) Compare using DOMAIN MODEL METHODS that are NOT mapped to anything:
session readManyOf: XXX where: [ :object | (object isEffectiveOn: Date today)  ]

In the first case 1) the #xxx method is an accessor for an instVar that is mapped to a field. Hence, Glorp can write the SQL in a way to filter the rows in the DB and just bring to memory the one that satisfies. 

Case 2) would need to instantiate each row of the table, send the message #isEffectiveOn: and check if it's true or not.  So, I have 2 questions here:

a) How can I make such a query work? The same query of the scenario 2 does not work for me and I get a MessageNotUnderstood: BaseExpression>>convertedDbValueOf: (I can attach PharoDebug.log if it helps). 

b) do such type of queries (scenario 2) bring only one object at a time and only keep the ones that satisfy the conditions or it brings (instantiates) all rows/objects at the same time in memory and then filter them?  I think this is important because there are some of my tables that won't fit in memory. 

c) if the answer to b) is that you do one by one (which I don't think so), all (or at least several) plain rows will be in memory right? I don't think you will go to the db for each row..

Thanks in advance, 


--
Mariano
http://marianopeck.wordpress.com

--
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 http://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/groups/opt_out.



--
Mariano
http://marianopeck.wordpress.com

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

Re: Question about filtering using object methods

jtuchel
In reply to this post by jtuchel
HI maarten,

I guess you are referring to my other post on 1:1 relationships and bidirectional navigability (Husband<->Wife example). I could resolve the issue by taking a deep look at the mappings. Your answer is unrelated to this discussion on whether you can send methods to materialized objects in an readManyOf:where: Block.

Anyway, thanks for confirming that the mapping stuff works.

Joachim




Am Montag, 19. August 2013 16:08:09 UTC+2 schrieb [hidden email]:

Humm, this does all works pritty well for me.

 

If you defined a working descriptor you should be able to access husband from wife from children from father from wife fom mother from husband etc without a single query only using accesor methods,select detect etc.

 

Take lessons form here: http://www.eli.sdsu.edu/SmalltalkDocs/GlorpTutorial.pdf

 

It provides examples to do this correctly.

 

Regards,

 

@+Maarten,

 

 

 

 

 

> "jtuchel" <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="Gt_F7k0GBQ8J">jtu...@...> |

Mariano,

the problem here is that what looks like a Block in fact isn't really. You cannot send messages to each of the resulting objects. The "Block" is used to generate an SQL statement, and there is no way to determine what isEffectiveOn: would look like in SQL by simply analyzing the descriptor.

I wish I could call some nice Smalltalk methods on rows as well, but GLORP does not support this, afaik. And I guess it is not really easy to implement. You'd have to decide for each message send in a Block whether it is something that can be expressed in SQL or has to be executed on a materialized object.

So I am not aware of any other possibility than turning such things into a two-pass select. First a readManyOf:where: for everything that's directly mapped, and a subsequent "pure old Smalltalk" select: on the results for everything else.

It would be great to simply forget about the SQL nature and write normal select:/reject: expressions and have Glorp determine how to convert parts of them into SQL and parts as Smalltalkcode.

I am afraid this is a very expensive feature, however.

Joachim

Am Dienstag, 23. Juli 2013 17:44:48 UTC+2 schrieb Mariano Martinez Peck:
Hi.  I know I can have 2 scenarios when writing queries:
1) Compare instance variables that have been mapped to fields. Example:
session readManyOf: XXX where: [ :object | object xxx = 'ABX'  ].
2) Compare using DOMAIN MODEL METHODS that are NOT mapped to anything:
session readManyOf: XXX where: [ :object | (object isEffectiveOn: Date today)  ]
In the first case 1) the #xxx method is an accessor for an instVar that is mapped to a field. Hence, Glorp can write the SQL in a way to filter the rows in the DB and just bring to memory the one that satisfies.
Case 2) would need to instantiate each row of the table, send the message #isEffectiveOn: and check if it's true or not.  So, I have 2 questions here:
a) How can I make such a query work? The same query of the scenario 2 does not work for me and I get a MessageNotUnderstood: BaseExpression>>convertedDbValueOf: (I can attach PharoDebug.log if it helps).
b) do such type of queries (scenario 2) bring only one object at a time and only keep the ones that satisfy the conditions or it brings (instantiates) all rows/objects at the same time in memory and then filter them?  I think this is important because there are some of my tables that won't fit in memory.
c) if the answer to b) is that you do one by one (which I don't think so), all (or at least several) plain rows will be in memory right? I don't think you will go to the db for each row..
Thanks in advance,
--
Mariano
http://marianopeck.wordpress.com
--
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="Gt_F7k0GBQ8J">glorp-group...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="Gt_F7k0GBQ8J">glorp...@....
Visit this group at http://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/groups/opt_out.

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