在TCX中使用SQLite3

我早就鼓吹过:SQLite是最好的本地文件型数据库。

在Windows下,它只要一个几百K的DLL就可以驱动,管理工具也只是一 个几百K的EXE程序就行了。相比之下,ACCESS庞大得令人生厌,即使是一个OLE-DB驱动也有至少10M以上的size,更不用说Foxpro, Paradox……那一大堆的表文件了。当然,SQLite的性能还不能跟那个BT的BerkeleyDB相比——BDB根本不能算是一个完整的数据库, 连 SQL都不支持。

不过因为VCL提供的BDE、ADO、DBX等开发手段都没有提供对SQLite的支持——PostgreSQL至少还可 以通过OLD-DB驱动用ADO方式连接。所以用Delphi或BCB访问SQLite还是比较麻烦的。我之前都只是在Python应用中使用 SQLite。

幸好开源社区很快为此提供了支持,那就是优秀的开源数据库控件包:ZEOSDBO。它基于VCL标准的数据库接口实现,可以像BDE、ADO、DBX那样使用这一组控件,它支持的数据库和开发工具有:

支持的数据库:Sybase/ASA、Oracle、MS SQL、MySQL、InterBase/Firebird、PostgreSQL、SQLite/3等。
支持的VCL开发工具:Delphi 5-10,BCB 5/6,Kylix 2/3,Lazarus等。

然 而因为版权的原因,我现在只使用CodeGear的免费开发工具:Turbo C++ Explorer(TCX)。由于免费版的License限制,不能在TCX中安装任何第三方控件,所以我无法直接使用ZEOSDBO。不过我既然已经大 言不惭地号称DELPHI专家多年,要是连这也搞不定,那也太没面子了吧。挖卡卡。

经过一番试验,这个问题最终还是得以解决。其实也没有什么技术含量,无非是麻烦一点罢了:

启动TCX,创建一个VCL应用,在Project里加入以下文件夹中的所有PAS文件:

ZEOSDBO\src\core
ZEOSDBO\src\dbc
ZEOSDBO\src\parsesql
ZEOSDBO\src\plain

然后在Project里加入 ZEOSDBO\src\component 文件夹中的必要文 件——用到哪几个控件就加哪几个控件的文件,比如常用的ZConnection.pas和ZDataset.pas,其它不必要的文件不用加入。特别是文 件名中包含"Editor"的属性编辑功能单元,因为它们用到了控件Design的一些东西,而这些在免费版的TCX中是没有的,加入这些单元将导致编译 失败。

加好文件以后暂时不要在程序中引用,而是先编译一下,生成必要的相关文件——如.hpp等。正常情况下除了会出现几个HINT或WARNING以外,都能成功编译。

之后就可以在程序中引用ZEOSDBO访问SQLite了。

Unit1.h内容大致如下(其中偷懒用了STL中的auto_ptr管理ZEOSDBO控件对象的生命周期):

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ZConnection.hpp>
#include <ZDataset.hpp>

#include <memory>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
std::auto_ptr<TZConnection> zConn;
std::auto_ptr<TZTable> tblPerson;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

在Unit1.cpp中就可以如下代码所示访问SQLite了:

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner),
zConn( new TZConnection(this) ),
tblPerson( new TZTable( this) )
{
zConn->Protocol = "sqlite-3";
zConn->HostName = "localhost";
zConn->Database = ChangeFileExt( Application->ExeName, ".sqlite3" );
zConn->User = "";
zConn->Password = "";
zConn->Connect();
tblPerson->Connection = zConn.get();
tblPerson->TableName = "person";
tblPerson->Open( );
//...
}

最后再废话一句:SQLite可是开源免费跨平台的哦。