• Welcome to OS2World OLD-STATIC-BACKUP Forum.
 

News:

This is an old OS2World backup forum for reference only. IT IS READ ONLY!!!

If you need help with OS/2 - eComStation visit http://www.os2world.com/forum

Main Menu

Call another script

Started by jep, 2011.12.24, 12:20:51

Previous topic - Next topic

jep

Hello,

This script use another script (see "Database engine written in rexx") through the use of SysAddRexxMacro available in Rexxutil that come with Object Rexx and is included with eComstation.
Please note that cut and paste may not work reliably for certain special characters, so please ensure to double check the code before usage.

This script also contain some functions you may want to try somewhere else.
rxProgress can handle up to 6 values for progress at once.
It can be quite handy if you want to show how large each processing step is and how much of that has been handled.
It only update the progress bar every second even though you may call it more often.

Notice the use of RIGHT( STREAM( file.i, 'C', 'QUERY SIZE' ), 10 ) to be able to order output according to numeric file size with SELECT ... ORDER BY FILESIZE in rxdb.cmd (see "Database engine written in rexx").

/*
* Filename: add2db.cmd
*   Author: JAN-ERIK
*  Created: Sat Dec 24 2011
*  Purpose: Script that use another script to add data to database (csv-like)
*  Changes:
*/

/* Load RexxUtil Library */
If RxFuncQuery('SysLoadFuncs') Then
Do
    Call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
    Call SysLoadFuncs
End

CALL SysCls
SAY ''
SAY ''
SAY ''
If RxFuncQuery('SysAddRexxMacro') Then
    RETURN 1

retval = SysAddRexxMacro( 'rxSQL','rxdb.cmd', 'B' )
IF ARG() = 0 THEN
DO
CALL CHAROUT , 'Specify drive to list and add to database: '
PARSE PULL answer
END
ELSE answer = ARG(1)

IF rxProcess( LEFT( answer, 1 )||':' ) THEN
    Call rxProgress 2, 1
RETURN 0

rxProcess: PROCEDURE EXPOSE  __meter.
    PARSE ARG path, progress, chunk
    IF progress = '' THEN progress = 0
    IF chunk = '' THEN chunk = 1
    rc = SysFileTree( path||'\*.*', 'folder', 'DO' )
    rc = SysFileTree( path||'\*.*', 'file', 'FO' )
    DO i = 1 TO file.0
        CALL rxBusy 1, file.i
        CALL rxProgress 2, progress + ( i - 1 ) / ( file.0 + folder.0 ) * chunk
        CALL rxSQL "INSERT INTO files (COMPUTER,PATH,NAME,DRIVE,FILESIZE) VALUES ('"||VALUE( 'HOSTNAME',, 'OS2ENVIRONMENT' )||"','"||FILESPEC( 'P', file.i )||"','"||FILESPEC( 'N', file.i )||"','"||FILESPEC( 'D', file.i )||"','"||RIGHT( STREAM( file.i, 'C', 'QUERY SIZE' ), 10 )||"')"
    END
    DO i = 1 TO folder.0
        CALL rxBusy 1, folder.i
        Call rxProgress 2, progress + ( i + file.0 - 1 ) / ( file.0 + folder.0 ) * chunk
        CALL rxProcess folder.i, progress + ( i + file.0 - 1 ) / ( file.0 + folder.0 ) * chunk, chunk / ( file.0 + folder.0 )
    END
RETURN 1

/* display_on_row, part  */
rxProgress: PROCEDURE EXPOSE  __meter.
/*    IF TRACE() <> 'O' THEN RETURN 0*/
    row = ARG(1)
    chr = '█▓▒░■█ '
    IF \DATATYPE( __meter.width, 'W' ) THEN
        PARSE VALUE SysTextScreenSize() WITH . __meter.width
    DO i = 2 TO MIN( ARG(), LENGTH( chr ) )
        j = i - 1
        IF \DATATYPE( ARG(i), 'N' ) THEN RETURN 0
        progress.j = FORMAT( ARG(i),,, 0 )
        IF LENGTH( FORMAT( 100 * progress.j,, 0, 0 ) ) > 3 THEN
            RETURN 0
    END
    progress.0 = j
    processed.0 = 0
    output = ''
    CALL SysStemSort 'progress'
    DO i = 1 TO MIN( progress.0, LENGTH( chr ) )
        j = i - 1
        processed.i = FORMAT( MIN( ( __meter.width - 4 ) * progress.i , __meter.width - 4 ),, 0, 0 )
        progress.i = FORMAT( 100 * progress.i, 3, 0, 0 )
       
        IF processed.i > processed.j THEN
            output = output||COPIES( SUBSTR( chr, i, 1 ), processed.i - processed.j )
    END
    i = i - 1
    output = output||COPIES( SUBSTR( chr, LENGTH( chr ), 1 ), __meter.width - 4 - processed.i )
    CALL rxOut ARG(1), output||RIGHT( progress.1||'%', 4 )
RETURN 0

/* display_on_row, text  */
rxBusy: PROCEDURE EXPOSE __meter.
/*    IF TRACE() <> 'O' THEN RETURN 0*/
    PARSE ARG row, txt   
    IF \DATATYPE( __meter.row.t_stamp , 'N' ) THEN
        __meter.row.t_stamp = TIME( 'S' )
    IF __meter.row.t_stamp + 1 < TIME( 'S' ) THEN
    DO
        SELECT
            WHEN __meter.counter = 1 THEN
                CALL rxOut row, '/ '||txt
            WHEN __meter.counter = 2 THEN
                CALL rxOut row, '- '||txt
            WHEN __meter.counter = 3  THEN
                CALL rxOut row, '\ '||txt
            OTHERWISE
            __meter.counter = 0
            CALL rxOut row, '| '||txt
        END
        __meter.counter = __meter.counter + 1
    END
RETURN 0

/* display_on_row, text  */
rxOut: PROCEDURE EXPOSE __meter.
/*    IF TRACE() <> 'O' THEN RETURN 0*/
    PARSE ARG row, txt
    IF \DATATYPE( __meter.row.t_stamp, 'W' ) THEN
        PARSE VALUE SysTextScreenSize() WITH . __meter.width
    isNum = DATATYPE( row, 'W' )
    IF isNum THEN
    DO
        IF DATATYPE( __meter.row.t_stamp, 'W' ) THEN
            IF __meter.row.t_stamp + 1 > TIME( 'S' ) THEN RETURN 0
        PARSE VALUE SysCurPos( row, 0 ) with prev_row prev_col
    END
    ELSE IF DATATYPE( __meter.row.t_stamp, 'W' ) THEN
        IF __meter.row.t_stamp + 1 > TIME( 'S' ) THEN RETURN 0
    SAY LEFT( txt, MAX( __meter.width, MIN( LENGTH( ARG(2) ), __meter.width ) ) )
    IF isNum THEN
    DO
        CALL SysCurPos prev_row, prev_col
        __meter.row.t_stamp = TIME( 'S' )
    END
    ELSE
        __meter.row.t_stamp = TIME( 'S' )
RETURN 0


Merry XMas from Sweden
//Jan-Erik

RobertM

#1
For those not up on Rexx MacroSpace, there are many advantages (and a few disadvantages) of using it. The disadvantages are pretty clearly spelled out in the documentation for the Macrospace functions, so I won't go into those. The advantages are primarily tied to one aspect of them:

Macrospace functions work very similar to a loaded shared dll. Inotherwords, by adding functions to Macrospace and calling them from there, they act just as making a function call to a shared dll. The macrospace functions/elements are loaded once into memory, and called from there.

THUS:


It allows streamlining scripts, saving memory (Function A through Function G do not need to get loaded on every script load - or at all if they aren't being used by the script), and finally, it allows easily having the same functionality for different scripts.

On that last one (and touching on a few of the others), here's a more in depth explanation:
Lets say Script1.cmd through Script10.cmd use RandomFunctionA(params). And lets say these scripts are being called by a web server. Somewhere along the way, you decide to improve RandomFunctionA() - let's say it was a sort routine, and instead of doing an entire list scan, it now uses a better search algorithm (or whatever type of changes to the function you can come up with). Now, you simply load the new RandomFunctionA into Macrospace and you are done. Otherwise, you'd have to edit Script1 through Script10 individually.

Now the other advantage, that can be important in a web server type environment (or similar) is the memory savings. Lets say RandomFunctionA is 50K. Lets say you've got a decent amount of traffic to your web server (say 100 connections per second). Your web server is now allocating 5MB of memory for JUST RandomFunctionA - even if a bunch of the calls to ScriptX.cmd never need to use RandomFunctionA (yes, this assumes those page loads are all calling Script1-Script10 - such as some of the fully dynamic websites we have). OR... RandomFunctionA could be in Macrospace and only loaded into memory once - again, just like a function in a shared DLL. The "environment" memory (for variables and such) remains basically the same - but the function now consumes 50K instead of 5MB. And the more functions moved to Macrospace, the greater the savings.






Or, the simple explanation: using Macrospace can (a) save memory resources, (b) disk usage (function loaded (ie: disk access) once into RAM), (c) improve speed (running something already in memory is faster than reading the disk to put it in memory each time) and (d) it makes maintaining multiple scripts a lot easier, as one only needs to update the Macrospace function (if it changes) instead of updating every script that uses that function (ie: if that function is coded into each script instead of being called from Macrospace).






Or... even simpler: using Macrospace functions whenever possible is much better than having those functions coded into scripts.




Learning how and when to use Macrospace functions can be a PITA (though a lot less so, thanks to Jep's post on that subject), but is worth the effort in many cases.

And to Jep, where were you 10 years ago when I was first learning how to use Macrospace?!?!?!  ;)  ;D  :P


|
|
Kirk's 5 Year Mission Continues at:
Star Trek New Voyages
|
|


jep

Thank you RobertM for the explenation.
I was thinking about it like a "plugin" one could load and use.
Quote from: RobertM on 2011.12.29, 21:35:35
And to Jep, where were you 10 years ago when I was first learning how to use Macrospace?!?!?!  ;)  ;D  :P
I started to try it out the day before XMAs, so you're about 10 years ahead of me :D

//Jan-Erik