iPhone sqlite3 заблокирован, можно только читать, а не писать - PullRequest
0 голосов
/ 31 октября 2009

Так что я работаю над этим проектом в течение короткого времени. У меня нет проблем с чтением данных из БД и форматированием их в UITableViews, а что нет. Но теперь я хочу также написать в БД. Проблема в том, что я получаю ошибку «База данных заблокирована» из sqlite. После того, как я возился с оригинальной версией, у меня был момент, когда я понял, что моя база данных находится в комплекте и, следовательно, недоступна для записи. Поэтому я переместил БД в папку «Документы приложений», в которую можно записывать. Но теперь я все еще получаю ту же ошибку «База данных заблокирована» sql. Я открываю и закрываю БД только при необходимости. И, насколько я могу судить, я нигде не оставляю это открытым. Ниже приведен код, где я хочу сделать обновления. Есть мысли?

    - (BOOL) loanBookTo:(NSString *)newborrower{
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"books.sqlite"];   

        if([[NSFileManager defaultManager] fileExistsAtPath:path]){
            NSLog(@"File Exists at: %@", path);
        }


        if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {  
            NSString *mySQL = @"UPDATE BOOKS SET LOANED = 1, BORROWER = \"<BORROWER>\" where ISBN = \"<ISBN>\"";
            mySQL = [mySQL stringByReplacingOccurrencesOfString:@"<ISBN>" withString:self.isbn];
            mySQL = [mySQL stringByReplacingOccurrencesOfString:@"<BORROWER>" withString:newborrower];
            const char *sql = [mySQL UTF8String];
            char* errmsg;
            sqlite3_exec(database, sql, NULL, NULL, &errmsg);

            // Q. Database is locked. Why?
            // A. Because it is in the Bundle and is ReadOnly.
            //    Need to write a copy to the Doc folder.

            // Database is Locked error gets spit out here. 
            printf(errmsg);
            sqlite3_close(database);
        }   
        return NO;
    }

Ответы [ 3 ]

0 голосов
/ 31 октября 2009

Как вы перемещаете БД в папку с документами из комплекта? Вам нужно проверить, что он там есть, а если нет, скопировать его. У меня такое ощущение, что вы либо скопировали его другим способом, но сохранили атрибут «только для чтения», либо, скорее всего, вы все еще ссылаетесь на оригинал в комплекте.

Подробнее см.

Где бы вы разместили файл базы данных SQLite в приложении для iPhone?

или, как говорит joshperry, образец SQLiteBooks содержит весь необходимый код.

0 голосов
/ 15 мая 2012

Как вы попадаете в loanBookTo? Если база данных открыта, а затем вы вызываете loanBookTo, она не может выдать ошибку открытия, однако база данных удерживает состояние, откуда вы пришли.

Кроме того, иногда база данных сохраняет заблокированное состояние при закрытии и выходе из приложения, поэтому вы можете «наследовать» заблокированное состояние от предыдущих сбоев. Удаление приложения из симулятора должно дать вам чистую копию.

0 голосов
/ 31 октября 2009

Откройте базу данных один раз в начале вашего приложения, затем закройте ее в applicationWillTerminate из AppDelegate.

После каждого exec вам нужно будет выполнить сброс, чтобы очистить состояние соединения.

Взгляните на пример приложения SQLiteBooks, оно закодировано следующим образом.

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