Menu

Tree [4396c3] master /
 History

HTTPS access


File Date Author Commit
 bin 2014-02-04 alkresin alkresin [27bad0] 2014-02-04 12:28 UTC+0300 Alexander Kresin (ale...
 include 2016-10-12 alkresin alkresin [2e69da] 2016-10-12 10:12 UTC+0300 Alexander Kresin (ale...
 source 2016-12-12 alkresin alkresin [4396c3] 2016-12-12 14:44 UTC+0300 Alexander Kresin (ale...
 tests 2015-08-01 ptsarenko ptsarenko [3e7b53] 2015-08-01 23:25 UTC+0300 Pavel Tsarenko (tpe2/...
 utils 2016-09-20 alkresin alkresin [ba65f9] 2016-09-20 13:26 UTC+0300 Alexander Kresin (ale...
 Changelog 2016-12-12 alkresin alkresin [4396c3] 2016-12-12 14:44 UTC+0300 Alexander Kresin (ale...
 Makefile.linux 2013-12-13 alkresin alkresin [e12c5b] 2013-12-13 20:40 UTC+0300 Alexander Kresin (ale...
 Readme.txt 2016-10-11 alkresin alkresin [d897e9] 2016-10-11 20:05 UTC+0300 Alexander Kresin (ale...
 Whatsnew.txt 2009-06-01 alkresin alkresin [9e76db] 2009-06-01 15:30 UTC+0300 Alexander Kresin (ale...
 leto.hbp 2014-01-04 alkresin alkresin [dd6cc1] 2014-01-04 18:50 UTC+0300 Alexander Kresin (ale...
 letodb.hbp 2015-05-26 ptsarenko ptsarenko [9c629c] 2015-05-26 17:45 UTC+0300 Pavel Tsarenko (tpe2/...
 letodyn.hbp 2014-01-04 alkresin alkresin [dd6cc1] 2014-01-04 18:50 UTC+0300 Alexander Kresin (ale...
 make_b32.bat 2009-04-06 alkresin alkresin [3f9dbd] 2009-04-06 11:50 UTC+0300 Alexander Kresin (ale...
 make_linux.sh 2009-04-06 alkresin alkresin [3f9dbd] 2009-04-06 11:50 UTC+0300 Alexander Kresin (ale...
 make_mingw.bat 2010-05-06 alkresin alkresin [b34dab] 2010-05-06 10:05 UTC+0300 Alexander Kresin (ale...
 make_vc.bat 2008-04-11 alkresin alkresin [04277d] 2008-04-11 11:02 UTC+0300 Alexander Kresin (ale...
 make_xhb.bat 2009-05-29 alkresin alkresin [e8cc51] 2009-05-29 13:25 UTC+0300 Alexander Kresin (ale...
 makefile.bc 2015-04-10 alkresin alkresin [54786f] 2015-04-10 10:10 UTC+0300 Alexander Kresin (ale...
 makefile.gcc 2015-04-10 alkresin alkresin [54786f] 2015-04-10 10:10 UTC+0300 Alexander Kresin (ale...
 makefile.vc 2013-12-13 alkresin alkresin [e12c5b] 2013-12-13 20:40 UTC+0300 Alexander Kresin (ale...
 rddleto.hbc 2009-06-05 alkresin alkresin [680932] 2009-06-05 10:30 UTC+0300 Alexander Kresin (ale...
 rddleto.hbp 2013-12-13 alkresin alkresin [e12c5b] 2013-12-13 20:40 UTC+0300 Alexander Kresin (ale...
 readme_pt_br.txt 2014-02-04 alkresin alkresin [27bad0] 2014-02-04 12:28 UTC+0300 Alexander Kresin (ale...
 readme_rus.txt 2016-10-11 alkresin alkresin [d897e9] 2016-10-11 20:05 UTC+0300 Alexander Kresin (ale...

Read Me

      /* $Id$ */

      Leto DB Server is a multiplatform database server or a database 
 management system, chiefly intended for client programs, written on Harbour,
 be able to work with dbf/cdx files, located on a remote server.

Contents
--------

1. Directory structure
2. Building binaries
   2.1 Borland Win32 C compiler
   2.2 Linux GNU C compiler
   2.3 xHarbour Builder
   2.4 Mingw C compiler
   2.5 Building letodb with hbmk
   2.6 Addition functions support
3. Running and stopping server
4. Server configuration
   4.1 letodb.ini
   4.2 Authentication
5. Features of work with the letodb server
   5.1 Connecting to the server from client programs
   5.2 Filters
6. Variables management
7. Functions list
   7.1 Connection management functions
   7.2 Transaction functions
   7.3 Additional functions for current workarea
   7.4 Additional rdd functions
   7.5 Setting client paramenter
   7.6 File functions
   7.7 Management functions
   7.8 User account management functions
   7.9 Server variable management functions
   7.10 Calling udf-functions on the server
   7.11 Functions for bitmap filters
8. Management utility
9. Server-side functions


      1. Directory structure

      bin/          -    server executable file
      doc/          -    documentation
      include/      -    source header files
      lib/          -    rdd library
      source/
          client/   -    rdd sources
          common/   -    some common source files
          client/   -    server sources
      tests/        -    test programs, samples
      utils/
          manage/   -    server management utilities


      2. Building binaries

      The letodb server can be compiled only by the Harbour compiler, and client
 library - both Harbour, and xHarbour. For OS Windows the letodb server can be
 compiled as Windows service (the macro by __WIN_SERVICE__ should be initialized),
 or as the daemon (process) for what it's necessary to set a macro __WIN_DAEMON__.
 For Linux it is necessary to set a macro __LINUX_DAEMON__.
      The server and the client library can be built with the support of the driver
 BMDBFCDX/BMDBFNTX.  In this case, the basic rdd letodb server will be used instead
 DBFCDX/DBFNTX driver BMDBFCDX/BMDBFNTX, and supported the same functionality that
 BMDBF*. To build on this mode, in build scripts (letodb.hbp, rddleto.hbp for hbmk2
 and makefile.* for other compilers) it's need to set a macro __BM.
 You can pass option -env for hbmk2 utility:
 hbmk2 -env:__BM=yes letodb.hbp
 hbmk2 -env:__BM=yes rddleto.hbp
      The server can be built with the support of functions leto_Zip and leto_UnZip.
 To build on this mode, in build script (letodb.hbp) it's need to set a macro __ZIP:
 hbmk2 -env:__ZIP=yes letodb.hbp

      2.1 Borland Win32 C compiler

      An environment variable HB_PATH, which defines a path to the Harbour
 directory, must be set before compiling. This can be done, for example, 
 by adding a line in a make_b32.bat:

          SET HB_PATH=c:\harbour

 If you use xHarbour, uncomment a line 'XHARBOUR = yes' in makefile.bc.
 Then run the make_b32.bat and you will get server executable file letodb.exe in a bin/
 directory and rdd library rddleto.lib in a lib/ directory.

      2.2 Linux GNU C compiler

      An environment variable HB_ROOT, which defines a path to the Harbour
 directory, must be set before compiling. Or just change the value of HRB_DIR
 in the Makefile.linux.

 Then run the make_linux.sh and you will get server executable file letodb in a bin/
 directory and rdd library librddleto.a in a lib/ directory.

      2.3 xHarbour Builder

      Run the make_xhb.bat to build binaries with this compiler. Probably,
  you will need to change the path to your xHarbour Builder copy in the
  make_xhb.bat. Default value is:

          set XHB_PATH=c:\xhb

      2.4 Mingw C compiler

      An environment variable HB_PATH, which defines a path to the Harbour
 directory, must be set before compiling. This can be done, for example, 
 by adding a line in a make_mingw.bat:

          SET HB_PATH=c:\harbour

 If you use xHarbour, uncomment a line 'XHARBOUR = yes' in makefile.gcc.
 Then run the make_mingw.bat and you will get server executable file letodb.exe in a bin/
 directory and rdd library librddleto.a in a lib/ directory.

      2.5 Building letodb with hbmk

      Now there is a possibility to build letodb with a Harbour make utility, provided by
 Viktor Szakats. The command line syntax is:

      hbmk2 [-hb10|-xhb] rddleto.hbp letodb.hbp [-target=tests/test_ta.prg]

 Optional parameters: -hb10 - Harbour version is 1.0 or 1.0.1,
                      -xhb - xHarbour,
                      -target="blank"\test_ta.prg - build the test, too.

      2.6 Addition functions support

      LetoDB use Harbour expression engine for evaluating index expressions and filters,
 and allows a call of the following functions:

      ABS, ALLTRIM, AT, CHR, CTOD, DATE, DAY, DELETED, DESCEND, DTOC, DTOS,
      EMPTY, I2BIN, L2BIN, LEFT, LEN, LOWER, LTRIM, MAX, MIN, MONTH, PAD, PADC,
      PADL, PADR, RAT, RECNO, RIGHT, ROUND, RTRIM, SPACE, STOD, STR, STRZERO,
      SUBSTR, REPLICATE, TIME, TRANSFORM, TRIM, UPPER, VAL, YEAR,
      hb_ATokens, hb_WildMatch

      If it's necessary to add this set of functions, in the source/server.prg module
it's necessary to add a line:

      REQUEST <cFName1>[, ...]

      And then rebuild server.

      3. Running and stopping server

      Just run it:
      
      letodb.exe                    ( under Windows )
      ./letodb                      ( under Linux )

      To shutdown the server, run the same executable with a 'stop' parameter:

      letodb.exe stop               ( under Windows )
      ./letodb stop                 ( under Linux )

      To reload letoudf.hrb module, run the same executable with a 'reload' parameter:

      letodb.exe reload             ( under Windows )
      ./letodb reload               ( under Linux )

      For windows service (server should be compiled with __WIN_SERVICE__ flag):

      To install and uninstall service, you must have administrative privileges.
      To install service, run letodb with 'install' parameter:

      letodb.exe install

      To uninstall service, run letodb with 'uninstall' parameter:

      letodb.exe uninstall

      To start and stop server, run service manager.

      4. Server configuration

      4.1 letodb.ini

      You may provide configuration file letodb.ini if you isn't satisfied with
 default parameters values. Currently following parameters exists ( default
 values are designated ), they should be written in section [MAIN]:

      [MAIN]
      Port = 2812              -    server port number;
      Ip =                     -    ip address, where Letodb listens for connections;
                                    If it doesn't set, all net interfaces ( all ip addresses ),
                                    available on the computer, are used.
      TimeOut = -1             -    connection timeout;
      DataPath =               -    path to a data directory on a server;
      LogPath = letodb.log     -    path and name of a log file;
      Default_Driver = CDX     -    default RDD to open files on server ( CDX/NTX );
      Memo_Type =              -    memo type ( FPT/DBT ). Default: FPT for DBFCDX, DBT for DBFNTX;
      Lower_Path = 0           -    if 1, convert all paths to lower case;
      EnableFileFunc = 0       -    if 1, using of file functions ( leto_file(),
                                    leto_ferase(), leto_frename() is enabled;
      EnableAnyExt = 0         -    if 1, creating of data tables and indexes with
                                    any extention, other than standard ( dbf,cdx,ntx )
                                    is enabled; 
      EnableUDF = 1            -    if 1 (by default), using of udf functions with prefix "UDF_*" is enabled,
                                    if 2, using of udf functions with any names is enabled,
                                    if 0, udf calls is disabled;
      Pass_for_Login = 0       -    if 1, user authentication is necessary to
                                    login to the server;
      Pass_for_Manage = 0      -    if 1, user authentication is necessary to
                                    use management functions ( Leto_mggetinfo(), etc. );
      Pass_for_Data = 0        -    if 1, user authentication is necessary to
                                    have write access to the data;
      Pass_File = "leto_users" -    the path and name of users info file;
      Crypt_Traffic = 0        -    if 1, the data passes to the network encrypted;
      Share_Tables = 0         -    if 0 (default, this mode server was the only from the
                                    start of a letodb project), the letodb opens all
                                    tables in an exclusive mode, what allows to increase
                                    the speed. If 1 (new mode, added since June 11, 2009),
                                    tables are opened in the same mode as client
                                    applications opens them, exclusive or shared, what
                                    allows the letodb to work in coexistence with other
                                    types of applications.
      No_Save_WA = 0           -    When this mode is set, each dbUseArea() will cause
                                    a real file open operation and creating a new 
                                    workarea on the server ( in default mode each file
                                    is opened only one time and have only one real
                                    workarea for all users ).
                                    Theoretically this new mode may increase the speed
                                    in case of a big number of active users. It isn't
                                    properly tested yet, so for production use default
                                    mode is recommended.
      Cache_Records            -    The number of records to read into the cache
      Max_Vars_Number = 10000  -    Maximum number of shared variables
      Max_Var_Size = 10000     -    Maximim size of a text variable
      Trigger = <cFuncName>    -    Global function letodb RDDI_TRIGGER
      PendingTrigger = <cFuncName>- Global function letodb RDDI_PENDINGTRIGGER
      EnableSetTrigger = 0     -    if 1, allows to change trigger settings,
                                    using dbInfo( DBI_TRIGGER, ... )
      Tables_Max  = 5000       -    Number of tables
      Users_Max = 500          -    Number of users
      Debug = 0                -    Debug level
      Optimize = 0             -    if 1, SET HARDCOMMIT OFF
      AutOrder = 0             -    SET AUTORDER setting
      ForceOpt = 0             -    _SET_FORCEOPT setting

      It is possible to define [DATABASE] structure if you need to have a
 directory, where files are opened via other RDD:

      [DATABASE]
      DataPath =               -    (mandatory option)
      Driver = CDX             -    ( CDX/NTX )

      You can define as many [DATABASE] sections, as needed.

      In Windows environment the letodb.ini must be placed in a directory, from
 where server is started.
      In Linux the program looks for it in the directory from where the server
 is started and, if unsuccessfully, in the /etc directory.

      4.2 Authentication

      To turn authentication subsystem on you need to set one of the following 
 letodb.ini parameters to 1: Pass_for_Login, Pass_for_Manage, Pass_for_Data. But before
 you need to create, at least, one user with admin rights, because when authentication
 subsystem works, only authenticated users with admin rights are able to add/change users
 and passwords.
      To add a user, you need to include a call of LETO_USERADD() in your client side
 program, for example:

      LETO_USERADD( "admin", "secret:)", "YYY" )

 where "YYY" is a string, which gives rights to admin, manage and write access. You may
 also use the utils/manager/console.prg program to set or change authentication data.

 To connect to a server with an authentication data ( username and password ) you need to
 use LETO_CONNECT() function.

      5. Features of work with the letodb server

      5.1 Connecting to the server from client programs

      To be able to connect to the server you need to link the rddleto library
 to your aplication and add at start of a main source file two lines:

      REQUEST LETO
      RDDSETDEFAULT( "LETO" )

      To open a dbf file on a server, you need to write in a SET PATH TO
 statement or in the USE command directly a path to the server in a standard
 form //ip_address:port/data_path/file_name.

      If a 'DataPath' parameter of a server configuration file is set to a non
 empty value, you need to designate not the full path to a file on the server,
 but only a relative ( relatively the 'DataPath' ).
      For example, if the you need to open a file test.dbf, which is located on
 a server 192.168.5.22 in a directory /data/mydir and the 'DataPath' parameter
 value ( of a letodb.ini server configuration file ) is '/data', the syntax
 will be the following:

      USE "//192.168.5.22:2812/mydir/test"

      If the server doesn't run or you write a wrong path, you'll get open error.
 It is possible to check accessibility of a server before opening files by using
 the leto_Connect( cAddress ) function, which returns -1 in case of unsuccessful
 attempt:

      IF leto_Connect( "//192.168.5.22:2812/mydir/" ) == -1
         Alert( "Can't connect to server ..." )
      ENDIF

     At connection with the server the client send to it information about codepage,
which the server then uses for operations of indexation, a filtration and for some
other operations. The client codepage should be established before connection with
the letodb server.

      5.2 Filters

      The filter is established usually: by the SET FILTER TO command or by a call
dbSetFilter() function. The filter which can be executed on the server, is called optimized.
If the filter can't be executed on the server, it is not optimized. Such filter
is slow as from the server all records, which are all the same requested then
are filtered on the client. To set the optimized filter, it is necessary, that in logical
expression for the filter there were no variables or the functions defined on the client.
To check, whether the filter is optimized, it is necessary to caall the LETO_ISFLTOPTIM()
function.

      6. Variables management

      Letodb allows to manage variables, which are shared between applications, connected
 to the server. Variables are separated into groups and may be of logical, integer or 
 character type. You can set a variable, get it, delete or increment/decrement
 ( numerical, of course ). All operations on variables are performed consecutively by
 one thread, so the variables may work as semaphores. See the functions list for a syntax
 of appropriate functions and tests/test_var.prg for a sample.
      Letodb.ini may contain lines to determine the maximum number of variables and a
 maximum size of a text variable.

      7. Functions list

      7.1 Connection management functions

      Below is a full ( at least, for the moment I write it ) list of functions,
 available for using in client applications with RDD LETO linked.

      LETO_CONNECT( cAddress, [ cUserName ], [ cPassword ], [ nTimeOut ], [ nBufRefreshTime ] )
                                                           --> nConnection, -1 if failed
 nBufRefreshTime defines the time interval in 0.01 sec. After this 
 time is up, the records buffer must be refreshed, 100 by default (1 sec)

      LETO_CONNECT_ERR()                                   --> nError
      LETO_DISCONNECT( [ cConnString | nConnection ] )     --> nil
      LETO_SETCURRENTCONNECTION( [ cConnString | nConnection ] ) --> nConnection
      LETO_GETCURRENTCONNECTION()                          --> nConnection
      LETO_GETSERVERVERSION()                              --> cVersion
      LETO_GETLOCALIP()                                    --> IP address of client station
      LETO_ADDCDPTRANSLATE(cClientCdp, cServerCdp )        --> nil
      LETO_PATH( [<cPath>], [cConnString | nConnection] )  --> cOldPath
      LETO_PING( [ cConnString | nConnection ] )           --> lResult

      7.2 Transaction functions

      LETO_BEGINTRANSACTION( [ nBlockLen ], [ lParseTrans ] )
 Parameter <nBlockLen> can be used for set memory allocation block size.
 For big transaction it can improve transaction speed at the client side.
 if parameter <lParseTransRec> is .F., transaction buffer isn't
 processing during record parsing from server.

      LETO_ROLLBACK()

      LETO_COMMITTRANSACTION( [ lUnlockAll ] )             --> lSuccess

      LETO_INTRANSACTION()                                 --> lTransactionActive

      7.3 Additional functions for current workarea

      LETO_COMMIT()
 This function can be used for current workarea instead of calls:

 dbCommit()
 dbUnlock()

 The client sends to the server 3 packages: for record updating
 on the server, for commit record and area unlock. Leto_Commit sends
 only one package for all these operations

      LETO_SUM( <cFieldNames>|<cExpr>, [ cFilter ], [xScope], [xScopeBottom] )
                                                           --> nSumma if one field or expression passed, or
                                                               {nSumma1, nSumma2, ...} for several fields
 The first parameter of leto_sum if comma separated fields or expressions:
 leto_sum("Sum1,Sum2", cFilter, cScopeTop, cScopeBottom) return
 an array with values of sum fields Sum1 and Sum2.

 If "#" symbol passed as field name, leto_sum returns a count of
 evaluated records, f.e:
 leto_sum("Sum1,Sum2,Sum1+Sum2,#", cFilter, cScopeTop, cScopeBottom) -->
 {nSum1, nSum2, nSum3, nCount}

  If only one field name or expression is passed, leto_sum() returns a numeric value

      LETO_GROUPBY(cGroup, <cFields>|<cExpr>, [cFilter], [xScopeTop], [xScopeBottom]) --> aValues
                                                               {{xGroup1, nSumma1, nSumma2, ...}, ...}

 This function return two-dimensional array. The first element of each row is
 a value of <cGroup> field, elements from 2 - sum of comma separated fields or
 expressions, represented in <cFields>. If "#" symbol passed as field name in cFields,
 leto_groupby return a count of evaluated records in each group

      LETO_ISFLTOPTIM()                                    --> lFilterOptimized

      dbInfo( DBI_BUFREFRESHTIME[, nNewVal])               --> nOldVal
  Setting new value for area skip and seek buffers refresh time in 0.01 sec.
  If -1: using connection setting. If 0 - buffers are used anyway.

      dbInfo( DBI_CLEARBUFFER )
  This command cleared skip buffer.

      7.4 Additional rdd functions

      leto_CloseAll( [ cConnString | nConnection ] )       --> nil
 Close all workareas for specified or default connection

      7.5 Setting client paramenter

      LETO_SETSKIPBUFFER( nSkip )                          --> nCount (buffer statistic using)
 This buffer is intended for optimization of multiple calls of skip.
 This function set size in records of skip buffer for current workarea.
 By default, the size of skip buffer is 10 records. Skip buffer is bidirectional.
 Skip buffer is refreshed after BUFF_REFRESH_TIME (1 sec)
 If parameter <nSkip> is absent, function returns bufferr statictic (number of buffer shooting)

      LETO_SETSEEKBUFFER( nRecsInBuf )                     --> nCount (buffer statistic using)
 This buffer is intended for optimization of multiple calls of seek.
 This function set size in records of seek buffer for current index order.
 If record is found in seek buffer on dbSeek(), it's not loaded from server.
 Like skip buffer, seek buffer is refreshed after BUFF_REFRESH_TIME (1 sec)
 If parameter <nRecsInBuf> is absent, function returns bufferr statictic
 (number of buffer shooting)
 By default, seek buffer is turned off.

      LETO_SETFASTAPPEND( lFastAppend )                    --> lFastAppend (previous value)
 If the fast append mode isn't set, record is added on the server at once
 after a dbAppend() function call. If this mode is set, record is added
 by dbCommit() call, or after a call of functions of navigation. By default
 a mode fast append isn't set. The switch working on all workareas.

      RddInfo( RDDI_REFRESHCOUNT, <lSet>,, [nConnection] )
 By default, the RDDI_REFRESHCOUNT flag is set to true.  If this flag is set,
 RecCount() function retrieve records count from server, if doesn't set -
 use last value from server.  If other applications are appending records
 to the table, new value of records count won't be immediately received.
 If RDDI_REFRESHCOUNT flag is cleared, dbGoto(0) cleared record buffer and
 set eof and other flags instead of server request.

      RddInfo( RDDI_BUFKEYCOUNT, <lSet>,, [nConnection] )
 By default, the RDDI_BUFKEYCOUNT flag is set to false.  If this flag isn't set,
 ordKeyCount() function retrieve key count from server, if set -
 use last value from server.

      RddInfo( RDDI_BUFKEYNO, <lSet>,, [nConnection] )
 By default, the RDDI_BUFKEYNO flag is set to false.  If this flag isn't set,
 ordKeyNo() function retrieve value from server, if set - use last value from server.

      RddInfo( RDDI_CLIENTID,,, [nConnection] )
 Returns self client ID (nUserStru) number.

      7.6 File functions

 The <cFileName> parameter of all file functions can contain a connection string
 to the letodb server in a format:
 //ip_address:port/data_path/file_name.
 If the connection string is omitted, the current active connection is used:
 /data_path/file_name.
 All files is searching at the DataPath catalog on the server. The ".."
 symbols are disabled.

      LETO_FILE( cFileName )                               --> lFileExists
 Determine if file exist at the server, analog of File() function

      LETO_FERASE( cFileName )                             --> -1 if failed
 Delete a file at the server.

      LETO_FRENAME( cFileName, cFileNewName )              --> -1 if failed
 Rename a file: <cFileName> --> <cFileNewName>. <cFileNewName> should be without
 connection string.

      LETO_MEMOREAD( cFileName )                           --> cStr
 Returns the contents of file at the server as character string, analog of
 MemoRead() function.

      Leto_MemoWrite( cFileName, cBuf )                    --> lSuccess
 Writes a character string into a file at the server, analog of
 MemoWrit() function.

      LETO_MAKEDIR( cDirName )                             --> -1 if failed
 Creates a directory at the server

      LETO_DIREXIST( cDirName )                            --> lDirExists
 Determine if directory exist at the server

      LETO_DIRREMOVE( cDirName )                           --> -1 if failed
 Delete a directory at the server.

      LETO_FERROR()                                        --> nError
 Returns an error code of last file function.

      Leto_FileRead( cFileName, nStart, nLen, @cBuf )      --> -1 if failed
 Read a content of file at the server from <nStart> offset and <nLen> length

      Leto_FileWrite( cFileName, nStart, cBuf )            --> lSuccess
 Write <cBuf> character string to a file at the server from <nStart> offset

      Leto_FileSize( cFileName )                           --> -1 if failed
 Returns a length of a file at the server

      Leto_FileAttr( cFileName [, cNewAttr] )              --> cAttr
 Get or set file attributes

      Leto_Directory( cDir[, cAttr] )                      --> aDirectory
 Returns a content of directory at the server in the same format as Directory() function

      7.7 Management functions

      LETO_MGGETINFO()                                     --> aInfo
 This function returns parameters of current connection as 17-element array
 of char type values:
 1 - count of active users
 2 - max count of users
 3 - opened tables
 4 - max opened tables
 5 - time elapsed
 6 - count of operations
 7 - bytes sent
 8 - bytes read
 9 - opened indexes
 10 - max opened indexes
 11 - data path
 12 - max day wait
 13 - ulWait
 14 - count of transactions
 15 - count successfully of transactions
 16 - current memory used
 17 - max memory used

      LETO_MGGETUSERS( [<cTableId>|<nTable>] )                        --> aInfo
 Function returns two-dimensional array, each row is info about user:
 aInfo[i,1] - user number
 aInfo[i,2] - ip address
 aInfo[i,3] - net name of client
 aInfo[i,4] - program name
 aInfo[i,5] - timeout

      LETO_MGGETTABLES( [<cUserId>|<nUser>] )                         --> aInfo
 Function returns two-dimensional array, each row is info about opened tables:
 aInfo[i,1] - table number
 aInfo[i,2] - table name

      LETO_MGGETLOCKS( [<cUserId>|<nUser>] )                          --> aInfo
 Function returns two-dimensional array, each row is info about locks:
 aInfo[i,1] - table name
 aInfo[i,2] - character string with list of locked records

      LETO_MGGETTIME()                                     --> aDateTime
 Function returns array {<dDate>, <nSeconds>}:
 dDate - server date;
 nSeconds - seconds after midnight.
 Convert this values to datetime variable (Harbour):
 hb_DTOT( aDateTime[1], aDateTime[2] )

      LETO_MGKILL( <nUser>|<cUserId> )
 Kill user number <nUser>

      LETO_LOCKCONN( lOnOff )                              --> lSuccess
 After leto_lockconn( .t. ) request new connections are blocked by server, until
 leto_lockconn( .f. ) called

      LETO_LOCKLOCK( lOnOff, nSecs )                       --> lSuccess
 This function wait until any updates are closed, commit all changes and
 trying to lock server from any updates from clients.
 It returns True, if lock is succesfull.

      7.8 User account management functions

      LETO_USERADD( cUserName, cPass [, cRights ] )        --> lSuccess
      LETO_USERPASSWD( cUserName, cPass )                  --> lSuccess
      LETO_USERRIGHTS( cUserName, cRights )                --> lSuccess
      LETO_USERFLUSH()                                     --> lSuccess
      LETO_USERGETRIGHTS()                                 --> cRights

      7.9 Server variable management functions

      LETO_VARSET( cGroupName, cVarName, xValue[, nFlags[, @xRetValue]] ) --> lSuccess

 This function assign value <xValue> to variable <cVarName> from group <cGroupName>
 Optional parameter <nFlags> defines function mode:
 LETO_VCREAT    - if variable doesn't exist, it's created;
 LETO_VOWN      - own user variable (free after user disconnect);
 LETO_VDENYWR   - write deny for other users;
 LETO_VDENYRD   - read deny for other users;
 LETO_VPREVIOUS - retusn previos value to <xRetValue> parameter.

      LETO_VARGET( cGroupName, cVarName )                  --> xValue

 Function return value of variable <cVarName> from group <cGroupName>

      LETO_VARINCR( cGroupName, cVarName )                 --> nValue

 Function increment value of variable <cVarName> from group <cGroupName>

      LETO_VARDECR( cGroupName, cVarName )                 --> nValue

 Function decrement value of variable <cVarName> from group <cGroupName>

      LETO_VARDEL( cGroupName, cVarName )                  --> lSuccess

 Function delete variable <cVarName> from group <cGroupName>

      LETO_VARGETLIST( [cGroupName [, nMaxLen]] )          --> aList

 Function return two-dimensional array with variables: { {<cVarName>, <value>}, ...}

      7.10 Calling udf-functions on the server

      LETO_UDF( cSeverFunc, xParam1, ... )                 --> xResult
 This function is called from client application. A string
 <cServerFunc> contains a server connection string and name
 of udf function:
 //ip_address:port/funcname
 A <funcname> function should be defined on the letodb server.
 The first parameter of udf function is nUserStru.
 Udf function can return result (any type) to client.
 Examples of udf-functions are in the tests/letoudf.prg

      LETO_UDFEXIST( cSeverFunc )                          --> lExist
 leto_udfExist check the existance of udf-function at the letodb server.
 <cSeverFunc> parameter is the same as for leto_udf().

      LETO_PARSEREC( cRecBuf )                             --> nil
 This function is necessary for calling, if udf-function returns as
 result the buffer of record which should be current after of it
 works.

      LETO_PARSERECODRS( cRecBuf )                         --> nil
 This function is necessary for calling to fill the skip-buffer as a result
 of udf-function UDF_dbEval. After calling this function, the data from the
 skip-buffer can be received by dbSkip() calls. See sample in comments for
 UDF_dbEval() in tests/letoudf.prg

      7.11 Functions for bitmap filters

 If letodb compiled with rdd BMDBFCDX/BMDBFNTX, then there is support
 the following functions:

      LBM_DbGetFilterArray()                               --> aFilterRec
      LBM_DbSetFilterArray( aFilterRec )                   --> nil
      LBM_DbSetFilterArrayAdd( aFilterRec )                --> nil
      LBM_DbSetFilterArrayDel( aFilterRec )                --> nil

 Purpose and the parameters of these functions is the same as for the
 corresponding functions BM_*.

      LBM_DbSetFilter( [<xScope>], [<xScopeBottom>], [<cFilter>] ) -> nil
 This function set bitmap filter by current index order and for condition,
 defined in <xScope>, <xScopeBottom>, <cFilter> parameters.
 The current record after LBM_DbSetFilter() is the first record satisfying
 filter condition.

      8. Management utility

      There are two management utilities, GUI and console, the sources are in
 utils/manage directory.

      GUI utility, manage.prg, is made with the HwGUI library. If you have HwGUI,
 just write in the line 'set HWGUI_INSTALL=' in utils/manage/bld.bat a path
 to your HwGUI directory and run the bld.bat, it will build manage.exe for you.
   
      For those, who doesn't use HwGUI, there is a console mode utility,
 console.prg. Build a console.exe with a make/bat files, which you use to build
 Harbour single-file programs, you just need to add rddleto.lib to the libraries
 list. Run the console.exe with a server name or ip and port as a parameter:

      console.exe server_name:nPort
      console.exe ip_address:nPort

 The server_name and ip_address in a command line must be without leading
 slashes ( '//' ), because Clipper/Harbour interprets them in a special way.

      9. Server-side functions

      These functions can be run from the client by function leto_udf,
 and also from the functions defined in a file letoudf.hrb.
 The first parameter such function always nUserStru

      leto_Alias( nUserStru, cClientAlias )                --> cRealAlias
 This function return server alias for client alias <cClientAlias>.
 The server alias then can be user in usial rdd-operations

      leto_RecLock( nUserStru [, nRecord] )                --> lSuccess
  leto_Reclock function locked record with <nRecord> number, or a current record.

      leto_RecUnLock( nUserStru [, nRecord] )              --> Nil
  leto_RecUnlock function unlocked record with <nRecord> number, or a current
  record.

      leto_RecLockList( nUserStru, aRecNo )                --> lSuccess
  leto_ReclockList function locked records with number in the <aRecNo> array.
  If any record isn't locked, all records are unlocked, and function returns
  .F. result.
  This function can be used at the server from letoodf.prg module, or from
  client by a call leto_UDF( "leto_RecLockList", aRecNo ).

      leto_TableLock( <nUserStru>, [<nFlag>], [<Secs>])    --> lSuccess
      leto_TableUnLock( <nUserStru>, [<nFlag>])

      nFlag - parameter from 1 to 32, nSecs - seconds for wait locking (1 by default)
      These functions are intended for concurrent access to the table for
      actions except updating of the data.

      leto_SelectArea( nUserStru, nAreaId )                --> lSuccess

      leto_areaID( nUserStru )                             --> nAreaId
 Function return internal id of current workarea

      leto_ClientID()                                      --> nUserStru
 Function return client ID (nUserStru), -1 if failed

      letoUseArea( nUserStru, cFileName, cAlias, lShared, lReadOnly, cdp ) --> nAreaId
      letoOrdListAdd( nUserStru, cBagName )                --> Nil
      letoOrdCreate( nUserStru, cBagName, cKey, cTagName,
                     lUnique, cFor, cWhile, lAll, nRecNo,
                     nNext, lRest, lDesc, lCustom,
                     lAdditive )                           --> Nil
      letoCloseArea( nUserStru )                           --> Nil

 The functions letoUseArea, letoOrdListAdd, letoOrdCreate, letoCloseArea,
 leto_RecLock, leto_RecLock is intended for using in udf-functions instead
 of rdd functions: dbUseArea, OrdListAdd, OrdCreate, dbCloseArea, RLock, dbUnlock

 Server variable management functions:

      LETO_VARSET( nUserStru, cGroupName, cVarName, xValue[, nFlags )
                                                           --> lSuccess
      LETO_VARGET( nUserStru, cGroupName, cVarName )       --> xValue
      LETO_VARINCR( nUserStru, cGroupName, cVarName )      --> nValue
      LETO_VARDECR( nUserStru, cGroupName, cVarName )      --> nValue
      LETO_VARDEL( nUserStru, cGroupName, cVarName )       --> lSuccess
      LETO_VARGETLIST( nUserStru, [cGroupName, [lValue]] ) --> aList

 Zip/Unzip functions:

      leto_Zip( nUserStru, [cDirName], [acFiles], [nLevel], [lOverwrite], [cPassword], [acExclude], [lWithPath] )
                                                           --> cZip
      leto_UnZip( nUserStru, [cDirName], cZip, [cPassword], [lWithPath] )   --> lSuccess
 parameters:
 cDirName - directory relatively DataPath;
 cZip - archive body to unzip;
 other parameters is the same as parameters of hb_ZipFile/hb_UnZipFile functions.
 Calling functions from a client:
 leto_UDF("leto_Zip", [cDirName], ...)
 leto_UDF("leto_UnZip", [cDirName], cZip, ...)