Hello!
I am using a DictionaryMapping in my code, and I wanted to use #includesKey: in #where: clause (something akin each tools includesKey: aToolId ) to select only rows for which DictionaryMapping uses certain key. It failed with the error in the lines of "#tools does not resolve to field". I had to come up with each tools anySatisfy: [ :tool | tool id = aToolId ] Is it the bug / feature / problem in my approach? If bug, is it planned to add #includesKey: translation to DictionaryMapping? Thanks, Herby -- 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. |
Hi Herby,
In my opinion, the way you found to make it work is the way it should be. The reason is that the first way doesn't translate into SQL and the second one does. It might be possible to add includesKey: functionality but resolving that to SQL would be more complex. I would not call this a bug. I would call it a limitation of the implementation. I don't know of anyone planning to add this feature to Glorp right now. Regards, Tom On 10/24/2017 12:27 PM, Herby Vojčík wrote: > Hello! > > I am using a DictionaryMapping in my code, and I wanted to use > #includesKey: in #where: clause (something akin > > each tools includesKey: aToolId > > ) to select only rows for which DictionaryMapping uses certain key. It > failed with the error in the lines of "#tools does not resolve to > field". I had to come up with > > each tools anySatisfy: [ :tool | tool id = aToolId ] > > Is it the bug / feature / problem in my approach? If bug, is it > planned to add #includesKey: translation to DictionaryMapping? > > Thanks, Herby > -- 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. |
In reply to this post by Herby Vojčík
Herby,
I must admit I've never used Dictionary Mappings with Glorp, so I don't have an answer. But I am a bit confused by your code examples. See below Am 24.10.17 um 20:27 schrieb Herby Vojčík: > Hello! > > I am using a DictionaryMapping in my code, and I wanted to use > #includesKey: in #where: clause (something akin > > each tools includesKey: aToolId What SQL expression would you expect here? I would guess that you want to build a subquery like exists, because the way I understand the query, you want to find all instances of (whatever each is) that hold an Association in their tools dictionary where the key is aToolId. > > ) to select only rows for which DictionaryMapping uses certain key. It > failed with the error in the lines of "#tools does not resolve to > field". I had to come up with > > each tools anySatisfy: [ :tool | tool id = aToolId ] Hmm. This makes me wonder. Is #tools really a Dictionary? Inside the Block, I'd expect the :tool parameter to be an Association, and that doesn't understand #id,does it? I guess @each is the parameter within an Block like in self session read: MyClass where: [:each| each tools ...] If so, I have a hard time believing that anySatisfy: would work (never tried)... > > > Is it the bug / feature / problem in my approach? If bug, is it > planned to add #includesKey: translation to DictionaryMapping? > I don't know, but would guess it is not currently on the Todo-list. My first tip would be to try and find some slides (most likely made by Niall and presented at an ESUG) including the words "subquery", "glorp" and "exists". You won't find much, but that may be a starting point. Not sure this helps, ;-) Joachim -- ----------------------------------------------------------------------- Objektfabrik Joachim Tuchel mailto:[hidden email] Fliederweg 1 http://www.objektfabrik.de D-71640 Ludwigsburg http://joachimtuchel.wordpress.com Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1 -- 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. |
In reply to this post by Tom Robinson
Tom Robinson wrote:
> Hi Herby, > > In my opinion, the way you found to make it work is the way it should > be. The reason is that the first way doesn't translate into SQL and the > second one does. It might be possible to add includesKey: functionality > but resolving that to SQL would be more complex. I would not call this a I think I disagree with this, but correct me if I am wrong. With DictionaryMapping, you map a set of (key, value) pairs into appropriate fields in a table. In essence, it does not differ at all to mapping any other collection containing objects with fields (actually, from what I understood, it does internal tricks to do just that - create internal "class mapping" for an association of that particular dictionary mapping). In case of primitive value dictionaries, it even _is_ the same: key is mapped to one field, value is mapped to different field. If I want to create subquery using value, I can freely use things like #anySatisfy: to filter on that value (which I did in my case, but I come to that later). Since Dictionary enumerates values in do:, select:, collect: (and anySatisfy:), writing each tools anySatisfy: [...] is the same as writing each tools values anySatisfy: [...] but what if I wanted to write each tools keys anySatisfy: [...] ? I cannot, Glorp fails on 'keys' (I tried to use `keys includes:` instead of `includesKey:`, to no avail). So what I want to point here is, that in DictionaryMapping I map keys and values to different fields in table (values can be complex, in which keys they are mapped to more fields, but that is not important distinction here), but Glorp only allows me to use values (and only implicitly) in where clauses; I have no way to use keys at all there. So I assert here that "resolving that to SQL would be more complex" is not true. Key is mapped the same way value is; if I can use where clause that uses value in certain way, I should be able to use key as well - SQL generating from one or the other have same level of difficulty (in fact, I think key is easier, as you do not actually need to join the foreign table); the generated SQL could be something like SELECT * FROM AGENT a WHERE a.tool_id = <toolId asDbValue> The fact that I found a each tools anySatisfy: [ :tool | tool id = aToolId ] is in fact only because non-primitive mappings are processed differently in DictionaryMapping, a non-primitive values are _required_ to have a field defined (not in table, that is understandable, I need to be able to make a join, but in descriptor) a mapping that contains the key. So in essence, that could be represented as SELECT * FROM AGENT a WHERE a.tool_id IN (SELECT * FROM TOOL t WHERE t.agent_id = a.id AND t.id = a.tool_id AND t.id = <aToolId asDbValue>) which is basically same as above, as actually, "a.tool_id = <aToolId asDbValue>" is executed here as well (plus checking that such dictionary actually exists at all; maybe that should be present in previous case as well, but Glorp can generate the join, that's not the question here). It is actually interesting question what SQL Glorp actually generated for "TgAgent readOneOf: [:a|a tools anySatisfy: [:t|t id = toolId]]". Point here is: 1. Why do I need to work it around via [:tool | tool id = aToolId] when I am only interested on "which tools the agent uses" (in fact, give me all agents using this tool). 2. Should this be key -> primitive value mapping, I have simple _no way_ to ask the equivalent of #includesKey: at all (as the value is, for example, a String or an Integer, so no `tool id` is available). > bug. I would call it a limitation of the implementation. I don't know of > anyone planning to add this feature to Glorp right now. That's why I would say #keys (and, ideally, #includesKey:) are actually needed addition to Glorp's set of known-and-translated selectors in case of DictionaryMapping. > Regards, > > Tom Thanks, Herby -- 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. |
In reply to this post by jtuchel
[hidden email] wrote:
> Herby, > > I must admit I've never used Dictionary Mappings with Glorp, so I don't > have an answer. > But I am a bit confused by your code examples. See below > > > Am 24.10.17 um 20:27 schrieb Herby Vojčík: >> Hello! >> >> I am using a DictionaryMapping in my code, and I wanted to use >> #includesKey: in #where: clause (something akin >> >> each tools includesKey: aToolId > > What SQL expression would you expect here? SELECT * FROM AGENT a WHERE a.tool_id = :aToolId AFAICT, DISTINCT is not needed as <id, tool_id> are fks to other table's compound primary key <agent_id, id>, so they are known to be unique. > I would guess that you want to build a subquery like exists, because the > way I understand the query, you want to find all instances of (whatever > each is) that hold an Association in their tools dictionary where the > key is aToolId. Yes. Maybe it needs EXISTS, I don't know. Semantics is clear, though. >> >> ) to select only rows for which DictionaryMapping uses certain key. It >> failed with the error in the lines of "#tools does not resolve to >> field". I had to come up with >> > >> each tools anySatisfy: [ :tool | tool id = aToolId ] > Hmm. This makes me wonder. Is #tools really a Dictionary? Inside the > Block, I'd expect the :tool parameter to be an Association, and that > doesn't understand #id,does it? I guess @each is the parameter within an > Block like in > > self session read: MyClass where: [:each| each tools ...] > > If so, I have a hard time believing that anySatisfy: would work (never > tried)... Yes, it works. Dictionary enumerates values, as I have written in reply to Tom's post. >> Is it the bug / feature / problem in my approach? If bug, is it >> planned to add #includesKey: translation to DictionaryMapping? >> > I don't know, but would guess it is not currently on the Todo-list. > > My first tip would be to try and find some slides (most likely made by > Niall and presented at an ESUG) including the words "subquery", "glorp" > and "exists". You won't find much, but that may be a starting point. I actually managed to get there, but a) using ugly workaround IMO, #includesKey: is part of dictionary's protocol, should be known; b) as I wrote in Tom's reply, the workaround only worked because mapping was to object. If the mapping was to primitive value (number, string), I would not have any 'tool id' ready to use and I would be left .... without option. There is no way to construct such query atm in Glorp, afaict, if I cannot use #keys not #includesKey: in where clause. Is that not a bug? > Not sure this helps, ;-) > > > Joachim Thanks, Herby -- 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. |
In reply to this post by Herby Vojčík
Niall Ross wrote:
> Dear Herby, > adding #includesKey: is certainly doable. If you look at callers above > and subcallers below #anySatisfyDefault: you will see the issues > involved. Your includesKey: needs the same degree of platform-awareness > that Glorp's #anySatisfy: and #allSatisfy: implementations use. But > since #anySatisfy: is there, you have a ready template to follow. I don't feel competent enough, from what I looked, Glorp innards are a bit complex. > Alternatively, I may well add #includesKey: - though not as my most > urgent task. :-) I did a fair amount of work to extend the usability of > DictionaryMappings in Glorp three years ago (part of demonstrating the > ObjectStudio business-mapping/Glorp-generating tools - see my ESUG 2014 > presentation for details) but I did not then think of providing > #includesKey:. Thanks for suggesting the idea. My pleasure. :-) As I wrote elsewhere, also #keys is something (probably the most general) one that could be added as a matter of allowing to work with the key field - as far as I was able to find out, there is no way to actually get to the key, for which I found workaround since I mapped object, but would be out of luck if I mapped single primitive value. For the moment, it is not pressing, but yes, it would be nice to be able to have #keys mapping to key field and #includesKey: as an idiomatic way to do keys includes:. Thanks again, Herby > If you were to work on this, be aware: > > - always reinitialise FunctionExpression class after adding/changing any > Glorp function (or just close and reopen your image, of course) > > - If (and only if) you construct Query whereClauses in stages (e.g. you > have code like > > myQuery AND: [:customer | customer orders includesKey: #onlineOrders] > > or similar) then, using its callers in GlorpTest as a guide, know when > you might need to send #setUpBaseFromSession: to your query while doing > so. (N.B. that method is a Glorp version 8.2.1 addition; you will not > have it in older Glorp.) The point is that stage-constructed where > clauses must convert from block to expression before execution, to > combine the stages. Any that use #anySatisfy:/#allSatisfy: need > platform-specific information to do this; I would expect any > #includesKey: implementation to be the same. > > HTH > Niall Ross > > > Tom Robinson wrote: > > Hi Herby, > > In my opinion, the way you found to make it work is the way it should > be. The reason is that the first way doesn't translate into SQL and the > second one does. It might be possible to add includesKey: functionality > but resolving that to SQL would be more complex. I would not call this a > bug. I would call it a limitation of the implementation. I don't know of > anyone planning to add this feature to Glorp right now. > > Regards, > > Tom > > On 10/24/2017 12:27 PM, Herby Vojčík wrote: > >> Hello! >> >> I am using a DictionaryMapping in my code, and I wanted to use >> #includesKey: in #where: clause (something akin >> >> each tools includesKey: aToolId >> >> ) to select only rows for which DictionaryMapping uses certain key. It >> failed with the error in the lines of "#tools does not resolve to >> field". I had to come up with >> >> each tools anySatisfy: [ :tool | tool id = aToolId ] >> >> Is it the bug / feature / problem in my approach? If bug, is it >> planned to add #includesKey: translation to DictionaryMapping? >> >> Thanks, Herby > -- 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. |
Free forum by Nabble | Edit this page |