max max - 17 days ago 6
iOS Question

List tables only show sqlite_sequence

I'm running an iOS program in the simulator and I'm getting this error


'ISDatabaseSQLiteException', reason: 'failed to execute statement: 'create table GroceryItem(primaryKey integer primary key autoincrement, name text NOT NULL, number integer NOT NULL)' with mesage: table GroceryItem already exists'


This is the code that I'm using, in my AppDelegate.m

self.database = [[[ISDatabase alloc] initWithFileName:@"db20121207.sqlite"] autorelease];

if(![[database tableNames] containsObject:@"GroceryItem"])
{
[database executeSql:@"create table GroceryItem(primaryKey integer primary key autoincrement, name text NOT NULL, number integer NOT NULL)"];
[database executeSql:@"insert into GroceryItem (name, number) values('apple', 5)"];
[database executeSql:@"insert into GroceryItem (name, number) values('zuoyou', 3)"];
}
else
{
[database executeSql:@"insert into GroceryItem (name, number) values('apple', 5)"];
[database executeSql:@"insert into GroceryItem (name, number) values('zuoyou', 3)"];
}


I have this methods to list table names in
sqlite_master


- (NSArray *) tables
{
return [self executeSql:@"select * from sqlite_master where type = 'table'"];
}

- (NSArray *) tableNames
{
NSLog(@"%@", [[self tables] valueForKey:@"name"] );
NSLog(@"%u", [[[self tables] valueForKey:@"name"] count] );
return [[self tables] valueForKey:@"name"];
}


but the console shows

GroceryList[7439:c07] (
"sqlite_sequence"
)

2012-12-10 16:59:40.305 GroceryList[7439:c07] 1

only get the table
sqlite_sequence
and the count is 1; from the exception above, it said "table GroceryItem already exists"

Answer

I think the issue is related to executeSql method.

From this code [[self tables] valueForKey:@"name"] it seems that you are adding the table names to a NSDictionary object.

Remember all keys in NSDictionary is unique. You are adding all table names to the disctionary using name as key.

So it'll overwrite the previously added value. That's why it is showing a single element.

Solution:

  1. Use different keys for different table names
  2. Use NSMutableArray instead of NSDictionary
  3. Change your table creating code like:

    [database executeSql:@"create table if not exists GroceryItem(primaryKey integer primary key autoincrement, name text NOT NULL, number integer NOT NULL)"];

There will be no need of that if...else condition