在网络共享上打开 Firebird 数据库文件

Opening a Firebird database file on a network share

我认为将映射的驱动器盘符转换为 UNC 路径就足以打开 .GDB 文件, 但唉:

function ConvertToUNCPath(AMappedDrive: string) : string;
var
   lRemoteString : array[0..255] of char;
   lpRemote      : PChar;
   lStringLen    : Cardinal;
begin
   lpRemote := @lRemoteString;
   lStringLen := 255;
   If WNetGetConnection(Pchar(ExtractFileDrive(AMappedDrive)) ,
                        lpRemote,
                        lStringLen) = NO_ERROR Then
      Result := lRemoteString
   else
      Result := ''; // No mapping found
end;

function TDataModuleData.OpenGDBDatabase(AGDBName: string) : Boolean;
var
   lDlgLogin: TFrmLogin;
   p        : Integer;
   lUNC,
   lErrMsg  : String;
begin
   Result := False;

   with FDConnection do   // TFDConnection
   begin
      Close;
      TxOptions.Isolation := xiDirtyRead;

      p := Pos(':',AGDBName);
      if p = 2 then
      begin
         lUNC := ConvertToUNCPath(Copy(AGDBName,1,2));
         if lUNC <> '' then
         begin
            lUNC := Copy(lUNC,3);
            p := pos('\',lUNC);
            AGDBName := Copy(lUNC,p) + Copy(AGDBName,3);
            lUNC := copy(lUNC,1,p-1);
         end;
      end;

      DriverName := S_FD_IBId;
      Params.Database := AGDBName;
      if lUNC <> '' then
         Params.Add('Server=' + lUNC)
      else   
         Params.Add('Server=localhost');  // Not strictly necessary

      Params.UserName := 'SYSDBA';
      Params.Password := 'masterkey';

      try
         Open;
         Result := Connected;
      except
         on E:Exception do
         begin
            lErrMsg := LowerCase(E.Message);
         end;
      end;
   end;
end;

根据我解析 ConvertToUNCPath 结果的方式,我会收到不同的错误消息:

[firedac][phys][ib]unavailable database
[firedac][phys][ib]i/o error during "createfile (open)" operation for file "persoonlijk\jan\klanten.gdb"'#$D#$A'error while trying to open file'#$D#$A'the system cannot find the path specified.

使用 ConvertToUNCPath 的代码部分成功转换为例如P:\Jan\KLANTEN.GDB\tt2012server\persoonlijk\Jan\KLANTEN.GDB.

当路径指向映射的驱动器盘符时,如何打开 GDB 文件?

补充:我尝试了这些硬编码的变体,它们都失败了:

// lUNC := '\2012server';  // Unable to complete network request to host
lUNC := 'tt2012server';
//AGDBName := '\tt2012server\persoonlijk\jan\klanten.gdb';
//AGDBName := 'tt2012server\persoonlijk\jan\klanten.gdb';
//AGDBName := '\persoonlijk\jan\klanten.gdb';
//AGDBName := 'persoonlijk\jan\klanten.gdb';
//AGDBName := '\jan\klanten.gdb';
//AGDBName := 'jan\klanten.gdb';
//AGDBName := 'p:\jan\klanten.gdb'; (original input)

(P: 映射到 \tt2012server\persoonlijk)

已添加:

抱歉,我在最初的文字中并不清楚:这与连接到远程服务器上的数据库本身无关。我只希望我的本地 'DB inspection' 工具能够打开 GDB 文件,如果有人将它放在我的网络共享中进行检查(而不是必须先将其复制到本地磁盘)。
使用 WNetGetConnection 的唯一目的是将驱动器号解析为 UNC 路径(我在网上找到的一些代码)。

1。 Firebird 明确拒绝尝试打开 non-local 磁盘

上的数据库文件

Firebird 是数据库服务器,因此它侧重于性能和可靠性。

http://www.firebirdfaq.org/faq46/

性能意味着大量数据被缓存,缓存用于读取和缓存写入。

可靠性意味着 Firebird 必须从 OS 那里获得有价值的保证:

一个。当服务器缓存了一些数据以供读取时,没有其他进程会修改数据库文件。

b。在任何时刻,服务器可能希望将任何数据从其缓存写入文件,并且保证该数据 - 在任何时刻 - 结束持久写入持久媒体。

Network-connected 磁盘使这两项保证无效,因此 Firebird 服务器拒绝信任它们。

您可以自行决定破解 Firebird 配置或源文件以删除此安全检查并打开 network-shared 文件,如果您真的需要它而不是安全和速度。

但正确的解决方案是在其磁盘确实带有数据库文件的机器上安装 Firebird 服务器。

2。连接字符串不是数据库文件名

AGDBName := '\tt2012server\persoonlijk\jan\klanten.gdb'

这并不意味着 "local Firebird server should connect to tt2012server server using LOCAL_SYSTEM credentials and read the database file from persoonlijk shared resource",正如您可能想要的那样。

http://www.firebirdfaq.org/faq260/

如果有的话,Windows LOCAL_SYSTEM 用户被明确禁止进行大多数网络操作以遏制入侵者和病毒。即使您破解 Firebird 打开网络文件,很可能 Windows 仍然会禁止此访问,除非您将 Windows 到 运行 Firebird 服务器服务设置为使用默认以外的其他用户帐户LOCAL_SYSTEM.

无论如何,\tt2012server\persoonlijk\jan\klanten.gdb 连接字符串实际上意味着您请求您的应用程序使用 WNET(又名 Microsoft 命名管道)协议连接到 tt2012server 并找到 Firebird 服务器 运行在该服务器上连接并通过 WNET 协议进行通信,而不是 TCP/IP 协议。

根据您引用的错误判断 - lUNC := '\2012server'; // Unable to complete network request to host - 所述 tt2012server 计算机可能没有 Firebird 服务器 运行ning 并接受命名管道连接.

WNET 协议被认为已过时,很可能会从未来的 Firebird 服务器版本中删除。截至目前它正在运行,但很少有人使用它,因此该领域几乎没有最新的经验。建议您默认使用 TCP/IP 协议将您的应用程序连接到 tt2012server 机器上的 Firebird 服务器 运行ning,而不是 WNET 协议。

PS。本题重复:

  • ibase_connect: remote computer host and shared db file from windows

PPS。 Firebird 是一个 multi-generation 数据库引擎。

因此,Interbase/Yaffil/Firebird 家庭中没有 "dirty read" 笔交易。

TxOptions.Isolation := xiDirtyRead; - 这条线行不通。它很可能会默默地将事务 class 更改为 "READ COMMITTED",但不太可能会给出明确的错误。