diff --git a/ChangeLog.txt b/ChangeLog.txt index 9b891b4592..49a41e9eca 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,28 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2024-05-31 11:49 UTC+0200 Aleksander Czajczynski (hb fki.pl) + * contrib/rddmisc/arrayrdd.prg + ! group of fixes contributed in #355 by @VarenL: + IndexOrd() didn't work, DbZap() didn't update indexes, problem + with larger number of indexes, erroneous AR_GOBOTTOM function. + + + doc/en/rdddb.txt + + readded a 2017 copy + + * contrib/hbamf/amfstdio.c + * flow-control is now optional, but still enabled by default + + ! fix missing free when exiting the loop + + * contrib/hbpgsql/rddcopy.c + ! fix c&p bug/typo in HB_PQCOPYFROMWA, corrected handling field list + passed in parameter + + := HB_PQCOPYFROMWA( , , [], + [], [], [], + [], [] ) + 2024-05-13 02:39 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * ChangeLog.txt * src/rtl/fscopy.c diff --git a/contrib/hbamf/amfstdio.c b/contrib/hbamf/amfstdio.c index bfd233e4a2..5fb53fd5d9 100644 --- a/contrib/hbamf/amfstdio.c +++ b/contrib/hbamf/amfstdio.c @@ -55,16 +55,23 @@ static int s_nCount = 0; -static void countCheck( int n ) +static void countCheck( int n, int nFlowCtrl ) { - /* yes, this is flow-control */ + /* implements flow control for interacting with ill-strange non-configurable + environments that lose data when writing too much into such STDIN pipe. + specify nFlowCtrl = 0 to disable */ + if( ! nFlowCtrl ) + return; s_nCount += n; - while( s_nCount >= SINGLEBUF ) + while( s_nCount >= nFlowCtrl ) { + /* this 32-bit uint 'zero' should be discarded from buffer every + nFlowCtrl bytes, when received on the other side - after such + notification other process is allowed to send more data */ hb_conOutStd( "\0\0\0\0", 4 ); - s_nCount -= SINGLEBUF; + s_nCount -= nFlowCtrl; } } @@ -72,9 +79,6 @@ HB_FUNC( AMFSTDIO_READ ) { char * pszStrIn = ( char * ) hb_xgrab( SINGLEBUF ); char * pszLenPrefix = ( char * ) hb_xgrab( 5 ); - #if 0 - char * pszBuf; = ( char * ) hb_xgrab( SINGLEBUF ); - #endif char * pszBuf; char * pszTmp = pszLenPrefix; HB_USHORT nBytes; @@ -82,13 +86,21 @@ HB_FUNC( AMFSTDIO_READ ) int nLen; int nToRead; HB_FHANDLE hStdIn = hb_fsGetOsHandle( HB_STDIN_HANDLE ); + int nFlowCtrl = hb_parnidef( 1, SINGLEBUF ); + /* 0 - disable flow control, 32768 - by default */ while( nTotal < 4 ) { nToRead = ( s_nCount + 4 - nTotal > SINGLEBUF ? SINGLEBUF - s_nCount : 4 - nTotal ); nBytes = hb_fsRead( hStdIn, pszStrIn, ( HB_USHORT ) nToRead ); - - countCheck( nBytes ); + if( ! nBytes ) + { + hb_xfree( pszStrIn ); + hb_xfree( pszLenPrefix ); + hb_ret(); + return; + } + countCheck( nBytes, nFlowCtrl ); memcpy( pszTmp, pszStrIn, nBytes ); nTotal += nBytes; @@ -100,6 +112,8 @@ HB_FUNC( AMFSTDIO_READ ) if( nLen >= MAXLEN ) { + hb_xfree( pszStrIn ); + hb_xfree( pszLenPrefix ); hb_ret(); return; } @@ -122,7 +136,7 @@ HB_FUNC( AMFSTDIO_READ ) nBytes = hb_fsRead( hStdIn, pszStrIn, ( HB_USHORT ) nToRead ); - countCheck( nBytes ); + countCheck( nBytes, nFlowCtrl ); memcpy( pszTmp, pszStrIn, nBytes ); nTotal += nBytes; diff --git a/contrib/hbpgsql/rddcopy.c b/contrib/hbpgsql/rddcopy.c index 5edbe6028d..5295b01364 100644 --- a/contrib/hbpgsql/rddcopy.c +++ b/contrib/hbpgsql/rddcopy.c @@ -396,7 +396,7 @@ HB_FUNC( HB_PQCOPYFROMWA ) { if( SELF_GETVALUE( pArea, ( HB_USHORT ) hb_arrayGetNI( pFields, uiIter ), pItem ) != HB_SUCCESS || ! exportBufSqlVar( context, pItem, sc_szQuote, sc_szEsc ) || - ! addStrToContext( context, uiIter == uiFields ? "\n" : sc_szDelim ) ) + ! addStrToContext( context, uiIter == uiFieldCopy ? "\n" : sc_szDelim ) ) { bFail = HB_TRUE; break; diff --git a/contrib/rddmisc/arrayrdd.prg b/contrib/rddmisc/arrayrdd.prg index 4bc2c789bf..26745e5256 100644 --- a/contrib/rddmisc/arrayrdd.prg +++ b/contrib/rddmisc/arrayrdd.prg @@ -585,7 +585,7 @@ STATIC FUNCTION AR_GOBOTTOM( nWA ) aWAData[ WADATA_ORDRECNO ] := 0 nResult := AR_GOTO( nWA, 0 ) ELSE - aWAData[ WADATA_ORDRECNO ] := Len( ATail( aIndexes[ nIndex ][ INDEX_RECORDS ] ) ) + aWAData[ WADATA_ORDRECNO ] := Len( aIndexes[ nIndex ][ INDEX_RECORDS ] ) nResult := AR_GOTO( nWA, ATail( aIndexes[ nIndex ][ INDEX_RECORDS ] )[ INDEXKEY_RECORD ] ) ENDIF ELSE @@ -1084,6 +1084,7 @@ STATIC FUNCTION AR_ZAP( nWA ) /* empty records */ aDBFData[ DATABASE_RECORDS ] := {} aDBFData[ DATABASE_RECINFO ] := {} + AEval( aDBFData[ DATABASE_INDEX ], {| aIndex | ASize( aIndex[ INDEX_RECORDS ], 0 ) } ) /* move to 0 recno */ AR_GOTO( nWA, 0 ) @@ -1319,6 +1320,9 @@ STATIC FUNCTION AR_ORDINFO( nWA, nMsg, aOrderInfo ) ENDSWITCH SWITCH nMsg + CASE DBOI_NUMBER + aOrderInfo[ UR_ORI_RESULT ] := nIndex + EXIT CASE DBOI_EXPRESSION IF nIndex < 1 .OR. Empty( aIndexes ) .OR. nIndex > Len( aIndexes[ nIndex ] ) aOrderInfo[ UR_ORI_RESULT ] := "" @@ -1327,7 +1331,7 @@ STATIC FUNCTION AR_ORDINFO( nWA, nMsg, aOrderInfo ) ENDIF EXIT CASE DBOI_POSITION - IF nIndex < 1 .OR. Empty( aIndexes ) .OR. nIndex > Len( aIndexes[ nIndex ] ) .OR. Empty( aIndexes[ nIndex ][ INDEX_RECORDS ] ) .OR. aWAData[ WADATA_ORDRECNO ] == 0 + IF nIndex < 1 .OR. Empty( aIndexes ) .OR. nIndex > Len( aIndexes ) .OR. Empty( aIndexes[ nIndex ][ INDEX_RECORDS ] ) .OR. aWAData[ WADATA_ORDRECNO ] == 0 aOrderInfo[ UR_ORI_RESULT ] := 0 ELSE IF aIndexes[ nIndex ][ INDEX_RECORDS ][ aWAData[ WADATA_ORDRECNO ] ][ INDEXKEY_RECORD ] != aWAData[ WADATA_RECNO ] diff --git a/doc/en/rdddb.txt b/doc/en/rdddb.txt new file mode 100644 index 0000000000..bf2adbe8b1 --- /dev/null +++ b/doc/en/rdddb.txt @@ -0,0 +1,1280 @@ +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbEval() + $CATEGORY$ + API + $SUBCATEGORY$ + Execute and Execution + $ONELINER$ + Performs a code block operation on the current Database + $SYNTAX$ + dbEval( , + [], [], + [], [], + [] ) --> NIL + $ARGUMENTS$ + Operation that is to be performed + + Code block for the For condition + + Code block for the WHILE condition + + Number of NEXT records to process + + Record number to work on exactly + + Toggle to rewind record pointer + $RETURNS$ + dbEval() always returns NIL + $DESCRIPTION$ + Performs a code block operation on the current Database + $EXAMPLES$ + LOCAL nCount + + USE test + + dbGoto( 4 ) + ? RecNo() + COUNT TO nCount NEXT 10 + ? RecNo(), nCount + COUNT TO nCount + ? RecNo(), nCount + $STATUS$ + S + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + Eval() + $END$ + */ + +/* $DOC$ + $TEMPLATE$ + Function + $NAME$ + Dbf() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Alias name of a work area + $SYNTAX$ + Dbf() --> cWorkArea + $RETURNS$ + Name of alias + $DESCRIPTION$ + This function returns the same alias name of the currently selected + work area. + $EXAMPLES$ + USE test + SELECT 0 + ? iif( Dbf() == "", "No Name", Dbf() ) + ? test->( Dbf() ) + ? Alias( 1 ) + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + Alias() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbAppend() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Appends a new record to a database file. + $SYNTAX$ + dbAppend( [] ) --> NIL + $ARGUMENTS$ + Toggle to release record locks + $RETURNS$ + dbAppend() always returns NIL + $DESCRIPTION$ + This function add a new record to the end of the database + in the selected or aliased work area. All fields in that + database will be given empty data values - character fields + will be filled with blank spaces, date fields with hb_SToD(), + numeric fields with 0, logical fields with .F., and memo fields + with NULL bytes. The header of the database is not updated until + the record is flushed from the buffer and the contents are + written to the disk. + + Under a networking environment, dbAppend() performs an additional + operation: It attempts to lock the newly added record. If + the database file is currently locked or if a locking assignment + is made to `LastRec() + 1`, NetErr() will return a logical true (.T.) + immediately after the dbAppend() function. This function does + not unlock the locked records. + + If is passed a logical true (.T.) value, it will + release the record locks, which allows the application to maintain + multiple record locks during an appending operation. The + default for this parameter is a logical false (.F.). + $EXAMPLES$ + LOCAL cName := "Harbour", nAge := 15 + USE test + test->( dbAppend() ) + test->first := cName + test->age := nAge + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUnlock(), dbUnlockAll() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbClearFilter() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Clears the current filter condition in a work area + $SYNTAX$ + dbClearFilter() --> NIL + $RETURNS$ + dbClearFilter() always returns NIL + $DESCRIPTION$ + This function clears any active filter conduction + for the current or selected work area. + $EXAMPLES$ + USE test + SET FILTER TO hb_LeftEq( test->first, "An" ) + dbGoTop() + dbEval( {|| QOut( test->first ) } ) + dbClearFilter() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbSetFilter(), dbFilter() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbCloseAll() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Close all open files in all work areas. + $SYNTAX$ + dbCloseAll() --> NIL + $RETURNS$ + dbCloseAll() always return NIL + $DESCRIPTION$ + This function close all open databases and all associated + indexes. In addition, it closes all format files and moves + the work area pointer to the first position + $EXAMPLES$ + USE test NEW + dbEdit() + USE test1 NEW + dbEdit() + dbCloseAll() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUseArea(), dbCloseArea() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbCloseArea() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Close a database file in a work area. + $SYNTAX$ + dbCloseArea() + $DESCRIPTION$ + This function will close any database open in the selected + or aliased work area. + $EXAMPLES$ + USE test + dbEdit() + test->( dbCloseArea() ) + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUseArea(), dbCloseAll() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbCommit() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Updates all index and database buffers for a given work area + $SYNTAX$ + dbCommit() + $DESCRIPTION$ + This function updates all of the information for a give, selected, + or active work area. This operation includes all database and index + buffers for that work area only. This function does not update all + open work areas. + $EXAMPLES$ + LOCAL GetList := {} + LOCAL cName := Space( 40 ) + LOCAL nAge := 0 + + USE test EXCLUSIVE NEW + + @ 10, 10 GET cName + @ 11, 10 GET nAge + READ + + IF Updated() + dbAppend() + test->first := cName + test->age := nAge + dbCommit() + ENDIF + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbCloseAll(), dbCommitAll(), dbUnlock() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbCommitAll() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Flushes the memory buffer and performs a hard-disk write + $SYNTAX$ + dbCommit() + $DESCRIPTION$ + This function performs a hard-disk write for all work areas. + Before the disk write is performed, all buffers are flushed. + open work areas. + $EXAMPLES$ + // FIXME + LOCAL GetList := {} + LOCAL cName := Space( 40 ) + LOCAL nId := 0 + + USE test EXCLUSIVE NEW + USE testid NEW INDEX testid + + @ 10, 10 GET cName + @ 11, 10 GET nId + READ + + IF Updated() + dbAppend() + test->first := cName + test->Id := nId + IF ! testid->( dbSeek( nId ) ) + testid->( dbAppend() ) + testid->Id := nId + ENDIF + ENDIF + dbCommitAll() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbCloseAll(), dbCommit(), dbUnlock() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbCreate() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Creates an empty database from a array. + $SYNTAX$ + dbCreate( , , [], [], [], + [], [], [] ) + $ARGUMENTS$ + Name of database file to be create + + Name of a multidimensional array that contains the + database structure + + Name of the RDD + + 3-way toggle to Open the file in New or Current work area: + + + NIL The file is not opened. + True It is opened in a New area. + False It is opened in the current area. + + + Name of database Alias + $DESCRIPTION$ + This function creates the database file specified as from the + multidimensional array . If no file extension is use with + the .dbf extension is assumed. + The array specified in must follow a few guidelines when being + built prior to a call to dbCreate(): + + - All subscripts values in the second dimension must be set to proper values + + - The fourth subscript value in the second dimension - which contains + the decimal value-must he specified. even 1kw non-numeric fields. + + - The second subscript value in the second dimension-which contains + the field data type-must contain a proper value: C, D, L, M or N + It is possible to use additional letters for clarity (e.g., 'Numeric' + for 'N'): however, the first letter of this array element must + be a proper value. + + The dbCreate() function does not use the decimal field to + calculate the length of a character held longer than 256. Values + up to the maximum length of a character field (which is 65519 bytes) + are stored directly in the database in the length attribute if that + database was created via this function. However, a file containing + fields longer than 256 bytes is not compatible with any interpreter. + + The parameter specifies the name of the Replaceable + Database Driver to use to create the database. If it is not + specified, then the Replaceable Database Driver in the current work + area is used. + + The parameter specifies if the already created database is + to be opened, and where. If NIL, the file is not opened. If True, + it is opened in a New area, and if False it is opened in the current + area (closing any file already occupying that area). + The parameter specifies the alias name for the new opened + database. + $EXAMPLES$ + LOCAL aStruct := { ; + { "CHARACTER", "C", 25, 0 }, ; + { "NUMERIC", "N", 8, 0 }, ; + { "DOUBLE", "N", 8, 2 }, ; + { "DATE", "D", 8, 0 }, ; + { "LOGICAL", "L", 1, 0 }, ; + { "MEMO1", "M", 10, 0 }, ; + { "MEMO2", "M", 10, 0 } } + + REQUEST DBFCDX + + ? dbCreate( "testdbf", aStruct, "DBFCDX", .T., "MYALIAS" ) + $STATUS$ + R + $COMPLIANCE$ + This function is not CA-Cl*pper compliant + $FILES$ + Library is rdd + Header is dbstruct.ch + $SEEALSO$ + AFields()*, dbStruct() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbDelete() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Mark a record for deletion in a database. + $SYNTAX$ + dbDelete() + $DESCRIPTION$ + This function marks a record for deletion in the selected + or aliased work area. If the DELETED setting is on, the record + will still be visible until the record pointer in that work area + is moved to another record. + + In a networking situation, this function requires that the record + be locked prior to issuing the dbDelete() function. + $EXAMPLES$ + LOCAL nAge := 50 + USE test NEW + INDEX ON field->age TO test + IF dbSeek( nAge ) .AND. RLock() + dbDelete() + ENDIF + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbRecall() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbFilter() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Return the filter expression in a work area + $SYNTAX$ + dbFilter() --> cFilter + $RETURNS$ + dbFilter() returns the filter expression. + $DESCRIPTION$ + This function return the expression of the `SET FILTER TO` command + for the current or designated work area. If no filter condition + is present, a null string will be returned. + $EXAMPLES$ + USE test INDEX test NEW + SET FILTER TO field->first = "Harbour" + USE testid INDEX testid NEW + SET FILTER TO field->age == 25 + SELECT test + + ? dbFilter() + ? testid->( dbFilter() ) + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbRelation(), dbRSelect() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbGoBottom() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Moves the record pointer to the bottom of the database. + $SYNTAX$ + dbGoBottom() + $DESCRIPTION$ + This function moves the record pointer in the selected or aliased + work area to the end of the file. The position of the record pointer + is affected by the values in the index key or by an active FILTER + condition. Otherwise, if no index is active or if no filter condition + is present, the value of the record pointer will be LastRec(). + $EXAMPLES$ + USE test + dbGoTop() + ? RecNo() + dbGoBottom() + ? RecNo() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + Bof(), Eof(), dbSkip(), dbSeek(), dbGoTop() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbGoto() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Position the record pointer to a specific location. + $SYNTAX$ + dbGoto( ) + $ARGUMENTS$ + Record number or unique identity + $DESCRIPTION$ + This function places the record pointer, if working with a .dbf file, + in selected or aliased work area at the record number specified by + . The position is not affected by an active index or + by any environmental SET condition. + + The parameter may be something other than a record + number. In some data formats, for example, the value of + is a unique primary key while in other formats, could + be an array offset if the data set was an array. + + Issuing a `dbGoto( RecNo() )` call in a network environment will refresh + the database and index buffers. This is the same as a `dbSkip( 0 )` call. + $EXAMPLES$ + // The following example uses dbGoto() to iteratively process + // every fourth record: + + dbUseArea( .T., "DBFNTX", "sales", "sales", .T. ) + + // toggle every fourth record + DO WHILE ! Eof() + dbGoto( RecNo() + 4 ) + sales->Group := "Bear" + ENDDO + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + Bof(), Eof(), dbGoTop(), dbGoBottom(), dbSeek(), dbSkip() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbGoTop() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Moves the record pointer to the top of the database. + $SYNTAX$ + dbGoTop() + $DESCRIPTION$ + This function moves the record pointer in the selected or aliased + work area to the top of the file. The position of the record pointer + is affected by the values in the index key or by an active FILTER + condition. Otherwise, if no index is active or if no filter condition + is present, the value of RecNo() will be 1. + $EXAMPLES$ + USE test + dbGoTop() + ? RecNo() + dbGoBottom() + ? RecNo() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + Bof(), Eof(), dbSkip(), dbSeek(), dbGoBottom() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbRecall() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Recalls a record previously marked for deletion. + $SYNTAX$ + dbRecall() + $DESCRIPTION$ + This function unmarks those records marked for deletion and + reactivates them in the aliased or selected work area. If a record + is DELETED and the DELETED setting is on, the record will still be + visible for a dbRecall() provided that the database record pointer + has not been skipped. Once a record marked for deletion with the + DELETE setting ON has been skipped, it no longer can be brought back + with dbRecall(). + $EXAMPLES$ + USE test NEW + dbGoto( 10 ) + dbDelete() + ? Deleted() + dbRecall() + ? Deleted() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbDelete() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbRLock() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + This function locks the record based on identity + $SYNTAX$ + dbRLock( [] ) --> lSuccess + $ARGUMENTS$ + Record identifier + $RETURNS$ + dbRLock() returns a logical true (.T.) if lock was successful + $DESCRIPTION$ + This function attempts to lock a record which is identified + by in the active data set. If the lock is successful + the function will return a logical true (.T.) value; otherwise + a logical false (.F.) will be returned. If is not + passed it will be assumed to lock the current active record/data + item. + $EXAMPLES$ + LOCAL nRecNo + USE test NEW + FOR nRecNo := 1 TO LastRec() + IF ! dbRLock() + dbUnlock() + ENDIF + NEXT + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUnlock(), dbUnlockAll(), FLock(), RLock() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbRLockList() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + This function return a list of locked records in the database work area + $SYNTAX$ + dbRLockList() --> aRecordLocks + $RETURNS$ + is an array of lock records + $DESCRIPTION$ + This function will return an array of locked records in a given + and active work area. If the return array is an empty array + (meaning no elements in it), then there are no locked records in that + work area. + $EXAMPLES$ + LOCAL nRecNo + USE test NEW + dbGoto( 10 ) + ? RLock() + dbGoto( 100 ) + ? RLock() + FOR EACH nRecNo IN dbRLockList() + ? nRecNo + NEXT + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + RLock(), dbRLock(), dbRUnlock() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbRUnlock() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Unlocks a record based on its identifier + $SYNTAX$ + dbRUnlock( [] ) + $ARGUMENTS$ + Record identifier, typically a record number + $DESCRIPTION$ + This function will attempt to unlock the record specified as + , which in a .dbf format is the record number. If not + specified, them the current active record/data item will be + unlocked + $EXAMPLES$ + USE test NEW + dbGoto( 10 ) + IF RLock() + ? test->age + dbRUnlock() + ENDIF + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + RLock(), dbRLock(), dbRLockList() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbSeek() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Searches for a value based on an active index. + $SYNTAX$ + dbSeek( , [], [] ) --> lFound + $ARGUMENTS$ + Any expression + + Toggle SOFTSEEK condition + + is an optional logical value that set the current + record position to the last record if successful + $RETURNS$ + dbSeek() returns logical true (.T.) if found, otherwise false + $DESCRIPTION$ + This function searches for the first record in a database file whose + index key matches . If the item is found, the function will + return a logical true (.T.), the value of Found() will be a logical + true (.T.), and the value of Eof() will be a logical false (.F.). If + no item is found. then the function will return a logical false, the + value of Found() will be a logical false (.F.), and the value of + Eof() will be a logical true (.T.). + + This function always "rewinds" the database pointer and starts the + search from the top of the file. + + If the SOFTSEEK flag is on or if is set to a logical true + (.T.) the value of Found() will be a logical false and Eof() will be + false if there is an item in the index key with a greater value than + the key expression ; at this point the record pointer will + position itself on that record. However, if there is no greater key + in the index, Eof() will return a logical true (.T.) value. If + is not passed, the function will look to the internal + status of SOFTSEEK before performing the operation. The default of + is a logical false (.F.) + $EXAMPLES$ + PROCEDURE Main() + + LOCAL nAge + + USE test NEW + INDEX ON field->age TO test + dbGoto( 10 ) + nAge := test->age + dbGoTop() + IF dbSeek( nAge ) + ? test->first + ENDIF + + RETURN + + STATIC PROCEDURE EmployeeLookup() + + LOCAL cName + + ACCEPT "Employee name: " TO cName + IF Employee->( dbSeek( cName ) ) + Employee->( ViewRecord() ) + ELSE + ? "Not found" + ENDIF + + RETURN + + STATIC PROCEDURE ViewRecord() + + ? field->name + + RETURN + $STATUS$ + S + $COMPLIANCE$ + dbSeek() is Compatible with CA-Cl*pper 5.3 + $FILES$ + Library is rdd + $SEEALSO$ + dbGoBottom(), dbGoTop(), dbSkip(), Eof(), Bof(), Found() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbSelectArea() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Change to another work area + $SYNTAX$ + dbSelectArea( ) --> NIL + $ARGUMENTS$ + Alias or work area + $DESCRIPTION$ + This function moves the Harbour internal primary focus to the work + area designated by . If is numeric, then it will + select the numeric work area; if is character, then it will + select the work area with the alias name. + + `dbSelectArea( 0 )` will select the next available and unused work area. + Up to 65534 work areas are supported. Each work area has its own alias + and record pointer, as well as its own Found(), dbFilter(), + dbRSelect() and dbRelation() function values. + $EXAMPLES$ + LOCAL nAge + USE test NEW + COPY TO test1 + USE test1 NEW + INDEX ON field->age TO test1 + dbSelectArea( "test" ) + dbGoto( 100 ) + ? nAge := field->age + dbSelectArea( "test1" ) + IF dbSeek( nAge ) + ? field->first + ENDIF + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUseArea(), Select() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbSetDriver() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Establishes the RDD name for the selected work area + $SYNTAX$ + dbSetDriver( [] ) --> cCurrentDriver + $ARGUMENTS$ + Optional database driver name + $RETURNS$ + dbSetDriver() returns the name of active driver + $DESCRIPTION$ + This function returns the name of the current database driver for the + selected work area. The default will be "DBFNTX". If specified, + contains the name of the database driver that should be + used to activate and manage the work area. If the specified driver is + not available, this function will have no effect. + $EXAMPLES$ + ? dbSetDriver( "DBFNSX" ) + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUseArea() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbSkip() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Moves the record pointer in the selected work area. + $SYNTAX$ + dbSkip( [] ) + $ARGUMENTS$ + Numbers of records to move record pointer. + $DESCRIPTION$ + This function moves the record pointer in the selected or + aliased work area. The default value for will be 1. + A `dbSkip( 0 )` will flush and refresh the internal database buffer and + make any changes made to the record visible without moving the record + pointer in either direction. + $EXAMPLES$ + USE test NEW + dbGoTop() + DO WHILE ! Eof() + ? test->age, test->first + dbSkip() + ENDDO + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + Bof(), dbGoBottom(), dbGoTop(), dbSeek(), Eof() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbSetFilter() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Establishes a filter condition for a work area. + $SYNTAX$ + dbSetFilter( , [] ) + $ARGUMENTS$ + Code block expression for filtered evaluation. + + Optional character expression of code block. + $DESCRIPTION$ + This function masks a database so that only those records that meet + the condition prescribed by the expression in the code block + and literally expressed as are visible. + If is not passed to this function, then the dbFilter() + function will return an empty string showing no filter in that work + area which in fact, would be not correct. + $EXAMPLES$ + USE test NEW + dbSetFilter( {|| test->age > 30 }, "test->age > 30" ) + dbGoTop() + ? RecNo() + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbFilter(), dbClearFilter() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Function + $NAME$ + dbStruct() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Creates a multidimensional array of a database structure. + $SYNTAX$ + dbStruct() --> aStruct + $RETURNS$ + dbStruct() returns an array pointer to database structure + $DESCRIPTION$ + This function returns a multidimensional array. This array has array + pointers to other arrays, each of which contains the characteristic + of a field in the active work area. The length of this array is based + in the number of fields in that particular work area. In other words, + `Len( dbStruct() )` is equal to the value obtained from FCount(). + Each subscript position + $EXAMPLES$ + #include "dbstruct.ch" + LOCAL field + USE test NEW + FOR EACH field IN dbStruct() + ? field[ DBS_NAME ] + NEXT + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + Header is dbstruct.ch + $SEEALSO$ + AFields()* + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbUnlock() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Unlock a record or release a file lock + $SYNTAX$ + dbUnlock() + $DESCRIPTION$ + This function releases the file or record lock in the currently + selected or aliased work area. It will not unlock an associated lock + in a related databases. + $EXAMPLES$ + LOCAL nAge := 30 + USE test NEW + INDEX ON field->age TO test + IF test->( dbSeek( nAge ) ) + IF test->( RLock() ) + dbDelete() + ELSE + dbUnlock() + ENDIF + ENDIF + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUnlockAll(), FLock(), RLock() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbUnlockAll() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Unlocks all records and releases all file locks in all work areas. + $SYNTAX$ + dbUnlockAll() + $DESCRIPTION$ + This function will remove all file and record locks in all work area. + $EXAMPLES$ + LOCAL nAge := 50 + USE test NEW + INDEX ON field->age TO test + IF test->( dbSeek( nAge ) ) + IF test->( RLock() ) + dbDelete() + ELSE + dbUnlock() + ENDIF + ELSE + dbUnlockAll() + ENDIF + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbUnlock(), FLock(), RLock() + $END$ + */ + +/* $DOC$ + $AUTHOR$ + Copyright 1999 Luiz Rafael Culik + $TEMPLATE$ + Procedure + $NAME$ + dbUseArea() + $CATEGORY$ + API + $SUBCATEGORY$ + Database + $ONELINER$ + Opens a work area and uses a database file. + $SYNTAX$ + dbUseArea( [], [], , [], + [], [] ) + $ARGUMENTS$ + A optional logical expression for the new work area + + Database driver name + + File Name + + Alias name + + Shared/exclusive status flag + + Read-write status flag. + $DESCRIPTION$ + This function opens an existing database named in the current + work area. If is set to a logical true (.T.) value, then + the database will be opened in the next available and unused + work area. The default value of is a logical false (.F.). + If used, is the name of the database driver associated with + the file that is opened. The default for this will be the + value of dbSetDriver(). + + If used, contains the alias name for that work area, If not + specified, the root name of the database specified in will be + used. + + If is set to a logical true (.T.) value, the database that + is specified in will be opened by the user *exclusively*. Thus + locking it from all other nodes or users on the network. If + is set to a logical false (.F.) value, then the database will be in + SHARED mode. If is not passed, then the function will turn + to the internal setting of SET EXCLUSIVE to determine a setting. + + If is specified, the file will be set to *read only* mode. + If it is not specified, the file will he opened in normal read-write + mode. + $EXAMPLES$ + ? dbUseArea( .T.,, "test" ) + $STATUS$ + R + $COMPLIANCE$ + C + $FILES$ + Library is rdd + $SEEALSO$ + dbCloseArea(), dbSetDriver(), Select(), Set() + $END$ + */