0

I am trying to insert data into one of my tables in a sqlite database via a test case.

Following is the test method:

-(void)testAddContact2
{
    [ContactsModel getInstance].mContactName = @"Arvind";
    [ContactsModel getInstance].mContactNo = @"556";
    [ContactsModel getInstance].mContactDob = @"July 10, 1988";
    [ContactsModel getInstance].mContactGender = @"Male";
    [ContactsModel getInstance].mContactEmail = @"arv@bnsad.co";
    [ContactsModel getInstance].mContactLatitude = @"33";
    [ContactsModel getInstance].mContactLongitude = @"44";

    STAssertFalse(([[ContactsModel getInstance] addNewContact] == TRUE),@"passed");
}

This is the method I'm trying to test:

-(BOOL)addNewContact
{
    BOOL tempFlag = NO;

    sqlite3_stmt    *statement;
    sqlite3 *mDiaryTemp = nil;

    const char *dbpath = [[UseDb getInstance].mDatabasePathDb UTF8String];

    if (sqlite3_open(dbpath, &mDiaryTemp) == SQLITE_OK)
    {
        NSString *insertSQL1=[NSString stringWithFormat:@"INSERT INTO CONTACTS VALUES(\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\")",
                              [ContactsModel getInstance].mContactName,
                              [ContactsModel getInstance].mContactNo,
                              [ContactsModel getInstance].mContactGender,
                              [ContactsModel getInstance].mContactDob,
                              [ContactsModel getInstance].mContactEmail,
                              [ContactsModel getInstance].mContactLatitude,
                              [ContactsModel getInstance].mContactLongitude];

        const char *insert_stmt1 = [insertSQL1 UTF8String];

        sqlite3_prepare_v2(mDiaryTemp, insert_stmt1, -1, &statement, NULL);

        NSString *tempName = [NSString stringWithFormat:@"%@",[ContactsModel getInstance].mContactName];
        tempName = [tempName stringByAppendingString:@"     "];

        NSString *tempNo = [NSString stringWithFormat:@"%@",[ContactsModel getInstance].mContactNo];
        tempName = [tempName stringByAppendingString:tempNo];

        [[ShowContactsViewController getInstance].phoneContacts addObject:tempName];

        NSLog(@"%d",[[ShowContactsViewController getInstance].phoneContacts count]);

        //  NSLog(@"%d",sqlite3_step(statement));
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            sqlite3_finalize(statement);
            sqlite3_close(mDiaryTemp);
            tempFlag = YES;
        }
        else
        {
            sqlite3_finalize(statement);
            sqlite3_close(mDiaryTemp);
            tempFlag = NO;
        }
    }
    if(tempFlag)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

The following condition always fails: if (sqlite3_step(statement) == SQLITE_DONE) I had posted a similar question earlier, but the issue was resolved when I used shared instances instead of new objects. But here I'm failing to insert even after using shared instances.

CRDave
  • 9,279
  • 5
  • 41
  • 59
StudentX
  • 2,506
  • 5
  • 19
  • 28
  • **I bet** your SQLite database is in the app bundle and not in some writable location... –  Jun 19 '13 at 05:45
  • the database is library/applicationsupport/iossimulator/6.0//documents. The project is in MacintoshHD. I don't know if it is in the appbundle as you're talking about. – StudentX Jun 19 '13 at 05:56
  • No, it isn't - fortunately. –  Jun 19 '13 at 05:59

2 Answers2

0

On iOS, you should consider using CoreData rather than using SQLite directly. CoreData, by default, persists to SQLite and it has much more friendly documentation. Also, since CoreData is not a C API, it will interoperate more nicely with the rest of your Objective-C code. There's also nice Xcode integration when using CoreData, which will let you define schemas easily. You'll also avoid, in many cases, writing SQL queries.

For comparisons between the two see this related question.

Community
  • 1
  • 1
Idles
  • 1,131
  • 5
  • 9
  • CoreData is not implemented using SQLite. It can optionally persist to SQLite, but it can also persist to other store formats such as XML. – Ken Jun 19 '13 at 05:09
  • actually I'm not allowed to use core data in my project. I have to use sqlite directly. – StudentX Jun 19 '13 at 05:10
  • Corrected the statement about SQLite. That's too bad you have to use sqlite directly. I'd recommend inserting your values into your SQL query and logging it to help debug, like the other answer indirectly suggests. – Idles Jun 19 '13 at 05:19
  • The addNewContact method actually works perfectly fine when access it using the view method, where I assign values from the text fields. i have checked the query statement. There is nothing wrong with it. – StudentX Jun 19 '13 at 05:25
  • You should look for a problem in your execution of `sqlite3_step();` Assign its return value to a variable so you can see what it's returning. `int return_code = sqlite3_step(statement);`. Then log the return code and compare it to the [possible return codes](http://www.sqlite.org/c3ref/c_abort.html) – Idles Jun 19 '13 at 05:34
  • Actually "if (sqlite3_open(dbpath, &mDiaryTemp) == SQLITE_OK)" is returning false as well. So control isn't going inside at all – StudentX Jun 19 '13 at 05:51
  • Folks, problem has been solved.. there were some settings to be done in Build settings. I don't exactly know which particular setting made the code work. I'll update once I know.. Thanks everybody for your time – StudentX Jun 19 '13 at 07:13
0

Try adding a semi-colon to the very end of your insertSQL1, and see where that gets you. Also be sure that there are no escape characters substituted into this statement.

Edit:

@"INSERT INTO CONTACTS VALUES(\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\")>>>;<<<"...

http://www.sqlite.org/syntaxdiagrams.html#sql-stmt-list

enter image description here

Ken
  • 30,811
  • 34
  • 116
  • 155