compile Insert RTI_XBAND_DATASOURCE_TEMPLATE

     Function {PROCNAME}(ACTION, PARAM1, PARAM2, PARAM3)
     /*
     **  Mimic BRW using An SQL stored procedure to build a recordset
     **  Build a workging table were oconv, sort is all done "server-side"
     **  So report can just have groups with Break-on, minimal chatter with OI.
     **
     ** Note: RTI_XBAND_DATASOURCE_TEMPLATE is the basis for the program
     **       RTI_XBAND_GENPROC uses the template to generate the code
     **       RTI_XBAND_SUPPORT calls RTI_XBAND_GENPROC, compiles the source, loads it on stack like rlist
     **
     **       The BRW, via NetOI / RunDotNet, calls RTI_XBAND_SUPPORT
     **
     ** 03-27-13  rjc Created
     ** 06-27-18  rjc Support @mv in readnext / read, use onGosub
     ** 07-17-18  rjc Fixes for 10.0.0.3
     ** 12-05-19  rjc Add records_processed for 10.0.8
     ** 01-14-20  rjc use rlist_text_1 for row processed
     */

     Declare Function dcount, isEventContext,calculatex

     equ OTHERWISE$   to 1
     equ TRUE$        to 1
     equ FALSE$       to 0
     equ YES$         to 1
     equ NO$          to 0
     Equ NULL$        to ""
     
     * FROM RLIST_EQU
       Equ TARGET_VARIABLE$    To 2 
     
     $Insert msg_equates
     
     Declare Function isEventContext
     If Assigned(ACTION) Else ACTION = ""
     If Assigned(PARAM1) Else PARAM1 = ""
     If Assigned(PARAM2) Else PARAM2 = ""
     If Assigned(PARAM3) Else PARAM3 = ""


     Equ logid$ To ""
     Open 'SYSLISTS' To f_syslists Else null

     If logid$ Then
          Writev "IN->":param1:"|":param2:"|":param3 on f_syslists, logid$,-1 Else null
     end


     Call Set_Status(0)
     * {CMD}
     com_id = "XBDS_{DATASOURCE_PROCNAME}"
     common //com_id//selected%, keys%,msgUp%,selected_Cnt%,processed_cnt%, progress_extent%, progress_value%,mvColumns%
     If Assigned(selected%) Else
          selected% = 0
          keys% = ''
          msgUp% = ''
          selected_cnt% = 0
          processed_Cnt% = 0
          progress_extent% = 0
          progress_value% = 0
     End
     RSLT = ""

     Locate action[1,2] In 'RE,FI,DA,KE,WR,DE' using ',' setting pos Then
          On pos Gosub onRead, onFields, onDataType, onKeys, onWrite, onDelete
     End Else
          rslt = Quote(action) : ' is not implemented'
     End

     If logid$ Then
          Writev "OUT->":quote(rslt) on f_syslists, logid$,-1 Else null
     end

Return RSLT

////////////////////////////////////////

onDataType:

     whichField = param1

     If logid$ Then
          Writev "Datatype->":param1:"|":param2:"|":param3 on f_syslists, logid$,-1 Else null
     end

     {DATATYPE_BLOCK}


Return

////////////////////////////////////////


onFields:

     * New report, cleasr the selected cache
     selected% = 0

     * return:
     * <1> Field Name]
     * <2> Field #]
     * <3> conv code]
     * <4> MVFlag (0/1)]
     * <6> Association]

     * For speed define a dict that is all hard fields, no oConv
     * Then on the read, do the calculations and oconv here, send result to BRW
     * Colname                ; * Position    ; * Conv

     If logid$ Then
          Writev "Fields->":param1:"|":param2:"|":param3 on f_syslists, logid$,-1 Else null
     end

     {FIELDS_BLOCK}

Return

////////////////////////////////////////

onKeys:
     * return:
     * <1-n> key
     * Build a dynamic select
     * Param1 looks like "100 WHERE FILTER = trUE
     * if there is any filter the BRW comes back a second time for the keys
     * else it wants them returned on the first call
     * so, we select on the first call, buffer in a common if needed
     * selected% is a flag, true$ if keys are already in the common
     *
     cmds = ''
     selstmt = trim(param1)
     tablename = "{TABLE}"
     dictname  = "{DICTIONARY}"
     colnames  = "{DATASOURCE_COLS}"
     convs     = "{DATASOURCE_CONVS}"
     col_cnt   = "{DATASOURCE_CNT}"
     mvFlags   = "{DATASOURCE_MVFLAGS}"
     sysFlags  = "{DATASOURCE_SYSFLAGS}"
     datasource_grpNames = "{DATASOURCE_GRPNAMES}"

     Convert ',' To @vm In colnames
     Convert ',' To @vm In convs
     Convert ',' To @vm In mvFlags
     Convert ',' To @vm In sysFlags
     Convert ',' To @vm In datasource_grpNames

     If logid$ Then
          Writev "Keys->":param1:"|":param2:"|":param3 on f_syslists, logid$,-1 Else null
     end


     If Not(selected%) then
          * first time called, do the select
          keys% = ''
          firstword = selstmt[1,' ']
          tablename = "{TABLE}"

          hold_at_Record = @record
          hold_at_id = @id
          hold_at_dict = @DICT


          mvColcnt = sum(mvFlags)
          mvColNames = null$
          mvSysFlags = null$
          isMvSorted = false$
          If mvColcnt then
               c1="";c2="";c3=""
               loop
                    bRemove colName From colnames at c1 setting mark
                    bRemove mvFlag From mvFlags at c2 setting unused
                    bremove sysFlag From sysFlags at c3 setting unused
                    If mvFlag Then
                         mvColNames<-1> = colname
                         mvSysFlags<-1> = ( sysFlag == true$ ) ;* force a 1 or zero so <-1> is not confused
                         If indexc(selStmt, 'BY ':colname,1) Or indexc(selStmt, 'BY-DSND ':colname,1) Then
                            isMvSorted = true$
                         end
                    End
               While mark
               repeat


          End


          Open tablename To f_Table Else
          End
          Open dictName To @DICT Else
          End
          Open 'SYSDICT' To f_sysdict Else
          end

          If Num(firstword) Then
               num_to_select = firstword
               with_clause = trim(Field(selstmt, ' ', 2, Len(selstmt)))
               by_clause = ''
          End Else
               num_to_select = ""
               with_clause = selstmt
               by_clause = ''
          End
          
          cmds = 'SELECT ': trim( num_to_select :' ' : tablename ) : ' ' : trim(with_clause)
          Begin Case
             Case mvColNames == ""
             Case indexc(with_clause, 'EXPLODE-ON',1)
             
                  Swap ' EXPLODE-ON' With @fm:'EXPLODE-ON' In cmds
             Case isMvSorted
             Case mvColNames != ""
                 * not sorted, need explode
                 Convert @fm To ' ' In mvColnames
                 cmds<-1> = 'EXPLODE-ON ' : tablename : ' ' : mvColNames  
          End case
             
          
        If logid$ Then
             Writev "Select cmds->":@fm:cmds on f_syslists, logid$,-1 Else null
        end
          
          * rjc  08-04-10
          call rti_rlistx(cmds, target_variable$, keys%, "KEYS", "", cursor, "", "","")
          Convert @vm To '|' In keys%
          
          
          If logid$ Then
             Writev "keys->":@fm:keys% on f_syslists, logid$,-1 Else null
        end
     End

     *

     * return the keys or buffer them?
     selected% = 1
     selected_Cnt% = fieldCount(keys%,@fm)
     rslt = keys%

     * Start Progess Bar
     If isEventContext() Then
          If selected_Cnt% gt 800 Then
               progress_extent% = 800
          End Else
               progress_Extent% = selected_Cnt%
          End

          def = ""
          def<mType$> = "G"
          def<mExtent$> = progress_extent%
          def<mCaption$> = "Reading report rows"
          def<mText$> = "Processing ":selected_cnt%:" rows"
          def<mIcon$> = "I"

          msgUp% = Msg(@Window, def)
     end

     Call Set_Status(0)

return

////////////////////////////////////////


onRead:


     If logid$ Then
          Writev "Read->":param1:" ":param2:" ":param3 on f_syslists, logid$,-1 Else null
     end
     

     rslt = ''
     @id = param1[1,"|"]
     mv = param1[bcol2() + 1,@rm]

     alloc_size = 500
     buffer = space(alloc_size)
     bsize = alloc_Size
     bpos = 1
     *LIST PERSON_SONG_PLAY FULL_NAME PLAY_COST PLAY_MONTH TITLE BY PLAY_MONTH BY TITLE
     tablename = "{TABLE}"
     dictname  = "{DICTIONARY}"
     colnames  = "{DATASOURCE_COLS}"
     convs     = "{DATASOURCE_CONVS}"
     col_cnt   = "{DATASOURCE_CNT}"
     mvFlags   = "{DATASOURCE_MVFLAGS}"
     sysFlags  = "{DATASOURCE_SYSFLAGS}"
     datasource_grpNames = "{DATASOURCE_GRPNAMES}"

     Convert ',' To @vm In colnames
     Convert ',' To @vm In convs
     Convert ',' To @vm In mvFlags
     Convert ',' To @vm In datasource_grpNames
     Convert ',' To @vm In sysflags
     processed_Cnt% += 1

      * Update Progess Bar
     If msgUp% != null$ Then

          * Bump record count every read, bump the display every progress_extent reads

          If mod(processed_Cnt%, progress_extent%) == 1 Or processed_Cnt% == selected_Cnt% Then
               * Bump the progress value, down the message if over 100%
               progress_value% += 1
               If progress_value% lt progress_extent% Then
                    unused = Msg(@window, MsgUp%, progress_value%, MSGINSTUPDATE$ )
               End else
                 * Xband won't call us when it is done, so down the message @100% progress
                    Msg(@window, MsgUp%, progress_value%, MSGINSTUPDATE$ )
               end
          end
     end

     If Index(sysFlags,'1',1) Then
          Open 'SYSDICT' To f_sysdict Else null
     end


     bHaveDict = 1
     Open dictname To @dict Else
        Open 'SYSDICT' To @dict Else
          bHaveDict = 0
        end
     End
     If bHaveDict then
          Open tablename To f_psp Then
               ReadO @record From f_psp, @id Then
                    clpos = 1; cvpos = 1; mvpos = 1; syspos = 1
                    For col_nr = 1 To col_cnt
                         colname = colnames[clpos,@vm,1];clpos = bcol2()+1
                         conv = convs[cvpos,@vm,1];cvpos = bcol2()+1
                         mvFlag = mvFlags[mvpos,@vm,1];mvpos = bcol2()+1
                         sysFlag =sysFlags[syspos,@vm,1];syspos = bcol2()+1
                         Begin Case
                              Case colname _Eqc '@ID' Or colname _Eqc 'AT_ID' Or colname == "DYNAMIC_ID"
                                   val = @id

                              case colname = 'RLIST_TEXT_1' Or colname == "DYNAMIC_SELECTED"
                                   val = if processed_Cnt% then processed_Cnt% else 'Zero'
                                   val:= ' Rows Processed'
                              case Num(colname)
                                   val = @record<colname>
                              Case sysFlag
                                   If logid$ Then
                                        Writev "Read sysdict ->":colname on f_syslists, logid$,-1 Else null
                                   end

                                   val = calculatex(colname, f_sysdict, @id, @record, 0)
                              Case 1
                                   val = calculate(colname)
                         End Case


                         /* Handle multivalues
                         ** Goal is to return <1,mv>, so single valued data appears once
                         ** But must repeat the breaking/group values else we trigger false breaks
                         */

                         Locate colname In datasource_grpNames using @vm setting unused Then
                              is_breakCol = true$
                         End Else
                              is_breakCol = false$
                         end

                         Begin Case
                              Case mv lt 1
                             * No multivalues in the row, Use the whole value
                              Case mvFlag
                             * Multivalued column, so <1,mv>
                                   val = val<1,mv>
                              Case is_breakCol
                                  * Breaking column.  return the full value, else we'll return a null, trigger a break
                                  //val = val<1,1>

                              Case otherwise$
                                   //val = val<1,mv>
                         End case

                        /* If conv # '' Then
                              val = Oconv(val, conv)
                              If conv[1,2] == "MT" Or conv[1,1] == "D" Then
                                   * brw wants them bracketed by "#"
                                   val = "#" : val : "#"
                              End

                         end
                         */
                         Gosub append
                    next
                    If bpos gt 2 Then
                         rslt = buffer[1,bpos-2]
                    end
               end
          End
     End
     Call Set_Status(0)
Return

////////////////////////////////////////


onWrite:
     id = param2
     rec = param3
Return

////////////////////////////////////////

onDelete:
     id = param1
Return

////////////////////////////////////////

append:


     vlen = getByteSize( val ) + 1

     If vlen + bpos gt bsize then
          buffer := space(alloc_size)
          bsize += alloc_Size
     End

     putbinaryValue( buffer, bpos,CHAR, val:@fm)
     bpos += vlen

return
