1
0
-1

Hi Freaks

I need a good idea (smile)

Having a "simple" READ-trigger like this

call SO_READ("")
IF($status<0) RETURN($status)
..do some code ..


Where in SO_READ is the "read" statement and "a little bit more"
After the read, there is a security check, if our if not the clerk should see the row.
If not, a simple DISCARD kick the row away

A simple was to handle this kind of requirement.

BUT   (Yes Ingo again with BUT)
The DISCARD triggers the READ-trigger again without leaving SO_READ before.

After around 100 DISCARDs : "Runtime error: Proc stack overflow"
One solution would be to return a DoDiscard-Flag and do the DISCARD directly in READ-trigger

But then I have to do so in hundreds of programms, sometime with code after SO_READ.
A simple search and replace is not appropriate.
My first thought was to set a global flag, leave the inner SO_READ, fetch the flag in outer SO_READ and then do the rest of the job.
Now the code after SO_READwill done even if I want to DISCARD.

Any idea is welcome.

Ingo

PS: In this very moment, my grey cells thinking about a solution with $status=-123456789 and fetch this



    CommentAdd your comment...

    6 answers

    1.  
      1
      0
      -1

      Good morging freaks

      So, I got a solution (smile)

      In short, it looks like this:

      -- SO_READ --
      IF($$DISCARD_PHASE==1)
      $$DISCARD_PHASE = 2 ; In nested DISCARD
      RETURN(-123456789) ; Tell code in READ-Trigger to leave the trigge
      ENDIF
      TAG_START_AGAIN:
      ...
      read
      ...
      IF(xyz) ; some condition to issue the DISCARD
      $$DISCARD_PHASE = 1 ; in DISCARD
      discard
      IF($$DISCARD_PHASE==2) ; From nested DISCARD
      $$DISCARD_PHASE = ""
      GOTO TAG_START_AGAIN ; Use this SO_READ to performe next read
      ENDIF
      $$DISCARD_PHASE = ""
      ENDIF... RETURN(0)
      END

      In reality, there is a "little more" to code especially  the error handling

      Hope, this works with all our code line (smile)

      Ingo

        CommentAdd your comment...
      1.  
        2
        1
        0

        Another solution is to do $next(...) just before the discard when not using the discard in the read trigger

          CommentAdd your comment...
        1.  
          1
          0
          -1

          Hi Stijn

          The week, we did have a "patch week", so I' could not check your solution (smile)
          Will do it in the next days.

          Thanks anyway

          Ingo




            CommentAdd your comment...
          1.  
            1
            0
            -1

            From the manual;

            Using discard in the Read Trigger

            After discarding an occurrence, Uniface makes another occurrence active. If this occurrence is not available in the component, the Read trigger for that entity is activated to get the data for the newly active occurrence. If the discard statement being executed occurs in the Read trigger of the entity being discarded, the Read trigger would be called recursively. After some number of these calls, a stack overflow error can occur, ending the application.


            To prevent this problem, in the Read trigger of the entity being discarded only , any code following a discard statement is ignored; the trigger ends immediately after the occurrence is discarded. If necessary, the trigger is reactivated to obtain data for the new active occurrence, but it is not called in a recursive manner. In the following example, the putmess statements are never executed because the Read trigger ends following the discard statement:

            Since you're in a 'call SO_READ' - I'd have as a guess that's why you're getting the stack overflow....

            As rw suggested - maybe an INCLUDE will fix this issue...

            Knut


              CommentAdd your comment...
            1.  
              1
              0
              -1

              Little bit more clue where the discard comes in as far as the SO_READ trigger is concerned might help but. 

              Replace the discard with a return -33

              set SO_READ to return numeric, end it with return $status (may not be necessary)

              replace call SO_READ("") with (if( SO_READ("") = -33) discard elseif($status <0) return $status

                CommentAdd your comment...
              1.  
                1
                0
                -1

                Isn't this documented behaviour?

                If you put the so_read code directly in the read trigger (as include proc?) the discard statement won't be fired a second time; no need for a flag.

                  CommentAdd your comment...