1

有没有办法在 iOS 应用程序中使用 SQLite soundex()?

请指导我找到方法...

尝试了 Homegrew,但它可以在终端上运行,我每次都需要在终端上运行 soundex。我也不知道如何移植到iOS APP。

终端工作

在此处输入图像描述

4

2 回答 2

2

您可以sqlite3_create_function创建soundexSQL 函数:

#import "ViewController.h"
#import <sqlite3.h>

void soundex(sqlite3_context *context, int argc, sqlite3_value **argv);

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self test];
}

- (sqlite3 *)openDatabase
{
    NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *path = [docsPath stringByAppendingPathComponent:@"test.db"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:path])
    {
        NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"db"];
        [fileManager copyItemAtPath:bundlePath toPath:path error:nil];
    }

    sqlite3 *db;
    int rc;

    if ((rc = sqlite3_open_v2([path UTF8String], &db, SQLITE_OPEN_READWRITE, NULL)) != SQLITE_OK)
    {
        NSLog(@"%s: sqlite3_open_v2 failed: %d", __FUNCTION__, rc);
    }

    return db;
}

- (BOOL)createFunction:(sqlite3 *)db
{
    int rc;
    if ((rc = sqlite3_create_function(db, "soundex", 1, SQLITE_ANY, NULL, soundex, NULL, NULL)) != SQLITE_OK)
    {
        NSLog(@"%s: sqlite3_create_function error: %s", __FUNCTION__, sqlite3_errmsg(db));
    }

    return rc;
}

- (void)test
{
    int rc;
    sqlite3 *db = [self openDatabase];

    [self createFunction:db];

    sqlite3_stmt *statement;

    if (sqlite3_prepare_v2(db, "SELECT name FROM todo WHERE soundex(name) = soundex('Mani')", -1, &statement, NULL) != SQLITE_OK)
    {
        NSLog(@"%s: sqlite3_prepare_v2 error: %s", __FUNCTION__, sqlite3_errmsg(db));
    }

    while ((rc = sqlite3_step(statement)) == SQLITE_ROW)
    {
        const unsigned char *name = sqlite3_column_text(statement, 0);
        if (name)
            NSLog(@"name=%s", name);
        else
            NSLog(@"name=NULL");
    }

    if (rc != SQLITE_DONE)
    {
        NSLog(@"%s: sqlite3_step error: %s", __FUNCTION__, sqlite3_errmsg(db));
    }

    sqlite3_finalize(statement);
    sqlite3_close(db);
}

@end

void soundex(sqlite3_context *context, int argc, sqlite3_value **argv)
{
    const char *str = (const char*)sqlite3_value_text(argv[0]);
    const char *in = str;

    static int code[] =
    {  0,1,2,3,0,1,2,0,0,2,2,4,5,5,0,1,2,6,2,3,0,1,0,2,0,2 };
    /* a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z */

    char ch;
    int last;
    int count;

    char key[5];
    /* Set up default key, complete with trailing '0's */
    strcpy(key, "Z000");

    /* Advance to the first letter.  If none present,
     return default key */
    while (*in != '\0'  &&  !isalpha(*in))
        ++in;
    if (*in == '\0') {
        sqlite3_result_text(context, key, 4, SQLITE_TRANSIENT);
        return;
    }

    /* Pull out the first letter, uppercase it, and
     set up for main loop */
    key[0] = toupper(*in);
    last = code[key[0] - 'A'];
    ++in;

    /* Scan rest of string, stop at end of string or
     when the key is full */
    for (count = 1;  count < 4  &&  *in != '\0';  ++in) {
        /* If non-alpha, ignore the character altogether */
        if (isalpha(*in)) {
            ch = tolower(*in);
            /* Fold together adjacent letters sharing the same code */
            if (last != code[ch - 'a']) {
                last = code[ch - 'a'];
                /* Ignore code==0 letters except as separators */
                if (last != 0)
                    key[count++] = '0' + last;
            }
        }
    }

    sqlite3_result_text(context, key, 4, SQLITE_TRANSIENT);  
}
于 2013-06-21T17:18:49.077 回答
0

您需要从sqlite 合并本身与使用 libsqlite dylib 的项目中包含 sqlite.c/sqlite.h 文件。

确保在构建时设置 SQLITE_SOUNDEX 预处理器标志以包含此功能。

1)下载并解压sqlite合并。将 sqlite.h/sqlite.c 文件添加到您的项目中。

2) 通过 XCode 中的构建设置屏幕将 SQLITE_SOUNDEX=1 添加到项目的预处理器宏中。

3) 通过 Xcode 中的 Build Phases 屏幕从项目的 Link With Libraries 列表中删除 libsqlite3XXX.dylib。

于 2013-06-21T17:17:10.680 回答