home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
-
- STATUS version 1.10
- (c) 1992
- by
- John T. Opincar, Jr.
- CID: 71631,541
-
- February 27, 1992
-
- =================================================================
- COPYRIGHT NOTICE
- =================================================================
- PLEASE READ THIS!
-
- You are free to distribute STATUS in any manner you choose and
- use STATUS in any setting, including commercial without any
- obligation to me. The only thing that I ask is that you do not
- distribute modified versions of STATUS without including the
- original code and documentation in its entirety. If you feel
- inclined to distribute STATUS with your own modifications (which
- I would discourage), ***PLEASE*** keep your changes in seperate
- files, and make the seperation and changes obvious to anyone who
- might subsequently encounter the ZIP.
-
- I have been informally supporting STATUS on CIS, and do not want
- a zillion messages about problems introduced by others. In lieu
- of making your own changes, I would prefer that you send me e-
- mail describing the additional features you would like to see in
- STATUS. The exceptional performance gains yielded by STATUS are
- the result of several key assumptions about how it will be used.
- Before making a suggestion, please read the section in the
- documentation entitled, "What Makes STATUS Tick." The main
- motivation behind this version of STATUS was input I received
- from users.
-
- Finally, some users of the first version expressed a desire to
- pay for STATUS, even though no payment was requested. If you
- wish to send in a payment (none is required, but WILL be
- appreciated) send it to:
- John T. Opincar, Jr.
- 6531 West Medalist
- Plano, TX 75023
-
- =================================================================
- INTRODUCTION
- =================================================================
- This small library was inspired by a thread I encountered while
- lurking on NANFORUM. The purpose of these functions is to
- provide the user with feedback on the progress of PACKs and
- INDEXes without incurring significant overhead. This is
- accomplished by hooking the timer interrupt and updating the
- progress display isosynchronously using the current values of
- RECNO() and LASTREC() in the currently SELECTed database.
-
- This is the second version of STATUS. New features include:
-
-
-
- 1
-
-
-
-
-
-
-
-
- * Simultaneous display of a progress bar and percent number
- * The ability to specify color as either a number or Clipper
- color string
- * The ability to specify the charcter used to fill in the
- progress bar
- * StatusPack(), a high-level interface to the STATUS functions
- that will let you use STATUS without really getting your
- hands dirty
-
- The best example of how to use the STATUS functions is in
- TIMENTXP.PRG. If StatusPack() does not do exactly what you want,
- then you will need to use the lower level functions. A brief
- overview of how to do this follows:
- 1) Enable/Disable the display of the progress bar using
- StatusBar()
- 2) Enable/Disable the display of the percent number using
- StatusNumber()
- 3) USE or SELECT the database which will be acted upon
- 4) Position the record pointer to the first record to be
- processed. The record numbers must be encountered in
- natural order, ie no index should be controlling the
- ordering of the records. A filter can be in effect, eg
- !deleted().
- 5) Call StatusOn()
- 6) Begin processing records, eg PACK or INDEX ON TO
- 7) Call StatusOff()
-
- You can use these functions in your Clipper 5.x code (NOT Summer
- '87 compatible) by including STATUS.LIB in your link file. If
- you wish to check the return codes of STATUS functions, #include
- "status.ch" in your program files.
-
- Please read the rest of this SHORT documentation carefully before
- attempting to use these functions.
-
-
- -----------------------------------------------------------------
- STATUSBAR()
- -----------------------------------------------------------------
-
- SYNTAX
- ------
- StatusBar(<nRow>, [<nCol>, <barChar>, <barColor>]) -> nErrorCode
-
- RETURNS
- -------
- 0 if everything is OK, a negative error code otherwise. The
- possible error codes returned by StatusBar() are BAD_PARM_COUNT,
- TYPE_MISMATCH, and BAD_COORDS. For a complete explanation, see
- "Description of Error Codes" below.
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
- ARGUMENTS
- ---------
- <nRow> is the row where the progress bar will be displayed. If
- <nRow> is negative, then display of the progress bar will be
- disabled. Note that when a negative value is specified for
- <nRow>, <nRow> is the only argument expected to be passed.
-
- <nCol> is the column where the progress bar will be displayed.
-
- <barChar> can be either a character or the ASCII value of the
- character which will be used in the progress bar.
-
- <barColor> can be either a number or Clipper color specification,
- eg. "W+/R". See "Specifying Colors As Numbers" below, if you are
- unfamiliar with numeric color attributes and would like to use
- them.
-
- DESCRIPTION
- -----------
- StatusBar() allows you to specify the position, color, and
- composition of the progress display bar. You can also disable
- the display of the progress bar by passing a negative value for
- <nRow>. Note that the number of arguments expected by
- StatusBar() changes depending on the value of <nRow>. If <nRow>
- is negative, then StatusBar() expects exactly one argument. If
- more arguments are passed, StatusBar() will return an error code,
- BAD_PARM_COUNT, and the erroneous call to StatusBar() will have
- no effect. If <nRow> is non-negative, exactly 4 arguments are
- expected.
-
- StatusBar() should be called before StatusOn(). Note that only
- one call to StatusBar() is needed, assuming that you do not want
- to change the position, color, or display character for
- subsequent progress displays.
-
- You can have both a progress bar and percent number displayed
- simultaneously. See StatusNumber() below.
-
- EXAMPLES
- --------
- /* Set progress bar display at position 10,5 using a shaded block
- character in high intensity white on red. */
- StatusBar(10, 5, 176, 'w+/r')
- use EMPLOYEE exclusive new
- StatusOn()
- pack
- StatusOff()
-
- /* Note that subsequent progress display will use settings from
- last call to StatusBar() */
- dbGoTop()
- StatusOn()
- index on upper(NAME) to EMPLNAME
- StatusOff()
-
-
-
- 3
-
-
-
-
-
-
-
-
-
- /* Disable progress bar display */
- StatusBar(-1)
-
- /* Erroneous call to StatusBar() that will be ignored */
- ? StatusBar(-1, 5, 176, 'w+/r') /* returns BAD_PARM_COUNT */
-
- /* Another erroneous call to StatusBar() that will be ignored */
- ? StatusBar(5, 5) /* returns BAD_PARM_COUNT */
-
- SEE ALSO
- --------
- StatusNumber()
-
-
- -----------------------------------------------------------------
- STATUSNUMBER()
- -----------------------------------------------------------------
-
- SYNTAX
- ------
- StatusNumber(<nRow>, [<nCol>, <numColor>]) -> nErrorCode
-
- RETURNS
- -------
- 0 if everything is OK, a negative error code otherwise. The
- possible error codes returned by StatusNumber() are
- BAD_PARM_COUNT, TYPE_MISMATCH, and BAD_COORDS. For a complete
- explanation, see "Description of Error Codes" below.
-
- ARGUMENTS
- ---------
- <nRow> is the row where the percent number will be displayed. If
- <nRow> is negative, then display of the percent number will be
- disabled. Note that when a negative value is specified for
- <nRow>, <nRow> is the only argument expected to be passed.
-
- <nCol> is the column where the percent number will be displayed.
-
- <numColor> can be either a number or Clipper color specification,
- eg. "W+/R".
- See "Specifying Colors As Numbers" below, if you are unfamiliar
- with numeric color attributes and would like to use them.
-
- DESCRIPTION
- -----------
- StatusNumber() allows you to specify the position and color of
- the percent number. You can also disable the display of the
- percent number by passing a negative value for <nRow>. Note that
- the number of arguments expected by StatusNumber() changes
- depending on the value of <nRow>. If <nRow> is negative, then
- StatusNumber() expects exactly one argument. If more arguments
- are passed, StatusNumber() will return an error code,
- BAD_PARM_COUNT, and the erroneous call to StatusNumber() will
-
-
-
- 4
-
-
-
-
-
-
-
-
- have no effect. If <nRow> is non-negative, exactly 3 arguments
- are expected.
-
- StatusNumber() should be called before StatusOn(). Note that
- only one call to StatusNumber() is needed, assuming that you do
- not want to change the position or color of the percent number
- for subsequent progress displays.
-
- You can have both a percent number and progress bar displayed
- simultaneously. See StatusBar() above.
-
- EXAMPLES
- --------
- /* Set percent number at position 10,5 in high intensity white on
- red. */
- StatusNumber(10, 5, 'w+/r')
- use EMPLOYEE exclusive new
- StatusOn()
- pack
- StatusOff()
-
- /* Note that subsequent progress display will use settings from
- last call to StatusNumber() */
- dbGoTop()
- StatusOn()
- index on upper(NAME) to EMPLNAME
- StatusOff()
-
- /* Disable percent number display */
- StatusNumber(-1)
-
- /* Erroneous call to StatusNumber() that will be ignored */
- ? StatusNumber(-1, 5, 'w+/r') /* returns BAD_PARM_COUNT */
-
- /* Another erroneous call to StatusNumber() that will be ignored
- */
- ? StatusNumber(5, 5) /* returns BAD_PARM_COUNT */
-
- SEE ALSO
- --------
- StatusBar()
-
-
- -----------------------------------------------------------------
- STATUSON()
- -----------------------------------------------------------------
-
- SYNTAX
- ------
- StatusOn([<nTicks>]) -> nErrorCode
-
-
-
-
-
-
-
- 5
-
-
-
-
-
-
-
-
- ARGUMENTS
- ---------
- <nTicks> is the number of timer ticks (approx. 1/18 seconds per
- tick) between updates of the progress display. This argument is
- optional and will default to 18 if not passed.
-
- RETURNS
- -------
- 0 if everything is OK, a negative error code otherwise. The
- possible error codes returned by StatusOn() are BAD_PARM_COUNT,
- TYPE_MISMATCH, BAD_TICKS, NO_DBF_USED, and BAD_ORDER.
-
- DESCRIPTION
- -----------
- StatusOn() activates the timed display of progress information at
- the specified coordinates. The display will be updated every
- <nTicks> based on the current position of the record pointer
- relative to the total number of records in the database.
- Progress will be displayed using a bar up to 50 characters wide
- and/or a number between 0 and 100 representing the percentage of
- the task which has been completed (see StatusBar() and
- StatusNumber() above).
-
- There are two important restrictions on the use of StatusOn().
- First, the currently SELECTed area CANNOT be changed between the
- calls to StatusOn() and StatusOff(). Second, the records of the
- currently selected database must be traversed in their natural
- order, ie record #1 must come before record #2, etc. There are
- good reasons for these restrictions. See "What Makes STATUS
- Tick" below. These restrictions reflect the two primary uses of
- STATUS -- to display the progress of the INDEX and PACK.
-
- A reasonable value for <nTicks> is 18 which means that the
- progress display will be updated every second. Keep in mind that
- smaller values for <nTicks> incur greater overhead because the
- progress display is updated more frequently.
-
- NOTE: StatusOn() should only be called AFTER the database for
- which progress will be monitored has been USEd or SELECTed and
- the record pointer has been positioned to the first record to be
- processed.
-
- NOTE: Every call to StatusOn() should be followed by a call to
- StatusOff() before the currently SELECTed area is changed.
-
- EXAMPLES
- --------
- See TIMENTXP.PRG
-
- SEE ALSO
- --------
- StatusOff()
-
-
-
-
-
- 6
-
-
-
-
-
-
-
-
- -----------------------------------------------------------------
- STATUSOFF()
- -----------------------------------------------------------------
-
- SYNTAX
- ------
- StatusOff() -> NIL
-
- DESCRIPTION
- -----------
- StatusOff() turns off the progress display. StatusOff() should
- always be called after StatusOn() and before the currently
- SELECTed database is CLOSEd or another area is SELECTed.
-
- SEE ALSO
- --------
- StatusOn()
-
-
- -----------------------------------------------------------------
- STATUSPACK()
- -----------------------------------------------------------------
-
- SYNTAX
- ------
- StatusPack(<cDbfName>, [<aNtxInfo>]) -> lSuccess
-
- ARGUMENTS
- ---------
- <cDbfName> is the name of the database to be PACKed and have its
- indices built. Do NOT add the .DBF extension.
-
- <aNtxInfo> is an array of arrays. Each sub-array should contain
- the index name as its first element and the index key as its
- second element. <aNtxInfo> is optional. If not passed, then the
- database will only be PACKed.
-
- RETURNS
- -------
- .T. if the PACK and INDEX operations were successful.
-
- DESCRIPTION
- -----------
- StatusPack() is a high-level interface to the rest of the STATUS
- functions. It displays a box with a line for the pack progress
- display and one line to display the progress for each index to be
- built. If the specified database is already in USE, it will be
- closed and an attempt will be made to re-USE it EXCLUSIVEly.
-
-
-
-
-
-
-
-
-
- 7
-
-
-
-
-
-
-
-
- EXAMPLES
- --------
- StatusPack('people', { {'peopname', 'upper(LAST)+upper(FIRST)'},;
- {'peopphon', 'PHONE'}, ;
- {'peopcity', 'upper(CITY)'}, ;
- {'peopzip', 'ZIP'} })
-
-
- =================================================================
- DESCRIPTION OF ERROR CODES
- =================================================================
- Error codes are returned as negative integers. These codes are
- defined in STATUS.CH. A brief explanation of what each of these
- codes means follows.
-
- BAD_PARM_COUNT (-1)
- -------------------
- The wrong number of arguments was passed to a function.
-
- TYPE_MISMATCH (-2)
- -------------------
- The wrong type of argument was passed to a function.
-
- BAD_COORDS (-3)
- -------------------
- Invalid coordinates were passed to either StatusBar() or
- StatusNumber(). Note that a negative row can be passed as the
- first and only argument to either StatusBar() or StatusNumber()
- which disables the respective display. In any other case,
- negative coordinates are invalid.
-
- BAD_TICKS (-4)
- -------------------
- A zero or negative value was passed to StatusOn() as the <nTicks>
- argument.
-
- NO_DBF_USED (-5)
- -------------------
- StatusOn() was called and no database was in USE in the currently
- SELECTed area.
-
- BAD_ORDER (-6)
- -------------------
- StatusOn() was called and the database in USE in the currently
- SELECTed area had an index controlling its order.
-
-
- =================================================================
- SPECIFYING COLORS AS NUMBERS
- =================================================================
- Both StatusBar() and StatusNumber() take a color as one of their
- arguments. You can specify color as a Clipper color string, or
- you can pass a number. I detest the cumbersome xBase color
- string system and never use it in my own code. If you also use
-
-
-
- 8
-
-
-
-
-
-
-
-
- color numbers, then you probably don't need to see this, but I
- included it for the sake of completeness.
-
- Black 0 Dark Gray 8
- Blue 1 Light Blue 9
- Green 2 Light Green 10
- Cyan 3 Light Cyan 11
- Red 4 Light Red 12
- Magenta 5 Light Magenta 13
- Brown 6 Yellow 14
- Light Gray 7 White 15
-
- To construct foreground and background combinations, use the
- following formula: (background * 16) + foreground. Note that
- using any of the colors in the second column as the background
- value may cause blinking depending on the current state of the
- video adapter.
-
- Note that many of these colors and combinations thereof will not
- be available on monochrome and LCD displays.
-
- =================================================================
- WHAT MAKES STATUS TICK?
- =================================================================
- The use of STATUS has very little impact on the time required to
- PACK and INDEX databases. One user compared three different
- methods of packing and indexing on a large database. The first
- method was straight PACK and INDEX with no progress display which
- was used as a baseline. The second method was to include a user-
- defined progress display function as part of the index
- expression. This resulted in 50% increase in the time required
- to PACK and INDEX the database. The third method was using
- STATUS which resulted in a mere 2% increase.
-
- There are two key reasons for this. First, STATUS uses the timer
- interrupt to update the progress display isosynchronously. This
- means that the rate at which the display is updated is driven by
- the needs of the user, not by the number of records in the
- database. A naive progress display UDF will update the display
- every time it is called, ie once for every record. If there are
- more than 100 records in the database, then some of these updates
- will re-write what is already on the screen. As the number of
- records in the database becomes large, the majority of updates
- are useless. A sophisticated UDF can avoid these needless
- updates by calculating a delta value or tracking time. Thus,
- isosynchronous display alone, does not make STATUS any better
- than a well-written UDF.
-
- However, any UDF, no matter how well-written must still incur the
- overhead of a Clipper function call and building a Clipper stack
- frame is relatively expensive. This points out the second key to
- STATUS's superior performance: no Clipper function call is
- required. STATUS directly accesses the record number and record
- count in the Workareas structure.
-
-
-
- 9
-
-