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 = "G" def = progress_extent% def = "Reading report rows" def = "Processing ":selected_cnt%:" rows" def = "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 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