|
| |
CodeBase 6 Hints
This document provides a list of solutions for common
problems and answers to frequently asked questions.
Common problems
Frequently Asked Questions
General CodeBase questions
Other CodeBase Errors
Common problems
Visual C++ 6 support
Visual C++ 6 will work with the
pre-built CodeBase 6.4 DLLs.
Visual C++ 6 may generate compile
errors when rebuilding the CodeBase static library or DLL. If this occurs,
download these fixed CodeBase 6.4 source
files and place them in your SOURCE directory.
Visual C++ 6 will work with CodeControls
3, but the example projects for Visual C++ 5 that come with CodeBase 6.4
will not work with Visual C++ 6. These
example projects have been updated for Visual C++ 6.
Two example source files will not
compile with Visual C++ 6. These example
source files have been updated to work.
Windows 98
GPF during installation GPF
A GPF can occur while running the
CodeBase 6.4 install program. It occurs when the Browse button in
the "Choose Destination Location" window is pressed. There are two solutions
to this problem:
-
Restart the computer and run the installation
program again before running any other programs. Do not click the Browse
button; you will not be able to modify the directory CodeBase is installed
to.
-
Copy the files directly from the CD.
The files on the CD are not compressed, so they can be copied directly
to your hard drive. Stand-alone support can be found in the CB64 directory,
and client/server support can be found in the CB64CS directory. NOTE: If
you wish to use CodeControls, you will have to manually register the OCX
files with REGSVR32.EXE.
Windows NT
A number of problems that arise
when using Windows NT can be fixed by installing the latest Windows
NT Service Pack. The problems that are solved include memory leaks
and interaction with NetWare drives.
Novell and Windows
Sometimes CodeBase will generate
a -200 error when opening a file on a NetWare drive. This is solved by
downloading an updated Windows
Novell Driver.
Overflow
Error calling report4parent()
There is a mistake in the declaration
of report4parent() in CODEBASE.BAS which causes an overflow error when
you run your program. Instead of:
Declare Function report4parent% Lib "c4dll.dll" (ByVal r4&,
ByVal hWnd%)
it should read:
Declare Function report4parent% Lib "c4dll.dll" (ByVal r4&,
ByVal hWnd&)
The character after the hWnd must be
changed from a '%' to a '&' to avoid this error.
Unresolved
External Symbol operator new
When compiling with Microsoft Visual
C++, the following error might be generated:
libcimtd.lib(iostrini.obj) : error LNK2001: unresolved external
symbol "void * __cdecl operator new(unsigned int,int,char const *,int)"
This is caused by using the wrong run-time
library. For the Release configuration, use the Multithreaded
run-time library. For the Debug configuration, use the Debug
Multithreaded run-time library.
NetBEUI
The NetBEUI driver has been found
to work better than other protocols like IPX/SPX when Windows 95 clients
are accessing data on a Windows NT server.
CodeUtil
The CodeBase installation program
is not always able to register the control COMDLG16.OCX. To register it
yourself, use the MSAREG.EXE utility provided in the CODEUTIL\SYSTEM directory.
msareg comdlg16.ocx
beginthread
Error Building DLL
This error appears when building
C4DLL.DLL with Microsoft Visual C++ 4.X with the calling convention set
to stdcall. To fix this, go into Build | Settings | C/C++ and change Category
to Code Generation. Then change Calling Convention to _cdecl*.
Frequent
Index Corruption under Windows 95
This problem is common in Windows
95 OEM Service Release 2.x. The source of the problem is the file VREDIR.VXD.
Microsoft has provided a new
version (210k) for Windows 95 that will fix this problem. The patch
executable is a self installing program which will install itself and make
the needed changes to your Windows setup.
More information on this bug can
be found in article
Q174371 in the Microsoft Knowledge Base.
more...
UNIX bus
errors or core dumps
Some Unix systems require that
data in memory is stored on strict byte boundaries. If these boundaries
are violated, a system error will usually occur. To ensure that CodeBase
adheres to these boundaries, set S4DATA_ALIGN in p4port.h.
Link Error:
LIBCI.LIB cannot be found
This link error is caused by a
change in the run-time libraries of Microsoft Visual C++. In version MSVC++
4.1 and previous, all of the iostream functions were located in LIBC.LIB,
LIBCMT.LIB and MSVCRT.LIB. However, with MSVC++ 4.2 and later versions,
these iostream functions were moved to their own libraries, called LIBCI.LIB,
LIBCIMT.LIB and MSVCIRT.LIB respectively. Because the pre-built CodeBase
libraries for MSVC++ 4.0 were actually built with MSVC++ 4.2, they require
the newer run-time libraries. To get around this problem, rebuild the CodeBase
libraries using your version of MSVC++ 4.x.
CodeBase
not working after error
When a CodeBase error is generated
in C, C++, Visual Basic or Delphi, CODE4.errorCode (or Code4::errorCode
in C++) is set to a negative value to indicate the error that occurred.
In order to resume, you must acknowledge the error by setting the errorCode
value back to zero.
Invalid
Transaction file (error -1210) when opening file
When CodeBase first opens a database,
if a log file has not yet been opened, CodeBase will look for one called
C4.LOG in the current directory and open it if found. This is to prepare
for transaction processing. When this error occurs, CodeBase has found
such a file, but its contents are invalid. This could be due to a power
failure or program crash that occurred during the last time the log file
was written to.
If the integrity of the log file
is important, use CodeUtil (in Windows) or the utility functions (in other
operating systems) to repair the log file. Otherwise, simply delete the
log file if it is not important.
If you do not intend to use a log
file in your application at all, you can force CodeBase to NOT automatically
open the log file by calling code4logOpenOff() before you open any database
files.
Class not registered.
Looking for object with CLSID: {...}
This error message occurs when
you try to open the Properties pages of the CodeControls, but there are
missing entries in your computer's system registry. You can manually add
these missing entries to the system registry by using REGEDIT.EXE. In the
MyComputer\HKEY_CLASSES_ROOT\CLSID folder, use Edit | New | Key from the
REGEDIT.EXE menu, to add these three keys (the curly braces must be included):
{0BE35200-8F91-11CE-9DE3-00AA004BB851}
{0BE35201-8F91-11CE-9DE3-00AA004BB851}
{0BE35202-8F91-11CE-9DE3-00AA004BB851}
When you select any of these keys, the
window on the right of REGEDIT.EXE displays its default value. Right click
on the word Default, select Modify from the pop-up menu and change the
default values of the keys to the following:
{0BE35200-8F91-11CE-9DE3-00AA004BB851}
- "Font Property Page"
{0BE35201-8F91-11CE-9DE3-00AA004BB851}
- "Color Property Page"
{0BE35202-8F91-11CE-9DE3-00AA004BB851}
- "Picture Property Page"
Each of the above keys should have its
own subkey called InprocServer32, which can also be created by using Edit
| New | Key. The default value of InprocServer32 should be the full path
to where MFC40.DLL has been installed on your computer (i.e.. "C:\WINDOWS\SYSTEM\MFC40.DLL"
or "C:\WINNT\SYSTEM32\MFC40.DLL").
Exceeding the
64K default data segment limit in a DOS application
This error can sometimes be resolved
by re-building the CodeBase client library with the E4OFF_STRING compiler
switch. This should free up approximately 40K in your default data segment.
With this switch set, CodeBase error messages will only output error numbers,
without any text information about the error. You can cross reference the
error message by looking up the error numbers in E4STRING.C.
Structure
Verification Failure (error -960) when using CodeBase 6.5 and C++Builder
4 or 5
This is due to a difference between
the compiler options used to build the CodeBase libraries, and the ones
you are using to build your application under C++Builder. Specifically,
the CodeBase libraries are compiled use the -b compiler option, which causes
the compiler to make enumerated data types integer-sized. However,
projects created by C++Builder use the -b- compiler option by default,
which makes enumerated data types byte-sized.
Under C++Builder 4, use the Project|View
Makefile menu command to examine the makefile for your project. In the
makefile, there is a variable called CFLAG1 that is assigned several compiler
options. Change the -b- option to -b, and save the makefile.
Under C++Builder 5, use the Project|Options
menu command, and go to the Compiler tab. Under the Compiling section,
check the box besides "Treat enum types as ints" and click the OK button.
Design-time
license error when using CodeControls
There are two common causes
of this error:
-
The CodeBase Administrator was installed
or re-installed after the installation of the CodeControls. This
results in the CodeBase Administrator's set of CodeControls, which does
not have a design-time license, to be registered, overwriting the registration
of the CodeControls with the design-time license. The CodeControl
OCX files in the \CodeBase\CodeCtrl directory must be re-registered using
the instructions on page 190 of the CodeControl 3 manual.
-
The CodeBase 6.5 CodeControls were registered
with the wrong set of design-time license files. The correct set
of license files can be downloaded from here
to replace the existing ones in the \CodeBase\CodeCtrl directory, and then
the CodeControl OCX files can be re-registered using the instructions on
page 190 of the CodeControl 3 manual.
"Specified driver
could not be loaded due to system error 127 (CodeBaseOdbcStand)"
The current releases of
the stand-alone CodeBase SQL/ODBC Driver (not the CodeBase
Reduced SQL/ODBC Driver) use their own version of the c4dll.dll.
However, the installation program for the driver will not install its c4dll.dll
over any pre-existing c4dll.dll in the \Windows\System or \WinNT\System32
directory. The c4dll.dll that is currently in the \Windows\System
or \WinNT\System32 directory must be removed, then the stand-alone CodeBase
SQL/ODBC Driver must be un-installed and re-installed.
Frequently Asked
Questions
What Files are used
by CodeBase?
|
Description
|
File Extension
|
|
FoxPro
|
dBASE IV
|
Clipper
|
| Data File |
DBF
|
DBF
|
DBF
|
| Memo File |
FPT
|
DBT
|
DBT
|
| Index File |
CDX
|
MDX
|
CGP, NTX
|
Data File: A file with the
DBF extension. It contains all the non-memo entries.
Memo File: A file with either
a DBT or FPT extension. It contains all memo entries.
Group File: A file with a CGP
extension. This file is unique to CodeBase and is used only in the Clipper
case. It contains the names of the index files.
Index File: A file with a CDX,
MDX or NTX extension. This file contains the sort order of the data file.
For further information about the
contents of the above files, please consult other questions in this document
or the User's and Reference Guides.
What
is the difference between opening a file in read-only mode, and opening
the file in exclusive mode?
When a file is opened in read-only
mode, other processes may have opened the same file at the same time. When
a process opens the file in exclusive mode, no other processes may have
open the same file at the same time. Also, no file locks are made. Opening
a file in exclusive mode yields faster access times, and prevents other
applications from accessing the file.
How can files
be opened in different modes?
Suppose that we want to open four
files using different modes:
| File Name |
Access Mode |
Read Only
|
| FILE1.DBF |
Fully Shared |
|
| FILE2.DBF |
Exclusive |
|
| FILE3.DBF |
Deny Others Write |
|
| FILE4.DBF |
Fully Shared |
|
|
In order to do this, we need only
change the CODE4 member values. In this particular case, the significant
members are:
CODE4.readOnly
CODE4.accessMode
|
I get an
error after opening several files simultaneously. However, if I first close
some files, and then open the rest, everything is fine.
You are running into an O/S limitation.
Refer to the explanation for Error -20 and Error -30.
See Also: Error -20, Error
-30
When I change
my database on one workstation, who do the changes not appear on another
workstation and I receive errors?
CodeBase, DOS and Windows sometimes
buffer their output data. Therefore, when one application makes changes,
the second may not be 'aware' of them since they were not flushed to the
disk. In order to overcome this 'optimization,' the programmer must FLUSH
the changes made. Although the process may be much more involved, the above
advice will get you started.
Why do I have
trouble with relations when I am using two files that have the same name,
even if they are in different directories?
This is because the two files have
the same alias. An alias is the 'name' that CodeBase associates with a
file. By default this 'name' is the same as the name of the file. Thus
a file called FILE.DBF will, by default, have the alias 'FILE.' In
order to get the name of the alias, you must make a call to d4alias. You
may change the alias of any file with the d4aliasSet command. Thus, in
order to open two files with the same name, you must open the first, change
its alias, and only then open the next file.
Let us assume that we have two files
called C:\DIR1\FILE.DBF and C:\DIR2\FILE.DBF. Click below for a short program
segment that will open both files.
What is a BLOB?
-
S4CLIPPER memo fields can not store
the '1A' character in any of their contents. This character is used to
indicate the 'end of memo entry.' This is because the length of the
memo is not stored explicitly. If the '1A' character must be stored in
the memo field then it will be necessary to create a character sequence
to denote it implicitly. However, each programmer must write their own
routine since a standard convention does not exist.
-
The size of the memo entry is not inherently
limited to a specific size by the memo type format. However, the largest
possible memo entry is always the maximum value of an 'unsigned integer.'
Thus, the size of the memo entry is compiler dependent; this is summarized
in the following two points:
-
The size of an unsigned integer in a
16 bit compiler is two bytes. Therefore, the maximum memo entry may be
as large as 64k bytes (2^16) long.
-
The size of an unsigned integer in a
32 bit compiler is four bytes. Therefore, the maximum memo entry may be
as large as 4G bytes (2^32) long.
-
When a 16 bit CodeBase application encounters
a memo entry that is greater than 64k bytes while compressing a memo file,
it will correctly compress the memo entry. It does this by performing segmented
partial reads on the memo file.
If I
search for the string "JOHN", I get a return code of 0
(r4success in Appendix B), yet I am positioned on record "JOHNSON".
How do I perform an exact match and find only "JOHN"
?
Let's assume that your field can
store seven characters, i.e. you defined it as "FIELD_NAME", r4str, 7,
0. When a seek is performed on "JOHN", CodeBase looks for the
first occurrence of "JOHN". This may be found in "JOHNSON".
When you store "JOHN", xBASE (which includes CodeBase) stores
the value as "JOHN
" (that is JOHN with three trailing spaces).
Therefore, if you want to do an "exact" seek to find JOHN, you will have
to pass " JOHN " to the seeking command.
How can I
perform a case-insensitive search?
In this case, you do not change
searching method; rather, you must change your indexing strategy. If you
use the index expression: "UPPER(field_name)" then a search for
"JOHN" will be case-insensitive: both "John" and "jOhN" will be found.
What is
the difference between a TAG and an INDEX?
A tag represents a particular sort
order of the records in the database. An index is a file on disk that stores
one or more tags.
Suppose we have a database with two
fields, NAME and ID. If we want to sort the database according to the NAME
field then we set up a TAG (sort order) based on the NAME field. Similarly,
if we want to sort on the ID field we can create a TAG based on the ID
field. If we want to search and skip through the database using the alphabetized
name tag, we must select the NAME tag using the "tag select" command. We
may do the same for the ID numbers.
In order to store the TAGs on disk,
xBASE (which includes CodeBase) uses INDEX files. CDX and MDX INDEX files
may contain several tags. However, NTX INDEX file only contain a single
tag. Once we open an INDEX file, we have access to all the tags that are
associated with the index.
When I try to
open my DBF, I get an error #-60: "Unable to open XXX.CGP." What
is a .CGP file?
To get a complete answer first read
the question: What is the difference between a TAG
and an INDEX.
Also, please refer to "Group Files"
in the CodeBase manuals.
CGP files are unique to CodeBase
and exist only in the cases when S4CLIPPER is defined. Because Clipper (NTX) does not have multiple-tag index files, CodeBase implements a CGP
file which emulates this functionality. A CGP file allows you to open your
NTX files as if they are a part of a multiple index. For instance, if you
have two NTX files called TAG1.NTX and TAG2.NTX, you may either open each
individually, or use a CGP file and open the two files as if they were
a single index file. Below is an example CGP file that contains a reference
to the above index files:
By inspection it becomes obvious that
the CGP file is simply a text file that contains the names of the tags
used by the data file. When a data file is opened, CodeBase automatically
attempts to open the associated CGP file so that it will be able to open
the separate index files. If the CGP file does not exist then a -60 error
will result. Therefore, in order to avoid the aforementioned error, set
CODE4.autoOpen variable to 0 (OFF), before opening the data file.
If a CGP file is not used then each
index file must be opened manually. Refer to the example programs NOGROUP1
and NOGROUP2 in the User's Guide.
How are
indexes in a non-default directory and indexes with non-standard name extensions
used with CodeBase?
CodeBase is able to create index
files in a non-default directory. In order to do so, the index file must
be created with a separate call from the data file creation call.
If the index file's name extension
is not specified in the call to i4create() or i4open() (Index4::create()
or Index4::open() in C++), CodeBase will use the standard Clipper, dBASE
or FoxPro extension, depending on the compatibility format set by the programmer
(see also "What are the index and data file names of Clipper,
dBASE and FoxPro?").
For those using Clipper compatibility,
the index file name passed to i4create() or i4open() (Index4::create()
or Index4::open() in C++) is the name of the CGP file. The individual index
files will still each have the .NTX file extension. To create Clipper indexes
with a non-default extension, you can specify the extension name when defining
the TAG4INFO.name element for any given index.
An alternate way to specify non-default
Clipper extensions is to manually modify an existing CGP file and its associated
index files.
For example, if the required file
names are DATAFILE.ABC (instead of DATAFILE.CGP), TAG1.ABC (instead of
TAG1.NTX), and TAG2.XYZ (instead of TAG2.NTX) you could perform the following
steps:
-
Rename DATAFILE.CGP to DATAFILE.ABC
-
Within DATAFILE.ABC modify the names
of existing indexes found in the file. For example, change the entry 'TAG.NTX'
to 'TAG1.ABC', etc.
-
Rename the indexes themselves, to match
the changes made to the index name entries in DATAFILE.ABC
For all cases (Clipper, dBASE and FoxPro),
CodeBase will not be able to automatically open any index with a non-standard
name extension. In order to do so, the CODE4.autoOpen member must be set
to 0 (FALSE) before opening the file. The index must then be manually opened.
The above is true for Clipper, dBASE
and FoxPro compatibility. However, in the Clipper case, each tag is stored
separately and a distinct index file is created for it (see also: What
is a CGP file). In this case, three possibilities exist:
-
The CGP file has a different extension.
The CGP must be opened as in the
previous example program.
-
The index (NTX) files have a different
extension.
The CGP file must be edited and
the name extensions should be added to the index file names. For example,
suppose that an existing CGP file contains the following index files:
TAG1
TAG2
In this case, CodeBase will attempt
to open TAG1.NTX and TAG2.NTX. Therefore, if the desired index files are
called TAG1.ABC and TAG2.XYZ, then the CGP file must be modified as follows:
TAG1.ABC
TAG2.XYZ
Now when CodeBase opens the above CGP
file, it will also open TAG1.ABC and TAG2.XYZ.
-
The CGP and/or index files are in separate
directories.
If the CGP and index files are in
different directories then the path name must be added to the CGP file.
For example, the above CGP file may be modified as follows:
C:\DIR1\TAG1.ABC
C:\DIR2\TAG2.XYZ
When this CGP file is used in conjunction
with the previous program, CodeBase will open DATAFILE.DBF in the default
directory. It will then open C:\PROGRAMS\DATAFILE.ABC. Finally, CodeBase
will open the index files C:\DIR1\TAG1.ABC and C:\DIR2\TAG2.XYZ.
If a CGP file is not used then t4open
must be used instead. Remember that the path names must be included.
Why are all
unique tags set to r4uniqueContinue, even though they were created with
the r4unique option?
In the xBASE format, the only information
stored to disk about a tag's uniqueness is a Boolean value that indicates
whether the tag is unique or non-unique. There is no place in the tag to
store more detailed information, such as whether unique tags should be
handled in a fashion similar to r4unique vs. r4uniqueContinue.
In addition, the default behavior
for dBASE, FoxPro and Clipper is to maintain unique tags in a manner similar
to that used by CodeBase when the tag is set to r4uniqueContinue.
Consequently, in order to be compatible
with their tag formats, CodeBase sets the default behavior for any unique
tag to r4uniqueContinue, even if the tag was originally created with the
r4unique setting. CodeBase accomplishes this be maintaining an internal
structure for each tag. When the index file containing the tag is opened,
CodeBase sets a specific 'unique' member of the structure to r4uniqueContinue.
The possible values of this member are as follows:
|
Value
|
Explanation
|
| 0 |
Duplicate keys are allowed in the tag. |
| e4unique |
When a duplicate key is created, via the appending
of a new record or the modification of an existing record, it is not added
to the tag, and an e4unique error is generated by the CodeBase function
that updated/appended the record. The record is not updated. |
| r4unique |
Same as e4unique, except no error message is generated,
and the CodeBase function returns r4unique instead of e4unique. |
| r4uniqueContinue |
When a duplicate key is created via the addition
or modification of a record, the key for that record is not added to the
tag, although the record containing the duplicate key is allowed to be
added/updated in the data file. The CodeBase function that created the
duplicate key record returns r4unique to let you know that the key was
a duplicate. |
-
The default unique error-handling
behavior for a tag is determined by the setting of the CODE4.errDefaultUnique
member. If you wish to change the default setting for all tags that are
opened, modify this member with one of the values listed above. The default
value of this member is r4uniqueContinue.
See also: i4create (Index4::create()
in C++).
Why
is my r4uniqueContinue tag not properly updated?
My tag is indexed on the following
data:
| Record Number |
NAME |
| 1 |
AAA |
| 2 |
BBB |
| 3 |
BBB |
The TAG4INFO settings used when the
tag was created was as follows:
| Name |
TAG_NAME |
| Expression |
NAME |
| Filter |
none |
| Unique |
r4uniqueContinue |
| Descending |
0 |
In this case, the tag's uniqueness
was set to 'r4uniqueContinue'. This setting tells CodeBase to allow the
update or appending of a record with a duplicate key (such as record 3),
but not to add an entry for that record in the index tag.
Therefore, based on the above data
file, only keys for records 1 and 2 are included in the tag; there is no
entry for record 3. Later, the NAME field of record 2 is changed to 'CCC'.
At this point, the 'BBB' value in record 3 would no longer be a duplicate
value, and you would expect all three records to appear in the index tag.
But it is not. Record 3 does not have a tag entry.
Answer: For performance reasons,
it is not possible for CodeBase to scan the entire data file searching
for a possible record that can now be included in the index due to the
modification of an existing record.
The only available work-around to
this problem would be to delete the duplicate-key record, and then re-append
the information to the data file, thus updating the index file tag. The
best solution to this problem is not to use r4uniqueContinue on indexes
where this situation might occur; instead use r4unique or e4unique.
Note also, this if you do not update
the index (by removing the record and adding it back in), you will end
up with a corrupted index file.
How
can I get the number of records that an index contains? For example, if
an index has the '.NOT. DELETED()' filter, how do I find the number
of undeleted records?
Unfortunately, there is not a simple
variable stored somewhere in the database that will keep count of the number
of records in an index. Although it is not difficult to create such a variable
and place it in the tag, it will not be xBase compatible. It is for this
reason that we have not included this functionality.
To find out the number of records
in an index, just select the required index, go to the top, and skip to
the bottom. Count the number of skips and add one. This number will correspond
to the number of valid records in the index.
How
do I create a tag consisting of two numerical fields?
If only one numerical field is used,
you only have to specify that single field in the tag expression. However,
if you need to use two fields, you must convert them to strings first,
and then join them in the expression. For example, if you have two numerical
fields defined as:
| Name |
Type |
Length |
Decimals |
| AGE |
r4num |
2 |
0 |
| WEIGHT |
r4num |
5 |
1 |
the tag expression to join the two
would be:
"STR(AGE, 2, 0) + STR(WEIGHT,
5, 1)"
If a person is 6 years old and weighs
50.3 pounds, you would seek the text " 6 50.3".
Take note of the spaces embedded
in the search string above. These spaces are required to match the search
value with the size of the two fields that make up the index key expression
(2 + 5).
Note also that even though this is
a character tag, which is normally left justified, because the expression
is based on numerical fields -- which are always right justified -- the
individual sub-expressions within the tag expression are also right justified.
See also: Expression
How do I seek
for a Unicode string?
In C, C++ and Delphi, pass a pointer
to your Unicode string to d4seekN (Data4::seek(char*, int) in C++). Remember
that the len parameter is the length ofthe string, in bytes. So
if the Unicode string that you are passing is 6 Unicode characters long,
len
will need to be 12.
How do I
seek for a value in a DateTime field?
Call d4seek or d4seekN (Data4::seek
or Data4::seekN(char*, int) in C++) and pass a string in the format "CCYYMMDDhh:mm:ss:ttt"
where CCYY is the year, MM is the month, DD is the day, hh is the hour,
mm is the minute, ss is the second, and ttt is thousandths of the second.
For example, 2:51 pm on December
6, 1999 would be formatted as "1999120614:51:00.000".
When reindexing
a database, why does the index file shrink dramatically?
When a record is added or modified,
CodeBase will only make an update to the index. It will not rebuild the
index. While this update will keep the index accurate and up to date, the
layout of the index may not be as efficient as when it is reindexed.
As an example, let's say that we
start with a blank database. To the database, we add these records, in
this order: B, A, C, D, F, E, G. Logically, the index will look something
like this:
This is not as efficient and compact
as it could be. As each record is added to the database, CodeBase just
adds the entry to the tag at the appropriate location in the tree.
When CodeBase reindexes the database,
the index will logically look more like this:
As you can see, this version of the
index contains exactly the same data as the one above, but it is organized
in a much more efficient manner. Consequently, the index file consumes
less disk space.
How can
I filter out deleted records when browsing a data file?
If you are using an index tag to
navigate the data file, the easiest way to prevent deleted records from
being encountered is to specify a filter condition when the tag is created.
This can be accomplished by including the following dBASE expression in
the TAG4INFO.filter member when the tag is created:
A second method to filter deleted records
is to use the CodeBase relation functions to set up a similar filter condition.
Refer to your User's Guide for more information on using relations.
What are the
criteria for Query Optimization (QO) technology to be activated?
-
Query Optimization (QO) technology will
be used only when using the relate4 queries.
-
QO uses tags previously created (check
the index file). That is, if the following query is made:
"(FLD1 10) .AND. (FLD2 = 'MALE')
.OR. (FLD3 < 5)"
-
then QO will automatically use TAG1
and TAG2 to generate the query faster.
-
TAG3 will not be used because it contains
a filter.
-
TAG4 will not be used because it contains
a filter -- note that this filter is useless since it accepts all deleted
and non-deleted records. Tags with filters are not used regardless of the
filter result.
-
TAG5 will be used since CodeBase is
indifferent to the record ordering.
-
TAG6 will not be used because more than
one field is included.
-
TAG7 will not be used since r4uniqueContinue
acts as a filter. That is, non-unique records will be in the database,
but not in the index.
Activation of QO also depends on the
compiler. QO uses one bit to represent each record. Therefore the following
restrictions apply:
-
-A 16 bit compiler is only able to allocate
memory locations up to 64K bytes (2^16). Since one bit is used per record,
the maximum number of records that QO can handle is 524,288. Thus, if the
data file has more than half a million records then the query will be made,
but QO will not be used. In this case it may be advisable to use a 32 bit
compiler.
-
- A 32 bit compiler is able to allocate
memory locations up to 4G bytes (2^32). Since one bit is used per record,
the maximum number of records that QO can handle is 34,359,738,368.
Why can QO not
use a r4uniqueContinue tag?
To optimize a query, CodeBase can
only use tags that have an entry for every record in the database.
Since the unique type r4uniqueContinue has only one tag entry for each
block of duplicate records, there may be tag entries missing for some records.
See Also: Query Optimization,
r4unique, r4uniqueContinue
Why
are some slaves in a relation set blank?
When the relation matches
master to slave, only one slave is matched to a master at one time.
Here is an example:
|
name.dbf
|
| ID |
F_NAME |
L_NAME |
| 1 |
JOHN |
BROWN |
|
phone.dbf
|
| ID |
PHONE_NUM |
| 1 |
444-5555 |
| 1 |
555-4444 |
|
internet.dbf
|
| ID |
E_MAIL |
| 1 |
john@abc.com |
| 1 |
jbrown@xyz.com |
| 1 |
jb@isp.com |
Both internet and phone
are slaves of name. So name relates to phone; and
name
relates to internet. But internet and phone do not
releate to each other.
Assuming there is no query, as you
skip through the relation, the records will look like this:
| NAME |
PHONE_NUM |
E_MAIL |
| JOHN BROWN |
444-5555 |
<BLANK> |
| JOHN BROWN |
555-4444 |
<BLANK> |
| JOHN BROWN |
<BLANK> |
john@abc.com |
| JOHN BROWN |
<BLANK> |
jbrown@xyz.com |
| JOHN BROWN |
<BLANK> |
jb@kkk.com |
If you create a query such as "PHONE_NUM
= '444-5555' .AND. E_MAIL = 'john@abc.com'", you would not find any
records.
When
a query that uses Query Optimization technology (QO) is made, how is it
possible to find out the number of records that are returned?
QO returns a bitmap which is used
to indicate which records comply with a query. However, CodeBase does not
have a function which will automatically count the number of records in
the bit map. Consequently, a manual count must be made.
How
can fields from different files be referenced in a query?
When a query is made, the default
database used is the Master. This means that a specified field will automatically
be associated with the master data file. For example, suppose that we are
using a master data file called FATHER.DBF and a slave data file called
SON.DBF. Let us also assume that each file has a field called NAME. For
these data files, a query such as:
"FATHER->NAME = 'Ben Nyland'"
would compare a field called NAME in
FATHER.DBF with the string "Ben Nyland". Because FATHER.DBF is the master
database, an equivalent query to the above would be:
In order to check for the composite
record that has Ben Nyland and his son Eric Nyland, the query would be:
"FATHER->NAME = 'Ben Nyland'
.AND. SON->NAME = 'Eric Nyland'"
As before, the following query would
be equivalent to the above:
"NAME = 'Ben Nyland' .AND. SON->NAME
= 'Eric Nyland'"
In conclusion, to refer to fields in
different data files, use the file's (alias) name followed by the arrow
( -> ) and the field name.
Is it
possible to have a master file with multiple relations to the same slave
file?
Yes. In order to do so, the slave
file must be opened more than once (see d4openClone). If an expression
needs to explicitly refer to either the original data file or one of the
clones, then aliases must be used to guarantee accurate results. For example,
if the slave file's alias is "EMPLOYEE" and d4openClone() is called, CodeBase
does not know which file to resolve to when the expression "EMPLOYEE->NAME
= 'SMITH'" is evaluated.
This can be rectified by calling
d4aliasSet() (Data4.alias() in C++) after the first instance of EMPLOYEE.DBF
is opened.
See also: Alias, Query
What
is code4calcCreate() used for?
Some expressions passed to expr4parse
may be too long for CodeBase to parse properly. For instance, an expression
may contain too many comparison operators. In this case, CodeBase responds
with an error code of -440. In order to get around this limitation, code4calcCreate()
may be used.
By using code4calcCreate, the ability
to create longer expressions than would otherwise be possible is gained.
Notice that the expression MYEXPR
in this example is constructed from other dBASE expressions. Furthermore,
notice that when it is used, a bracket pair always follows the expression
name.
In this particular example, a -440
error will be generated if the call to expr4parse is made with more than
19 comparisons. That is, if the expression "FIELD1=1 .OR. FIELD1=2
.OR. ... .OR. FIELD1=20" is passed, then the above error will be generated.
Consequently, the code4calcCreate could be used for the first 19 comparisons
and the query would be called as "MYEXPR() .OR. FIELD1 = 20."
See also: expr4parse, relate4querySet,
Error -440
How
do I shorten an expression with code4calcCreate?
In this example, there are three
fields in the table: FNAME, LNAME, CITY and COUNTRY. The query expression
is "LNAME + FNAME + COUNTRY + CITY". Here is the pseudocode that will break
this up:
exName = expr4parse(data,"LNAME
+ FNAME")
exPlace = expr4parse(data,"COUNTRY
+ CITY")
code4calcCreate(cb,exName,"NAME")
code4calcCreate(cb,exPlace,"PLACE")
relate4querySet(relate,"NAME()
+ PLACE()")
The expression is now broken down
into two smaller expressions which are each made into a dBASE function.
The query expression uses those functions and is shorter than what we had
before.
How
can fields be concatenated (linked together) into a meaningful expression?
In order to concatenate two or more
field expressions together into a meaningful dBASE expression, each field
expression must first be converted to a character expression. Once converted
to a string each field expression may be linked to the next with the '+'
operator.
Suppose that our data file includes
fields that were defined as follows:
| Name |
Type |
Length |
Decimals |
| NAME |
r4num |
10 |
0 |
| BIRTH |
r4date |
8 |
0 |
| WEIGHT |
r4num |
6 |
2 |
| MARRIED |
r4log |
1 |
0 |
In order to concatenate any of the
fields together, the rules below should be applied:
-
Character fields (defined as 'C' or
r4str) are already in string format; thus, they do not need any conversion.
-
Date fields (defined as 'D' or r4date)
must be converted to strings using the 'DTOS' dBASE expression. For example,
in order to convert the BIRTH field to a string, we may use the following:
-
Logical fields (defined as 'L' or r4log)
must be converted to strings using the 'IIF' dBASE expression. For example,
in order to convert the MARRIED field to a string, we may use the following:
-
Numeric fields (defined as 'N' or 'F'
or r4num) must be converted to strings using the 'STR' dBASE expression.
For example, in order to convert the WEIGHT field to a string, we may use
the following:
Hence, to concatenate any of the above
fields with another in any type of expression whether in a query or tag,
convert each field to a string with the appropriate dBASE expression, and
add all the individual dBASE expressions together with the '+'
symbol.
In order to create an expression
which uses all of the above fields, the following sequence may be used:
"NAME + STR(WEIGHT, 6, 2) +
DTOS(BIRTH) + IIF(MARRIED, 'T', 'F')"
How is
a query with a date field made?
In order to perform a date query,
it must be ensured that a comparison is made between two identical types.
That is, the date field must first be converted to a string type before
making a comparison. Alternatively, the string may be converted to a date.
Suppose we have a field defined
as:
| Name |
DUE_DATE |
| Type |
r4date |
| Length |
8 |
| Decimals |
0 |
To find all the records with a DUE_DATE
of April 24, 2001, use one of the following queries:
relate4querySet( relation, "DTOS(DUE_DATE)
= '20010424'" );
relate4querySet( relation, "DUE_DATE
= STOD('20010424')" );
The above two queries yield identical
results.
See also: Expression
When
I append many records to file, why does performance gradually degrade after
the first few hundred records?
The execution time is dependent
on the time it takes to update the index file. Since you are appending
many records, it will probably take less time to close the index, make
the appends and then reindex.
How can I ensure
optimal performance of the CodeBase database server?
-
Run the server on as fast a machine
as possible.
-
Run the server from a local drive versus
a network drive.
-
Do not run any other applications on
the server machine.
How do
I know what host name to pass to code4connect()?
The host name in this example is
"server5.network.com". That is the string to pass to the connect
function.
If you do not get a host name before
the IP address on the first line of the reply (server5.network.com
in this example), PING cannot locate the necessary resources to resolve
an IP address to a host name. See the Appendix on Protocols in your Getting
Started book or contact your network administrator.
Can I
speed up the time it takes to display a sorted report? I am using the Report
| Sort Expression dialog box.
A sort expression is slow because
it does not use the speedy Query Optimization technology (QO). You should
thus try to distance yourself, whenever possible, from using this expression.
Instead, use the tags that you (may have) already created. To do this you
must simply choose the Relate | Modify dialog box and click the right mouse
button on the master data file. Then choose the appropriate tag. Your master
data file will now be sorted according to your selected tag!
How is
it possible to calculate a total without showing it on the screen?
Create an area and place the 'TOTAL'
object inside the new area. Since the Total will always display, you will
need to suppress the area output. Therefore, set the area suppression condition
to '.TRUE.'.
Another possible solution is to set
the font color of the 'TOTAL' object to be identical to the background
color. However, this will not work for a DOS report.
Lastly, you may create the 'TOTAL'
object and set the object size to 0.
How
do I re-compile any of the launch utilities?
To compile LAUNCH_W.C or LAUNCH_D.C,
follow the steps below:
-
Switch to the CODEREP\LAUNCH directory.
-
COPY ..\..\<LANG>\SOURCE\*.H
Where <LANG> is the 'C' or 'CPP'
directory name.
-
Edit D4ALL.H and change the appropriate
switches for the target application type.
-
Run the appropriate .MAK/.IDE file to
compile the executable.
Why are
all reports printed from DOS double spaced and have extra blank pages in
the middle and end?
Your problem begins with the report
design. All objects should be set to 12 points. A different size will cause
too many roundoff problems.
The next step is done from the program
itself. When printing reports from DOS, it is recommended that the page
be reset. The following commands should be called before report4do:
-
report4pageSize()
-
report4margins()
-
report4output()
How
can I make my report page size on screen identical to the sheets I use
for my printer?
To set the page size of the report
to the physical sheet of paper, use report4pageSize() and report4margins().
Then, set the member REPORT4.screen_breaks to 1, which will display your
report using the physical size of the paper instead of the screen size.
After viewing
one report with an invalid printer driver, why do subsequent reports also
appear blank?
-
Situation
-
The default printer is set in Windows
to a printer with an invalid printer driver. CodeReporter is loaded and
a report is opened. A print preview shows that the report is blank. This
is correct because the printer does not exist (invalid device driver).
A new printer is selected with a valid driver. The reports still display
as blanks.
-
Answer
-
After selecting a legitimate printer,
the report margins must be reset by the user to valid values. For instance,
set all margins to one inch.
-
Explanation
-
A device driver may be invalid because
the printer is not connected. Therefore, a printer device context is not
allocated. Consequently, the report margins are not valid. When another
(valid) printer driver is selected, CodeReporter corrects its setup of
the report. However, the margins are not changed since only the user may
change them.
Other CodeBase
Errors
Error Number:
-1 or e4codeBase
-
Possible Cause
-
A previous CodeBase error causes CodeBase
function calls to return -1.
-
Explanation
-
When a call to a CodeBase function fails,
CODE4.errorCode is set to a particular error code. These codes may be found
in the 'Error Codes' Appendix of the Reference Guide. When the error
code is set to a number less than 0, each subsequent CodeBase function
will simply return a -1, without executing the function. This is done for
safety purposes.
-
Solution
-
Set CODE4.errorCode to 0 after an error
has occurred.
Error Number:
-20
-
Description
-
Unable to create file
-
Possible Cause #1
-
The specified file already exists.
-
By default, when CodeBase attempts to
create a data, index, or memo file, it does not over-write any existing
file of the same name, and instead returns an error. This default behavior
is specified by the value contained in the CODE4.safety member variable,
which is set to 1 by default. To create a file if one by the same name
already exists, set CODE4.safety to 0. See the example for CODE4.safety
in the Reference Guide.
-
Possible Cause #2
-
CodeBase ran out of valid file handles.
-
Stand-alone 16-bit C/C++ applications
-
By default, only 20 file handles are
available to 16-bit applications at any one time, regardless of the settings
in CONFIG.SYS. Five of these handles are used by default devices such as
STDOUT, STDPRN, etc. This leaves 15 file handles available for the application.
Opening one data file can use up to three handles if there is also an associated
index and memo file. To overcome this limitation, refer to the CodeBase
COMPILER.TXT file, found in the CodeBase compiler directory for your compiler
(e.g. \MSC15). If the outlined procedure is not satisfactory, contact the
maker of your compiler. It is important to understand that this limitation
is due to both the operating system and the compiler, not CodeBase.
Error Number:
-30
-
Description
-
Determining File Length
-
Possible Cause
-
CodeBase ran out of valid file handles.
-
Explanation:
-
See Error -20.
Error
Number: -440
-
Description
-
Overflow while evaluating expression
-
Possible Cause
-
The expression passed to expr4parse
is too long.
-
Explanation:
-
The parsing algorithm limits the number
of comparisons made in a query. Thus, very long expressions may not be
parsed.
-
Solution
-
Use code4calcCreate
to "shorten" the expression.
Error Number:
-910
-
Description
-
Unexpected Information. Database file
already open
-
Possible Cause
-
The file that is being opened has been
opened previously.
-
Explanation
-
Each opened file is assigned an alias.
Furthermore, no two files may share the same alias. The above error occurs
when an attempt to open a file with an alias that already exists is made.
-
Solution
-
Change the file's alias with d4aliasSet,
or call d4openClone() which will give a new handle to the open data file
with the same alias without generated the alias error. If you need specify
the data alias via a function call or through an expression, it is not
defined which data handle you will get, so use with caution.
See also: d4aliasSet, d4openClone
Error Number: -930
-
Description
-
Unexpected Parameter
-
Possible Cause
-
A call to a CodeBase function included
a parameter that was not valid.
-
Explanation
-
In some cases the programmer will forget
to initialize some pointers.
-
Solution
Initialize the appropriate pointer.
Back
to the Sequiter Tech Support Page
Sequiter
Home Page
| |
|