sqlite:sqlite3_column_count总是返回0

时间:2016-11-30 18:36:17

标签: ios sqlite cocoapods google-analytics-api

我在iOS项目中使用sqlite。但是sqlite3_column_count总是返回0,即使我确定查询确实返回了一些列(我甚至认为SQL中的SELECT查询不可能有零输出列)。奇怪的是,这种行为会发生变化,具体取决于我链接的库的版本,特别是该库使用的编译时选项。

这些是用于库版本的编译时选项:

COMPILER=clang-8.0.0 (clang-800.2.34)
ENABLE_API_ARMOR
ENABLE_FTS3
ENABLE_FTS3_PARENTHESIS
ENABLE_JSON1
ENABLE_LOCKING_STYLE=1
ENABLE_RTREE
ENABLE_UPDATE_DELETE_LIMIT
HAS_CODEC
HAVE_ISNAN
MAX_MMAP_SIZE=20971520
OMIT_AUTORESET
OMIT_BUILTIN_TEST
OMIT_LOAD_EXTENSION
SYSTEM_MALLOC
THREADSAFE=2

以下是适用版本的标志:

COMPILER=clang-8.0.0
SYSTEM_MALLOC
THREADSAFE=1

可能导致此行为的原因是什么?

更新2016/12/01

这是一个可用于重新创建问题的项目:https://github.com/iannewson/Stackoverflow40895740.git

ViewController.swift包含以下代码:

Test.doDbStuff()

此功能包含以下内容:

public static func doDbStuff() {
    do {

        var db :OpaquePointer?
        let dbPath = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            .appendingPathComponent("\(Date.init().timeIntervalSince1970)".replacingOccurrences(of: ".", with: "") + ".db")
            .path

        var returnCode :Int32 = sqlite3_open(dbPath, &db)
        if SQLITE_OK != returnCode {
            preconditionFailure("Failed to open db")
        }

        var stmt :OpaquePointer?
        returnCode = sqlite3_prepare_v2(db, "CREATE TABLE Things (name TEXT)", -1, &stmt, nil)
        if SQLITE_OK != returnCode {
            preconditionFailure("Failed to prepare table creation SQL")
        }
        returnCode = sqlite3_step(stmt)
        if SQLITE_DONE != returnCode {
            preconditionFailure("Failed to execute tbl creation SQL")
        }
        returnCode = sqlite3_prepare_v2(db, "SELECT name FROM sqlite_master WHERE type ='table'", -1, &stmt, nil)
        if SQLITE_OK != returnCode {
            preconditionFailure("Failed to prepare count SQL")
        }
        returnCode = sqlite3_step(stmt)
        if SQLITE_ROW != returnCode {
            preconditionFailure("Failed to execute count SQL")
        } else {
            let columnCount = sqlite3_column_count(stmt)
            print("columnCount: \(columnCount)")
            let name = String(cString: sqlite3_column_text(stmt, 0))
            //print("Num tables: \(count)")
            print("Table name: \(name)")
        }

    } catch let error {
        preconditionFailure(error.localizedDescription)
    }
}

此函数在所有情况下都能正常工作,并始终创建表并从sqlite_master中检索其名称而不会出错。

ViewController.swift还包含以下代码:

    Database.instance().executeSql("CREATE TABLE IF NOT EXISTS Things (name TEXT)")
    Database.instance().printTableNames()
    Database.instance().withStatementFromSql("SELECT name FROM sqlite_master WHERE type ='table'", callback: {statement in
        while SQLITE_ROW == sqlite3_step(statement) {
            print("Column index: \(sqlite3_column_count(statement))")
            let name = SqlHelper.toString(statement, columnName: "name")
            print("Table: \(name)")
        }
    })

此代码创建一个表,然后尝试从sqlite_master检索其名称。这适用于当前在repo中设置的项目,因此要重现安装Google Analytics pod所需的错误。您可以通过在Podfile中取消注释pod 'Google/Analytics'并运行pod install来执行此操作。现在,当您尝试运行此项目时,第一组代码(Test.doDbStuff())仍然可以正常工作,但使用Database的第二组代码将使用EXC_BAD_ACCESS错误或返回{{ 1}}来自SQLITE_MISUSE

0 个答案:

没有答案