How I can protect my tables

Q: How I can protect my tables ( .dbf files ) against to open with any other Program (like Excel, access) ?

A: There is too many method to solve this problem. Sadly non of its has warranty, always there is a solution to open any file by experienced users. You can ask Google.

Against non experienced users one method will be changing file extensions ( .dbf ). In this case you need modify your programs to change “file name” ( open dbf ) parameter  in USE statements (USE commands or DBUSEAREA() functions).




Open an existing database (.dbf) and its associated files


      USE [<xcDatabase>
            [INDEX <xcIndex list>]
            [ALIAS <xcAlias>] [EXCLUSIVE | SHARED]
            [NEW] [READONLY]
            [VIA <cDriver>]]


<xcDatabase> is the name of the database file to be opened and may be specified either as a literal file name or as a character expression enclosed in parentheses.

INDEX <xcIndex list> specifies the names of 1 to 15 index files to be opened in the current work area. Specify each index as a literal file name or as a character expression enclosed in parentheses. The first index in the list becomes the controlling index. If you specify an <xcIndex> as an expression and the value returned is spaces or NIL, it is ignored.

ALIAS <xcAlias> specifies the name to associate with the work area when the database file is opened. You may specify the alias name as a literal name or as a character expression enclosed in parentheses. A valid <xcAlias> may be any legal identifier (i.e., it must begin with an alphabetic character and may contain numeric or alphabetic characters and the underscore). Within a single application, Harbour will not accept duplicate aliases. If this clause is omitted, the alias defaults to the database file name.

EXCLUSIVE opens the database file for nonshared use in a network environment. All other users are denied access until the database file is CLOSEd.

SHARED opens the database file for shared use in a network environment. Specifying this clause overrides the current EXCLUSIVE setting.

NEW opens <xcDatabase> in the next available work area making it the current work area. If this clause is not specified, <xcDatabase> is opened in the current work area.

READONLY opens <xcDatabase> with a read-only attribute. This lets you open database files marked read-only. If you cannot open the <xcDatabase> this way, a runtime error is generated. If this clause is not specified, <xcDatabase> is opened as read-write.

VIA <cDriver> specifies the replaceable database driver (RDD) with which to process the current work area. <cDriver> is the name of the RDD specified as a character expression. If <cDriver> is specified as a literal value, it must be enclosed in quotes.

If the VIA clause is omitted, the DBFNTX driver is used by default. Note that if the specified driver is not linked, an unrecoverable error occurs.

In no arguments are specified, the database file open in the current work area is closed.


USE opens an existing database (.dbf) file, its associated memo (.dbt) file, and optionally associated index (.ntx or .ndx) file(s) in the current or the next available work area. In Harbour, there are 250 work areas with a maximum of 255 total files open in DOS 3.3 and above. Before USE opens a database file and its associated files, it closes any active files already open in the work area. When a database file is first opened, the record pointer is positioned at the first logical record in the file (record one, if there is no index file specified).

In a network environment, you may open database files as EXCLUSIVE or SHARED. EXCLUSIVE precludes the USE of the database file by other users until the file is closed. SHARED allows other users to USE the database file for concurrent access. If the database file is SHARED, responsibility for data integrity falls upon the application program. In Harbour, FLOCK() and RLOCK() are the two basic means of denying other users access to a particular work area or record. If a USE is specified and neither EXCLUSIVE nor SHARED is specified, the database file is opened according to the current EXCLUSIVE setting. In Harbour, all USE commands should explicitly specify how the database file is to be opened, EXCLUSIVE or SHARED. The implicit open mode specified by SET EXCLUSIVE is supplied for compatibility purposes only and not recommended.

Opening a database file in a network environment requires some special handling to be successful. First, attempt to USE the database file without specifying the INDEX list. Then, test for the success of the operation using NETERR(). If NETERR() returns false (.F.), the open operation succeeded and you can SET INDEX TO the index list. A USE will fail in a network environment if another user has EXCLUSIVE USE of the database file. Refer to the “Network Programming” chapter in the Programming and Utilities Guide for more information on opening files in a network environment.

You can open index files with USE or SET INDEX. The first index in the list of indexes defines the current ordering of records when they are accessed. This index is referred to as the controlling index. You can change the current controlling index without closing any files by using the SET ORDER command.

To close a database and its associated files in the current work area, specify USE or CLOSE with no arguments. To close database files in all work areas, use CLOSE DATABASEs. To close index files in the current work area without closing the database file, use CLOSE INDEX or SET INDEX TO with no arguments.

Refer to the “Basic Concepts” chapterfor more information about the Harbour database paradigm.


. Setting the maximum open files: Control of the number of file handles available to a Harbour application is controlled by a combination of the CONFIG.SYS FILES command, and the F parameter of the CLIPPER environment variable. The F parameter specifies the maximum number of files that can be opened at any one time within the current Harbour program. Harbour determines the number of files that can be opened using the smaller of the two parameters. For example, if the FILES command is set to 120 and the F parameter is set to 50, the maximum number of files that can be opened is 50. In a network environment, file handles also need to be set in the network configuration file.

The file limit is controlled by the operating system. Under DOS versions less than 3.3, the maximum number of files that can be opened at one time is 20 files. In DOS versions 3.3 and greater, the maximum limit is 255 files.

. Opening the same database file in more than one work area: Although opening a database file in more than one work area is possible in a network environment, this practice is strongly discouraged. If done, each file must be opened with a different alias, otherwise a runtime error will occur.

. Opening two database files with the same names, in different directories: Although opening two database files with the same names in different directories is possible, the database files MUST have unique alias names; otherwise, a runtime error will occur.


      .  This example opens a shared database file with associated
         index files in a network environment.  If NETERR() returns
         false (.F.), indicating the USE was successful, the indexes
         are opened:

      USE Accounts SHARED NEW
      IF !NETERR()
         SET INDEX TO AcctNames, AcctZip
         ? "File open failed"

      .  This example opens a database file with several indexes
         specified as extended expressions.  Note how the array
         of index names is created as a constant array:

      xcDatabase = "MyDbf"
      xcIndex = {"MyIndex1", "MyIndex2", "MyIndex3"}
      USE (xcDatabase) INDEX (xcIndex[1]), ;
            (xcIndex[2]), (xcIndex[3])





Establish shared or exclusive USE of database files


      SET EXCLUSIVE ON | off | <xlToggle>


ON causes database files to be opened in exclusive (nonshared) mode.

OFF causes database files to be opened in shared mode.

<xlToggle> is a logical expression that must be enclosed in parentheses. A value of true (.T.) is the same as ON, and a value of false (.F.) is the same as OFF.


In a network environment, SET EXCLUSIVE determines whether a USE command specified without the EXCLUSIVE or SHARED clause automatically opens database, memo, and index files EXCLUSIVE. When database files are opened EXCLUSIVE, other users cannot USE them until they are CLOSEd. In this mode, file and record locks are unnecessary.

When EXCLUSIVE is ON (the default), all database and associated files open in a nonshared (exclusive) mode unless the USE command is specified with the SHARED clause. Use EXCLUSIVE only for operations that absolutely require EXCLUSIVE USE of a database file, such as PACK, REINDEX, and ZAP.

When EXCLUSIVE is OFF, all files are open in shared mode unless the USE command is specified with the EXCLUSIVE clause. Control access by other users programmatically using RLOCK() and FLOCK().

SET EXCLUSIVE is a compatibility command and not recommended. It is superseded by the EXCLUSIVE and SHARED clauses of the USE command.

Refer to the “Network Programming” chapter for more information.


. Error handling: Attempting to USE a database file already opened EXCLUSIVE by another user generates a runtime error and sets NETERR() to true (.T.). After control returns to the point of error, you can test NETERR() to determine whether the USE failed.



Harbour All Functions – D









Harbour Database Functions

Database Functions

AFields Fills referenced arrays with database field information
Alias Returns the alias name of a work area
BOF Test for the beggining-of-file condition
dbAppend Appends a new record to a database file
dbClearFilter Clears the current filter condiction in a work area
dbCloseAll Close all open files in all work areas.
dbCloseArea Close a database file in a work area
dbCommit Updates all index and database buffers for a given workarea
dbCommitAll Flushes the memory buffer and performs a hard-disk write
dbCreate Creates an empty database from a array
dbDelete Mark a record for deletion in a database
dbEval Performs a code block operation on the current Database
DBF Alias name of a work area
dbFilter Return the filter expression in a work area
dbGoBottom Moves the record pointer to the bottom of the database
dbGoto Position the record pointer to a specific location
dbGoTop Moves the record pointer to the top of the database
dbRecall Recalls a record previousy marked for deletion
dbSeek Searches for a value based on an active index
dbSelectArea Change to another work area
dbSetDriver Establishes the RDD name for the selected work area
dbSetFilter Establishes a filter condition for a work area
dbSkip Moves the record pointer in the selected work area
dbSkipper Helper function to skip a database
dbStruct Builds a multidimensional array of a database structure
dbUseArea Opens a work area and uses a database file
Deleted Tests the record’s deletion flag
EOF Test for end-of-file condition
FCount Counts the number of fields in an active database
FieldDeci Determines the number of decimal places of a given numeric field
FieldGet Obtains the value of a specified field
FieldName Return the name of a field at a numeric field location
FieldPos Return the ordinal position of a field
FieldPut Set the value of a field variable
FieldSize Determines the size of a given field
FieldType Determines the type of a given field
Found Determine the success of a previous search operation
Header Return the length of a database file header
LastRec Returns the number of records in an active work area or database
LUpdate Yields the date the database was last updated
RecCount Counts the number of records in a database
RecNo Returns the current record number or identity
RecSize Returns the size of a single record in an active database
Select Returns the work area number for a specified alias
Used Checks whether a database is in use in a work area



Establishes the RDD name for the selected work area


      DBSETDRIVER( [<cDriver>] ) --> cCurrentDriver


<cDriver> Optional database driver name


DBSETDRIVER() returns the name of active driver


This function returns the name of the current database driver for the selected work area. The default will be “DBFNTX”. If specified, <cDriver> contains the name of the database driver that should be used to activate and manage the work area. If the specified driver is not avaliable, this function will have no effect.






Library is rdd





Change to another work area


      DBSELECTAREA(<xArea>) -


<xArea> Alias or work area


This function moves the Harbour internal primary focus to the work area designated by <xArea>. If <xArea> is numeric, then it will select the numeric work area; if <xArea> is character, then it will select the work area with the alias name.

DBSELECTAREA(0) will select the next avaliable and unused work area. Up to 255 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.


      PROCEDURE Main()
         LOCAL nId
         USE tests NEW INDEX tests
         USE tests1 NEW INDEX tests1
         DBSELECTAREA( 1 )
         nId := tests->Id
         DBSELECTAREA( 2 )
         IF DBSEEK( nId )
            ? tests1->cName




Library is rdd






Close a database file in a work area.




This function will close any database open in the selected or aliased work area.


      PROCEDURE Main()
         USE test
         Test->( dbCloseArea() )




Library is rdd






Close all open files in all work areas.


      DbCloseAll() --> NIL


DBCLOSEALL() always return NIL


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


      PROCEDURE Main()
         USE test NEW
         USE test1 NEW




Library is rdd



C5DG-8 DBPX Driver

Clipper 5.x – Drivers Guide

Chapter 8

DBPX Driver Installation and Usage

DBPX is the Paradox 3.5 compatible RDD for Clipper. It connects to the low-level database management subsystem in the Clipper architecture. When you use the DBPX RDD, you add a number or features, including the ability to:

. Create access to and modify Paradox tables, records, and fields

. Create, select, and activate secondary indexes on Paradox tables

. Create and modify Paradox table structures, including primary index fields

. Use explicit record and file locks with concurrent execution of other Clipper applications

. Import Paradox tables directly into Clipper arrays

In This Chapter

This chapter explains how to install DBPX and how to use it in your applications. The following major topics are discussed:

. Overview of the DBPX RDD

. Installing DBPX Driver Files

. Linking the DBPX Driver

. Using the DBPX Driver

Overview of the DBPX RDD

The DBPX driver lets you create and maintain (.db), (.px), (.x??), and (.y??) files with features different from those supplied with the original DBFNTX driver and compatible with files created under Paradox 3.5. The new features are supplied in the form of several syntactical additions to database and indexing commands and functions. Specifically you can:

. Create tables that recognize the standard Clipper data types as well as Currency ($) and Short (S) numbers between -32,767 to +32,767

. Create equally efficient keyed and unkeyed tables

. Create, select, and activate secondary indexes on Paradox tables

The DBPX driver provides simple, seamless access to the Paradox database system. The Clipper application programmer who intends to access Paradox tables with the “VIA” clause need only include the RDD header file at compile time and make the appropriate libraries available at link time.

Paradox stores data in tables (known to Xbase developers as data files (.db)’s), consisting of fields and records. Unlike Xbase databases, a Paradox database refers to a group of files that are related to each other in some way, rather than to one file.

Also, Paradox employs the concept of companion files, known as objects, that are related to the table. Some examples of object files are report forms, indexes, and data entry forms. A table and its accompanying objects are referred to as a family.

It is easy to identify objects belonging to a particular family since they all have the same base filename and are distinguished by their extensions as shown in the table below.

Paradox File Descriptions
——————–  —————————————————
Extension         Object

.DB                       Table

.PX          Primary Index 
.X?? or Y??  Secondary Index
.F or F??    Data Entry Forms
.R or R??    Report Formats
.G or G??    Graph Specifications
.SET         Image Settings
.VAL         Field Validity Specifications
------------ ------------------------------------------------------------

The DBPX driver only deals with the table and index files (.db, .px, .x?? and y??) so only these files are discussed here.

Though Paradox tables are limited to 8 character filenames, each table can contain an unlimited number of records in files up to 256M in size. Paradox records in nonkeyed tables can be up to 4000 bytes each while keyed tables have a 1350 byte limitation. Each record can contain up to 255 fields of up to 255 characters each.

There are some field naming restrictions you must observe. Field names may:

. Although the Paradox file structure allows fields to be up to 25 characters long, since Clipper symbols can only be 10 characters, DBPX truncates the field name to 10 characters.

. The Paradox file structure allows embedded spaces in field names. Since this is illegal in Clipper, the DBPX driver converts spaces into underscores (_).

. Not be duplicated in the same table.

Also, most Paradox data types directly match data types in standard Xbase data files, with these differences:

. Paradox tables support both the Numeric (N) data type as well as a more specific Currency ($) data type. Both the N and $ data types can have 15 significant digits. Numeric types that exceed this length are rounded and stored as scientific notation. Also, DBPX supports the Short (S) data type to represent numbers between -32,767 and +32,767.

. The Alphanumeric field type allows all ASCII characters except embedded nulls (ASCII 0). The Alphanumeric type is identical to the Character (C) data type in Xbase. Paradox limits this field type to 255 characters.

. Paradox also supports a Date (D) field type, stored as a long integer. It can contain any value between January 1, 100 A.D. and December 31, 9999.

Installing DBPX Driver Files

The DBPX RDD is supplied as the file, DBPX.LIB:

The Clipper installation program installs this driver in the \CLIPPER5\LIB subdirectory on the drive that you specify, so you need not install the driver manually.

Linking the DBPX Database Driver

To link the DBPX driver, you must specify DBPX.LIB to the linker along with your application object (.OBJ) modules.

1. To link with .RTLink using positional syntax:

C>RTLINK <appObjectList> ,,,DBPX

2. To link with .RTLink using freeformat syntax:

C>RTLINK FI <appObjectList> LIB DBPX

Note: These link commands all assume the LIB, OBJ, and PLL environment variables are set to the standard locations. They also assume that the Clipper programs were compiled without the /R option.

Using the DBPX Database Driver

To use Paradox files in a Clipper program:

1. Place REQUEST DBPX at the top of each program file (.prg) that opens a database file using the DBPX driver.

2. Specify the VIA “DBPX” clause if you open the database file with the USE command.


3. Specify “DBPX” for the <cDriver> argument if you open the database file with the DBUSEAREA() function.


4. Use RDDSETDEFAULT( “DBPX” ) to set the default driver to DBPX.

Except in the case of REQUEST, the RDD name must be a literal character string or a variable. In all cases it is important that the driver name be spelled correctly using uppercase letters.

The following program fragments illustrate:

USE Customers INDEX Name, Address NEW VIA "DBPX"
USE Customers INDEX Name, Address NEW

Index Management 

The greatest variation from the standard Xbase database design in Paradox tables is index management. As in other systems, Paradox indexes are an efficient method of dynamically sorting or locating specific data within a table without forcing a search of all data in that table. Paradox tables take two forms: unkeyed and keyed.

An unkeyed table has no fields in its structure that have been identified as specific index keys. Therefore, records are maintained in natural order. New records are added to the end of an existing table, and the unique identity for each record is a record number.

Unlike Xbase data files, unkeyed tables are not more efficient in design or faster to traverse than keyed tables. This is because Paradox tables are built as linked lists rather than fixed-length, sequential tables. Therefore, it is actually less efficient to SKIP through a unkeyed table than it is through a keyed table.

A keyed table, on the other hand, can be lightning fast as long as the data you seek is part of the key. Otherwise, just as in an unkeyed table, you are forced to do a sequential search through the table’s data fields.

Paradox tables support two types of keys or indexes.

. Primary

. Secondary

Primary Indexes

Primary indexes are directly tied to keyed tables because a primary index indicates the table is keyed. Simply, it is impossible to have a keyed table without a primary index. If you remove the primary index from a keyed table it becomes an unkeyed table.

When you identify one or more of the table’s fields as a key field (by placing an asterisk (*) at the end of the field name) during table creation/restructuring, these fields are used to create a primary index. (Note that all key fields must be together as the first fields in a table). This invisibly rebuilds the table’s structure, though in operation it only seems to change or create the key index.

Once you identify this primary key, the table is automatically maintained in the key field order and all new records are checked to make sure that no duplicate keys are added to the table. This type of index is called a unique key index. You may have only one primary key per table, but this key can be a composite of many fields in the table. You may only modify by restructuring the table.

If it is necessary to change a primary key and restructure a table, all data in the table will still be bound to the unique key restriction. This is important if you change the primary key by adding a new field to it and there is already data in the table where this new composite key would have duplicates.

DBPX handles this situation by generating a runtime error and removing every record that violates this unique key and moving it to another table named KEYVIOL.db which has the identical structure of the offending table.

The KEYVIOL.db is automatically generated whenever this situation occurs. If there is already a KEYVIOL table, it is overwritten. Because of this you should always check for the existence of a KEYVIOL.db table immediately after any type of table restructuring.

Secondary Indexes

Secondary indexes are more like common Xbase-type indexes because they can be generated or modified on the fly without having any effect on the data or table structure and aren’t restricted to unique key data.

Unlike Xbase indexes, secondary indexes can only contain a single field as their key. As mentioned earlier, primary indexes are automatically maintained so that they are always up to date. Secondary indexes are created in two different types.

. Incremental (for keyed tables)

. Independent (for unkeyed tables)

Independent indexes are created only for unkeyed tables and are not dynamically maintained in any way. Because of this they can only be considered accurate at the time of their creation. If data changes inside the table that affects the index, the index must be completely regenerated before it can be considered useful again.

Alternately, incremental indexes are created only for keyed tables and are automatically maintained similarly to primary indexes except that instead of a complete rebuild at every change, only the portion of the index affected is updated. Incremental indexes are preferable when you are handling large tables since they take considerably less time and energy to keep accurate.

Temporary Indexes

ALL, NEXT, RECORD, and REST are all supported in the scoping expressions. The syntax of these keywords is identical to that used in Clipper. Note that you can only use one scope keyword at a time. If more than one of these keywords is encountered in a scoping expression, then the last keyword in the expression is the option used.

The ALL keyword (default) specifies that all records in the table should be included in the operation, starting at the first record.

NEXT processes the specified number of records, starting with the current record. For example, NEXT 5 would process the current record and the four records following it.

The RECORD keyword identifies a specific record to process. The desired record number should follow the keyword RECORD. To process record number 3, you would include “RECORD 3” in the expression.

The REST keyword causes processing to begin with the current record, instead of starting at the beginning of the table.


In the event that you want to reorder a table based on field data but don’t need or want to have an index attached to it, you have the option of sorting the table based on the current index. This entails a simple copy from a keyed table to an unkeyed table using the table sort function.

Passwords and Security

Although the Paradox DBMS cannot be considered a data dictionary system, it does have some special characteristics that make it more suitable to networks than the standard Xbase tables. One of these features is the level of security available.

There are two methods to make sure that your data is secure: master passwords and auxiliary passwords. As the owner of a table, you can limit access by attaching a master password to it. Auxiliary passwords can also be identified to establish access to the table and its family.

Once any type of password is identified for a table, its is encrypted. This protects it not only from unauthorized Paradox users but also from anyone trying to dissect it at the DOS file level. The encryption method used by Paradox is literally unbreakable and if you (or your users) forget a table password, there is no way to recover that information.

Auxiliary passwords allow access control at the table and field levels. Access to tables can be restricted to:

. ReadOnly: No changes to the table can be made

. Update: Changes to nonkey fields are allowed, no records can be added or deleted

. Entry: Same as update except that new records can be added

. InsertDelete: Same as Entry except that records can be inserted and deleted

. All: Full access including restructuring and table deletion

Access to the fields can be identified as:

. None: This field data cannot be displayed to the user

. ReadOnly: User can see the field value, but cannot change it

. All: Full access

With DBPX, you may perform basic database operations on Paradox tables without code changes.

Note that because Paradox tables can have primary indexes which are actually part of the table structure specification, when you open a Paradox table, its associated primary index (if applicable) is also opened and activated. The only exception to this rule is if you indicate that you want a secondary index to be activated at the time you open the table. If no primary index is available and no secondary index is specified, the table is opened in natural sequence order.

You can have up to twenty-four Paradox tables open simultaneously. These may be separate tables or the same table repeatedly or any variation in between. This might be important if you want to have more than one secondary index active for a single table, allowing you to move from one work area to another with the only change being the index order of the data in the table. Be careful with this type of multiviewed approach, however, since you will be eating up memory for each work area, despite the fact that they refer to the same table.

Sharing Data in Networks

The DBPX driver supports the native Clipper single-lock locking scheme. Therefore, in a shared environment, your application and Paradox will not see each other’s record locks. This may result in some concurrency corruption and errors.

In a shared environment, DBPX performs no record buffering; immediately writing all changes to disk.

Concurrency is an issue whenever your application is running either on a network or in some other shared environment. One example of a non- network shared environment is when your application is called from another program (like Paradox, Quatro Pro, etc.) that also has access to the Paradox tables. Even if you don’t have any plans to use your program on a network, you should design it to be smart enough not to become a problem if faced with this type of shared example.

Also be aware that many networks have different rights and privilege restrictions and you should know what they are and how to handle them.

Using (.px) and (.ntx) Files Concurrently

You can use both (.px), as well as (.x), (.y) and (.ntx) files concurrently in a Clipper program like this:

// (.ntx) file using default DBFNTX driver
// (.idx) files using DBPX driver

Note, however, that you cannot use (.px) and (.ntx) files in the same work area. For example, the following does not work:

USE File1 VIA "DBFNTX" INDEX File1.ntx, File2.px


In this chapter, you were given an overview of the features and benefits of the DBPX RDD. You also learned how to link this driver and how to use it in your applications.