Click or drag to resize

DbServer Class

Create a data server that can operate with existing .DBF database files and their associated index files.
Inheritance Hierarchy
Object
  DataServer
    DbServer
      AdsSQLServer

Namespace:  VO
Assembly:  VORDDClasses (in VORDDClasses.dll) Version: 2.5
Syntax
 CLASS DbServer INHERIT DataServer

The DbServer type exposes the following members.

Constructors
  NameDescription
Public methodCode exampleDbServer
Construct a DBServer object.
Top
Properties
  NameDescription
Public propertyAlias
A string representing the alias of the work area.
Public propertyAliasSym
A symbol representing the alias of a DBServer object.
Public propertyCode exampleBoF
A logical value indicating whether the server is positioned at the beginning of the file, on the first record.
(Overrides BoF.)
Public propertyCode exampleConcurrencyControl
A constant, identifying the mode of automatic concurrency control for this data server, determining when and how records are locked and released:
(Overrides ConcurrencyControl.)
Public propertyCode exampleDBStruct
An array containing the structure of this data server, whose length (that is, number of elements) is equal to the number of fields in the server.
(Overrides DBStruct.)
Public propertyDbStructure
**Missing documentation **
Public propertyCode exampleDeleted
A logical value indicating whether the current record is marked as deleted.
Public propertyDriver
A string representing the name of the database driver in use with this server.
Public propertyCode exampleEoF
A logical value indicating whether the server is positioned at the end of the file, on the last record
(Overrides EoF.)
Public propertyCode exampleErrInfo
An Error object identifying the error condition after the last operation.
Public propertyErrorInfo
**Missing documentation **
Public propertyCode exampleFCount
The number of fields in the server.
(Overrides FCount.)
Public propertyFieldDesc
**Missing documentation **
Public propertyCode exampleFileSpec
The FileSpec object that defines the path and file name of the DBF file.
Public propertyCode exampleFilter
A string representing the current active filter.
Public propertyCode exampleForBlock
The "FOR block" component of the "general server scope," which affects several bulk processing methods if they are called with no explicit scope.
Public propertyCode exampleFound
A logical value indicating whether the previous search operation succeeded.
Public propertyCode exampleHeader
A numeric value representing the length of the database file header.
Public propertyIndexExt
A string representing the default index extension based on the database driver currently linked (for example, ".NTX" for the DBFNTX driver).
Public propertyIndexList
**Missing documentation **
Public propertyCode exampleLastRec
The number of records in the current database file.
Public propertyLupdate
The last modification date of the DBF file used in the server.
Public propertyMemoExt
**Missing documentation **
Public propertyName
**Missing documentation **
(Overrides Name.)
Public propertyOleExt
**Missing documentation **
Public propertyOrderBottomScope
A key value representing the record of the bottom boundary in the range of key values that will be included in the controlling order's current scope.
Public propertyOrderKeyVal
The key value of the current record from the controlling order.
Public propertyOrderTopScope
A key value representing the record of the top boundary in the range of key values that will be included in the controlling order's current scope.
Public propertyPaintedStructure
**Missing documentation **
Public propertyRddName
A string representing the name of the database driver in use with this server.
Public propertyRdds
**Missing documentation **
Public propertyCode exampleReadOnly
A logical value indicating whether the file was opened as a read-only file.  This is determined by an instantiation parameter of the server.
Public propertyCode exampleRecCount
The number of records in the current database file.
(Overrides RecCount.)
Public propertyCode exampleRecNo
A numeric value representing the current record number, identifying the position of the record pointer.
(Overrides RecNo.)
Public propertyCode exampleRecSize
A numeric value representing the record length of the server in bytes.
Public propertyRelationChildren
**Missing documentation **
Public propertyRetries
**Missing documentation **
Public propertyCode exampleRLockList
An array of record numbers that are currently locked.
Public propertyCode exampleScope
The "scope" component of the "general server scope," which affects several bulk processing methods if they are called with no explicit scope.  The initial value of the scope is NIL.
Public propertySelectionWorkArea
**Missing documentation **
Public propertyCode exampleShared
A logical value indicating whether the server is sharable or exclusive.
Public propertyCode exampleStatus
A HyperLabel object identifying the status after the last operation.  If
(Overrides Status.)
Public propertyTableExt
**Missing documentation **
Public propertyUsed
A logical value indicating whether the server is currently open
Public propertyCode exampleWhileBlock
The "WHILE block" component of the "general server scope," which affects several bulk processing methods if they are called with no explicit scope
Public propertyWorkArea
A number representing the workarea of the server
Top
Methods
  NameDescription
Public methodAppend
Append a blank record to the table; this blank record becomes the current position and is ready for assignment of data values.  The record is automatically locked if the Append() method returns TRUE.
Public methodAppendDB
Append new records to the table from another DBF file.
Public methodAppendDelimited
Append new records to the table from a delimited file, such as the "comma-separated-value" (CSV) file format.
Public methodAppendSDF
Append new records to the table from an SDF-formatted file.
Public methodAverage
Calculate the average of a series of numeric expressions, based on the number of actual records involved.
Public methodCode exampleBLOBDirectExport
Export the contents of a binary large object (BLOB) pointer to a file.
Public methodCode exampleBLOBDirectGet
Retrieve data stored in a BLOB file without referencing a specific field.
Public methodCode exampleBLOBDirectImport
Import a file into a BLOB file and return a pointer to the data.
Public methodCode exampleBLOBDirectPut
Put data in a BLOB file without referencing a specific field.
Public methodCode exampleBLOBExport
Copy the contents of a BLOB, identified by its memo field number, to a file.
Public methodCode exampleBLOBGet
Get the contents of a BLOB, identified by its memo field number.
Public methodCode exampleBLOBImport
Read the contents of a file as a BLOB, identified by a memo field number.
Public methodCode exampleBLOBRootGet
Retrieve the data from the root area of a BLOB file.
Public methodCode exampleBLOBRootLock
Obtain a lock on the root area of a BLOB file.
Public methodCode exampleBLOBRootPut
Store data in the root area of a BLOB file.
Public methodCode exampleBLOBRootUnlock
Release the lock on a BLOB file's root area.
Public methodClearFilter
Clear a filter condition specified with the DBServer:SetFilter() method.
Public methodClearIndex
Clear all indexes currently associated with the server.
Public methodClearLocate
Clear the LOCATE condition of the server, if any.
Public methodClearOrderScope
Set or clear the boundaries for scoping key values in the controlling order.
Public methodClearRelation
Clear all active relations held by this server to other servers.
Public methodClearScope
Clear the settings that define the default scope for multi-record operations.
Public methodClose
Close the database file and its associated index files.
(Overrides Close.)
Public methodCommit
Commit all changes to disk from the buffer, ensuring that all buffers are flushed.
(Overrides Commit.)
Public methodConstructUniqueAlias
**Missing documentation **
Public methodContinue
Resume a pending DBServer:Locate() operation, searching for the next record that matches (like the DBContinue() function).
Public methodCode exampleCopyDB
Copy records to another DBF file.
Public methodCopyDelimited
Copy records to a delimited file.
Public methodCopySDF
Copy records to an SDF file.
Public methodCode exampleCopyStructure
Create a DBF file with the same record layout as the server object to which the message is sent.
Public methodCode exampleCount
Return the number of records that match a specified scope.
Public methodCreateIndex
Create an index file with an order in it.
Public methodCreateOrder
Create an order within an existing index file.  The behavior depends on which driver is used.
Public methodDataField
Retrieve the data field object at the specified field position.
(Overrides DataField(Usual).)
Public methodDelete
Delete the current record or the records specified with the scoping parameters.
Public methodDeleteAll
Delete all records of the table.
Public methodDeleteOrder
Delete an order from an index file.
Public methodCode exampleError
Provide a method for handling error conditions raised during database processing.
Public methodEval
Evaluate a code block for each record matching a scope and condition.  If neither conditions nor scope is passed to the method, it is subject to the general server scope.
Public methodCode exampleFIELDGET
Get the contents of a field that is identified by its position.
(Overrides FIELDGET(Usual).)
Public methodFieldGetBytes
Read an array of bytes direct from the workarea buffer.
Public methodFieldGetFormatted
Return the contents of a specified field according to the formatting specifications of its FieldSpec object.
(Overrides FieldGetFormatted(Usual).)
Public methodFieldHyperLabel
Return the hyperlabel of a specified field.
(Overrides FieldHyperLabel(Usual).)
Public methodCode exampleFieldInfo
Return and optionally change information about a field.
Public methodFieldName
Return the name of a specified field as a string.
(Overrides FieldName(Usual).)
Public methodFieldPos
Return the position of a specified field within the data server, as a number starting with 1.
(Overrides FieldPos(Usual).)
Public methodCode exampleFIELDPUT
Set the value of a field identified by its position.
(Overrides FIELDPUT(Usual, Usual).)
Public methodFieldPutBytes
Write an array of bytes direct to the workarea buffer.
Public methodFieldSpec
Return the FieldSpec object in the specified field.
(Overrides FieldSpec(Usual).)
Public methodFieldStatus
Return the status of a field after the last operation.
(Overrides FieldStatus(Usual).)
Public methodFieldSym
Return the name of a specified field.
(Overrides FieldSym(Usual).)
Public methodFieldValidate
Perform all the validations defined to the FieldSpec object of a field (for example, required, maximum and minimum digits, maximum and minimum value, validation rule) and return the result of the test.
(Overrides FieldValidate(Usual, Usual).)
Public methodFLOCK
Lock the table used by this server for exclusive access.
(Overrides FLOCK.)
Public methodCode exampleGetArray
Retrieve an array of values from a field in the server, subject to the currently active selection, if any.
Public methodGetLocate
Retrieve the code block of the current LOCATE condition, or NIL if no code block is set.
Public methodCode exampleGetLookupTable
Retrieve a two-column array of values from two fields in the server, subject to the currently active selection, if any.
Public methodGoBottom
Position the data server at the last record.
(Overrides GoBottom.)
Public methodGoTo
Position the data server at a specified record number.
(Overrides GoTo(Usual).)
Public methodGoTop
Position the data server at the first record.
(Overrides GoTop.)
Public methodINDEXKEY
Return the key expression of a specified single-order index.
Public methodINDEXORD
Return the ordinal position of the controlling order in the order list.  (Similar to the IndexOrd() function.)
Public methodCode exampleInfo
Return and optionally change information about a data server.
Public methodJoin
Join this DBServer object with another DBServer object and place the results in the file specified.
Public methodLocate
Search sequentially for a record matching a condition.  If neither conditions nor scope is passed to the method, it is subject to the general server scope.
Public methodLockCurrentRecord
Lock the current record.  This method is identical to invoking RLock() with the current record number as a parameter.
Public methodCode exampleLockSelection
Lock all the records in the currently active selection.
Public methodNoIVarGet
Provide a general error interception that is automatically called (in any class) whenever an access reference is made to a non-existent exported instance variable.  In the DBServer class, it is used to implement the virtual field variable.
Important!  NoIVarGet() should not be called directly; it is called by the system for handling invalid references.
(Overrides NoIVarGet(Usual).)
Public methodNoIVarPut
Provide a general error interception that is automatically called (in any class) whenever an assignment reference is made to a non-existent exported instance variable.  In the DBServer class, it is used to implement the virtual field variable.
Important!  NoIVarPut() should not be called directly; it is called by the system for handling invalid references.
(Overrides NoIVarPut(Usual, Usual).)
Public methodNotify
An event handler that responds to events that have occurred in methods of this server, or in other servers that are linked to this server in some way.  The standard implementation notifies all the server's clients of the event.
Important!  This method is automatically called by the various action methods of the data server, and should normally not be called by application code.
(Overrides Notify(Usual, Usual).)
Public methodCode exampleOrderDescend
Return and optionally change the descending flag of an order.
Public methodCode exampleOrderInfo
Return and optionally change information about orders and index files.
Public methodCode exampleOrderIsUnique
Return the status of the unique flag for a given order.
Public methodCode exampleOrderKeyAdd
Add a key to a custom built order.
Public methodCode exampleOrderKeyCount
Return the number of keys in an order.
Public methodCode exampleOrderKeyDel
Delete a key from a custom built order.
Public methodCode exampleOrderKeyGoTo
Move to a record specified by its logical record number in the controlling order.
Public methodCode exampleOrderKeyNo
Get the logical record number of the current record.
Public methodCode exampleOrderScope
Set the boundaries for scoping key values in the controlling order.
Public methodCode exampleOrderSkipUnique
Move the record pointer to the next or previous unique key in the controlling order.
Public methodPack
Remove deleted records from a database file.
Public methodRDDINFO
Return and optionally change settings controlled directly by the RDD.
Public methodRecall
Recall those deleted records indicated by a specified scope.
Public methodRecallAll
Recall all deleted records in the table.
Public methodRecordInfo
Retrieve information about the indicated record.
Public methodRefresh
Reread the current record from the database, discarding any changes that have been made.
Public methodReindex
Recreate all active indexes for this server.
Public methodRelation
Return the linking expression of a specified relation.
Public methodCode exampleReplace
Replace one or several fields with a new expression, for all records that match a specified scope.
Public methodResetNotification
Resume the broadcasting of Notify messages to the server's attached clients (after DBServer:SuspendNotification() has been called).
(Overrides ResetNotification.)
Public methodRLOCK
Lock a record for exclusive write access; other users can still make read-only reference to the record.
(Overrides RLOCK(Usual).)
Public methodRLockVerify
Determine if the current record in this data server has any pending updates and lock it for exclusive write access if there are none.
(Overrides RLockVerify.)
Public methodCode exampleSeek
Move to the record having the specified key value in the controlling order.
Public methodSELECT
**Missing documentation **
Public methodSetDataField
Assign a DataField object to a specified field.
(Overrides SetDataField(Usual, Usual).)
Public methodCode exampleSetFilter
Set a filter condition.
Public methodCode exampleSetIndex
Open an index file and select its order as the controlling order, if this is the first index being opened.
Public methodSetOrder
Select an order from one of the open index files as the controlling order.
Public methodSetOrderCondition
Set conditions that is applied to index and order creation.  If SetOrderCondition() has not been called, order creation is subject to the general server scope.  If neither has been set, orders are not conditional.
Public methodCode exampleSetRelation
Set a relation from this server to the child server.
Public methodCode exampleSetSelectiveRelation
Set a selective relation from this server to the child server; standard database operations are restricted to those records that match the relation.
Public methodSkip
Move the record pointer forward or backward a specified number of records.
(Overrides Skip(Usual).)
Public methodSort
Copy records to another database file in sorted order.  If neither conditions nor scope is passed to the method, it is subject to the general server scope.
Public methodCode exampleSum
Calculate the sum of a series of numeric expressions.
Public methodSuspendNotification
Suspend the broadcasting of Notify messages to the server's attached clients.
(Overrides SuspendNotification.)
Public methodCode exampleTotal
Aggregate records by key value, producing grouped summarizations, and write the aggregate records to another database.
Public methodUnLock
Release a specified lock or all locks.
Public methodUpdate
Update this server with data from another server or table.
Public methodZap
Permanently remove all records from the server and release the disk space.
Top
Remarks
Once a DBF table is opened in a DBServer object, it can be manipulated through the methods of the DBServer class, several of which are shown in the following examples:
X#
1oDBCust := DBServer{"customer"}
2oDBCust:Skip(3)
3? oDBCust:CustName
4oDBCust:CustNo := NewNumber
5oDBCust:GoTo(86)
6oDBCust:Delete()
7oDBCust:Append()
8oDBCust:Close()
The fields of the table can be considered as exported instance variables of the object.  They can also be accessed through the FieldGet() and FieldPut() methods, with the field identified through a symbol, a string, or a number:
X#
1oDBCust := DBServer{"customer"}
2oDBCust:CustNo := 1234
3? oDBCust:CustNo
4oDBCust:FieldPut(#CustNo, 1234)
5oDBCust:FieldPut("CustNo", 1234)
6oDBCust:FieldPut(1, 1234)
7? oDBCust:FieldGet(#CustNo)
8? oDBCust:FieldGet("CustNo")
9? oDBCust:FieldGet(1)
(The fields are, of course, not real exported variables of the DBServer class.  See "Objects, Classes, and Methods" in the Programmer's Guide for a discussion of how these "virtual" exported variables are created using the NoIVarGet() and NoIVarPut() methods.) All the traditional database operations available through commands or functions are available as methods for the DBServer object.  In general, they behave the same way, with two exceptions:  expanded parameter types and general scope-setting. Whenever an operation requires the specification of a file, an alias, a work area, or a field, the methods accept an object of the corresponding class:  a FileSpec object for a file, a DBServer object for an alias or a work area, or a DataField object for a field.  These options allow a more consistent use of objects and all the benefits they convey.  The new, object-oriented approach is not required:  a file can be specified as either an object or a string, an alias as an object, string or symbol, fields as objects, strings, or symbols. The classical SetRelation() operation allows you to link to servers, so that a movement in the parent server causes an automatic movement in the child server.  The prototypical situation is a relation between a customer server and an order server, to make the order server show the orders for the current customer:
X#
1oDBCust := DBServer{"customer"}
2oDBCust:SetIndex("custname")
3oDBOrder := DBServer{"order"}
4oDBOrder:SetIndex("ordcstno")
5oDBCust:SetRelation(oDBOrder,#CustNo)
After this relation is established, any movement in the parent of the relationship causes a corresponding repositioning of the client:  moving to customer Jones positions the order database at the first of Jones's orders, if any.  The DBServer:SetRelation() method works exactly the same as the corresponding command and function in traditional Xbase DML. However, this type of relation is not very helpful.  The child database is positioned correctly at the beginning of the orders, but it is not limited at the end of the orders.  Thus, the application that uses the server must continually check if it is still on the appropriate customer's orders.  DBServer:SetFilter() is not very helpful, because if you skip past the last of the customer's orders, DBServer:Skip() continues to scan the file until it finds one that matches.  This kind of behavior is particularly burdensome for general purpose tools like data windows, which have to express these tests in a general way while they provide for data browsing. This is where a selective relation is more valuable.  If we establish a selective relation, all operations on the child server are restricted to those records that match.  DBServer:GoTop(), DBServer:GoBottom(), DBServer:BOF, DBServer:EOF, and DBServer:Skip() act as if the only records that exist are those that match the relation.  Specifically, if you try to skip past the last appropriate order, Skip() fails and returns an end-of-file condition.  Similarly, if you try to GoTo() a record that doesn't match, GoTo() fails as if that record didn't exist and stays on the current record.  And utilities like Eval(), Count(), Sum(), etc., by default apply only to the selection (although explicitly specified scopes are allowed to violate this restriction).
X#
 1LOCAL aSum
 2oDBCust := DBServer{"customer"}
 3oDBCust:SetIndex("custname")
 4oDBOrder := DBServer{"order"}
 5oDBOrder:SetIndex("ordcstno")
 6oDBCust:SetSelectiveRelation(oDBOrder,#CustNo)
 7oDBCust:Seek("Jones")
 8DO WHILE ! oDBOrder:EOF
 9? oDBOrder:OrderNumber
10ENDDO
11aSum := oDBOrder:Sum(#Charge)
12? "Number of orders:",oDBOrder:RecCount
13? "Total value:",oDBOrder:aSum[1]
The following table lists the properties and methods that reflect the currently active selection:
Method or PropertyDescription
BOFAttempt to position before first record in selection.
EOFAttempt to position after last record in selection.
FoundIndicates if a record is found within the selection only (after Seek(), Locate(), Continue())
RecCountReturns number of records in selection (note that LastRec is not dependent on selection)
Average()If no scope is specified, makes the calculation over the current selection instead of ALL records
Continue()Limits the search to the current selection
CopyDB(), CopySDF(), CopyDelimited() If no scope is specified, copies the current selection instead of ALL records
Count()If no scope is specified, makes the calculation over the current selection instead of ALL records
DeleteAll()Deletes all the records of the selection, instead of all records in the file
Eval()If no scope is specified, evaluates the code block over the current selection instead of ALL records
GetArray()Limits array to current selection
GetLookupTable()Limits array to current selection
GoTop()Goes to first record in selection
GoTo()Fails if the record number is not within selection
GoBottom()Goes to last record in selection
Locate()Succeeds only if the record is found within the selection
LockSelection()Locks all records in the current selection
RecallAll()Recalls all the records of the selection, instead of all records in the file
Replace()If no scope is specified, processes the current selection instead of ALL records
Seek()Positions to the beginning of the current selection — only if the seek value is the same as the selection value; otherwise, positions to the last record of the file and set the EOF flag.  (Softseek is ignored.)
Skip()If the move would lead out of the selection: positions to the last record of the selection and sets the EOF flag or positions to the first record in the selection and sets the BOF flag, depending on the direction of the move.
Sort(), Sum(), Total()If no scope is specified, processes the current selection instead of ALL records
Tip Tip
The following methods are not subject to the limitations of an active selection: AppendDB(), AppendDelimited(), and AppendSDF(), because their scoping parameters apply to the source file, not to this server Delete(), because its default is this record rather than all Recall(), because its default is this record rather than all
Several Xbase database commands provide a number of options for specifying the scope of the operation through keywords: ALL, REST, NEXT <nRecords>, RECORD <nRecord>, as well as through FOR and WHILE clauses.  The semantics of these clauses, and how they interact when several are specified, are described under "Using DBF Files" in the Programmer's Guide. The corresponding DBServer methods (like Average(), AppendDB(), CopyDB(), Sort(), Sum(), Total(), and others) allow the specification of a FOR clause, a WHILE clause and a scope as arguments in the invocation.  In addition, it is possible to set up a "general server scope" using simple assigns (the corresponding accesses are also provided).  This general scope applies whenever one of these bulk processing methods is invoked without an explicit scope.  This approach can in many cases be more convenient. For example, to delete the next five records:
X#
1oDB:Scope := 5            // NEXT 5 records
2oDB:Delete()
3oDB:Scope := NIL        // Don't forget to reset the scope!
For example, to delete all the remaining records:
X#
1oDB:Scope := DBScopeRest        // REST
2oDB:Delete()
3oDB:Scope := NIL            // Don't forget to reset the scope!
To count the number of Smiths in New Jersey:
X#
1oDBCust:SetOrder("CustomerName")    // ORDER by name
2oDBCust:Seek("Smith")            // FIND first Smith
3oDBCust:WhileBlock := {||CustomerName = "Smith"}
4// WHILE still on the Smiths...
5oDBCust:ForBlock := {||State = "NJ"}    // FOR                                     // customers
6// in NJ...
7Tally := oDBCust:Count()            // COUNT 'em!
8oDBCust:ClearScope()            // RESET everything
Remember to restore the scope afterwards:  the scope is persistent and applies to all following scope-based methods until reset.  The convenience of this style of specifying a scope comes with the danger of leaving it active for too long.  The scope can be reset with the DBServer:ClearScope() method, or by assigning NIL to the individual components. The general server scope can be set with: Property Meaning ForBlock A string or codeblock specifying the FOR condition. Scope DBSCOPEALL, DBSCOPEREST or a number <nRecords> (meaning NEXT <nRecords>). WhileBlock A string or codeblock specifying the WHILE condition. Note that there is no provision for specifying a specific record number with this approach.  There is rarely a need to process a specific record (e.g., the average of the salary of record 5).  In cases where there is, such as for Delete(), use RecNo :=  <n>, GoTo(<n>) or Seek(<Value>) to position the server, and then invoke Delete(). The methods that are subject to the general server scope are:
Method NameDescription
AppendDB()Append records from DBF.
AppendDelimited()Append records from delimited file.
AppendSDF()Append records from SDF file.
Average()Calculate average of expressions.
CopyDB()Copy records to DBF.
CopyDelimited()Copy records to delimited file.
CopySDF()Copy records to SDF file.
Count()Count how many records match.
Delete()Delete records.
Eval()Evaluate code block for each record.
Join()Join with another DBF, write to DBF.
Locate()Find record that matches conditions.
Recall()Recall deleted records.
Replace()Replace values with data from DBF.
Sort()Sort records to a DBF.
Sum()Calculate sums of expressions.
Total()Summarize fields to a DBF.
The default scope is, of course, "no scope," so these methods have the same default behavior as the corresponding commands and functions.  Most of them process all records or all remaining records, depending on how the scope is defined; those for which the default is "the current record" also have corresponding "all" methods:
Method NameDescription
Delete()Delete current record.
DeleteAll()Delete all records.
Recall()Recall current record.
RecallAll()Recall all records.
But note that if a selective relation has been specified, the default source scope is the selection, not the entire file.  Thus, we have four levels of inheritance with regard to the scope of an operation: 1. The scope that explicitly specified through arguments of the call 2. If none was provided, the scope that is set through the ForBlock, WhileBlock and Scope properties 3. If none was set, the selection specified with the selective relation 4. If no selective relation is active, the entire file The exceptions Delete() and Recall() use options 1 and 2, then default to the current record.  DeleteAll() and RecallAll() apply to the current selection, if any; otherwise, to the entire file.  Of course, a selection scope is not relevant to the Append... methods, for which the conditions apply to the source file, not this server. The DBServer Editor generates a subclass of the generic DBServer class, one with specific information such as file names and virtual fields created as access/assign methods. It is not possible to use the DBServer class to create a database file; the file must exist before a server can be opened on it.  To create a database file, use the DBCreate() (recommended) method, the VODBCreate() function, or the DBServer Editor. This section describes the shared access and aliasing mechanisms used when creating multiple DBServer work areas or servers, as well as hybrid object/procedural operation. Work area Creating a DBServer object opens a database in a work area.  There is no provision for specifying whether a new or existing work area should be used; the DBServer always uses a new work area. After the instantiation, the new work area is not selected; the work area that was selected before the instantiation remains active.  Thus, traditional database commands and functions issued after the instantiation of the DBServer does not apply to the newly opened database.  The proper way to operate on the new DBServer is through its methods. Shared access Creating two DBServer objects on the same database file is equivalent to opening the same file in two different work areas.  The two servers (work areas) each maintain its own position and record locks, and operate as two users sharing access to the same file. To allow creating two servers on the same database file (opening the same file in two work areas), they must, of course, be opened in shared mode; otherwise the second attempt produces a sharing violation.  However, this does not raise an error condition, it simply stores an invalid status of the object.  Use the DBServer:Status or DBServer:Used properties after the instantiation to verify if a file was successfully opened. Shared mode can be specified as an instantiation parameter (for example, SetExclusive(FALSE) in the Start() function) or as a system default (see DBServer:Init()). Alias When using the methods of the DBServer to work with the database, an alias is not needed; the DBServer object provides the handle by which the database is referenced.  The alias has no role in operating with a DBServer object, but internally the system needs a unique alias for every work area. The DBServer automatically constructs a unique alias.  If the file is not open in any other work area or server, it uses the file name as the alias in the traditional manner, but if the file is already open, it creates a unique alias by appending a number.  Thus, opening the CUSTOMER file twice would produce the two aliases #Customer and #Customer_1. The only reason for explicitly using the alias is to perform "hybrid" operation, using traditional, procedural operations with commands or functions on a DBServer object.  This practice is strongly discouraged, however.  Because the DBServer object may not be aware of what is done through the commands, DBServer methods can malfunction after use of procedural commands.  (For more details, see "Using DBF Files" in the Programmer's Guide.) It is possible to retrieve the automatically generated alias from the DBServer object, to enable selection of the work area as the focus of procedural database operations:
X#
1oDBCust := DBServer{"customer"}
2cCust := oDBCust:Alias
3SELECT (cCust)
4SKIP
5DELETE
6? (cCust) -> CustNo
Most of the changes we made in the RDD classes were made to improve the speed of the RDD classes. One change in particular could influence your application: in the old implementation Visual Objects was restoring the ‘current workarea’ after each DbServer:Method call. This is only useful if you are mixing Object Oriented DBF access with traditional work area oriented DBF access. If all you do is Object Oriented DBF access, the work area switching is unnecessary and may have a negative impact on your applications performance. Therefore we have added a switch to the RDD classes that allows you do enable/disable this restore mechanism. The default for Visual Objects 2.8 is to NOT restore the workarea. The switch is in the function:
X#
1DbSetRestoreWorkarea (lEnable)
This is a global switch, which changes the behaviour of the DBServer class. The default value of the lEnable switch is FALSE which means that workarea restoring is disabled. As a result of this at the end of each DbServer method the current workarea is the workarea of the DBServer. If you set the lEnable flag to TRUE every DBServer method restores the workarea at the end of the method to the value of the work area at the beginning of the method. This is the old behavior, but costs some extra time. The return value of DbSetRestoreWorkarea () is the previous value. If lEnable is NIL the switch is not set and SetRestoreWorkarea() returns only the current value. DbSetRestoreWorkarea () also changes the internal behaviour of the new internal function __DBSetSelect(siNew). If you call DbSetRestoreWorkarea (TRUE) which is the default __DBSetSelect() is identical to VODBSetSelect(), if  you call DbSetRestoreWorkarea (FALSE) DBSetSelect() is empty and do nothing.
Tip Tip
There have been some major changes in the DbServer class in VO 2.8. Please read the section on the bottom of this topic carefully if you are migrating from an older version of Visual Objects.
See Also

Reference