Programming Languages on Power

Power Programming Languages

IBM Power, including the AIX, IBM i, and Linux operating systems, support a wide range of programming languages, catering to both traditional enterprise applications and modern development needs.


#Power

 View Only
  • 1.  Running the QSH command grep in RPG is taking too long

    Posted Thu June 29, 2023 02:34 PM
      |   view attached

    Hello,

    I have an IFS folder with thousands of XML files.

    And I am developing an application coded in RPG, that will list on a subfile, each IFS file name that contain a specific search string.

    My program is working as expected, but the "grep" took about 4 to 5 minutes to return successfully with the search results.

    Here are my steps, please let know what I am doing Wrong OR what I can do to increase the performance.

    One thing I can think is that there are 745 files in the folder that i am searching. 

    And size of each file range from 18 KB up to 1 MB. Is that too many files & size are huge ?

    So far i am only testing in a Test environment. And the production system could have up to a half a million IFS files.

    1.  Change to Directory "/i3pl/XX/arc"

                Cmd_Str = 'CD DIR(' + Quote + Source_Dir + Quote + ')';
                Exec_OS_Command (Cmd_Str : %size(Cmd_Str));
    2. Create the QTEMP file that will have the file listing from from "grep"
                Cmd_Str = 'CRTDUPOBJ OBJ(I3DIR_LIST) FROMLIB(*LIBL)  OBJTYPE(*FILE) TOLIB(QTEMP)';
                Exec_OS_Command (Cmd_Str : %size(Cmd_Str));
     
    3 Direct the output of grep command from STDOUT to the QTEMP file 
                Cmd_Str = 'OVRDBF FILE(STDOUT) TOFILE(QTEMP/I3DIR_LIST) ' +
                          'OVRSCOPE(*JOB) SHARE(*YES) ' +
                          'OPNSCOPE(*JOB) SECURE(*YES) INHWRT(*NO)';
                Exec_OS_Command (Cmd_Str : %size(Cmd_Str));
     
     4 Run the Shell command to search
          *     QSH CMD('grep -Rli "00353970985316338146" *.xml')
                Cmd_Str = 'grep -Rli ' + D_Quote + %Trim(The_Search) + D_Quote + ' *.xml';
     
                Cmd_Str = 'QSH CMD(' + Quote + %Trim(Cmd_Str) + Quote + ')';
                Exec_OS_Command (Cmd_Str : %size(Cmd_Str));



    ------------------------------
    Mohan Eashver
    ------------------------------

    #RPG

    Attachment(s)



  • 2.  RE: Running the QSH command grep in RPG is taking too long

    Posted Thu June 29, 2023 10:00 PM

    Does the grep command run faster when you run it directly in QSH?

    Or does it run faster when you direct the output to an IFS file instead of using an override?



    ------------------------------
    Barbara Morris
    ------------------------------



  • 3.  RE: Running the QSH command grep in RPG is taking too long
    Best Answer

    Posted Fri June 30, 2023 01:39 AM

    It is not the answer for your problem ... but it can be easily (and much easier as with RPG) done with (embedded) SQL.

    The following SELECT returns all IFS-Files under /home/Hauser including all Sub-trees which contain 'whatever'.

    The only thing you have to consider is, the statement has to be excecuted under commitment control!

    Select Path_Name

      From Table (Qsys2.Ifs_Object_Statistics(Start_Path_Name     => '/home/Hauser',

                                              Subtree_Directories => 'YES',

                                              Object_Type_List    => '*ALLSTMF')) x

      Where   Lower(Get_Clob_From_File(Path_Name)) like '%whatever%'

      Order By Path_Name      ;   



    ------------------------------
    Birgitta Hauser
    Database and Software Engineer
    Selfemployed - Modernization-Education-Consulting on IBM i
    Kaufering
    +49 170 5269964
    ------------------------------



  • 4.  RE: Running the QSH command grep in RPG is taking too long

    Posted Fri June 30, 2023 07:53 AM

    Hi Birgitta,

    Thank you for your answer.

    I see that using Get_Clob_From_File table function will search within contents of the file.

    May I ask if you have a simple example of any embedded SQL in RPG that will show how to execute the statement under commitment control.



    ------------------------------
    Mohan Eashver
    ------------------------------



  • 5.  RE: Running the QSH command grep in RPG is taking too long

    Posted Fri June 30, 2023 08:16 AM

    You have to compile your embedded SQL Program with COMMIT *CHG.

    Or you add a SET OPTION Statement (SQL first statement in your RPG source) with COMMIT = *CHG

     EXEC SQL                  
    Set Option  Commit = *Chg;



    ------------------------------
    Birgitta Hauser
    Database and Software Engineer
    Selfemployed - Modernization-Education-Consulting on IBM i
    Kaufering
    +49 170 5269964
    ------------------------------



  • 6.  RE: Running the QSH command grep in RPG is taking too long

    Posted Fri June 30, 2023 03:59 PM
      |   view attached

    Hi Birgitta,

    I have followed your direction, but running into a problem.

    I must be making a rookie mistake & I cannot identify what it is.

    I am getting SQLSTATE = '42703' with SQLCOD = -206 after Prepare and Declare.

    An undefined column or parameter name was detected.

    Here is my SQL string:

    Select Path_Name 
    From Table(Qsys2.IFS_Object_Statistics(
    Start_Path_Name => '/i3pl/CD/arc/', 
    Subtree_Directories => 'YES', 
    Object_Type_List => '*ALLSTMF')) X 
    Where Lower(Get_Clob_From_File(Path_Name)) like '%00353970985316338146%'    

    Here is rest of my research thru debug & the SQLRPGLE source:

    MY_RAW_SQL_STR =                                                         
              ....5...10...15...20...25...30...35...40...45...50...55...60   
         1   'Select Path_Name From Table(Qsys2.IFS_Object_Statistics(Star'  
        61   't_Path_Name => '/i3pl/CD/arc/', Subtree_Directories => 'YES''  
       121   ', Object_Type_List => '*ALLSTMF')) X Where Lower(Get_Clob_Fr'  
       181   'om_File(Path_Name)) like '%00353970985316338146%'           '  
       241   '                                                            '  
       301   '                                                            '  
       361   '                                                            '  
       421   '                                                            '  
       481   '                    '   
        
    After Prepare and Declare ... An undefined column or parameter name was detected. 
    SQLSTATE = '42703' 
    SQLCOD = -000000206.         
    Class Code 42: Syntax Error or Access Rule Violation
    42703 An undefined column or parameter name was detected.
    
    After Close ...
    SQLSTATE = '24501'     
    SQLCOD = -000000501.   
    
    After Open ...
    SQLSTATE = '26501'       
    SQLCOD = -000000514.     
    
    Class Code 26: Invalid SQL Statement Identifier
    26501 The statement identified does not exist.
    
    After Fetch 
    SQLSTATE = '24501'                                                         
    SQLCODE = -501  
    Class Code 24: Invalid Cursor State
    24501 The identified cursor is not open.
    
    
             exec SQL
               Set Option Commit = *Chg;
    
             My_Raw_SQL_Str =
               'Select Path_Name ' +
               'From Table(' +
                     'Qsys2.IFS_Object_Statistics(' +
                         'Start_Path_Name => ' +
                              Quote + Source_Dir + Quote +
                         ', Subtree_Directories => ' +
                              Quote + 'YES' + Quote +
                         ', Object_Type_List => ' +
                              Quote + '*ALLSTMF' + Quote +
                                                ')' +
                         ') X ' +
               'Where Lower(Get_Clob_From_File(Path_Name)) like ' +
                        Quote + '%' + %Trim(The_Search) + '%' + Quote;
    
             exec SQL
               Prepare Dynamic_SQL_Stmt From My_Raw_SQL_Str;
    
             exec SQL
               Declare The_Cursor Cursor for Dynamic_SQL_Stmt;
    
             exec SQL
               Close The_Cursor;
    
             exec SQL
               Open The_Cursor;
    
             doW 1 = 1;
    
                 Clear Full_File_Path;
    
                 exec SQL
                   Fetch Next From The_Cursor Into :Full_File_Path;
    
                 if %Subst(SQLSTATE : 1 : 2) = '00';
    



    ------------------------------
    Mohan Eashver
    ------------------------------



  • 7.  RE: Running the QSH command grep in RPG is taking too long

    Posted Sun July 02, 2023 05:03 AM
    1. Why you are using dynamic (embedded) SQL? It is not necessary in this situation. (also if you are only searching for numbers, there is no need to wrap the Get_CLOB_From_File with LOWER.
    2. In the PREPARE Statement you missed the colon in front of My_Raw_SQL_Str


    ------------------------------
    Birgitta Hauser
    Database and Software Engineer
    Selfemployed - Modernization-Education-Consulting on IBM i
    Kaufering
    +49 170 5269964
    ------------------------------



  • 8.  RE: Running the QSH command grep in RPG is taking too long

    Posted Sun July 02, 2023 12:20 PM
      |   view attached

    Oh Birgitta thank you for spotting my rookie error. You made my day. 

    I could not wait for Monday & had try your solution right away on a Sunday morning.

    The table function returns result instantaneously. Thank you for your help.

    Yes I was missing the colon prefix on the HOST variable. 

    I needed to use Dynamic since the my path name is a variable. You will see the complete code below. (sorry earlier I did not show that)

    I will keep the LOWER since it will help when I search for alpha string.

    I am going to outline the entire code here for the benefit of our IBM i community.

    Also like to mention couple of things i noticed :

    1. This requires CCSID(37) (is it because i am in the USA...please shed a light)
    2. This SQL table function initially compiled only on OS version V7R3M0 on Friday the June 30th. 
    3. After I did all the fix I needed from Birgitta today, now strangely it can compile on V7R1M0. 
             Cmd_Str = 'CHGJOB CCSID(37)';
             Exec_OS_Command (Cmd_Str : %size(Cmd_Str));
    
             exec SQL
               Set Option Commit = *Chg;
    
             My_Raw_SQL_Str =
               'Select Path_Name ' +
               'From Table(' +
                     'Qsys2.IFS_Object_Statistics(' +
                         'Start_Path_Name => ' +
                              Quote + Source_Dir + Quote +
                         ', Subtree_Directories => ' +
                              Quote + 'YES' + Quote +
                         ', Object_Type_List => ' +
                              Quote + '*ALLSTMF' + Quote +
                                                ')' +
                         ') X ' +
               'Where Lower(Get_Clob_From_File(Path_Name)) like ' +
                        Quote + '%' + %Trim(The_Search) + '%' + Quote;
    
             exec SQL
               Prepare Dynamic_SQL_Stmt From :My_Raw_SQL_Str;
    
             exec SQL
               Declare The_Cursor Cursor for Dynamic_SQL_Stmt;
    
             exec SQL
               Close The_Cursor;
    
             exec SQL
               Open The_Cursor;
    
          *  DLTF FILE(QTEMP/I3DIR_LIST)
             Cmd_Str = 'DLTF FILE(QTEMP/I3DIR_LIST)';
             CallP(e) Exec_OS_Command (Cmd_Str : %size(Cmd_Str));
             if %Error();
                // OK if file does not exist to delete
             endIF;
    
          *  CRTDUPOBJ OBJ(I3DIR_LIST) FROMLIB(NEWSKELET) OBJTYPE(*FILE) TOLIB(QTEMP)
          *  This file I3DIR_LIST is in NEWSKELET
             Cmd_Str = 'CRTDUPOBJ OBJ(I3DIR_LIST) FROMLIB(*LIBL) ' +
                       'OBJTYPE(*FILE) TOLIB(QTEMP)';
             Exec_OS_Command (Cmd_Str : %size(Cmd_Str));
    
             Open(e) I3Dir_List;
             if %Error();
                Msg_Log = 'Cannot Open File ! ' + QTemp_File;
                exSR Write_AWMS_Log;
                exSR Return_2_CL;
             endIF;
    
             doW 1 = 1;
    
                 Clear Full_File_Path;
    
                 exec SQL
                   Fetch Next From The_Cursor Into :Full_File_Path;
    
                 if %Subst(SQLSTATE : 1 : 2) = '00';
                 else;
                    Leave;
                 endIF;
    
                 xmlFileNam = Full_File_Path;
                 Write f3Dir_List;
    
             endDO;
    
             exec SQL
               Close The_Cursor;
    
             Close I3Dir_List;
    


    ------------------------------
    Mohan Eashver
    ------------------------------