Неверная таблица SQLite на iPhone? - PullRequest
1 голос
/ 27 марта 2011

Я пытался получить доступ к базе данных SQLite3 через мой iphone, но я продолжаю получать сообщение об ошибке «нет такой таблицы: user_info».

Итак, вот шаги, которые я прошел:

  1. Создать базу данных с помощью командной строки:

    • sqlite3 users.sqlite
    • создать таблицу user_info (текст названия, текст информации);
    • вставить в значение user_info ('Name1', 'Это информация для Name1');
    • выберите * из user_info;
    • [результат]: Name1 | Это информация для Name1
    • выберите * из sqlite_master;
    • [результат]: таблица | user_info | user_info | 3 | CREATE TABLE user_info (текст названия, текст информации)
  2. Скопируйте это в папку ресурсов в XCode, с возможностью скопировать его в соответствующий каталог.

  3. Попытка получить к нему доступ и получить ошибку «нет такой таблицы: user_info».

Хорошо, так как у меня дела # 3? Ну, я немного обновился, так что теперь я пытаюсь создать таблицу, если она не существует. Вот мой текущий код:

static NSString *dbname = @"users.sqlite";

-(NSString *) dbFilePath {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(
        NSDocumentDirectory, NSUserDomainMask, YES
    );
    NSString *documentsDir = [paths objectAtIndex:0];
    NSString *dbPath = [documentsDir stringByAppendingPathComponent:dbname];
    BOOL success = [fileManager fileExistsAtPath:dbPath];
    if (!success) {
        fprintf(stderr, "Database is not writeable!\n");
    }
    return dbPath;
}

- (void)createEditableCopyOfDatabaseIfNeeded {
    BOOL success;
    NSError *error;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *writeableDBPath = [self dbFilePath];

    success = [fileManager fileExistsAtPath:writeableDBPath];
    if (success) {
        return;
    }

    NSString *defaultDBPath =
        [[[NSBundle mainBundle] resourcePath]
            stringByAppendingPathComponent:dbname];

    success = [fileManager
                    copyItemAtPath:defaultDBPath
                    toPath:writeableDBPath
                    error:&error];

    if (!success) {
        fprintf(stderr, "Failed to create writable database file\n");
    }
}

-(void) openDB {
    if (sqlite3_open([[self dbFilePath] UTF8String], &db) != SQLITE_OK) {
        sqlite3_close(db);
        fprintf(stderr, "Database failed to open.\n");
    }
}

-(void) createTableIfNeeded {
    NSString *result = @"";
    sqlite3_stmt *statement;

    char *sql = sqlite3_mprintf(
        "CREATE TABLE IF NOT EXISTS user_info (name text info text);"
    );

    dbresult = sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL);
    if (SQLITE_OK != dbresult) {
        NSAssert1(0, "no user_info table!", nil);
        fprintf(
            stderr,
            "Error in preparation of query: %s\n", 
            sqlite3_errmsg(db)
        );
        sqlite3_close(db);
        return;
    }
    sqlite3_finalize(statement);
    sqlite3_free(sql);
}

- (NSString *)getDatabaseEntry:(NSString *)i_name {
    NSString *result = @"";
    sqlite3_stmt *statement;

    char *sql = sqlite3_mprintf(
        "SELECT 'info' FROM 'user_info' WHERE name='%q'",
        [i_name cStringUsingEncoding:NSASCIIStringEncoding]
    );

    dbresult = sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL);
    if (SQLITE_OK != dbresult) {
        fprintf(
            stderr,
            "Error in preparation of query: %s\n", 
            sqlite3_errmsg(db)
        );
        sqlite3_close(db);
        return result;
    }
    dbresult = sqlite3_step(statement);
    if (SQLITE_ROW == dbresult) {
        char *nfo = (char *)sqlite3_column_text(statement, 0);
        result = [NSString stringWithUTF8String:nfo];
    }
    sqlite3_finalize(statement);
    sqlite3_free(sql);
    return result;
}

// viewDidAppear
- (void)viewDidAppear:(BOOL)animated {
    [self createEditableCopyOfDatabaseIfNeeded];
    [self openDB];
    [self createTableIfNeeded];
}

// Later, when I have a valid user:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
        shouldContinueAfterSelectingPerson:(ABRecordRef)person {
    ...
    NSString *nfo = [self getDatabaseEntry:name.text];
    ...
}

Я пару дней против этой стены, так что любая помощь очень ценится.

1 Ответ

0 голосов
/ 27 марта 2011

Ну, я исправил это, но я не уверен, как.Я создал пустой проект и следовал инструкциям здесь: http://www.raywenderlich.com/913/sqlite-101-for-iphone-developers-making-our-app И убедился, что это сработало.(Это так.)

Затем я использовал бит отсюда: http://www.raywenderlich.com/725/how-to-read-and-write-xml-documents-with-gdataxml Чтобы скопировать базу данных в место, где она доступна для записи.Раньше у меня был очень похожий код.

Так что теперь он работает.Я построил новую таблицу специально с расширениями "sqlite3".Я не знаю, если это действительно имеет значение или нет.Я также использовал:

[[NSBundle mainBundle] pathForResource:@"users" ofType:@"sqlite3"];

В отличие от:

[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbname];

Опять не знаю, имеет ли это значение.

Надеюсь, это поможет кому-то еще!1017 *

//----------------------------------------------------------------------------
-(NSString *) dbFilePath {
    NSError *error;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask,
                                                         YES);
    NSString *documentsDir = [paths objectAtIndex:0];
    NSString *dbPath = [documentsDir stringByAppendingPathComponent:@"users.sqlite3"];
    BOOL success = [fileManager fileExistsAtPath:dbPath];
    if (!success) {
        fprintf(stderr, "Database is not writeable!  Attempting to create writeable database.\n");
        NSString *bundle_path = [[NSBundle mainBundle] pathForResource:@"users" ofType:@"sqlite3"];
        success = [fileManager copyItemAtPath:bundle_path toPath:dbPath error: &error];
        if (!success) {
            fprintf(stderr, "Failed to create writeable database file\n");
        }
    }
    return dbPath;
}

//----------------------------------------------------------------------------
-(void) openDB {
    if (sqlite3_open([[self dbFilePath] UTF8String], &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(0, @"Database failed to open.");
        fprintf(stderr, "Database failed to open.\n");
    }
}

//----------------------------------------------------------------------------
- (NSString *)getDatabaseEntry:(NSString *)i_name {
    NSString *result = @"";
    sqlite3_stmt *statement;

    char *sql = sqlite3_mprintf(
        "SELECT info FROM user_info WHERE name='%q'",
        [i_name cStringUsingEncoding:NSASCIIStringEncoding]
    );
    dbresult = sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL);
    if (SQLITE_OK != dbresult) {
        fprintf(stderr,
                "Error in preparation of query: %s\n",
                sqlite3_errmsg(db));
        sqlite3_close(db);
        sqlite3_free(sql);
        return result;
    }

    dbresult = sqlite3_step(statement);
    if (SQLITE_ROW == dbresult) {
        char *nfo = (char *)sqlite3_column_text(statement, 0);
        result = [NSString stringWithUTF8String:nfo];
    }
    sqlite3_finalize(statement);
    sqlite3_free(sql);

    return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...