📄 dbidorestructure.html
字号:
begin
{ Add the master password to the session }
Session.AddPassword(mstrpswd);
{ Make sure that the table is opened and is exclusive }
if (Table.Active = False) or (Table.Exclusive = False) then
raise EDatabaseError.Create('Table must be opened in exclusive mode to add passwords');
{ Initialize the table and security descriptor }
FillChar(TblDesc, SizeOf(CRTblDesc), #0);
FillChar(SDesc, SizeOf(SDesc), #0);
crType := crAdd;
{ Table privileges }
SDesc.eprvTable := rights;
{ Family rights }
SDesc.iFamRights := NoFamRights;
{ Aux Password name }
StrPCopy(SDesc.szPassword, pswd);
{ Set field rights to full }
for W := 1 to Table.FieldCount do
SDesc.aprvFld[W - 1] := prvFULL;
{ Place the table name in descriptor }
StrPCopy(TblDesc.szTblName, Table.TableName);
{ Place the table type in descriptor }
StrCopy(TblDesc.szTblType, szPARADOX);
{ Number of security definitions }
TblDesc.iSecRecCount := 1;
{ This should be crAdd }
TblDesc.pecrSecOp := @crType;
{ Attach the security descriptor to the Table Descriptor }
TblDesc.psecDesc := @SDesc;
{ Copy in the master password }
StrPCopy(TblDesc.szPassword, mstrpswd);
{ Set bProtected to True }
TblDesc.bProtected := RESTRUCTURE_TRUE;
{ Get the database handle from the cursor handle }
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
{ Close the table }
Table.Close;
{ Add the auxilary password to the Paradox table }
Check(DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, FALSE));
{ Re-Open the table }
Table.Open;
end;</PRE>
<!-- SF -->
<HR SIZE=2 NOSHADE>
<H3>Example 6: Remove a master password from a Paradox table.</H3>
This example uses the following input:<BR>
<I>RemoveMasterPassword(Table1)</I>
<PRE>procedure RemoveMasterPassword(Table: TTable);
const
RESTRUCTURE_FALSE = WordBool(0);
var
TblDesc: CRTblDesc;
hDb: hDBIDb;
begin
{ Make sure that the table is opened and is exclusive }
if (Table.Active = False) or (Table.Exclusive = False) then
raise EDatabaseError.Create('Table must be opened in exclusive mode to add passwords');
{ Initialize the table descriptor }
FillChar(TblDesc, SizeOf(CRTblDesc), 0);
with TblDesc do
begin
{ Place the table name in descriptor }
StrPCopy(szTblName, Table.TableName);
{ Place the table type in descriptor }
StrCopy(szTblType, szPARADOX);
{ Set bProtected to False }
bProtected := RESTRUCTURE_FALSE;
end;
{ Get the database handle from the cursor handle }
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
{ Close the table }
Table.Close;
{ Add the master password to the Paradox table }
Check(DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, FALSE));
{ Re-Open the table }
Table.Open;
end;</PRE>
<HR SIZE=2 NOSHADE>
<H3>Example 7: Remove an auxilary password from a Paradox table.</H3>
This example uses the following input:<BR>
<I>RemoveAuxPassword(Table1, 'MstrPswd', 'AuxToRemove')</I>
<PRE>procedure RemoveAuxPassword(Table: TTable; mstrpswd, pswd: string);
function GetSecNoFromName(hDb: hDBIDb; TblName, pswd: string): word;
var
hCur: hDBICur;
Sec: SECDesc;
begin
Result := 0;
Check(DbiOpenSecurityList(hDb, PChar(TblName), nil, hCur));
try
Check(DbiSetToBegin(hCur));
while DbiGetNextRecord(hCur, dbiNOLOCK, @Sec, nil) = DBIERR_NONE do
begin
if CompareText(Sec.szPassword, pswd) = 0 then
begin
{ Set the Security Number to the result }
Result := Sec.iSecNum;
break;
end;
end;
finally
Check(DbiCloseCursor(hCur));
end;
end;
const
RESTRUCTURE_TRUE = WordBool(1);
var
{ Specific information about the table structure, indexes, etc. }
TblDesc: CRTblDesc;
{ Security descriptor }
SDesc: SECDesc;
{ Uses as a handle to the database }
hDb: hDBIDb;
{ crAdd }
crType: CROpType;
begin
{ Make sure that the table is opened and is exclusive }
if (Table.Active = False) or (Table.Exclusive = False) then
raise EDatabaseError.Create('Table must be opened in exclusive mode to add passwords');
{ Initialize the table and security descriptor }
FillChar(TblDesc, SizeOf(CRTblDesc), 0);
FillChar(SDesc, SizeOf(SECDesc), 0);
crType := crDrop;
{ Descriptor number that specifies the password to remove }
SDesc.iSecNum := GetSecNoFromName(Table.DbHandle, Table.TableName, pswd);
if SDesc.iSecNum = 0 then
begin
ShowMessage('Could not find auxilary password.');
Exit;
end;
with TblDesc do
begin
{ Place the table name in descriptor }
StrPCopy(szTblName, Table.TableName);
{ Place the table type in descriptor }
StrCopy(szTblType, szPARADOX);
{ Number of security definitions }
iSecRecCount := 1;
{ This should be crDrop }
pecrSecOp := @crType;
{ Attach the security descriptor to the Table Descriptor }
psecDesc := @SDesc;
{ Copy in the master password }
StrPCopy(szPassword, mstrpswd);
{ Set bProtected to True }
bProtected := RESTRUCTURE_TRUE;
end;
{ Get the database handle from the cursor handle }
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
{ Close the table }
Table.Close;
{ Remove the auxilary password to the Paradox table }
Check(DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, FALSE));
{ Re-Open the table }
Table.Open;
end;</PRE>
<!-- SF -->
<HR SIZE=2 NOSHADE>
<H3>Example 8: Use the pOptData portion of DbiDoRestructure.</H3>
This example uses the following input:<BR>
<I>RestructureTable(Table1, 'LEVEL', '7')</I> Change table level to 7<BR>
<I>RestructureTable(Table1, 'BLOCK SIZE', '4096')</I> Change table block size to 4096<BR>
This function calls DbiDoRestructure with the Option to change and the OptData which is
the new value of the option. Since a database handle is needed and the table cannot be opened when
restructuring is done, a new database handle is created and set to the directory where the
table resides.
<PRE>procedure RestructureTable(Table: TTable; Option, OptData: string);
var
hDb: hDBIDb;
TblDesc: CRTblDesc;
Props: CurProps;
pFDesc: FLDDesc;
begin
// If the table is not opened, raise an error. Need the table open to get
// the table directory.
if Table.Active <> True then
raise EDatabaseError.Create('Table is not opened');
// If the table is not opened exclusively, raise an error. DbiDoRestructure
// will need exclusive access to the table.
if Table.Exclusive <> True then
raise EDatabaseError.Create('Table must be opened exclusively');
// Get the table properties.
Check(DbiGetCursorProps(Table.Handle, Props));
// If the table is not a Paradox type, raise an error. These options only
// work with Paradox tables.
if StrComp(Props.szTableType, szPARADOX) <> 0 then
raise EDatabaseError.Create('Table must be of type PARADOX');
// Get the database handle.
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
// Close the table.
Table.Close;
// Setup the Table descriptor for DbiDoRestructure
FillChar(TblDesc, SizeOf(TblDesc), #0);
StrPCopy(TblDesc.szTblName, Table.Tablename);
StrCopy(TblDesc.szTblType, szParadox);
// The optional parameters are passed in through the FLDDesc structure.
// It is possible to change many Options at one time by using a pointer
// to a FLDDesc (pFLDDesc) and allocating memory for the structure.
pFDesc.iOffset := 0;
pFDesc.iLen := Length(OptData) + 1;
StrPCopy(pFDesc.szName, Option);
// The changed values of the optional parameters are in a contiguous memory
// space. Sonce only one parameter is being used, the OptData variable
// can be used as a contiguous memory space.
TblDesc.iOptParams := 1; // Only one optional parameter
TblDesc.pFldOptParams := @pFDesc;
TblDesc.pOptData := @OptData[1];
try
// Restructure the table with the new parameter.
Check(DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, False));
finally
Table.Open;
end;
end;</PRE>
<!-- SF -->
<HR SIZE=2 NOSHADE>
<H3>Example 9: Add referential integrity to a Paradox or dBASE v7 table.</H3>
This example uses the following input:<BR>
<I>AddRI(Table2, Table3, 'CustomerRI', rintRESTRICT, rintRESTRICT);</I><BR>
This function calls DbiDoRestructure passing it one RINTDesc descriptor to add referential integrity.
There are some conditions prior to using this function that need to be met:
<UL>
<LI>The tables must have a primary index on the master table and a primary or secondary index
on the detail table.
<LI>The table must be opened exclusively on the index that the RI is going to be placed on.
<LI>The fields that are going to be joined by RI must be of the same type and size.
</UL>
<PRE>procedure AddRI(Master, Detail: TTable; RIName: string; ModOp, DelOp: RINTQual);
var
MasterProps, DetailProps: CURProps;
hDb: hDBIDb;
TableDesc: CRTblDesc;
Op: CROpType;
RInt: RINTDesc;
MIndex, DIndex: IDXDesc;
MNo, DNo: Word;
begin
if Master.Active = False then
raise EDatabaseError.Create('Master table: ' + Master.TableName +
' is not opened');
if Detail.Active = False then
raise EDatabaseError.Create('Detail table: ' + Detail.TableName +
' is not opened');
if Master.Exclusive = False then
raise EDatabaseError.Create('Table: ' + Master.TableName +
' must be opened exclusively');
if Detail.Exclusive = False then
raise EDatabaseError.Create('Table: ' + Detail.TableName +
' must be opened exclusively');
// Make sure the tables are opened with an index and get their descriptors...
FillChar(DIndex, sizeof(DIndex), 0);
FillChar(MIndex, sizeof(MIndex), 0);
Check(DbiGetIndexDesc(Detail.Handle, 0, DIndex));
Check(DbiGetIndexDesc(Master.Handle, 0, MIndex));
// Get the table properties to determine table type...
Check(DbiGetCursorProps(Master.Handle, MasterProps));
Check(DbiGetCursorProps(Detail.Handle, DetailProps));
// If the table is not a Paradox table, raise an error...
if (MasterProps.szTableType <> szPARADOX) and
(MasterProps.szTableType <> szDBASE) then
raise EDatabaseError.Create('Master table: ' + Master.TableName +
' must be a Paradox or dBASE table type');
if (DetailProps.szTableType <> szPARADOX) and
(DetailProps.szTableType <> szDBASE) then
raise EDatabaseError.Create('Detail table: ' + Detail.TableName +
' must be a Paradox or dBASE table type');
if MasterProps.szTableType <> DetailProps.szTableType then
raise EDatabaseError.Create('Master and Detail tables must be of same type');
// Blank out the structures...
FillChar(TableDesc, sizeof(TableDesc), 0);
FillChar(RInt, sizeof(RInt), 0);
// Get the database handle from the table's cursor handle...
Check(DbiGetObjFromObj(hDBIObj(Master.Handle), objDATABASE, hDBIObj(hDb)));
// Put the table name in the table descriptor...
StrPCopy(TableDesc.szTblName, Detail.TableName);
// Put the table type in the table descriptor...
TableDesc.szTblType := MasterProps.szTableType;
// Set the operation type...
Op := crADD;
TableDesc.pecrRintOp := @Op;
// Set the amount of new RI descriptors...
TableDesc.iRintCount := 1;
// Connect the table descriptor to the RI descriptor...
TableDesc.printDesc := @RInt;
// Setup the RI descriptor...
// Put in the name of the RI...
StrPCopy(RInt.szRintName, RIName);
// Do the restructure on the dependent (detail) table...
RInt.eType := rintDEPENDENT;
// Add the master table name...
StrPCopy(RInt.szTblName, Master.TableName);
// Modify operations will be restricted (this can be changed to rintCASCADE)...
RInt.eModOp := ModOp;
// Delete operations will be restricted (NOTE: rintCASCADE will not work)...
RInt.eDelOp := DelOp;
// Only one field in link...
RInt.iFldCount := 1;
// If the tables are Paradox, then put the associated field numbers in the descriptor...
if (MasterProps.szTableType = szPARADOX) then
begin
//
if RInt.eDelOp = rintCASCADE then
raise EDatabaseError.Create('Cannot use cascading delete RI with Paradox tables');
// Put the detail field index in the array...
RInt.aiThisTabFld := DIndex.aiKeyFld;
// Put the master field index in the array...
RInt.aiOthTabFld := MIndex.aiKeyFld;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -