【问题标题】:CPP, How to connect to sqlite3 db from stringCPP,如何从字符串连接到 sqlite3 db
【发布时间】:2021-09-02 00:42:41
【问题描述】:

在我的程序中,我需要从字符串连接到 sqlite db。

我从用户那里收到 sql db (UTF-8) 作为字符串,我正在使用sqlite3_open 函数接收 db 文件的文件路径,所以我正在创建一个文件,将字符串写入它并使用它连接到数据库:

sqlite3*
SQLiteUtils::ConnectToDatabase(std::string const& dbStr)
{
    sqlite3* db;

    std::ofstream dst("sql.db", std::ios::binary);
    dst << dbStr;

    int const ret = sqlite3_open("sql.db", &db);
    if (SQLITE_OK != ret) {
        LOG_ERROR("Can't open database: " + std::string(sqlite3_errmsg(db)));
        CloseConnectionToDatabase(db);
        return nullptr;
    }

    return db;
}

有没有办法在不将字符串写入文件并连接到文件的情况下连接到字符串?

【问题讨论】:

  • 你能解释一下你在 dbStr 中有什么吗?因为你的数据库是 sql.db 文件,你不应该自己往里面写数据。
  • 我从外部接收作为字符串的 sql DB,创建“sql.db”文件并将字符串写入其中,以便连接到接收到的数据。
  • 我正在使用int sqlite3_open(const char *filename /* Database filename (UTF-8) */, sqlite3 **ppDb /* OUT: SQLite db handle */) API 接收文件作为数据库。我的问题是是否有办法连接到字符串而不是文件?
  • 是否使用 sqlite lib 从字符串创建临时内存数据库(假设它包含Create table ...等)一个选项?
  • 查看sqlite3_serialize()sqlite3_deserialize()

标签: c++ sqlite


【解决方案1】:

感谢@Shawn 在我使用 sqlite3_serialize()sqlite3_deserialize() 的 cmets 中。

这个解决方案对我有用:

const char* IN_MEMORY_DB = ":memory:";

sqlite3* ImportDatabase(const std::string &dbStr)
{
    sqlite3 *db;
    int ret = sqlite3_open(IN_MEMORY_DB, &db);

    if (SQLITE_OK != ret)
    {
        return nullptr;
    }        

    // give serialized buffer ownership to SQLite
    unsigned int flags = SQLITE_DESERIALIZE_FREEONCLOSE|SQLITE_DESERIALIZE_RESIZEABLE;

    // allocate the serialized buffer from heap, SQLite requires to dynamic allocation for deserialize to work correctly
    unsigned char* data = static_cast<unsigned char*>(sqlite3_malloc(dbStr.size()));

    if (nullptr == data)
    {
        sqlite3_close(db);
        return nullptr;
    }

    for (int i = 0; i < dbStr.size(); ++i)
    {
        data[i] = static_cast<unsigned char>(dbStr[i]);
    }

    int err = sqlite3_deserialize(db, "main", data, dbStr.size(), dbStr.size(), flags);
    if (err != SQLITE_OK)
    {
        sqlite3_close(db);
        return nullptr;
    }

    return db;
}

在这个解决方案中,我分配了 sql 内存并将字符串复制到其中,而不将数据字符串写入中间的文件。

【讨论】:

    【解决方案2】:

    如何从字符串连接到 sqlite3 db

    sqlite3_open 的默认行为是打开/创建数据库,因此您唯一需要做的就是:

    int const ret = sqlite3_open(dbStr.c_str(), &db);
                              // ^^^^^^^^^^^^^
    

    【讨论】:

    • 谢谢@Andreas,我在SQLite C Interface 中看到sqlite3_open 的第一个参数是db 文件路径,它也可以获取db 数据作为参数吗?
    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 2011-07-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    相关资源
    最近更新 更多