⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbidorestructure.html

📁 Delphi API应用手册
💻 HTML
📖 第 1 页 / 共 3 页
字号:

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 + -