Need To Populate Core Data From SQLite Database - iphone

I have an SQLite database with 4 tables in it that I want to load into my Core Data database so I can implement core data. Can anyone help me with this?
I have the core data app ready, and I have the SQLite database ready. I need to copy the data from SQLite tables their 4 respective entities in core data in App delegate.
I'm currently using this code, how can I edit it so that instead of adding to array, it creates a new object in MOC?
-(NSMutableArray *) getCPTCodes
{
sqlite3 *database = CodesDatabase();
NSMutableArray *cptCodes = [[[NSMutableArray alloc] init] autorelease];
NSString *nsquery = [[NSString alloc] initWithFormat:#"SELECT code, short_description, medium_description FROM cpt_codes"];
const char *query = [nsquery UTF8String];
[nsquery release];
sqlite3_stmt *statement;
int prepareCode = (sqlite3_prepare_v2( database, query, -1, &statement, NULL));
if(prepareCode == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW)
{
CPTCodes *code = [[CPTCodes alloc] init];
code.code = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 0) encoding:NSUTF8StringEncoding];
code.name = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 1) encoding:NSUTF8StringEncoding];
code.description = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 2) encoding:NSUTF8StringEncoding];
[cptCodes addObject:code];
// NSLog(#"Code: %# Short Description: %# Long Description: %#", hcpcsCode.code, hcpcsCode.name, hcpcsCode.description);
[code release];
}
sqlite3_finalize(statement);
}
return cptCodes;
}
Instead of loading that into an array, I need to add it as an object in core data, using this?
insertNewObjectForEntityForName:inManagedObjectContext:

It looks like you can create an entity and NSManagedObject subclass to take the place of the Code class in your existing code.
Your entity would look like:
CPTCode{
code:string
name:string
desc:string // "description" is a method of NSObject so you can't use it as a property name
}
... and then you could have Xcode generate a custom subclass, lets call it CPTCodeMO just for clarity.
Then you adapt your existing code:
CPTCodeMO *code;
while (sqlite3_step(statement) == SQLITE_ROW){
code=[NSEntityDescription insertNewObjectForEntityForName:#"CPTCode" inManagedObjectContext:self.managedObjectContext];
code.code = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 0) encoding:NSUTF8StringEncoding];
code.name = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 1) encoding:NSUTF8StringEncoding];
code.description = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 2) encoding:NSUTF8StringEncoding];
}
Each pass through the loop would create a new CPTCodeMO instances and insert it in the managed object context. When you have created all the new instances you would just save the context:
[self.managedObjectContext save:&saveError];
... and your done.
There are nuances of course but this is the basic idea.
Do that once and you will have a Core Data SQLite store file with the existing data. You can then include that in the app bundle to ship with the app or do something else with it.
I usually create a small utility app project in Xcode just to do this kind of import.

Related

How to release an NSMutable Array which we need to use in return statements

IM USING SQLITE DATABASE for my iPhone app
In my app in data base to retried the content from the database i used an array and i return this array in a database method for select statement,
for this purpose i allocate an array and i need to release the array,
NSMutableArray *allContacts = [[NSMutableArray alloc] init];
return allContacts;
if i release an array how sh'd i used in return statement
viceversa if i tried to release after return (we can do anything after return)
Any solution please....
How should we use auto release NSMutable array
//Select statement for contacts
//==================================
+ (NSMutableArray*) selectAllContactsFromDB
{
NSString *DBPath = [self copyDBFile];
sqlite3 *contactsDB = nil;
sqlite3_stmt *statement = nil;
NSMutableArray *allContacts = [[NSMutableArray alloc] init];
if (sqlite3_open([DBPath UTF8String], &contactsDB) == SQLITE_OK)
{
NSString *query = [NSString stringWithFormat: #"SELECT ROWID, NAME, MOBILE, FROM CONTACTINFO"];
if(sqlite3_prepare_v2(contactsDB, [query UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
Contact *contact = [[Contact alloc] init];
contact.rowid = sqlite3_column_int(statement, 0);
contact.name = [NSString stringWithUTF8String:(const char*) sqlite3_column_text(statement, 1)];
contact.mobile = [NSString stringWithUTF8String:(const char*) sqlite3_column_text(statement, 2)];
[allContacts addObject:contact];
}
}
else {
NSLog(#"Statement not prepared");
}
}
[DBPath release];
return allContacts;
}
When you return an allocated object from a method pass it as an autoreleased object.
return [allContacts autorelease];
When you get an autoreleased object you need to retain it for further use:
So change the calling method like;
NSMutableArray *temp = [[YourClass selectAllContactsFromDB] retain];
try like this
NSMutableArray *allContacts = [[[NSMutableArray alloc] init] autorelease];
and also like this..
return [allContacts autorelease];
You can write return statement
return [allContacts autorelease];
OR you can use ARC in your project.
You will have to use autorelease :
return [allContacts autorelease];
This way il will be released the next time the autorelease pool will be flushed. And you have followed the golden rule : For each alloc, copy or retain, you must have a release or autorelease.
use ARC(Automatic Reference Counting) or you have a property as a mutuable array and just return the array...
to get u started on ARC, watch this: http://www.youtube.com/watch?v=FxuI4e_Bj58

How can I query a sqlite database using objective c?

I'm trying to display food by type to a user. The different types of foods are different elements in a table (fruits, veggies, meats, etc). I have all the foods in one database using sqlite. How can I query this database using objective c so that I can display only the correct type of food the user selected in the next view's table?
We use FMDB in two apps. It works fine.
-(NSArray *)GetAllFoods
{
NSMutableArray *filesArray = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
NSString *DBPath = [ClsCommonFunctions GetDatabasePath];
if ([self OpenDBWithPath:DBPath])
{
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "your query";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(filesDB, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Need to get data from database...
NSSstring *foodObj = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)]
[filesArray addObject:foodObj];
FileObj = nil;
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
sqlite3_close(filesDB);
}
return filesArray;

How to load uipickerview values from database in iphone?

I want to load data to uipickerview from database.
this is my code
if (sqlite3_prepare_v2(UsersDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
int i=0;
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"select");
self.coun=[[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(#"Coun = %#",coun);
self.animals=[coun componentsSeparatedByString:#":"];
NSLog(#"String value=%#",self.animals);
}
sqlite3_finalize(statement);
} else
{
NSLog(#"not select");
}
and button actions code is
- (IBAction)selectAnItem:(UIControl *)sender {
//Display the ActionSheetPicker
[ActionSheetPicker displayActionPickerWithView:sender data:self.animals selectedIndex:self.selectedIndex target:self action:#selector(itemWasSelected::) title:#"Select Country"];
}
but it run load only last value. Not all values loaded in UIpickerview. How to load all values from database using this code. Anyone pls help me. Thanks in advance.
You have to do like this,
NSArray *splitedString = [coun componentsSeparatedByString: #":"];
NSString *animalName;
if ([splitedString count]>0)
{
animalName=[splitedString objectAtIndex:0];
[self.animals addObject:animalName]; //here animals should be NSMutableArray
}
In the while loop, you have to collect all the self.coun values in an array. When you come out of the loop, having all the values, populate the picker.
NSMutableArray *countries = [[NSMutableArray alloc] init];
while (sqlite3_step(statement) == SQLITE_ROW){
self.coun=[[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(#"Coun = %#",coun);
[countries addObject:coun];
//self.animals=[coun componentsSeparatedByString:#":"];
//NSLog(#"String value=%#",self.animals);
}
// Now you can use countries to populate in picker.
You have to implement data source and delegates for the UIPickerView.
Seems, you are storing countries in DB, reading from DB you are assigning in self.animals. Thats kind of not matching things with variable names. And why are your parsing by ":"?

Need To Optimize SQLite Loading Into TableView

I have an SQLite Database with 5000 rows that is loaded into a tableview.
It takes around 5-10 sec (which is extremely long on the iPhone) to load the table. Is there a way I can load the cells in smaller batches or something else to speed this up? Also, when I go back up in hierarchy then revisit this view, it has to reload all over again. Can I cache this out instead?
- (void)viewDidLoad
{
[super viewDidLoad];
[NSThread detachNewThreadSelector:#selector(myThread:) toTarget:self withObject:nil];
}
-(void) myThread:(id) obj {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [[Database sharedDatabase] getICD9DiseaseCodes];
[self performSelectorOnMainThread:#selector(dataDoneLoading:) withObject:array waitUntilDone:NO];
[pool release];
}
-(void) dataDoneLoading:(id) obj {
NSMutableArray *array = (NSMutableArray *) obj;
self.codeAray = array;
[self.myTableView reloadData];
[self dismissHUD];
NSLog(#"done");
}
In my database class:
-(NSMutableArray *) getICD9DiseaseCodes
{
sqlite3 *database = CodesDatabase();
NSMutableArray *icd9DiseaseCodes = [[[NSMutableArray alloc] init] autorelease];
NSString *nsquery = [[NSString alloc] initWithFormat:#"SELECT code, title, description FROM icd9_disease_codes ORDER BY code"];
const char *query = [nsquery UTF8String];
[nsquery release];
sqlite3_stmt *statement;
int prepareCode = (sqlite3_prepare_v2( database, query, -1, &statement, NULL));
if(prepareCode == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW)
{
ICD9DiseaseCodes *code = [[ICD9DiseaseCodes alloc] init];
code.code = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 0) encoding:NSUTF8StringEncoding];
code.name = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 1) encoding:NSUTF8StringEncoding];
code.description = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 2) encoding:NSUTF8StringEncoding];
[icd9DiseaseCodes addObject:code];
// NSLog(#"Code: %# Short Description: %# Long Description: %#", hcpcsCode.code, hcpcsCode.name, hcpcsCode.description);
[code release];
}
sqlite3_finalize(statement);
}
return icd9DiseaseCodes;
}
My first question is why do you use SQLite directly, and not Core Data? Core Data will do fast partial fetches from the data store for you, for free with no extra code on your part.
If you want to do the same thing manually with SQLite directly, then you are in for some heavy lifting code. You will need to use LIMIT and OFFSET in your SQL queries to fetch partial data, and extend your API to fetch only smaller sub-sets at a time.
Have you considered or looked into CoreData? CoreData has a lot of optimization for large recordsets.
Thanks.
James

iphone xcode sqlite3_open remote host

i try to get a connection my server, with the sqlite3_open command!
my question...is it possible to that? i got the following code...
// Get the path to the documents directory and append the databaseName
databaseName = #"AnimalDatabase.sql";
NSString *serverpath = #"http://localhost/app/";
databasePath = [serverpath stringByAppendingPathComponent:databaseName];
and then this here
-(void) readAnimalsFromDatabase {
// Setup the database object
sqlite3 *database;
// Init the animals Array
animals = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from animals";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// Create a new animal object with the data from the database
Animal *animal = [[Animal alloc] initWithName:aName description:aDescription url:aImageUrl];
// Add the animal object to the animals Array
[animals addObject:animal];
[animal release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
any suggestion??
Where you get the idea that SQLite can open database from URL??
It can open files only (or, create temporary db in memory).
The answer is just NO, there are lot of mistakes in your code anyway. For example:
databaseName = #"AnimalDatabase.sql";
Where did you get this. iPhone is working with sqlite database, it has nothing in common with sql files:)