Christoph v
Christoph v

Reputation: 475

iphone sdk: Adding data to sqlite database not working?

I use the code below to insert data into my sqlite-database but for some reason the application always crashes as soon as the method gets called and the problem seems to be the "sqlite3_open" statement. Does anyone have any idea what I might be doing wrong?

- (void)viewDidLoad 
{
    [super viewDidLoad];

    self.title = @"Animals";
    animalsArray = [[NSMutableArray alloc] init];
    animalDetailController = [[AnimalDetailViewController alloc] init];
    addAnimalController = [[AddAnimalViewController alloc] init];
    addAnimalController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction)];
    self.navigationItem.rightBarButtonItem = addItem;

    databaseName = @"AnimalDatabase.sql";

    NSArray *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentsPath objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
    [self checkAndCreateDatabase];

    [self readDataFromDatabase];

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)addAction{  
    [self presentModalViewController:addAnimalController animated:YES];     
}

- (void)checkAndCreateDatabase{     
    BOOL databaseIsSaved;   
    NSFileManager *fileManager = [NSFileManager defaultManager];
    databaseIsSaved = [fileManager fileExistsAtPath:databasePath];  
    if (databaseIsSaved == YES) {
        return;
    }
    else {
        NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
        [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
    }
    [fileManager release];
}

- (void)readDataFromDatabase{

    sqlite3 *database;
    if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
            const char *sqlStatement = "select * from animals";
            sqlite3_stmt *compiledStatement;
            if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

                    while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
                            [animalsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)], @"name", [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)], @"description", nil]];
                    }
            }

            sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);
}

- (void)writeToDatabase{    
    sqlite3 *database;
    if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
            const char *sqlStatement = "insert into animals(name, description) VALUES(?, ?)";
            sqlite3_stmt *compiledStatement;                
            if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK){
                    sqlite3_bind_text(compiledStatement, 1, [addAnimalController.animalName UTF8String], -1, SQLITE_TRANSIENT);
                    sqlite3_bind_text(compiledStatement, 2, [addAnimalController.animalDescription UTF8String], -1, SQLITE_TRANSIENT);
            }

            if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
                    NSLog( @"Error: %s", sqlite3_errmsg(database) );
            } else {
                    NSLog( @"Insert into row id = %d", sqlite3_last_insert_rowid(database));
            }
            sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (addAnimalController.saveButtonPressed == YES && [addAnimalController.animalName length] != 0 && [addAnimalController.animalDescription length] != 0) {
            [animalsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:addAnimalController.animalName, @"name", addAnimalController.animalDescription, @"description", nil]];
            [self.tableView reloadData];

            [self writeToDatabase];
            addAnimalController.saveButtonPressed = NO;
        }
}

Upvotes: 0

Views: 1617

Answers (2)

Kris Markel
Kris Markel

Reputation: 12112

You need a retain when you set databasePath.

databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

Should be

databasePath = [[documentsDir stringByAppendingPathComponent:databaseName] retain];

Make sure you release it in your viewDidUnload and dealloc implementations. (It's probably smart to release it before you set it as well.)

Upvotes: 1

Lou Franco
Lou Franco

Reputation: 89172

Probably has nothing to do with this function. I wrote this blog to help understand EXC_BAD_ACCESS

http://www.loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

You should turn on Zombies and see if you are over-releasing any objects.

Upvotes: 0

Related Questions