18 Replies Latest reply on Nov 25, 2008 12:18 PM by Newsgroup_User

    problem with struct and cf8

    tbranden
      Hello everyone

      I have following cf script (see bottom) with the following problem: I' never get the two structs in the 2nd row of the query. Should be the last dump.
      In cf 7 it works fine. But in cf8 i allways get with #myQuery.Advanced[2]# the second struct of the first row. why that??? It seems to be a bug?!?

      thanks for your help!

      __________________________________________



      <cfset strPerson1 = structNew()>
      <cfset strPerson1.firstName = "Jean">
      <cfset strPerson1.lastName = "Dupont">
      <cfset strPerson1.city = "Paris">

      <cfset strPerson2 = structNew()>
      <cfset strPerson2.firstName = "Pierre">
      <cfset strPerson2.lastName = "Lemont">
      <cfset strPerson2.city = "Provence">


      <cfset strPerson = structNew()>
      <cfset strPerson[1] = strPerson1>
      <cfset strPerson[2] = strPerson2>





      <cfset str1Person1 = structNew()>
      <cfset str1Person1.firstName = "Jean1">
      <cfset str1Person1.lastName = "Dupont1">
      <cfset str1Person1.city = "Pari1s">

      <cfset str1Person2 = structNew()>
      <cfset str1Person2.firstName = "Pierre1">
      <cfset str1Person2.lastName = "Lemont1">
      <cfset str1Person2.city = "Provenc1e">


      <cfset str1Person = structNew()>
      <cfset str1Person[1] = str1Person1>
      <cfset str1Person[2] = str1Person2>


      <cfset myQuery = QueryNew("Name, Time, Advanced")>

      <cfset newRow = QueryAddRow(MyQuery, 2)>

      <!--- Set the values of the cells in the query --->
      <cfset temp = QuerySetCell(myQuery, "Name", "The Wonderful World of CMFL", 1)>
      <cfset temp = QuerySetCell(myQuery, "Time", "9:15 AM", 1)>
      <cfset temp = QuerySetCell(myQuery, "Advanced", strPerson, 1)>
      <cfset temp = QuerySetCell(myQuery, "Name", "CFCs for Enterprise Applications", 2)>
      <cfset temp = QuerySetCell(myQuery, "Time", "12:15 PM", 2)>
      <cfset temp = QuerySetCell(myQuery, "Advanced", str1Person, 2)>


      <cfdump var="#myQuery#">

      <cfoutput>structcount: #structCount(myQuery.Advanced[2])#</cfoutput>


      <cfdump var="#myQuery.Advanced[2]#">
      <cfabort>

        • 1. Re: problem with struct and cf8
          -==cfSearching==- Level 4
          Whatever the issue, it seems to be related to the usage of array notation and the fact that your structure keys are numeric. It yields the expected results using cfloop:

          <cfloop query="myQuery">
          <cfset obj = myQuery.Advanced>
          <cfdump var="#obj#" label="CFLOOP Row #currentRow#">
          </cfloop>

          .. or if you change the structure keys to strings like "A" and "B" instead of 1 and 2
          • 2. Re: problem with struct and cf8
            tbranden Level 1
            thanks for your answer.

            but the problem is, i can't change my structure keys, this is set automaticyle while i fill a structure dynamic. And looping is also not solving the problem, because i need for example exacty only the second row. so it's not very performant when i always loop through the entire query.

            isn't that very strange? in fact in cf7 it works with the same code!
            • 3. problem with struct and cf8
              -==cfSearching==- Level 4
              Yes, it does seems like a possible bug. But .. I do not recall reading any documentation about the expected behavior when storing structures in query, or if that is even recommended. While it seems valid to me (it is just an object), I have not read any guarantees about this one way or the other.

              > i can't change my structure keys, this is set automaticyle while
              > i fill a structure dynamic.

              How are you setting the keys? They do not have to be "A","B","C". Just appending any non-numeric character should do it. ie So the key itself is not numeric. Example: "1c", "2c", "3c", ...

              • 4. Re: problem with struct and cf8
                Level 7
                > isn't that very strange? in fact in cf7 it works with the same code!

                It sure is (strange).

                The reason you're seeing what you're seeing is that CF8 is intepretting the
                "myQuery.Advanced" in "myQuery.Advanced[2]" as a reference to the column,
                and when referring to query.column outside of a <cfoutput query="query"> or
                <cfloop query="query">, CF inteprets that as "the first row of that
                column", so within the first row of the advanced column, it's seeing the
                [2] as a reference to the key within the struct, rather than the row
                number. If that makes sense. It's kind of an order of operations problem,
                I think.

                It ltook me a couple of minutes of head scratching to come up with the (an
                ~) answer to this, but -==cfSearching==- was on the right track with the
                looping. Kind of.

                When a query is being looped over, it's accessed slightly differently than
                if just doing a straight query reference, because one is accessing a
                wrapper object rather than the query itself. So that when citing "column"
                in a statement, it means the column *in the current row* (whichever the
                currentRow value is), so one can point to a specific row without a row
                reference, provided currentRow is pointing to where you want it.

                We can leverage this without actually needing to loop over stuff, like
                this:

                <cfoutput query="myQuery" startrow="2" maxrows="1">
                structcount: #structCount(advanced)#
                <cfdump var="#advanced#">
                </cfoutput>

                :-)

                It's a bit grubby, but it works. I'd say it's definitely a bug in CF8.


                --
                Adam
                • 5. Re: problem with struct and cf8
                  -==cfSearching==- Level 4
                  > And looping is also not solving the problem

                  BTW, I was not recommending you use a loop. The loop code was just to demonstrate that the issue seems to involve the numeric keys and usage of array notation.
                  • 6. Re: problem with struct and cf8
                    -==cfSearching==- Level 4
                    Adam Cameron wrote:
                    > CF inteprets that as "the first row of that
                    > column", so within the first row of the advanced column, it's seeing the
                    > [2] as a reference to the key within the struct, rather than the row
                    > number. If that makes sense. It's kind of an order of operations problem,
                    > I think.

                    Yes that would make sense. At least in terms of the exhibited behavior. It also explains why there is no issue when the structure keys are non-numeric.
                    • 7. Re: problem with struct and cf8
                      gdemaria
                      Did you try this syntax?
                      #myquery['Advanced'][2]# ( Query['Column'][RowNum] )

                      Since myquery is a query, not a structure, it has to be referenced a particular way, not sure this syntax is quite the same for a query...

                      <cfdump var="#myQuery.Advanced[2]#">
                      • 8. Re: problem with struct and cf8
                        gdemaria Level 1
                        Here's the other problem..

                        <cfset temp = QuerySetCell(myQuery, "Advanced", str1Person, 2)>

                        str1Person is a complex variable, you cannot assign it's value into a query. A query is different from a structure, it cannot contain arrays or structures, just simple variables. If you want to do something like this, you can use a structure instead of a query.
                        • 9. Re: problem with struct and cf8
                          Level 7
                          > str1Person is a complex variable, you cannot assign it's value into a query.
                          > A query is different from a structure, it cannot contain arrays or structures,
                          > just simple variables.

                          Of course you can. What are you talking about?

                          --
                          Adam
                          • 10. Re: problem with struct and cf8
                            tbranden Level 1
                            first of all, thanks everybody for your answers.

                            I see, there exists some work arounds (thanks adam).

                            But it's not very good, so I' have to rewrite a lot of my cf7 code :-(

                            hmm maybe I have to contact adobe bug request team ;-)

                            @gdemaria
                            your suggestion (#myquery['Advanced'][2]# ( Query['Column'][RowNum] )), returns the same...
                            and of course a query can contain complex data!!!





                            • 11. Re: problem with struct and cf8
                              -==cfSearching==- Level 4
                              > I see, there exists some work arounds (thanks adam).
                              > But it's not very good, so I' have to rewrite a lot of my cf7 code :-(

                              Other than changing the keys, I do not know if there is a way to avoid it. In this case, Adam's solution is probably cleaner. But changing the keys (if only to append a blank space) would also work. Neither solution is great. But they both work. At least until you have another option...
                              • 12. Re: problem with struct and cf8
                                david.collie Level 1
                                Logged as bug 73740. Please use the workaround of using the <cfloop notation.
                                • 13. Re: problem with struct and cf8
                                  tbranden Level 1
                                  hi david,

                                  thanks for your answer.

                                  When Can I except a hotfix? Otherwise I've got a lot code to change. looping is not a solution
                                  • 14. Re: problem with struct and cf8
                                    Level 7
                                    > Logged as bug 73740. Please use the workaround of using the <cfloop notation.

                                    Oops: I'd already raised it as 73603. I didn't mention it because of the
                                    NDA. I've recommended merging the two...

                                    --
                                    Adam
                                    • 15. Re: problem with struct and cf8
                                      Level 7
                                      > When Can I except a hotfix?

                                      You shouldn't *expect* one at all. That's not to say it won't be fixed
                                      (equally, it's not to say it *will* be fixed!), but you should not make
                                      plans around the fact a couple of people have raised a bug entry for you.


                                      > Otherwise I've got a lot code to change. looping is not a solution

                                      My solution, using <cfloop>, does no looping. It just uses <cfloop> to
                                      access the internal iterator.

                                      You can hold your breath for a hotfix, or you can write some simple code to
                                      sort the problem out. I see these as your only two available options. One
                                      of those won't work out so well for you ;-)

                                      --
                                      Adam
                                      • 16. Re: problem with struct and cf8
                                        tbranden Level 1
                                        Hi Adam

                                        Thanks for your post.

                                        But I'm not very pleased about this answer. Sorry but what is this for a statement:

                                        >>You shouldn't *expect* one at all. That's not to say it won't be fixed
                                        (equally, it's not to say it *will* be fixed!)<<

                                        This is not a feature request this is a bug!

                                        Otherwise can you tell me how I do the loop in a cfscript? Because I work a lot with cfscript.

                                        Thanks for your help.
                                        • 17. Re: problem with struct and cf8
                                          Level 7
                                          > But I'm not very pleased about this answer.

                                          Sure. But you can either wring your hands about it or get on with it.
                                          Those are the two options available to you. If you don't want to fix it
                                          the way I suggested... you'll have to live with broken code, or revise how
                                          you're keying your structs. Or a do a lot more horsing round that the
                                          recommended solution.

                                          > Sorry but what is this for a
                                          > statement:
                                          > (equally, it's not to say it *will* be fixed!)<<
                                          > This is not a feature request this is a bug!

                                          Sure. I can't vouch for when a bug will be fixed. I do not work for
                                          Adobe, however I can bring issues to their attention, and put your case
                                          forward (I cannot report back on the results of this, due to an NDA I've
                                          signed). That said, whilst I don't work for Adobe, I *do* work in the
                                          software world, I and I know full well that not all bugs are fixed
                                          immediately someone identifies them. And it's naive to think otherwise.


                                          > Otherwise can you tell me how I do the loop in a cfscript? Because I work a
                                          > lot with cfscript.

                                          Not without accessing the query object via methods that are not supported
                                          by Adobe, no. The only way a query object is iterated over and
                                          "currentrow" is exposed is via <cfloop> or <cfoutput>.

                                          However if you check the methods of the coldfusion.sql.QueryTable class,
                                          that's what a query object is an instance of. One can iterate over the
                                          object using methods from that class, and perhaps also reference the
                                          elements correctly somehow. It's not something I have done, so have no
                                          specific knowledge of it.

                                          --
                                          Adam
                                          • 18. Re: problem with struct and cf8
                                            Level 7
                                            > Not without accessing the query object via methods that are not supported
                                            > by Adobe, no. The only way a query object is iterated over and
                                            > "currentrow" is exposed is via <cfloop> or <cfoutput>.

                                            Of course there's nothing to stop you wrapping the <cfloop> bit up into a
                                            UDF and calling the UDF from within a script block.

                                            --
                                            Adam