Advertise Books Events Forum News Social Networking Support Us

sdkIQ for iPhone ($4.99)

dotnetIQ ($4.99)

Your First iPhone App ($1.99)

iPocket Tools 9 in 1 ($0.99)

Catch-Me (Free)

Alien Strike ($0.99)

Historic Olympic Medal-Table ($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 07-07-2009, 10:12 AM   #1 (permalink)
Registered Member
 
Join Date: Jul 2009
Posts: 11
Default Creating Data Access Component using sqlite3

I am trying to create a class that I can use as a generic Data Access Component (DAC), with sqlite3 as the storage mechanism. I am doing this so as to centralise the data access in my app(s). Before starting the DAC I had successfully managed to get data into and out of a database using sqlite3. However, I am having problems getting the same functionality to work within a central class.

For example, I have a Mood class that stores 5 integers relating to a person's mood for a given date. I have created a Mood class to hold this information. Within the Mood class I have - amongst others - two methods; load and save. 'load' retrieves data for a given date, while save writes the data to the database.

In my original - pre-DAC - code I had calls to sqlite methods within the load method of my Mood class. Now I am trying to put that code into a generic 'runSQLNoRecords' method on my DAC class, i.e. all my future classes can then use the DAC rather than me having to re-write sqlite statements over and over.

In order to do this, I figured my DAC class would need to have two global variables (not sure if that's the right terminology here); namely the database and the statement. By being Globals I could repeatedly access the records within the statement and therefore be able to traverse a recordset.

The DAC def looks as follows:

@interface DAC : NSObject
{
sqlite3_stmt *statement;
sqlite3 *database;
}

// Init the database
- (void) initDatabase;

// Open the database
- (void) openDatabase;

// Close the database
- (void) closeDatabase;

// Run a query that DOES NOT return records
- (void) runSQLNoRecords: (NSString*) theSQL;

// Run a query that DOES return records
- (BOOL) runSQLReturnRecords: (NSString*) theSQL;

// Step through to next record, return TRUE if ok, FALSE otherwise
- (BOOL) isNextRecord;

// Return an Int from the recordset
- (int) returnInt: (int) column;

// Return a String from the recordset
- (NSString*) returnString: (int) column;


@end


The definition for the problematic method is:

// Run a Query that DOES return records
- (BOOL) runSQLReturnRecords: (NSString*) theSQL
{

// Check if the DB is available
if (sqlite3_open([[self dbFilePath] UTF8String], &database) != SQLITE_OK)
{
NSAssert(0, @"Failed to open db.");
sqlite3_close(database);
return FALSE;
}

// Get the row
if (sqlite3_prepare_v2(database, [theSQL UTF8String], -1, &statement, nil) != SQLITE_OK)
{
return FALSE;
}

// Must be ok if we get this far
return TRUE;
}


My logic in the above is to open the database and the statement and, in theory, that statement should then be available to future calls to methods on my DAC, e.g. returnInt, returnString etc - up until the point I release the DAC from memory.

The problem is that the above method always fails on the prepare statement with an error code of SQLITE_ERROR. According to the docs that's either a SQL error - I'm using the exact same SQL as what previously worked when running code outside of the DAC class - or a database not open error. As I am opening the database successfully prior to the prepare I'm not sure that's an issue either.

I am new to this development environment - C, Objective-C, XCode - and as such am having a hard time learning how to debug etc with this tech. I'd really appreciate any help with this problem.

EDIT: Code added to show how my Mood class calls the DAC

Below is the load method from my Mood class. Note, this method used to contain all the relevant sqlite commands, e.g. opening the database, preparing the statement, stepping the statement etc and that code worked correctly for me.

// Load the object with data from the Date passed in
- (void) load: (NSDate*) theDate
{

// Get today's date in the format it will be stored in the database
NSString* date;
date = GETS DATE FROM DATE PICKER;

NSString *select = [[NSString alloc] initWithFormat:@"Select CalendarDate, Work, Mood, Home, Exercise, Food From Mood Where CalendarDate = '%@'", date];

// Get a DAC object
DAC *myDAC = [DAC alloc];

// Open the database
[myDAC openDatabase];

// Open the Recordset based on 'select'
// This will stay open until we close the Database later
[myDAC runSQLReturnRecords:(select)];

// NOTE TO READERS: The above call ALWAYS fails


/*
CODE HERE TO READ IN THE DATA, BUT CODE NEVER GETS THIS FAR
CODE REMOVED FOR CLARITY
*/

}

Last edited by LordMooch; 07-07-2009 at 10:20 AM. Reason: Further code to aid clarification of calling the DAC
LordMooch is offline   Reply With Quote
Reply

Bookmarks

Tags
data, database, sqlite, sqlite3

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


» Advertisements
» Stats
Members: 21,505
Threads: 35,786
Posts: 156,783
Top Poster: smasher (2,449)
Welcome to our newest member, SimonK
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 03:12 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0