65.9K
CodeProject 正在变化。 阅读更多。
Home

SQLite3 的一个易于使用的包装器(完全免费的嵌入式数据库引擎!)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (29投票s)

2007年8月19日

CPOL

4分钟阅读

viewsIcon

130757

downloadIcon

2485

我创建了一些类来包装 SQLite3 库,以消除许多麻烦...

引言

最近,我一直在寻找一个嵌入式 SQL/数据库库解决方案,这样我就不必分发 DAO/Jet/SQL Server Express/ODBC 或其他数据库驱动程序...

我遇到了 SQLite3,它是一个可移植库,完全用 C 编写,允许您使用 SQL 语句创建/管理数据库。它是开源的,不需要任何许可证,占用的空间很小(大小取决于编译器优化,但只有大约 200 KB!),而且没有任何外部依赖项。

我下载了 SQLite3(http://www.sqlite.org),并想立即开始使用它。

等等,没有 OOP??(面向对象编程,C++...)

正如我之前提到的,该库完全是用 C 编写的。不仅如此 - 它还支持多字节 UTF-8 编码...

我立即意识到我需要创建一些类来包装该库,以便我能够无痛地使用它...

SQLite 是一个数据库引擎,您可以下载它,添加到您的项目中,然后运行!完全不需要配置!

Using the Code

基本上有两个类:DatabaseTable,位于 SQLite 命名空间下。

后续更新:另一个类 TablePtr 用于包装 Table 类的指针。

这两个类都使用 TCHAR 来支持 Unicode。使用非常简单,所有内容都在代码中进行了记录。这些类期望在 .\SQLite\ 文件夹中找到 sqlite3。您可以根据需要在源代码中更改它。

当一个函数被指定为“安全”时,这意味着即使它是一个 null 对象(例如 Table * pTbl=0),程序也会继续运行...

Database 类中,有以下方法:

  • int Open( LPCTSTR strFileName)
  • 打开一个新的数据库,如果不存在则创建它。

  • void Close()
  • 关闭数据库...

  • bool IsOpen()

    数据库是否已打开?(安全函数)

  • sqlite3 * GetPtr()
  • 返回 sqlite3 数据库的句柄。

  • int GetLastError()
  • 返回最后一个错误...

  • void CleanError()
  • 清除最后一个错误...

  • Table QuerySQL( LPCTSTR strSQL )
  • 执行 SQL 查询,并将结果返回到 Table 类中。

  • TablePtr QuerySQL2( LPCTSTR strSQL)
  • 与上面相同,但它返回一个指向 Table 类的指针,该指针被包装在 TablePtr 中。

  • int ExecuteSQL( LPCTSTR strSQL)
  • 执行 SQL 查询,不期望任何结果。

  • bool IsSQLComplete()
  • 检查 SQL 语句是否完整(根据 SQLite3 的想法和规范...)。

  • int GetLastChangesCount()
  • 返回最后一个 SQL 语句所做的更改计数。

  • int ReadBlob( LPCTSTR strSQL, BYTE ** pData, int * iLenBlob)
  • 将 BLOB 值读取到 pData 中,BLOB 的长度存储在 iLenBlob 中。仅期望 1 条记录,1 列!

  • int WriteBlob( LPCTSTR strSQL, BYTE * pData, int iLenBlob)
  • 使用 INSERTUPDATE SQL 语句写入 BLOB 值。

  • sqlite_int64 GetLastInsertRowID()
  • 获取使用 INSERT 插入的最后一行行的 ID。有关更多信息,请参阅 SQLite 文档。

  • 函数 Open()GetLastError()ExecuteSQL() 返回一个 SQLITE_ 错误,请参阅库中的 sqlite3.h 以获取错误定义。

Table 类中,有以下方法:

  • int GetColCount()
  • 返回列数。安全函数。

  • int GetRowCount()
  • 返回行数。安全函数。

  • int GetCurRow()
  • 返回当前选定的行。安全函数。

  • LPCTSTR GetColName( int iCol)
  • 返回索引为 iCol 的列的名称。

  • bool GoFirst()
  • 导航到第一条记录,如果没有记录则返回 false。安全函数(如果 Tablenull 则返回 false)。

  • bool GoLast() / GoNext() / GoPrev() - 遍历记录...
  • bool GoRow()
  • 导航到特定记录。安全函数(如果 Tablenull 或超出边界则返回 false)。

  • LPCTSTR GetValue(LPCTSTR lpColName)
  • 获取当前行的值,位于 lpColName(列名)指定的列中。

  • LPCTSTR GetValue(int iColIndex)
  • 获取当前行的值,位于 iColIndex 列(按列索引)中。

  • LPCTSTR operator [] (LPCTSTR lpColName)
  • GetValue() 相同,用于与 [] 一起使用。

  • LPCTSTR operator [] (int iColIndex)
  • GetValue() 相同,用于与 [] 一起使用。

  • void JoinTable(Table & tblJoin)
  • tblJoin 的行添加到此表中,如果列计数相等(或为空)。

TablePtr 类中:

  • Table * m_pTable
  • 指向 Table 类的 public 成员。

  • Table * Detach()
  • Table 分离类,并返回刚刚分离的 Table...

  • void Attach( Table * pTable)
  • 释放当前 Table,并附加 pTable

  • operator ()
  • 现在您不必使用 TablePtr::m_pTable,只需使用 TablePtr() 即可。

  • operator bool()
  • 现在您不必检查 m_pTable 是否有效。只需“if (TablePtr) {...}”。

关注点

您可能已经注意到,您只能获得 string 类型的值... 这是因为 SQLite3 不限制任何字段的数据类型... 因此,您可以将 float 放入字符串而不是字符串,或者将 integer 放入字符串而不是整数,例如...

但是 SQLite3 会尝试在可能的情况下转换为“首选”数据类型。

因此,您总是可以得到一个 string,然后如果您知道它应该是 integer,可以使用 _ttoi() 进行转换,或者使用 _tstof() 转换为 float...

注释

如果您有任何评论、请求、bug... 请随时与我联系,我会尽快更新。

更新

  • 20/08/2007
    • 刚刚为 BLOB 的读写添加了一个基本接口,请参阅源代码中的注释。
  • 25/08/2007
    • 添加了 TablePtr 类来包装 Table 类的指针。由 Douglas R. Keesler 建议,感谢!
  • 01/10/2007
    • 进行了一些修改,使代码更安全。
    • 还实现了用于连接两个表类的 JoinTable(),以及 TablePtr() 运算符。
    • 此外,现在也实现了 GetLastInsertRowID()
  • 20/11/2007
    • Table 类中添加了简单的 GetCurRow()...
    • 还添加了关于 GoRow() 的文档。
  • 23/12/2007
    • TablePtr 添加了 bool 运算符,因此您可以使用“if (TablePtr) {...}”来检查 m_pTable 成员是否有效。
© . All rights reserved.