使用iPhone模拟器的SQLite错误/可能的权限问题

时间:2023-01-10 23:07:03

I'm working on a new iPhone project and I'm running into problems with sqlite. I've done this before on a different project and it worked just fine so I'm not sure exactly what is going on with this one. I'm using the same code from before, but the situation is a little different.

我正在研究一个新的iPhone项目,我遇到了sqlite的问题。我之前在一个不同的项目上完成了这项工作并且工作正常,所以我不确定这个项目到底发生了什么。我以前使用相同的代码,但情况有点不同。

First of all, I'm trying this time to use Unit Testing so I've created a Cocoa Unit Test Bundle, and I got that working correctly, then I wanted to make a Unit Test for my sqlite database.

首先,我正在尝试使用单元测试,因此我创建了一个Cocoa Unit测试包,并且我正确地工作,然后我想为我的sqlite数据库进行单元测试。

The first thing run with this test is [self checkAndCreateDatabase] which is as follows:

运行此测试的第一件事是[self checkAndCreateDatabase],如下所示:

-(void) checkAndCreateDatabase{
        BOOL success;

        // Create a FileManager object, we will use this to check the status
        // of the database and to copy it over if required
        NSFileManager *fileManager = [NSFileManager defaultManager];

        // Check if the database has already been created in the users filesystem
        success = [fileManager fileExistsAtPath:databasePath];

        // If the database already exists then return without doing anything
        if(success) return;

        // If not then proceed to copy the database from the application to the users filesystem

        // Get the path to the database in the application package
        NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

        // Copy the database from the package to the users filesystem
        [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];

        [fileManager release];
    }

Then I attempt to open the database with the following line:

然后我尝试使用以下行打开数据库:

int result = sqlite3_open([databasePath UTF8String], &database);

This fails everytime with error code 14 SQLITE_CANTOPEN, and databasePath is "/Users/labuser/Library/Application Support/iPhone Simulator/Documents/projectfusion.db3".

每次都会失败,错误代码为14 SQLITE_CANTOPEN,而databasePath为“/ Users / labuser / Library / Application Support / iPhone Simulator / Documents / projectfusion.db3”。

What is odd is that when I go to that directory, Documents/ isn't there, so if I create that, then it doesn't fail, BUT projectfusion.db3 then has a size of 0kb; the tables aren't there. That makes any sqlite3_prepare_v2() fail, because the tables aren't there. If I manually copy the projectfusion.db3 file to that directory before running, then it works just fine.

奇怪的是,当我去那个目录时,Documents /不存在,所以如果我创建它,那么它不会失败,但是projectfusion.db3的大小为0kb;桌子不在那里。这使得任何sqlite3_prepare_v2()失败,因为表不存在。如果我在运行之前手动将projectfusion.db3文件复制到该目录,那么它可以正常工作。

Is it because I'm doing this inside the unit tests and the scripts don't have permission or something? Or is it possibly because I'm working on a school computer at my university and can't write to that directory? (I tried logging in as admin and it didn't work either).

是因为我在单元测试中执行此操作并且脚本没有权限或其他内容?或者可能是因为我在我大学的学校电脑上工作而无法写入该目录? (我尝试以管理员身份登录,但它也无法正常工作)。

2 个解决方案

#1


0  

Try the code given below,

试试下面给出的代码,

I've set a macro called TEST so I don't have to keep commenting code out.

我已经设置了一个名为TEST的宏,所以我不必继续注释代码。

- (NSString *)createEditableCopyOfDatabaseIfNeeded {
    // First, test for existence.
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    #ifdef TEST
    documentsDirectory = [[NSFileManager defaultManager] currentDirectoryPath];
    #endif


    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:DBNAME];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success) { return writableDBPath;} ;
    // The writable database does not exist, so copy the default to the appropriate location.

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DBNAME];    
    #ifdef TEST
    defaultDBPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"YOURDB" ofType:@"sqlite"];
    #endif

    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
    return (defaultDBPath);
}

#2


0  

Try adding the database to your application bundle in xcode and then copy it to the applications Documents directory. You can get that path using

尝试将数据库添加到xcode中的应用程序包中,然后将其复制到应用程序文档目录。你可以使用这条路径

- (NSString *)applicationDocumentsDirectory {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}

#1


0  

Try the code given below,

试试下面给出的代码,

I've set a macro called TEST so I don't have to keep commenting code out.

我已经设置了一个名为TEST的宏,所以我不必继续注释代码。

- (NSString *)createEditableCopyOfDatabaseIfNeeded {
    // First, test for existence.
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    #ifdef TEST
    documentsDirectory = [[NSFileManager defaultManager] currentDirectoryPath];
    #endif


    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:DBNAME];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success) { return writableDBPath;} ;
    // The writable database does not exist, so copy the default to the appropriate location.

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DBNAME];    
    #ifdef TEST
    defaultDBPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"YOURDB" ofType:@"sqlite"];
    #endif

    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
    return (defaultDBPath);
}

#2


0  

Try adding the database to your application bundle in xcode and then copy it to the applications Documents directory. You can get that path using

尝试将数据库添加到xcode中的应用程序包中,然后将其复制到应用程序文档目录。你可以使用这条路径

- (NSString *)applicationDocumentsDirectory {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}