JULY 1992 VOLUME 4 NUMBER 7
INDEX
Hello and welcome to the July 1992 issue of Bullets!
I am never sure what to expect at computer conferences. Last month, two potentially different
conferences were held: Novell's BrainShare/Japan and Microsoft's NT Developers Conference.
The audiences and their expectations could have been quite different. I wondered what would the
attendees be looking for and what messages would be delivered.
I was surprised to discover that the developers, their needs and their wishes were not that
different. One of the keynote speakers at Brainshare reminisced about a conference he attended
during the mid-1980's. At that conference, he said developers wanted three things: performance,
stability and consistency. (I am surprised that, back then, it wasn't performance, performance and
performance.) He said these are still the basic developer needs.
If he is correct, what does this say about the past decade? Have we been unsuccessful?
I think we have been successful in fulfilling some basic programming requirements and,
while the computer industry continues to change as rapidly as ever, we are constantly working to
meet the others. It is a very positive development to see the companies at these conferences
asking their customers what their specific needs are. This trend can only help to "accelerate the
growth of the network computing industry" in the next decade.
Happy_Programming!
Mad Poarch
Director
Developer Support/Service
Keeping Your Database in Sync
NetWare SQL v3.0 is the latest version of Novell's relational data access system
developed specifically as a NetWare Loadable Module (NLM) for the NetWare v3.11 platform.
NetWare SQL v3.0 offers Named Database support, page-level transactions (cursor stability),
continuous operations during backups, and referential integrity (RI), which ensures that cross
references between tables are always valid. This article will familiarize you with RI, NetWare
SQL 3.0's implementation of it and how to install RI to keep your database in sync.
NetWare SQL's Implementation of Referential Integrity
Keeping a database in sync requires two types of data integrity: physical and logical.
NetWare v3.11 works with NetWare Btrieve v6.0, a server-based version of the Btrieve record
manager included as a component of NetWare SQL v3.0, to provide the physical data integrity
with their automatic recovery functions. NetWare SQL v3.0 provides logical data integrity
through two mechanisms: transaction control and RI.
NetWare SQL's transaction control utilizes the transaction and record-locking capabilities of
NetWare Btrieve. In NetWare SQL v3.0, RI is initially established by the system administrator or
application developer, and once established, it is transparent to any application development.
RI ensures that, when a field or group of fields in one table reference a field or group of fields in
another table, any changes made to these fields are synchronized. A set of rules, referred to as
referential constraints, define the relationships between tables. Several definitions are useful in
understanding RI:
- A primary key is a field or group of fields whose collective key value uniquely
identifies each record in a table. Primary keys are implemented as unique, non-null indexes.
- A foreign key is a field or group of fields that reference a primary key in the same or a
different table. A foreign key cannot contain null values.
- A parent table is a table containing a primary key referenced by a foreign key.
- A dependent table is a table containing a foreign key that references a primary key in the
same or a different table. A dependent table can contain multiple foreign keys.
- A dependent row is a record in a dependent table whose foreign key value matches a
primary key value in the referenced parent table.
- A self-referencing table is a table which is its own parent table; in other words, it contains
a foreign key that references its primary key.
- A cycle is a reference path in which the parent table is its own descendant.
Every foreign key value in a dependent table must have a matching primary key value in
the referenced parent table. Consequently, an attempt to insert a record with an unmatched
foreign key value into a dependent table will fail. Similarly, an attempt to delete a record in a
parent table to which a foreign key currently refers may fail, depending on how the foreign key is
defined.
Managing an invoice tracking system is one example of a task in which RI is useful. Suppose
that customer information is contained in one table and invoice information for each customer is
kept in a second table. If a customer is deleted from the database while the customer had an
outstanding invoice, the database would be logically corrupted because an invoice would exist
for a customer that does not exist. If you used RI on this database, you could establish constraints
to prevent customer information from being deleted if invoices exist.
Btrieve fully enforces all referential constraints defined by NetWare SQL. This prevents both
Btrieve and NetWare SQL applications from compromising integrity constraints when modifying
data. To implement RI, two new files have been added to the NetWare SQL system (which only
exist if referential constraints have been defined via NetWare SQL). A file called RELATE.DDF
is located with the rest of the dictionary files and contains the relationships between the primary
and foreign keys in the tables. In addition, the SYS:\SYSTEM directory contains the file,
DBNAMES.CFG, which is created when you define a Named Database.
DBNAMES.CFG contains the descriptive name of the database and the location of the dictionary
files associated with that database. Named Database support is a new feature of NetWare SQL
v3.0 that allows you to define a name for a database, and associate a dictionary path and datafile
paths with that name. You can then use this name to access the database. A Named Database is
required to set up RI and, by default, RI is enabled when you define a new Named Database.
When you define a referential constraint for a field in a given table, information is added to the
physical Btrieve file to indicate that the file has RI constraints. Included in this information is the
SQL database name and the SQL table name. NetWare Btrieve uses this information to look up
the location of the dictionary files in DBNAMES.CFG, and then to check the relationships in
RELATE.DDF. Based on the information in RELATE.DDF, NetWare Btrieve may access other
Btrieve files involved in the relationship to verify data prior to performing the modification to the
Btrieve file. As a result, NetWare Btrieve is opening more than just the file being modified. This
can be seen using the NetWare SQL Monitor Utility (NDBMON.NLM), and should also be taken
into account when configuring the maximum number of open files in the NetWare SQL Setup
Utility (NDBSETUP.NLM).
Establishing RI
Establishing RI with NetWare SQL v3.0 is very easy. There are a few simple guidelines
for defining referential constraints.
- The database must be defined as a "Named Database" using the NDBSETUP
utility.
- All of the files in the database must reside on a single server; they can, however, be split
across multiple volumes on that server.
- Data paths defined in the dictionary cannot contain drive letters. Paths must be simple file
names or relative paths.
- If security is enabled on the database, a user must have the References right on a table to
define referential constraints on the database.
- SQL statements are used to define referential constraints. Referential constraints can not
be defined using the primitives.
- RI can be defined on both new and existing databases. All files need to be in the NetWare
Btrieve v6.0 file format. For existing databases, files can be rebuilt to the new format using the
BREBUILD utility.
- Referential constraints are easy to define by using either the "CREATE TABLE" or
"ALTER TABLE" SQL statement. These statements are used to define primary and foreign keys.
The "ALTER TABLE" statement can also be used to remove referential constraints. These
statements can be executed from one of the interactive utilities provided with NetWare SQL v3.0
(SQLScope or XQLI), or can be executed from an application using SQL-Level function calls.
Figure 1 shows how to define RI with SQL statements.
FIGURE 1: Defining RI using SQL Statements
CREATE TABLE CUSTOMER
USING 'CUST.BTR'
( PRIMARY KEY (ID),
IDINT(2),
NAME CHAR(20),
ADDR CHAR(20),
CITY CHAR(10),
STATE CHAR(2),
ZIP CHAR(10))
WITH INDEX (ID UNIQUE)
ALTER TABLE INVOICE
ADD FOREIGN KEY custID (CUSTID)
REFERENCES CUSTOMER
ON DELETE RESTRICT
END of FIGURE 1
The "WITH INDEX" clause on the create table statement is optional, since NetWare
SQL will automatically create the first index according to the field(s) specified as the primary
key. Also notice that a "delete rule" is specified for deleting records in the INVOICE table.
With NetWare SQL, there are rules to Insert, Update and Delete foreign keys.
- The Insert rule is RESTRICT. This means that for each foreign key in the record
being inserted, the foreign key value must have an equivalent primary key value in the parent
table.
- The Update rule is RESTRICT. This means that a foreign key value must be updated to a
new value that has an equivalent primary key value in the parent table.
- The Delete rule can be either RESTRICT or CASCADE. If you specify RESTRICT as
the delete rule, when you attempt to delete a record from the parent table, NetWare SQL first
checks to see if a foreign key exists in any of the dependent tables before it allows the delete. For
example, in Figure 2, the EMPLOYEE table has a foreign key, DeptID, which references the
DeptID field from the DEPARTMENT table. If you try to delete an DeptID from the
DEPARTMENT table which is referenced by a matching ID in the EMPLOYEE table, the delete
will fail.
FIGURE 2: NetWare SQL CASCADE and RESTRICT delete rules
DEPARTMENT table
DeptID < RESTRICT
EMPLOYEE table
> Employee Employee Employee Dept
ID Name Location ID
CASCADE
PROJECTS table
Project Project Project Employee
ID Name Description ID
END of FIGURE 2
If you specify CASCADE as the delete rule, when you attempt to delete a record from
the parent table, NetWare SQL will check to see if a matching foreign key value exists in any of
the dependent tables. In Figure 2, the EMPLOYEE table has a primary key, EmployeeID, which
is referenced by the EmployeeID field in the PROJECTS table. With the CASCADE delete rule,
if you delete an EmployeeID from the EMPLOYEE table, NetWare SQL will delete all
dependent rows from the PROJECTS table as well. If all descendants of a primary key have
CASCADE as the delete rule, NetWare SQL will delete all dependent rows on a reference path to
the original parent table.
When specifying the delete rule for a given foreign key, use the following guidelines:
- The delete rule for a self-referencing table must be cascade.
- A cycle with two or more tables cannot be delete-connected to itself. This means that the
delete rule for at least two of the dependent tables in the cycle must be restrict.
- Delete rules from multiple paths (dependent tables that reference the same parent table)
must be the same.
Installing RI on a New Database
To setup RI on a new database, use the following steps:
- Create a dictionary
- Establish a database name for the dictionary with the NDBSETUP utility. You may wish
to disable RI for the database until you have finished defining your constraints.
- Design your database
- Decide how many tables the database will contain, what fields will be in each of
the tables, and how the tables' fields relate to each other.
- Decide what fields need referential constraints and what the delete rules will be for the
foreign keys; this step is sometimes easier if it is done graphically as in the diagram in Figure 2.
- Define your tables and your referential constraints to the dictionary. Referential
constraints can be added when tables are created, or after the tables have been created.
- Enable RI for the database through NDBSETUP and populate the tables. These two steps
can be interchanged depending on how you plan to populate your tables. If you are loading data
into your tables from some type of sequential file, you may want to do this without enabling RI.
Then, after you have added all the data, you can use the RIUTIL utility to check the consistency
of your existing data, based on the referential constraints defined. If you are adding new data into
a new system, you may want to enable RI from the start to ensure that all new data complies with
the defined constraints.
Installing RI on an Existing Database
Before setting up referential constraints on an existing database, check with the application
vendor or developer to make sure the restraints you install will not interfere with the applications.
Some applications might allow null values for fields you wish to define as a primary or foreign
key, or might perform inserts on dependent tables with no matching primary key values. In these
cases, RI will cause new status codes to be returned which the application is not expecting. If the
vendor or developer indicates that RI will not interfere with the application, follow these steps to
install RI.
- Convert all files created with version of Btrieve before v6.0, including the
dictionary files, to the NetWare Btrieve v6.0 file format using BREBUILD.
- Establish a database name for the dictionary with NDBSETUP. You may wish to disable
RI until you finish defining your constraints.
- Plan your referential constraints based on the existing indexes, or add new indexes as
necessary to implement the constraint that you want. Again, this process may be easier if it is
done graphically as in Figure 2.
- Define your referential constraints to the dictionary using the ALTER TABLE statement.
- Use the RIUTIL utility to check the consistency of your existing data based on the
referential constraints that have been defined.
- Make any necessary modifications to your data so that it conforms to the referential
constraints defined. This can be done manually, or by using the RIUTIL -CHECK utility.
RIUTIL -CHECK has an option that will remove any records that violate the RI constraints.
- Once the RIUTIL utility reports that the database is "in sync," enable RI using
NDBSETUP.
NetWare SQL v3.0 has been released only for the NetWare v3.11 environment as a
NetWare v3.11 NLM. For additional product information, please contact 1-800-RED-WORD
(1-800-733-9673) or 1-512-794-1796. For technical and developer support questions regarding
any released Novell products, please call 1-800-NETWARE (1-800-638-9273) or 801-429-5588.
New ReturnVersion API for DLLs (NetWare C Interface for Windows v1.3)
The function, GetDLLVersion( ), was not exported or supported by the NetWare C
Interface for Windows v1.3. However, Figure 3 contains an API, ReturnVersion( ). which, when
placed directly into applications or an OBJ file, returns DLL version information.
FIGURE 3: Replacement for GetDLLVersion API
extern void ReturnVersion( BYTE far *majorVersion,
BYTE far *minorVersion,
BYTE far *revisionLevel,
BYTE far *betaReleaseLevel );
:
void GetDLLVersionInfo( char far *DLLName,
BYTE far *majorVersion,
BYTE far *minorVersion,
BYTE far *revisionLevel,
BYTE far *betaReleaseLevel )
{
HANDLE hDriver;
static FARPROC lpfnReturnVersion;
hDriver = LoadLibrary( DLLName );
lpfnReturnVersion = GetProcAddress( hDriver, "ReturnVersion" );
if ( lpfnReturnVersion != NULL )
( *lpfnReturnVersion )( (BYTE far *)&majorVersion,
(BYTE far *)&minorVersion,
(BYTE far *)&revisionLevel,
(BYTE far *)&betaReleaseLevel );
if( lpfnReturnVersion == NULL ) {
majorVersion = 0;
minorVersion = 0;
revisionLevel = 0;
betaReleaseLevel = 0;
}
} /* GetDLLVersionInfo */
/* Usage example */
:
static char DLLName[20] = "NWIPXSPX.DLL";
BYTE majorVersion;
BYTE minorVersion;
BYTE revisionLevel;
BYTE betaReleaseLevel;
:
GetDLLVersionInfo(DLLName, (BYTE far *)&majorVersion,
(BYTE far *)&minorVersion,
(BYTE far *)&revisionLevel,
(BYTE far *)&betaReleaseLevel );
END of FIGURE 3
IPX Function Calls in a WEP Fail (NetWare C Interface for Windows v1.3)
DLLs can use a Windows Exit Procedure (WEP) that is executed before unloading the
DLL from memory. When the WEP procedure is called, your data or code segments may no
longer be valid. For example, calling an IPX/SPX function where one of the parameters is an
ECB will result in an invalid memory reference.
Instead of cleaning up IPX/SPX resources in a WEP procedure, you should write a function for
clients to call to clean up resources before exiting. Novell's IPXSPX.DLL is an example of this
design. This DLL exports a function called IPXSPXDeinit that clients call to clean up resources.
TTS & Pre-Imaging (NetWare Btrieve (NLM) v5.15)
If TTS is disabled at the server and the Btrieve data files to be accessed with the NetWare
Btrieve v5.15 are flagged "transactional" (T), Btrieve will return a status 15 (Pre-image I/O
Error) on all updates (Insert, Update and Delete operations) to the data files between Begin
Transaction (19) and End Transaction (20) operations.
The status 15 is not returned when:
- The update is performed outside of a Btrieve transaction
- Before the update is performed inside of a Btrieve transaction, a successful update has
occurred outside of a transaction with the current instance of Brequest. This case is reinitialized
once Brequest is unloaded and loaded again on the workstation.
In all cases, even when the status 15 is not returned, no pre-imaging is performed if TTS is
not enabled at the server.
If Btrieve data files are flagged transactional, TTS must be enabled at the server for pre-imaging
to be performed. When TTS is disabled, flag all Btrieve files non-transactional (-T).
How To Get NetWare SQL v3.0 (NetWare SQL (NLM) v3.0)
New customers can obtain NetWare SQL v3.0 through an authorized Novell reseller.
Registered users of NetWare SQL v2.x can upgrade to any user count of NetWare SQL v3.0.
Registered users of XQL v2.x can only upgrade to the NetWare SQL Developer's Kit v3.0.
- To upgrade a copy of NetWare SQL v2.x or XQL v2.x, customers should contact
their local Novell resellers.
- Customers in the U.S. and Canada may also order upgrades by calling Novell After
Market Products (AMP) at 1-800-346-7177. Novell resellers are now able to furnish NetWare
SQL v3.0 upgrades through the NetWare upgrade program.
Windows, TBMI, VIPX.386, & DOS Applications (NetWare Btrieve v5.x)
Within Windows, running Brequest and a DOS application in a DOS box requires
different setups depending on which version of Windows you use and whether or not you run
Windows in standard mode or enhanced mode.
- If you run Windows v3.0 in standard mode, load TBMI.COM before starting
Windows. In the DOS box, load TASKID.COM, BREQUEST.EXE, and the DOS application (in
that order). TBMI.COM and TASKID.COM are currently available on Novell's CompuServe
forum, NetWiresm (NOVLIB, LIB 1 or 5, WINUP6.ZIP).
- If you run Windows v3.1 in standard mode, load TBMI2.COM before starting Windows.
In the DOS box, load BREQUEST.EXE and then the DOS application. TBMI2.COM is provided
with Windows v3.1.
- If you run either Windows v3.0 or v3.1 in enhanced mode, then you should use
VIPX.386. Modify the SYSTEM.INI file under the [386Enh] header by adding the line:
"network=VIPX.386."
After starting Windows, load BREQUEST.EXE in the DOS box, and then load the DOS
application. Use the VIPX.386 that is included in WINUP6.ZIP on NetWire. Do not use the
version included with Windows v3.0.
- If a Windows application (not DOS) requires BREQUEST.EXE, then load
BREQUEST.EXE before you start Windows.
Pre-imaging in NetWare Btrieve v6.0 (NetWare Btrieve (NLM) v6.0)
NetWare Btrieve v6.0 creates a pre-image file when writing to a Btrieve file created with
an earlier version of Btrieve. However, the format of this pre-image file is different from the
format of a pre-image file created by earlier versions of Btrieve. Earlier versions of Btrieve
cannot accurately interpret a pre-image file created by NetWare Btrieve v6.0 and vice versa.
If you need to interchange the Btrieve engine that will be accessing the pre-v6.0 Btrieve file, all
pre-image files must be cleaned up prior to swapping engines. Use the following procedure to
clean up these pre-image files:
- Check to see if a .PRE file exists for any Btrieve files
- If a .PRE file exists with a pre-v6.0 version of Btrieve:
- open the Btrieve file in Exclusive mode
- perform a Get First operation
- perform an Update operation
- close the Btrieve file (this should cause the .PRE file to be deleted)
- Switch engines
Remember that a Btrieve file can not be accessed simultaneously with a client Btrieve
engine and the NetWare Btrieve server-based engine. This procedure should be used if it is
necessary to swap between a pre-v6.x client engine and a v6.x server engine.
Novell Database Products & Case-Insensitivity (NetWare SQL (NLM) all versions)
With Btrieve, if a string, lstring or zstring key is created with the alternate collating
sequence, UPPER.ALT, the case of the data in the key is ignored when performing a search on
that key. For example, if a record is inserted with the key value "test," this record can be
retrieved by performing a Get Equal operation with a Key Buffer parameter containing the value
"TEST," "Test," "test" or any other combination of upper and lower case letters.
In addition, if two records are inserted with the values "test" and "TEST," they are considered
duplicate key values. Get Equal on any case representation of "test" will always return the first
record entered. When scanning the key values for this key, it may appear that Btrieve is not
sorting the values properly, since "test" will be returned before "TEST" if the records were
inserted in that order.
Case searches work differently with NetWare SQL. There is a CASE key-word which indicates
that a field or index should be treated as case-insensitive (i.e. upper and lower case letters will be
treated the same). There are two situations to consider. The CASE keyword can be specified for
any string, lstring or zstring field in the dictionary and/or for any string, lstring or zstring index.
For a case-insensitive field, restrictions are evaluated regardless of case. So, a record containing a
Name field with the value "John" will be returned when a restriction of "Name = 'JOHN'" is
specified. If CASE is not specified for a field, only exact matches with the value in the restriction
will be returned, regardless of whether or not there is a case-insensitive index specified for this
field.
For a case-insensitive index, the case of the data is ignored when sorting the data. Specifying that
an index is case-insensitive causes Btrieve to create and maintain that key using the UPPER.ALT
alternate collating sequence.
Figure 4 contains an example that demonstrates the different types of fields. Notice that the
Name1 index is case-insensitive, but the Name2 index is case-sensitive.
FIGURE 4: CASE sensitivity and field types
CREATE TABLE Test USING "TEST.DAT"
(Name1 CHAR(10) CASE, Name2 CHAR(10)) WITH INDEX (Name1 CASE, Name2)
INSERT INTO Test
VALUES("John", "Doe") VALUES("jane", "doe") VALUES("JOHN", "BROWN")
SELECT * FROM Test SELECT * FROM Test SELECT * FROM Test
WHERE Name1 = "john" WHERE Name2 = "Doe" ORDER BY Name1
Name1 Name2 Name1 Name2 Name1 Name2
---------------------------------------------------------------
John Doe John Doe jane doe
JOHN BROWN John Doe
JOHN BROWN
END of FIGURE 4
When using Xtrieve PLUS v4.1x to create tables, case-insensitivity for a field is
specified by selecting "No" for the "Case?" option for a string, lstring or zstring field on the field
definition screen. When the cursor is in the "Case?" column, the help text at the bottom of the
screen reads "Specify Case-sensitivity when used in view restrictions?"
Case-insensitivity for indexes is also specified by selecting "No" at the "Case" prompt on the
index definition screen. When the Case selection box appears, the help text reads "Treat upper
and lower case letters differently in sort?" Answering "No" to this question implies
case-insensitivity. Figure 5 contains the Xtrieve PLUS definition for the table Test described
above.
FIGURE 5: Example Xtrieve PLUS definition table
FIELD DEFINITIONS
----------------------------------------------------------------
Position Key Name Type Size Dec Delimiter Case
----------------------------------------------------------------
1 * Name1 String 10 No
11 * Name2 String 10 Yes
INDEX DEFINITIONS
----------------------------------------------------------------
Key Name Field Type Dups Mod Case Asc Total
----------------------------------------------------------------
0 Name1 String Yes No No Yes 0
1 Name2 String Yes No Yes Yes 0
END of FIGURE 5
A confusing situation might occur if a field is defined as case-insensitive and that field is
also an index, but the index is defined as the opposite: case-sensitive. Usually, a case-insensitive
field implies that case is ignored on restrictions. However, if an index exists, NetWare
SQL/Xtrieve PLUS will use that index to optimize the search. If the index is not defined with
case-insensitivity (thus Btrieve is NOT using UPPER.ALT for this index), the optimized search
will only find exact matches, and the restriction will only find exact matches. In this situation,
the case-insensitivity of the field is overridden by the case-sensitive index. Therefore, if a
case-insensitive field is also part of an index, that index should also be defined as
case-insensitive.
Record Locking In Embedded SQL (NetWare SQL (NLM) all versions)
Record locking is not part of the industry standard for embedded SQL, so NetWare SQL's
implementation of embedded SQL does not support it. Guaranteed access is only available
through the use of transactions. In fact, by default, transaction processing is automatically
enabled, causing all embedded SQL calls to be performed within NetWare SQL transactions.
Record locking is supported by both the Relational Primitive and SQL-Level functions,
which can also be used to develop NetWare SQL applications.
Lotus Configuration for DataLens Driver (NetWare SQL (NLM) v3.0)
If a drive letter and path are used in the LOTUS.BCF file to specify the location of the
Datalens Driver for NetWare SQL (NLM) v3.0, and this location is not the Lotus directory or the
current working directory, the driver will not be found.
Always place the Datalens Driver (LTSNWSQL.DLD or LTSNWSQL.DLL) in the Lotus
directory or in the current working directory.
NetWare Btrieve v6.0 & Patch311.NLM (NetWare Btrieve (NLM) v6.0)
When using BTRIEVE.NLM v6.0 with NetWare v3.11, make sure that PATCH311.NLM
(the patch file for the version of CLIB.NLM released with NetWare v3.11) is in the
SYS:\SYSTEM directory before you attempt to load BTRIEVE.NLM, regardless of which
version of CLIB.NLM the networkuses. BTRIEVE.NLM v6.0 always attempts to automatically
load this patch file. PATCH311.NLM will only load if the released CLIB.NLM is running. If the
system uses a newer version of CLIB.NLM, PATCH311.NLM will detect it and do nothing. As
long as the Btrieve NLM can locate the patch file, it will load whether PATCH311.NLM
successfully loads or not.
Using Brequest in Multiple Desqview Sessions (NetWare Btrieve (NLM) v5.x)
With Desqview v2.40, if you have multiple sessions running Btrieve applications using the
NetWare Btrieve requester (BREQUEST.EXE), Btrieve may return a status 79 (Programming
Error). The Desqview v2.40 configuration option, "Network Buffers," can be increased to resolve
this status code.
From a Desqview window, run the program DVSETUP. Then, select the advanced setup
procedure. From the advanced menu, select the Network option. One of the network options is
called "Network Buffers." The default for this parameter is 8. Raising this value to 16 will
usually resolve the status 79.
Is TBMI/TBMI2 Loaded? (NetWare C Interface for Windows v1.x)
You can determine if TBMI/TBMI2 is loaded by using the interrupt INT 2Fh with 7A10h
in AX with DX initialized to zero. The version will be returned in DX (Major version in DH,
minor version in DL). The values in these registers will be zero if TBMI/TBMI2 is not installed.
Using IPX/SPXInitialize can serve the same purpose by indicating that IPX could not be
initialized (error 240 or 0xF0).
If you use the INT 2Fh method, remember that TBMI/TBMI2 are TSRs and run in REAL mode.
If you run a Windows application which needs to check on TBMI, use DPMI to simulate the
REAL mode interrupt.
Error Using Turbo Pascal Interface for NetWare SQL NetWare SQL (NLM) v3.0
The Turbo Pascal interface included with NetWare SQL (NLM) v3.0 lets you specify
whether the application will use SQL-level functions, primitive functions, or both. To choose one
type of function or both, "comment out" one or both of the following lines, which appear at the
top of the interface file NWSQLINT.PAS:
{$DEFINE NWSQL_RELATIONAL_PRIMITIVES}
{$DEFINE NWSQL_SQL_FUNCTIONS}
If the second $DEFINE line (for the SQL-level functions) is "commented out," this indicates that
only the primitive calls will be included and the interface cannot be compiled into a Turbo Pascal
Unit. The compiler will return an error 59 (Undefined Forward).
Two of the prototypes defined in the miscellaneous section of this interface should be moved into
the SQL-level prototype section:
- PROCEDURE SQLLevelCall;
- FUNCTION SQLManagerLoaded : BOOLEAN;
Passing Parameters with XQLP & Visual Basic (NetWare SQL (NLM) v3.0)
To pass Visual Basic strings "by reference," the function declaration section must specify
"ByVal" on any string parameter. According to the Microsoft Visual Basic Programmer's Guide
(1991) (pg. 382, "Calling DLL Routines with Specific Data Types"), the routines in most DLLs
expect standard C strings which end in a null character. If a DLL routine expects a C string as an
argument, declare the argument as a string with the "ByVal" keyword. When used with a string
argument, "ByVal" tells Visual Basic to pass the string as a C string ending with a null character.
The "ByVal" clause tells Visual Basic to pass the string address by value (not by reference),
instead of just passing the string itself. So, if the XQLP documentation requires a string
parameter to be passed by reference, the Visual Basic Function Declaration needs to specify
"ByVal." If XQLP requires the string by value, the Visual Basic function declaration needs to
specify "as String" or "as VarName$."
Integers work just the opposite. If XQLP requires the integer by value, the Visual Basic function
declaration must specify "ByVal." If XQLP requires the integer by reference, the Visual Basic
function declaration needs to specify "as Integer" or "as VarName%." If XQLP requires a
structure, which is generally the data buffer, Visual Basic stores "TypeDefs" in a different area
than strings, and as such, it gets handled the same way as integers with respect to the "ByVal"
clause in the Function Declaration.
Status 2001 with WBTRCALL (NetWare Btrieve (NLM) v5.15)
With the Windows Btrieve requester, WBTRCALL.DLL v5.17a (date: 6-28-91), Btrieve
returns a status 2001 (Insufficient Memory) on any Btrieve call issued after a WBTRVSTOP
call. The status 2001 only occurs within a single task or program. If an application that makes
Btrieve calls is running and that application, or any other application calls WBTRVSTOP, the
NetWare Btrieve NLM will return a status 2001 on each successive Btrieve call in all Btrieve
applications that are running until the applications are restarted.
This situation has been resolved in the version of WBTRCALL.DLL (NetWare Btrieve v6.0) that
ships with NetWare SQL (NLM) v3.0. If you use the v6.0 WBTRCALL.DLL, you also need
WBTRVRES.DLL (also included with NetWare Btrieve v6.0).
IPXODI Options Affect SPX & Diagnostics (NetWare C Interface for DOS v1.2)
IPXODI allows certain options to be specified when it is loaded that affect what protocol
support is installed. Specifically, the D option tells IPXODI NOT to load Diagnostics support.
The A option tells IPXODI not to load Diagnostics support or SPX support. If diagnostics
support is not loaded, BeginDiagnostics() will return 0xFE (254). If SPX support is not loaded,
SPXInitialize() will return a zero.
Retrieving NetWare Volume Serial Numbers (NetWare System Calls for DOS v1.0)
Beginning with DOS v4.x, volume serial numbers were introduced. This information
could usually be retrieved from the DOS BOOT sector. Under NetWare volumes, there is no
DOS BOOT sector.
You can use an undocumented DOS function to retrieve volume serial numbers: INT 21h,
function 69h. The example code in Figure 6 shows how you can retrieve data from drive I.
FIGURE 6: Retrieving NetWare Volume Serial Numbers
union REGS inRegs, outRegs;
struct SREGS segRegs;
struct MID {
WORD midInfoLevel;
LONG midVolumeSerialNumber;
BYTE midVolumeLabel[11];
BYTE midFileSystemType[8];
} MidInfo;
far *pMidInfo;
void main (void)
{
memset (&MidInfo, 0, sizeof (MidInfo));
pMidInfo = (int *)&MidInfo;
segread (&segRegs);
inRegs.h.ah = 0x69;
inRegs.h.al = 0x00;
inRegs.h.bh = 0x08; /* drive letter to target */
segRegs.ds = FP_SEG (pMidInfo);
inRegs.x.dx = FP_OFF (pMidInfo);
int86x (0x21, &inRegs, &outRegs, &segRegs);
printf ("\nSerial Number: %lx", MidInfo.midVolumeLabel,
MidInfo.midVolumeSerialNumber);
} /* main */
END of FIGURE 6
Fast Answers to Common Questions
NetWare C Interface for Windows
Q - What drivers do I need to develop and run Windows v3.1 applications?
A - The current driver requirements for developing and running Windows v3.1
applications are:
- the versions of VNETWARE.386, NETWARE.DRV, and VIPX.386 supplied
with Windows v3.1.
- the DLLs supplied with the NetWare C Interface for Windows v1.3 (not the drivers
mentioned in the '\DRVRS' directory).
- for Standard mode, the version of TBMI2.COM supplied with the NetWare C Interface
for Windows v1.3.
NetWare C Interface for DOS
Q - I have a TSR which manages IPX/SPX communications to other nodes. I do not
have to login to NetWare, so I only load IPX.COM. When I unload my TSR, the
SHORT_LIVED socket I opened remains open. Are SHORT_LIVED sockets supposed to
remain open upon program termination?
A - When a program terminates, the NetWare shell (e.g., NETX) closes Sockets
opened as SHORT_LIVED. However, if the shell is not loaded, all sockets are treated like
LONG_LIVED_SOCKETS. In this case, call IpxCloseSocket () before terminating the program.
NetWare & OS/2
Q - When will the NetWare OS/2 v2.0 requester be available?
A - The OS/2 v2.0 requester is available now from 1-800-UPDATE1. The price
includes documentation. Members of the Professional Developers' Program (PDP), can also
obtain the requester from the NDEVREL forum on NetWire. (Remember to unzip the file with
the /d option.)
Q - Can 32-bit OS/2 v2.0 applications call the 16-bit Novell libraries?
A - Yes, but a thunk is required. A thunk is the procedure of telling a 32-bit function
to handle a 16-bit API call.
NetWare for SAA LU6.2 Tools
Q - When I recompile the NLM example, CPIS.C, that is supplied with NetWare for
SAA LU6.2 Tools (Feb. release) with the WATCOM v8.0 compiler, the example will not run
correctly. What should I do?
A - This situation occurs with v8.x (and above) of the WATCOM compiler, which
has been updated to define "far." In the NLM environment, the normal definition of "far" causes
"far" pointers to be 48-bit (not 32-bit) and will not work with NetWare Lu6.2. For usable "far"
pointer definitions, delete lines 40 through 42 of the header file CPIC_NET.H and insert the
following four lines:
#ifdef far
#undef far
#endif
#define far
Btrieve
Q - With NetWare Btrieve v6.0, when I perform an Insert (2) operation, NetWare
Btrieve inserts for a while, then it returns a status 84 (Record in Use). What should I do?
A - Your application should retry if it receives a status 84. In this case, NetWare
Btrieve is locking the key page for a brief moment and at this time another user is trying to
access it.
Q - After I create a Btrieve file with an alternate collating sequence, is the alternate
collating sequence file (the file that contained the new collating sequence) still required?
A - No. Btrieve stores the new collating sequence within the Btrieve file.
Q - If you create a supplemental index and then close the Btrieve file, does the
supplemental index disappear from the file?
A - No, the supplemental index remains in the file until you perform a Drop
Supplemental Index operation.
NetWare SQL (NLM) v3.0
Q - When I received NetWare SQL v3.0, I was surprised to find a NetWare Btrieve
v5.15 diskette in the package. Why was this diskette included?
A - The NetWare Btrieve (NLM) v5.15 diskette is always shipped with NetWare
v3.11, and since NetWare SQL v3.0 (20+ user) packages include a copy of NetWare Runtime,
they also include a NetWare Btrieve (NLM) v5.15 diskette. This should not be used on the
NetWare Runtime server; you should use the NetWare SQL v3.0 install utility to load NetWare
Btrieve v6.0.
Q - Does NetWare SQL (NLM) v3.0 support Lotus 1-2-3 for Windows at this time?
A - No, there is currently no interface for Lotus 1-2-3 for Windows.
Xtrieve PLUS for DOS v4.10
Q - If I install Xtrieve PLUS for DOS v4.10 on a network, will the license agreement
be violated if more than one person uses it?
A - No. Xtrieve PLUS 4.10 is licensed per server. Everyone who has access to the
server where Xtrieve PLUS resides can use it without violating the license.
Novell Education is now offering several new and updated courses for developers who use
Novell's development and database tools, including Btrieve, Xtrieve PLUS, and the NetWare
Client APIs.
- 904: Btrieve: An Overview
- This new course provides a general overview of Btrieve and its new features. Covers file
structures, indexing, data integrity, record and file locking, caching, operating modes, segmented
keys, backward compatibility and utilities.
Aug. 11 Sunnyvale, CA
Sept. 15 Chicago, IL
- 905: Programming with Btrieve
- This course has been enhanced to cover all Btrieve operations & environments, including
COBOL. Provides a complete introduction to Novell's server-based record manager. 50% of
class time is spent in programming workshops. Working knowledge of C, BASIC, Pascal, or
COBOL required. Prerequisite: 904: Btrieve: An Overview
Aug. 12-14 Sunnyvale, CA
Sept. 16-18 Chicago, IL
- 907: Xtrieve PLUS
- This course has been updated to include new features introduced with NetWare SQL v3.0.
Teaches application developers to use Xtrieve PLUS as a Btrieve or NetWare SQL programming
utility. Trains users of Btrieve- or NetWare SQL-based database applications to work effectively
with this menu driven utility.
Sept. 22-23 Austin, TX
- 930: Developing NetWare Loadable Modules (NLMs)
- This course introduces C programmers to server-based application development in the
32-bit NetWare 3.x environment. Covers basic concepts for writing server-based C applications
that access the NetWare 3.x C library (CLib). Requires working knowledge of the C language.
Sept. 15-17 Austin, TX
- 940: NetWare Client Programming: NWCALLS
- This new lab-oriented course (40% lab work) introduces network programming concepts
and topics like bindery services, file system services, print services, queue management,
connection and file server services and accounting and synchronization services. Requires
knowledge of the C programming language.
Sept. 22-24 Provo, UT
Oct. 13-15 Chicago, IL
- 945: NetWare Client Programming: Protocol Support
- This new course covers Protocol Support features. Covers network programming concepts
and techniques for developing client-side applications, including SAP, IPX/SPX, diagnostics,
NetBIOS emulation, TLI, & Named Pipes. Requires strong knowledge of C programming
language.
Sept. 15-17 Austin, TX
Oct. 20-21 Sunnyvale, CA
To register or obtain information on pricing, location and course content for classes held
in the US, call 1-800-233-3382, 1-801-429-5508 or 1-800-NETWARE. International customers
should call 1-801-429-5508. For information on availability, location, and prices of international
classes, contact your local Novell office.
Test your "developing" skills by taking our Fun & Facts quiz. Have fun and good luck! (See the
end of this section for answers.)
1. Which of the following statements is true of BREBUILD.NLM?
A. It allows you to redirect the file to another server
B. It keeps a copy of the file in 5.x format
C. It preserves the owner name after the conversion
2. How many NLMs work together to provide communication services to the NetWare
v3.11 operating system?
A. 8
B. 7
C. 6
3. What Btrieve data type does not exist in Xtrieve PLUS?
A. Bit
B. Unsigned Binary
C. Money
4. What module standardizes and manages the primary details of interfacing ODI multi-link
interface drivers to the LSL and the NetWare operating system?
A. MSM.NLM
B. HSM.NLM
C. TSM.NLM
5. What DDF file contains information about referential integrity constraints?
A. VIEW.DDF
B. FILE.DDF
C. RELATE.DDF
6. What NLM allows you to use connection encapsulating IPX packets within IP packets?
A. SNMP.NLM
B. TCPIP.NLM
C. IPTUNNEL.NLM
7. How do you initialize Btrieve for OS/2 (client-only version) within an application?
A. Cannot be initialized through an application
B. Use function BTRVINIT(char *)
C. Use function WBTRINIT(char *)
8. Name the socket number for the Diagnostic Packet
A. 0x454
B. 0x455
C. 0x456
9. What console command is used to address memory above 16 MB on EISA computers ?
A. None
B. Register Memory
C. Auto Register Memory Above 16 Meg
FUN & FACTS ANSWERS
1. C
2. A
3. B
4. A
5. C
6. C
7. B
8. C
9. A
Developer Support
Developers in the U.S. and Canada may contact Novell Developer Support via telephone, fax,
BBS or electronic mail via CompuServe, MHS or the Internet.
Voice
For both presales and postsales support, call Novell Developer Support between 8:00 a.m. and
5:00 p.m. Mountain Time at 1-801-429-5588. Many calls to Novell Developer Support are
passed to a software support engineer immediately. Calls to Novell Developer Support generally
will be acknowledged or answered within four hours.
Fax
If you prefer, you may contact Novell Developer Support via fax at 1-801-429-2990. Faxed
questions are acknowledged or answered within 24 hours.
Developer BBS
If you do not have access to either CompuServe or the Internet, send test cases to our BBS. Set
your communication software to N-8-1 and call 1-801-429-5836.
E-mail: CompuServe
Post your messages in the appropriate section addressed to Novell at 76701,171. These messages
will receive a response within 24 hours.
E-mail: MHS
You may direct your questions and comments to Novell Developer Support via Novell's Message
Handling Service E-mail facility. Address your messages to devsup@novell. These messages
will receive a response within 24 hours.
E-mail: Internet (SMTP)
An alternative method of contacting Novell Developer Support is through the Internet E-mail
system. Send your messages to devsup@novell.com. These messages will receive a response
within 24 hours.
NetWire on CompuServe
Novell's NetWire forum is open to all registered CompuServe subscribers. Through the
NDEVSUP forum, professional developers writing applications with Novell development tools
can gain access to information specific to Novell development. Support, patches, periodicals and
product information, as well as information on all of the programs and services provided for
Novell developers are accessible through this forum. Post your messages in the appropriate
section addressed to Novell at 76701,171. Technical questions will be acknowledged or
answered by Novell Developer Support within 24 hours.
Novell Products and SDKs
Novell products on the "Currently Shipping Developer Products" list (see page 15 of this
issue), including the Red Box Products, are available to Novell Professional Developer's
Program members. Call 1-800-RED-WORD (1-800-733-9673) or 1-303-894-4135 to order these
products or to receive additional information. To order other Red Box Products not listed,
contact your local Novell office or Novell Authorized Reseller.
Novell Labs
For information on Novell Labs development tools, education classes and product certification,
in the U.S. and Canada call 1-800-453-1267 ext. 5544 or 1-801-429-5544, or call your local
Novell office (see back cover of this issue).
Novell Developer Relations
Novell Professional Developers or those wishing to become members may contact Novell
Developer Relations via telephone, fax, or electronic mail via Compuserve, MHS or the Internet.
Voice
For general information or questions on Novell Developer Relations programs, in the U.S.
or Canada call 1-800-RED-WORD (1-800-733-9673). All others call 1-801-429-5281.
Fax
If you prefer, you may contact Novell Developer Relations via fax at 1-801-429-7207.
NetWire on CompuServe
Novell's NetWire forum is open to all registered Compuserve subscribers. Through the
NDEVREL forum, Novell Professional Developer's Program-related issues or general questions
may be posted. Through the NDEVINFO forum, customers who do not have products may post
pre-sales product information questions on all Novell SDKs.
E-mail: MHS or Internet (SMTP)
You may direct your questions and comments to Novell Developer Relations via Novell's
Message Handling Service E-mail facility. Address your messages to devprog@novell.com. Use
the same address when going through the Internet E-mail system.
Publisher: Mad Poarch
Editor: Kirk R. Humphries
Design: Creative Services, Provo
Contributors: Gaurang Amin, Linda Anderson, Vitek Boruvka, Irit Diaz, Neda Eslami, Kumar
Gaddam, David Harris, Sudz Khawaja, Ken Lowrie, Diane Klinetob, Nancy Kromar, Rudy
McNeese, Chris Ojeda, Paige Parker, Jose Pruneda, Randy Reddy, Glenn Stephens, Brenda
Wallace
Special thanks to the Developer Support, Development, Developer Relations, Product Marketing,
and Marketing Communications staff who contributed time and valuable input.
(c) 1992 Novell, Inc. All rights reserved.
Novell, the N design, NetWare, Btrieve, XQL and LAN WorkPlace are registered
trademarks, NetWare Lite, NetWare System Calls for DOS, NetWare Loadable Module (NLM),
NetWare SQL, NetWare Btrieve, Xtrieve PLUS, NetWare C Interface for DOS, NetWare System
Interface Technical Overview, NetWare RPC, NetWare RPC 386, NetWare LU6.2, Report
Executive, and Professional Development Series (PDS) are trademarks, and NetWire and
Professional Developers' Program (PDP) are servicemarks of Novell, Inc. Apple, Macintosh and
AppleTalk are registered trademarks of Apple Computer, Inc. CompuServe is registered
trademark of CompuServe Corporation. Microsoft is a registered trademark, and Windows and
Visual Basic are trademarks of Microsoft, Inc. IBM and OS/2 are registered trademarks, and
NetBIOS and SAA are trademarks of International Business Machines Corporation. Sun
Microsystems and NFS are registered trademarks of Sun Microsystems, Inc. WATCOM is a
trademark of WATCOM Systems, Inc.
|