📄 dbunit.pas
字号:
unit DBUnit;
{*************************************************************************
DBUNIT.PAS -- Delphi Database Maintenance API for Paradox and DBASE
tables. See the accompanying demonstration application
and help file for instructions and examples of use.
NOTICE: This source code is NOT freeware. It must be
registered with Logic Process Corporation before it
can be used in your applications. Registered users
have the right to deliver this API (in object code
format) with their applications royalty-free. However,
this source code may NOT be delivered without first
securing a separate license for each system on which
the source code is to be installed.
Copyright (c) 1995 - 2000 by Logic Process Corporation,
Dallas, Texas USA. Protected by international law.
All rights reserved.
IMPORTANT: This API carries no warranties, either expressed or implied.
Use of this API and the underlying Borland International
Database Engine and TUTILITY.DLL (TUTIL32.DLL) table maintenance
libraries are at your own risk. Logic Process Corporation
assumes no responsibility for any loss of information resulting
from the use of this API or the Borland products aforementioned.
CHANGE HISTORY:
Version 1.18.200 (23 December 1999)
-- Made minor modification to "DBStructGetField" to make field type
validation case-insensitive.
-- Made minor modification to "DBRestructureTableFromTableExtended" and
"DBCreateTableFromStructure" routines to force the database operation
result value back to DBIERR_NONE from DBIERR_NOTINDEXED (which was also
considered a successful result). This change was necessary to avoid
a potential misinterpretation of the database result value later in
the routines.
Version 1.18 (16 September 1999)
-- Made minor conditional compilation modification to "GetDLLVersion"
routine to accommodate a Windows API function prototype change in
Delphi 5.
Version 1.17c (8 May 1999)
-- Qualified modifications made in Version 1.17b with "$IFDEF WIN32"
conditional compiler directives to overcome an object pascal limitation
in Delphi 1.0.
Version 1.17b (27 March 1999)
-- Modified the "DBRestructureTable" and "DBStructSyncTables" functions
to eliminate several memory leaks during table structure comparison
and sync operations.
Version 1.17a (11 January 1999)
-- Modified the "DBCompareTables" function to be more intelligent in
determining what steps (add/copy/drop) are required to get from one
table structure to the comparison table structure.
Version 1.17 (29 July 1998)
-- Moded "GetDLLVersion" function to conditionally define "VerQuerySize"
variable type as Cardinal for Delphi 4 only.
-- Fixed bug in "DBCheckAutoIncTranslationAllowed" function where a loop
variable was being used improperly (nested).
Version 1.16 (16 June 1998)
-- Moded "DBGetBDEVersion" function to use a read-only call to the registry
HKEY_LOCAL_MACHINE. Defined new "TReadOnlyRegistry" class as a subclass
of the Delphi "TRegistry" class and added a new read-only key open
function ("OpenKeyReadOnly") that is now called in "DBGetBDEVersion".
This corrects a problem in Windows NT when the user is not granted
write access to this registry key.
-- Added "VerboseDBResponse" global variable to provide control over the
use of message dialogs in relevant API functions/procedures. The variable
defaults to True in order to remain consistent with previous versions of
this API. Functions affected by this variable include "DBCheckAlias",
"DBConfigureTableStructure", "DBCreateTableFromStructure",
"DBRestructureTable", "DBDeleteNetFile", and "PublishBDEResult".
Version 1.15a (10 June 1998)
-- NEW -- Added "DBRestructureTableFromTableExtended" function that provides
more complete coverage of restructuring operations from a clone table.
Careful staged use of this function will allow rebuilding of most tables
protected by RI rules, for example.
-- Moded "DBRestructureTableFromTable" function to eliminate duplicate
allocation of field storage 'FDesc'. Output pointer 'pFldDes' was never
functional ... now just set to 'nil'. Caller should not use 'pFldDes'
upon return. Left as a param to avoid syntax problems.
Version 1.15 (12 January 1998)
-- NEW -- Added "DBProtectTable" function which sets or clears the master
password for a specified table. See the SCAPI.HLP for a complete syntax
description.
-- Revised "DBCheckIndexes" to remove an unnecessary call to 'DbiOpenTable'.
-- Cleaned up "DBRebuildTable" to consistently return BDE error string in
caller-provided 'strError' var error string.
Version 1.14b (7 December 1997)
-- Corrected problem in "DBRestructureTable", "DBRestructureTableFromTable",
and "DBCreateTableFromStructure" routines where calls to 'DbiGetIndexDescs'
returning DBIERR_NOTINDEXED (i.e., tables were not indexed) was being
viewed as an error. This condition is now caught and treated as a normal
condition.
Version 1.14a (19 November 1997)
-- NEW ROUTINE -- Added the "DBRestructureTableFromTable" routine which allows
an existing (or 'target') table to be restructured to bring it in sync
with a second (or 'base') table. This routine is an extension of the
"DBRestructureTable" routine which uses a structure definition file
as the 'base' table definition. This new routine allows the developer
to accomplish the same task using a 'base' table instead of the structure
file. See the API help file for complete details. NOTE: This function
does not currently support table security or referential integrity
features.
-- Fixed an issue in the "DBCompareTables" routine in which the 'BaseTable'
component was not being updated prior to use. Added field and index
'Update' statements at the start of the routine to make sure the routine
is working with the latest image of the base table structure.
-- Rewrite a section of the "DBRestructureTable" routine to more properly
delete all target table indices before the restructure takes place. Prior
API versions would assume that deleting the first index (i.e., assumption
that this was the primary index) would also force deletion of all secondary
indices. New version more gracefully deletes all secondary indices and
finally deletes the primary index last.
Version 1.14 (11 November 1997)
-- Finalized interim changes since 1.13 release.
-- Added the 'VerifyOptions' parameter to the "DBCheckTable" routine to
provide the caller with control over the verification process. The most
common use is to control whether verification errors overwrite or are
appended to the specified error table. See the SCAPI.HLP file for a
complete syntax description. *** IMPORTANT *** This is a change to the
calling syntax of the "DBCheckTable" function. Update your applications
which call this function to include the new input parameter. To be
consistent with previous API versions, simply set this input to zero
when calling the "DBCheckTable" routine.
-- Simplified "DBGetTutilityVersion" function to use the Windows path search
mechanism to locate the TUTILITY.DLL (or TUTIL32.DLL) in use. This change
eliminates the requirement that this DLL reside in the SYSTEM directory.
It can now reside in the application directory if desired. This change
also corrects a problem which would occur in calls to DBRebuildTable on
16-bit apps if TUTILITY.DLL was not located in the SYSTEM directory. The
call to "DBGetTutilityVersion" found in DBRebuildTable would return all
zeros, which would result in the rebuild routine using the wrong call to
"TURebuildTable". The resulting error message would be 'file or directory
does not exist.'
-- Forced the conversion of the 'szUserName' string to Pascal format in the
"DBBDEUsersList" routine before assigning it to the string list. The
previous version resulted in an error when using this string value in
16-bit apps only.
-- Forced conversion of table type string to Pascal before comparison in
"DBTableIsProtected" function. In 16-bit apps, this null-terminated string
to Pascal string comparison always failed. The result was that this routine
always thought that tables were unprotected in 16-bit apps only.
Version 1.13b (22 October 1997) *** interim release ***
-- Fixed a bug in the "DBCloneTableStructure" routine which could result in
the attempted disposal of an allocated memory structure using an invalid
size value. On 32-bit systems, the invalid operation usually did not
immediately result in an error. On 16-bit systems, the invalid operation
often resulted in a GPF. The problem only occured on calls to this routine
with the 'Mode' input set to 'cmDropSecondary'.
Version 1.13a (22 September 1997) *** interim release ***
-- Reworked 'DBRebuildTable' to correct an invalid pointer exception which
occurred when there were problems retrieving the table security information
in 32-bit mode (using the special workaround code in this routine). If the
workaround retrieval was not successful, the routine would subsequently
attempt to free memory that had already been freed. Also changed BDE error
handling slightly to properly return the error code/string.
-- Special Note: The current version of 'DBRebuildTable' uses a special
workaround to retrieve table security information. It seems that the TUTILITY
table description retrieval call returns an invalid image of this security
information. This workaround uses BDE calls which require that the clone
table NOT be write protected. If you are trying to use write-protected
clone tables, send mail to "support@logicprocess.com" to request a code
sample which illustrates how to temporarily set the clone table family files
to write-enabled during the repair process.
Version 1.13 (16 September 1997)
-- Eliminated "MessageDlg" calls in DBPackTable. If protection copy cannot
be made, sets 'LastDBError' to DBIERR_WRITEERR, 'LastDBErrorString' with
an appropriate error information string, and returns False. Moved original
table restore attempt (occurs after a failed pack operation) outside the
database operations block. If the restore attempt fails, leaves the
protection copy in the BDE Session Private directory.
-- Changes to 'DBGetTableAssociatedFiles' routine to be specific about which
file extensions are valid table family members. Would previously pick up
all files with the same root name.
-- Made changes to callback structure (TUTIL.PAS) and routines (BDEUTIL.PAS)
to correctly handle callbacks. Also required a new parameter to the
callback register and unregister functions. Previous callback routines
could cause unexpected table rebuild failures in 16-bit applications.
Often these failures were silent with symptoms including fewer than
expected records in the repaired table. Also added example code in the
BDEUTIL callback routines which illustrate how to access callback
information in your own application.
-- Added a section to the SCAPI.HLP file which describes how to use the
SelfCheck API in your own applications.
Version 1.12 (11 August 1997)
-- Rewrote 'DBGetTableAssociatedFiles' routine to be more cautious when using
the 'FindFirst/FindNext' method to locate family members. The find method
was returning incorrect results on certain system configurations when a
null table name was specified. Problem was first reported for aliases located
on remote Novell 4.11 networked drive volumes. Symptoms were erroneous file
removals.
-- Fixed a quirky problem in 'DBCheckStructureFile' routine where the second
'Reset(F);' was not repositioning the file pointer to the top. Added a manual
close and reopen to fix. Only saw this on a single system, and was unable to
determine the cause.
-- added 'DBGetAliasPath' routine which returns the full path for a given alias.
Version 1.11 (14 July 1997)
-- Better use of "AddSlash" support routine to ensure that trailing slashes
are present where needed. Replaced manual backslash check with "AddSlash"
as needed. Routines affected (DBCheckAlias, DBCopyTable, DBCheckTable,
DBRebuildTable, DBGetCursorPropsProtected, DBTableIsProtected).
Version 1.10 -- Initial release.
**************************************************************************}
interface
uses DBTables, SysUtils, Forms, Classes, BDEUtil, DB, TUtil,
{$IFDEF WIN32}
BDE, Registry;
{$ELSE}
WinTypes, DbiProcs, DbiTypes, DbiErrs, IniFiles, Ver;
{$ENDIF}
const
{ self-imposed constants ... determined by memory constraints, etc. May be changed as needed }
MAX_TABLES_IN_STRUCTURE_FILE = 256; { max tables in alias / structure file }
MAX_REF_INT_DESCRIPTORS = 20; { max referential integrity descriptors per table }
type
TTableIndices = record
IndexName : String; { Index Name }
IndexFields : String; { List of fields in index }
IndexOptions : String; { Index options, primary, descending etc }
end;
type
TStructureRec = record
AliasName : String; { Alias Name }
AliasPath : String; { Alias Path }
{ Limit MAX tables in structure file (add 3 for '.DB') }
Tables : array[0..(MAX_TABLES_IN_STRUCTURE_FILE - 1)] of String[DBIMAXNAMELEN + 3];
end;
type
{ holds special table creation info }
TDBTableSpecialInfo = record
AutoIncFieldIndex : Integer; { autoinc field index (0 = none) }
end;
type
{ File Version Info Structure -- convert to string as "MSDW_MSW.MSDW_LSW.LSDW_MSW.LSDW_LSW" }
TFileVersionRecord = Record
MSDW_MSW : Word; { high word of upper double-word }
MSDW_LSW : Word; { low word of upper double-word }
LSDW_MSW : Word; { high word of lower double-word }
LSDW_LSW : Word; { low word of lower double-word }
end;
type
TCloneMode = (cmNoChange, cmDropAllIndices, cmDropSecondary, cmChangeAutoIncToInt, cmChangeIntToAutoInc);
TDBExtendedRestructureOption = (eroClearValidityChecks, eroClearReferentialIntegrity, eroClearSecurity,
eroFields, eroIndices, eroValidityChecks, eroReferentialIntegrity,
eroSecurity);
TDBExtendedRestructureOptions = set of TDBExtendedRestructureOption;
{ Database Functions }
function DBAddAlias(Alias, Path, DefaultDriver: String): Boolean;
function DBBDEUsersList(var UserList: TStringList): Boolean;
function DBCheckAlias(Alias, DefaultDriver: String; var Path: String): Boolean;
function DBDeleteAlias(strAlias: String): Boolean;
function DBGetAliasPath(strAlias: String): String;
function DBOpenLockList(strDataBase, strTableName: String; var LockList: TStringList): Boolean;
{ Table Manipulation Functions }
function DBCloneTableStructure(strDatabase, strTableName, strCloneDir, strCloneTableName, strPassword: String;
Mode: TCloneMode; var AutoIncField: Integer): Boolean;
function DBCompareTables(CheckTable, BaseTable: TTable; var FOpType: array of CROptype;
var IOpType: array of CROptype; var pFldDes: pFldDesc): Boolean;
function DBRestructureTableFromTable(strTargetDataBase, strTargetTableName,
strBaseDatabase, strBaseTableName: String;
FOptype: array of CROptype; IOptype: array of CROptype;
var pFldDes: pFldDesc): Boolean;
function DBRestructureTableFromTableExtended(strTargetDataBase, strTargetTableName,
strBaseDatabase, strBaseTableName, strPassword: String;
ExtendedOptions: TDBExtendedRestructureOptions): Boolean;
function DBCopyTable(strDataBase, strTableName, strDestDir, strDestName: String): Boolean;
function DBCopyTableFileIO(strDataBase, strTableName, strDestDir, strDestName: String): Boolean;
function DBDeleteTableFileIO(strDataBase, strTableName: String): Boolean;
function DBPackTable(strDataBase, strTableName, strPassword: String; TableType: DBINAME; Protect: Boolean): Boolean;
{ Table Check & Repair Functions }
function DBCheckIndexes(strDataBase, strTableName: String; var IndexList: TStringList) : Boolean;
function DBCheckTable(strDataBase, strTableName, strErrorTable, strPassword: String;
var strResult: String; VerifyOptions: Integer) : Boolean;
function DBRebuildIndexes(strDataBase, strTableName: string; var strError: string): Boolean;
function DBRebuildTable(strDataBase, strTableName, strCloneTable, strErrorTable, strBackupTable,
strKeyViolTable, strProblemTable, strPassword: String;
var strResult: String) : Boolean;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -