[comp.databases] So does Clipper do it ?

v442wwjl@ubvmsb.cc.buffalo.edu (Atif S Mir) (05/20/91)

Hello everyone,

		I had a minor question (w/ two parts)

1-	Is there anyway to get an index bar that shows the amount of database
	indexed at a particular instance (w/o geting into memory resident 
	programs). I tried using a function that replicates itself but it does
	not work (i.e. INDEX ON function(field) to NTX ).

2-	Before a READ, how can we find out the position of the cursor (i.e.
	which GET field it is in).


	I will really really....appriciate any help.

									Ed.

tleylan@pegasus.com (Tom Leylan) (05/21/91)

In article <77135@eerie.acsu.Buffalo.EDU> v442wwjl@ubvmsb.cc.buffalo.edu writes:
>
>1-	Is there anyway to get an index bar that shows the amount of database
>	indexed at a particular instance (w/o geting into memory resident 
>	programs). I tried using a function that replicates itself but it does
>	not work (i.e. INDEX ON function(field) to NTX ).
>
>2-	Before a READ, how can we find out the position of the cursor (i.e.
>	which GET field it is in).
>
Ed,  First thing I need to know is if you want it in S'87 or 5.0.  The index
progress indicator can be done in either but my favorite is 5.0.  I wrote
an article for Reference(Clipper) Dec '90 issue about Function Reusability
and Contracts which demonstrates three variations on a progress indicator.

Using code blocks I demonstrated a "records remaining" counter, a "percentage
done" character graphic bar and an "time remaining" indicator that reaccesses
the time after each record.  The killer with code blocks is the last part of
the demo combines all three indicators operating at the same time.

In either S'87 or 5.0 you will need a function to re-write the index header
however (I supplied it with the article) since the name of the function that
you index on will end up in the header which complicates ordinary usage.

I suppose I could place the code here as a message (other ClipperHeads may
be interested) what do you think ?

Not quite certain I understand question #2 "before a READ" ?  When you issue
the READ you'll be at the first GET in the current table.  I also need to know
whether it is S'87 or 5.0 for this one.  Check the manual on the GET system
or GETSYS.PRG on the diskettes for ideas.  Have you received your 5.01 update
yet ?

tom

kms@well.sf.ca.us (Kelly Stanonik) (05/21/91)

v442wwjl@ubvmsb.cc.buffalo.edu (Atif S Mir) writes:

>1-	Is there anyway to get an index bar that shows the amount of database
>	indexed at a particular instance (w/o geting into memory resident 
>	programs). I tried using a function that replicates itself but it does
>	not work (i.e. INDEX ON function(field) to NTX ).

Well, first of all, what version of Clipper are you trying to use?  Second
of all you can index on a function to display the update bar.  I personally
shy away from this approach since it places garbage in your index key, but
it will work.  In my systems I typically display a bar for all indexes in
the system when full-reindexing is taking place and update it after each
index.  Of course for large indexes you can be in for a wait.

>2-	Before a READ, how can we find out the position of the cursor (i.e.
>	which GET field it is in).

Well, technically the cursor isn't in a get until after a read (well I 
guess you'd say DURING a read).  row() and col() will return the row and
column of the cursor from a valid function.
-- 
* "My God, it's full of stars" -- overheard in a hamburger hamlet in west la.
* kms@well.sf.ca.us,  or bix: kms, or prodigy (yuck!) cgpd47a
* 2zip/arip              cis: 74730,77  
* free software        snail: 4469 ventura cyn #e107, sherman oaks, ca 91423

kms@well.sf.ca.us (Kelly Stanonik) (05/22/91)

tleylan@pegasus.com (Tom Leylan) writes:

>In either S'87 or 5.0 you will need a function to re-write the index header
>however (I supplied it with the article) since the name of the function that
>you index on will end up in the header which complicates ordinary usage.

>I suppose I could place the code here as a message (other ClipperHeads may
>be interested) what do you think ?

Do it!

jgb@prism.gatech.EDU (James G. Baker) (05/23/91)

In article <24910@well.sf.ca.us> kms@well.sf.ca.us (Kelly Stanonik) writes:
>Well, first of all, what version of Clipper are you trying to use?  Second
>of all you can index on a function to display the update bar.  I personally
>shy away from this approach since it places garbage in your index key, but
>it will work. 

Very true.  BUT, you can use low-level file calls to change to index
expression in the .NTX file.  fopen, fread, fwrite.  I have an index routine
that does an INDEX ON expression+stat_bar() TO index_file and then calls
a function to clean up the index_file.  (Places a null right after it finds
"expression".  Might seem a bit dangerous, but it works.  Of course your
stat_bar() needs to handle what ever type expression is and return 0 or ""
appropriately after to displays the status bar.

I've got code, if anyone is interested.  Hmmm... the xbase news seems 
to be growing... maybe it is time for a comp.databases.xbase or
comp.databases.sources.

-J Baker
-- 
BAKER,JAMES G - Undergraduate Lab Instructor, School of Electrical Engineering
____  _    _    Georgia Institute of Technology, Atlanta Georgia, 30332
  |  | _  |_)   uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!jgb 
(_|. |_). |_).  Internet: jgb@prism.gatech.edu, jgb@ee, jgb@eecom, jgb@cc

ericp@beach.csulb.edu (Eric Pederson CSE) (05/24/91)

In article <29638@hydra.gatech.EDU> jgb@prism.gatech.EDU (James G. Baker) writes:
>In article <24910@well.sf.ca.us> kms@well.sf.ca.us (Kelly Stanonik) writes:
>>Well, first of all, what version of Clipper are you trying to use?  Second
>>of all you can index on a function to display the update bar.  I personally
>>shy away from this approach since it places garbage in your index key, but
>>it will work. 
>
>Very true.  BUT, you can use low-level file calls to change to index
>expression in the .NTX file.  fopen, fread, fwrite.  I have an index routine
>that does an INDEX ON expression+stat_bar() TO index_file and then calls
>a function to clean up the index_file.  (Places a null right after it finds
>"expression".  Might seem a bit dangerous, but it works.  Of course your
>stat_bar() needs to handle what ever type expression is and return 0 or ""
>appropriately after to displays the status bar.

If you use INDEX ON stat_bar(expression) and

FUNCTION stat_bar
PARAMETERS X

... stat bar code ...

RETURN X

You don't have to worry about the type of expression.

Eric Pederson - CSULB
ericp@beach.csulb.edu

jgb@prism.gatech.EDU (James G. Baker) (05/24/91)

In article <1991May23.182713.5914@beach.csulb.edu> ericp@beach.csulb.edu (Eric Pederson  CSE) writes:
>If you use INDEX ON stat_bar(expression) and
>FUNCTION stat_bar
>PARAMETERS X
> ....
>RETURN X
>
>You don't have to worry about the type of expression.

Yes, BUT.... Now your index file has "stat_bar(expression)" and will really
die if used in any program that does not have stat_bar() defined (such as
DBU).  The idea was to keep a valid .NTX file expression.  I'm cleaning up my 
code that does it... I'll submit it tomorrow.

-J Baker
-- 
BAKER,JAMES G - Undergraduate Lab Instructor, School of Electrical Engineering
____  _    _    Georgia Institute of Technology, Atlanta Georgia, 30332
  |  | _  |_)   uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!jgb 
(_|. |_). |_).  Internet: jgb@prism.gatech.edu, jgb@ee, jgb@eecom, jgb@cc

cushman@frith.cps.msu.edu (PUT YOUR NAME HERE) (05/25/91)

This message is empty.

cushman@cpsin2.cps.msu.edu (Roderick J Cushman) (05/25/91)

In article <1991May24.173628.15324@msuinfo.cl.msu.edu> cushman@frith.cps.msu.edu (PUT YOUR NAME HERE) writes:
>   ... NULL posting; please accept my apology...  The following is what I 
>>      intended to post...

        Hi:

        (I apologize for the previous NULL posting)

                After perusing multiple articles discussing the usage of
        an index gauge (and reading the methods used), I thought I would
        attempt to shed some light (or more mud ???) upon the subject.

                Internal to Clipper version 5.0 (and I believe it is
        now documented in version 5.01) is a function called dbCreatIndex()
        (spelling ??).  I would have to look up the actual spelling of the
        function;  it can be found if you pre-process your code, then
        observe the .PPO file relevant to the INDEX ON <expr> to file.
        The parameters to the function are as follows:
 
        dbCreatIndex( cFileName, cFileExpr, bCreatExpr, lUniqflag)

                cFileName:   The name of the .NTX file to be created

                cFileExpr:   The expression to be placed in the index
                             (.NTX) file header.

                bCreatExpr:  a code block (similar to cFileExpr) which
                             is used to create the index tables.

                lUniqFlag:   a logical parameter which indicates to the
                             internal function whether the user wished
                             to INDEX ON <expr> to FILE UNIQUE
                                                        ^^^^^^


        If you examine the preprocessed code, the lUniqFlag parameter is
        an interesting if(...) conditional.  I am not sure why this was
        implemented in this manner, but a simple .T. or .F. value will
        suffice.

        You can pass to the .NTX file the expression (minus any display
        function calls), and pass to the code block the same expression,
        appended with any display function calls the user wishes.

        I tried to implement a BARCHART() routine, provided by either Rick
        Spence or Steven Straley & Assoc. (I cannot recall which book I 
        derived it from) in Summer '87.  Like the other messages I have
        read, using this feature in Summer '87 is a precarious position
        to uphold.  With the new versions (5.0*), seperating the code
        block from the file expression allows the programmer to cleanly
        perform video output of graphs, percentages, etc.

        Incidently, I have implemented the above code, deriving the params
        from a database (containing filenames, expressions, code blocks,
        unique flags, etc) and a revised function originated from the 
        people at Nantucket's tech support (theirs required a fixed position,
        color, etc.).  If anyone would like to see it, I could post a
        sample of it on the net (or email it individually).  

        I am a graduating student at this university (Michigan State U.)
        on June 8th.  I am not sure how long I will still be able to use
        this account after that.  I can be reached via the following office
 
        Rod Cushman
        W26 Holmes Hall
        Michigan State University
        East Lansing, MI, 48823

        if I cannot be contacted via the net...

        There is more information regarding indexxing, but, alas, I must
        be off to work...

Rod.

tleylan@pegasus.com (Tom Leylan) (05/26/91)

In article <1991May24.180404.18538@msuinfo.cl.msu.edu> cushman@cpsin2.cps.msu.edu (Roderick J Cushman) writes:
>
>                Internal to Clipper version 5.0 (and I believe it is
>        now documented in version 5.01) is a function called dbCreatIndex()
>        (spelling ??).  I would have to look up the actual spelling of the
>        function;  it can be found if you pre-process your code, then
>        observe the .PPO file relevant to the INDEX ON <expr> to file.
>        The parameters to the function are as follows:
> 
>        dbCreatIndex( cFileName, cFileExpr, bCreatExpr, lUniqflag)
>
Rod,  Just by way of clarification.  dbCreateIndex() is not undocumented
and is not "internal".  It should be in the NG that came with 5.01.  And
rather than read preprocessor output one can see it plainly sitting in
the STD.CH file.  I believe you will find that the NG has a small error
in the order of the arguments.

In both S'87 and 5.01 you will be required to "fix" the index header if
you index on a function.  A simple look at the index header with your
favorite hex editor will veryify the index expression.  I suggest leaving
the index string empty "" and supplying just the index code block if you
want a progress indicator.  If you don't do that you can test with a compound
key expression  lastname + firstname (for instance) and you will notice that
the index block is called only once at the beginning of the index process
and never again.  Your indicator will therefore not indicate.

I'll probably post my version later today if I can figure out how to
imbed it into a response to this thread.

tom

tleylan@pegasus.com (Tom Leylan) (05/26/91)

In article <1991May26.034816.21511@pegasus.com> tleylan@pegasus.com (Tom Leylan) writes:
>
>In both S'87 and 5.01 you will be required to "fix" the index header if
>you index on a function.  A simple look at the index header with your
>favorite hex editor will veryify the index expression.  I suggest leaving
>the index string empty "" and supplying just the index code block if you
>want a progress indicator.  If you don't do that you can test with a compound
>key expression  lastname + firstname (for instance) and you will notice that
>the index block is called only once at the beginning of the index process
>and never again.  Your indicator will therefore not indicate.
>
>I'll probably post my version later today if I can figure out how to
>imbed it into a response to this thread.
>
>tom

I sort of messed up my memory there.  Compound keys were not the problem
keys that were not compound was.  BUT... guess what ?  If you surround
the index string with "("+ "<key goes here>" + ")" then the progress
indicator will always operate and the index key imbedded in the .NTX file
is okay.  It will have parens around it but appears to make no difference
in normal operation.  In the following piece of code I have substituted
the IBM box characters with 7-bit ASCII ones and also the % done block
with an "X".  You'll want to change these back for maximum effect.>


/*
   ntx.prg

   Copyright (c) 1990, 1991, The Leylan Factor

   The Leylan Factor
   98-626 Moanalua Loop, #201
   Aiea, HI  96701-5172
   (808) 487-2230
  
   Compuserve : 74216,3212
     Internet : tleylan@pegasus.com

   compile : clipper ntx /n/w

   By The Way : to run this demo you need the following file

   Structure for database: NTX
   Number of data records:  100 to 1000 for a meaningful test

   Field  Field Name  Type       Width    Dec
       1  NAME        Character     30     
       2  STATE       Character      2     
   ** Total **                      33

*/

#include "set.ch"
#include "fileio.ch"

/* to curtail the warnings */
FIELD name, state


FUNCTION Main
   LOCAL nRec, nMax, bIndex
   LOCAL xCursor := SET( _SET_CURSOR, .F. )

   CLS

   /* index with "records remaining" indicator */

   @ 5, 21, 7, 54 BOX "+-+|+-+| " ; @ 6, 23 SAY "Records Remaining :"

   USE ntx EXCLUSIVE NEW

   nRec := 1
   nMax := (LASTREC() + 1)

   bIndex := { || DevPos( 6, 43), ;
                  DevOutPict( ( nMax - nRec ), "99,999,999" ), nRec++, ;
                  state + name }

   dbCreateIndex( "ntx1", "("+"name + state"+")", bIndex, NIL )

   CLOSE ntx


   /* index with "percentage done" indicator */

   @ 11, 10 SAY "0% " + REPL( ".", 50 ) + " 100%"

   USE ntx EXCLUSIVE NEW

   nRec := 1
   nMax := (LASTREC() + 1)

   bIndex := { || DevPos( 11, 13 + ((nRec / nMax) * 49) ), ;
                  DevOut( "X" ), nRec++, ;
                  state + name }

   dbCreateIndex( "ntx2", "("+"name + state"+")", bIndex, NIL )

   CLOSE ntx


   /* index with "approximate time remaining" indicator */

   @ 15, 23, 17, 52 BOX "+-+|+-+| " ; @ 16, 25 SAY "Time Remaining :"

   USE ntx EXCLUSIVE NEW

   nRec := 1
   nMax := (LASTREC() + 1)

   bIndex := { || DevPos( 16, 42), ;
                  DevOut( NtxTime( ((Timer( TIME() ) / nRec) * ;
                        (nMax - nRec))) ), nRec++, ;
                  state + name }

   NtxTime( NIL )
   Timer( NIL )

   dbCreateIndex( "ntx3", "("+"name + state"+")", bIndex, NIL )

   CLOSE ntx


   /* index with "the kitchen sink" indicator */

   @ 5, 21, 7, 54 BOX "+-+|+-+| " ; @ 6, 23 SAY "Records Remaining :"

   @ 11, 10 SAY "0% " + REPL( ".", 50 ) + " 100%"

   @ 15, 23, 17, 52 BOX "+-+|+-+| " ; @ 16, 25 SAY "Time Remaining :"

   USE ntx EXCLUSIVE NEW

   nRec := 1
   nMax := (LASTREC() + 1)

   bIndex := { || DevPos( 6, 43), ;
                  DevOut( TRANSFORM(( nMax - nRec ), "99,999,999" )), ;
                  DevPos( 11, 13 + ((nRec / nMax) * 49) ), ;
                  DevOut( "X" ), ;
                  DevPos( 16, 42), ;
                  DevOut( NtxTime( ((Timer( TIME() ) / nRec) * ;
                        (nMax - nRec))) ), nRec++, ;
                  state + name }

   NtxTime( NIL )
   Timer( NIL )

   dbCreateIndex( "ntx4", "("+"name + state"+")", bIndex, NIL )

   CLOSE ntx


   /* position cursor and exit */

   DevPos( 23, 0)
   
   SET( _SET_CURSOR, xCursor )
   RETURN NIL


FUNCTION NtxTime( nSeconds )
   STATIC nOld

   LOCAL nHr, nMin, nSec, nNew

   IF nSeconds == NIL
      nOld := 999999
      nSeconds := 0
   ENDIF

   nSec := nSeconds
   nHr  := INT( nSec / 360)
   nSec := ( nSec - ( nHr * 360 ) )
   nMin := INT( nSec /  60)
   nSec := ( nSec - ( nMin * 60 ) )

   nNew := (nHr * 10000) + (nMin * 100) + nSec

   IF (nNew <= nOld ) .AND. !(nSeconds == 0 )
      nOld := nNew
   ENDIF

   nSec := nOld
   nHr  := INT( nSec / 360)
   nSec := ( nSec - ( nHr * 360 ) )
   nMin := INT( nSec /  60)
   nSec := ( nSec - ( nMin * 60 ) )

   RETURN RIGHT( STR( nHr  + 100, 3 ), 2 ) + ":" + ;
          RIGHT( STR( nMin + 100, 3 ), 2 ) + ":" + ;
          RIGHT( STR( nSec + 100, 3 ), 2 )


FUNCTION Timer( cTime )
   STATIC nMark

   IF cTime == NIL
      cTime := TIME()
      nMark := ((VAL( SUBS( cTime, 1, 2 )) * 360 ) + ;
                (VAL( SUBS( cTime, 4, 2 )) *  60 ) + ;
                (VAL( SUBS( cTime, 7, 2 )) - 1 ))
   ENDIF

   RETURN ((VAL( SUBS( cTime , 1, 2 )) * 360 ) + ;
           (VAL( SUBS( cTime , 4, 2 )) *  60 ) + ;
           (VAL( SUBS( cTime , 7, 2 )))) - nMark

tleylan@pegasus.com (Tom Leylan) (05/27/91)

In article <1991May26.095656.25202@pegasus.com> tleylan@pegasus.com (Tom Leylan) writes:
>
>   dbCreateIndex( "ntx4", "("+"name + state"+")", bIndex, NIL )
>
I sort of overly complicated that string expression.

   "(name + state)"
or "(name)" would work also.

Use parens if you use a progress indicator, don't bother if you aren't.

tom