在iOS上使用LLVM进行编译时,Sqlite FTS不起作用

时间:2012-06-18 18:48:15

标签: ios sqlite full-text-search llvm

我一直在开发一款企业iPad应用程序。由于应用程序开发大约在2年前开始,我需要从源代码编译自己的SQLite版本,因为默认的SQLite库(sqlite3.dylib)默认没有启用FTS。

好的,从那时起一切正常。我一直在使用GCC作为项目编译器。

问题是,现在我正在尝试将整个项目转换为使用ARC。为此,我需要使用Apple的LLVM编译器。

就是这样。当我更改编译器(从GCC 4.2到LLVM 3.1或4.0,而不转换为ARC,而不更改任何其他内容)时,我的应用程序构建正常,一切运行正常,除了我的FTS查询,它根本不起作用最简单的。它们总是运行并返回没有结果(但是使用SQLITE_OK代码)。

我被困在这里。我已经在WWDC'12与一位Apple工程师谈过了,但我们找不到任何解决方案。

我保证它不太可能是格式错误的查询或类似的东西,因为该应用程序与GCC正常工作。此外,我能够在SQLite的终端版本上运行查询(或使用其他应用程序,如Base)

我也使用旧版本的SQLite,但我已更新到最新版本(3.7.13)。一切都保持不变。我也注意到,现在(我不知道从什么时候开始)mac附带的sqlite支持FTS(!!!),我能够删除自己的版本并使用Apple的版本。问题是,我有完全相同的行为。

我一直在寻找解决方案,但找不到一个。我发现了一些与armv6和编译器优化相关的错误(可以通过使用-mno-thumb标志来修复),但这不是我的情况。我还注意到,当我使用Clang分析我的自定义sqlite文件时,它指出了许多“潜在的错误”。

我有这种非怀疑的观点,我(仍然)不相信这是一个LLVM或SQLite错误。在解决它们之前,我更愿意检查所有可能的内容。也许我忘记配置某些东西或者需要在编译器中添加一些我没有做过的标记。

我感谢任何帮助。同样,该错误仅发生在使用LLVM编译的项目中(即使使用默认的sqlite)。如果我在sqlite3的终端版本上运行相同的查询,一切都很顺利。

更新:

此代码有效。它创建一个新数据库,一个使用fts的新虚拟表,插入几个项目然后执行选择。我稍后会尝试更复杂的查询,但是,就目前而言,似乎我的应用程序的问题可能是我的代码中的错误。

NSArray *dirPaths = dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
sqlite3 *database;

// Build the path to the database file
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"test.db"]];

NSFileManager *filemgr = [NSFileManager defaultManager];
NSError *error = nil;
[filemgr removeItemAtPath:databasePath error:&error];

const char *dbpath = [databasePath UTF8String];

if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
    char *errMsg;
    const char *sql_stmt = "CREATE VIRTUAL TABLE IF NOT EXISTS pages USING fts3(title, body);";

    if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
    {
        NSLog(@"Failed to create table");
    } else {

        sql_stmt = "INSERT INTO pages(docid, title, body) VALUES(53, 'Home Page', 'SQLite is a software...');";
        if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
        {
            NSLog(@"Failed to insert");
        }

        sql_stmt = "INSERT INTO pages(title, body) VALUES('Download', 'All SQLite source code...');";
        if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
        {
            NSLog(@"Failed to insert");
        }
    }

    sqlite3_stmt *statement;
    const char *query_stmt = "select * from pages where body match 'soft*';";

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
        if (sqlite3_step(statement) == SQLITE_ROW)
        {
            NSLog(@"%@ - %@", [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)],
                  [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]);
        } else {
            NSLog(@"no results");
        }
        sqlite3_finalize(statement);
    }

    sqlite3_close(database);

} else {
    NSLog(@"Failed to open/create database");
}

1 个答案:

答案 0 :(得分:3)

毕竟,我发现了这个错误。这是在我的代码中。总之,那是我发现的: 如果我有类似的东西(我知道这很奇怪/错误):

int a = 0;
a = a++;
NSLog(@"%d", a);

如果使用gcc编译此代码,则记录的值为1;如果使用llvm编译,则记录的值为0。

我不知道为什么,但这是另一个问题:)