FMResultSet can't be add to NSMuatbleArray

Discussion in 'iOS Programming' started by mikezang, Oct 3, 2010.

  1. mikezang macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #1
    I am using FMDB to select data in SQLite3 and the result is saved in FMResultSet, I tried to add it to NSMutableArray and use it later, but it seems like the FMResultSet can't be used, does anyone tell me why?
    Code:
    FMDatabase *db = [FMDatabase databaseWithPath:pathInDocumentsFolder(kDatabase)];
    	
    if (![db open]) {
        NSLog(@"Could not open db.");
        return;
    }
    	
    FMResultSet *rs = [db executeQuery:@"SELECT date, open, high, low, close, volume FROM stock_t1 WHERE code = ? ORDER BY date DESC", stockCode.code];
    	
    [stockDataList release];
    stockDataList = nil;
    	
    stockDataList = [[NSMutableArray alloc] init];
    	
    while ([rs next]) {
        [stockDataList addObject:rs];
    }
    
    [rs close];
    [db close];
    
    Code:
    FMResultSet *stock = [stockDataList objectAtIndex:indexPath.row];//no correct result
    cell.labelDate.text = [stock stringForColumn:@"date"];
    cell.labelOpen.text = [stock stringForColumn:@"open"];
    cell.labelHigh.text = [stock stringForColumn:@"high"];
    cell.labelLow.text = [stock stringForColumn:@"low"];
    cell.labelClose.text = [stock stringForColumn:@"close"];
    cell.labelVolume.text = [stock stringForColumn:@"volume"];
    
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #2
    The result set is like a direct connection to the database and it's a kind of temporary thing. You should get the information out of the result set and add that to your array. I usually use a dictionary to hold the results, or an object that has a dictionary.
     
  3. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #3
    Thanks, I did like you did, but I am not sure about the reason, now I see.

    But this way will cost more for copy them from FMResultSet, I think the performance will be better if FMDB can support dictionary or object directly, do you thinks so?
     
  4. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #4
    One more question, where did you init FMDatabase?

    I tried to init it in my app delegate, and release it in dealloc, then I get app delegate in all didLoadView and use that FMDatabse in app delegate, but it seems like I can't refer that FMDatabase. Now I just init it before I need to open it, is this normal usage?
     
  5. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #5
    Sure, it will cost more. But what is the cost? Is it significant or insignificant? I think only you can make that judgement call, based on your app and its needs. I get the feeling you are overly concerned with performance without really having enough justification as to why you should be. "I think" is not a strong enough reason; you should apply the scientific method to confirm or deny your claims.
     
  6. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #6
    You are right, I am very care about performance, because I have a lot of years software development experience, in many cases, at last There is performance problem, but at that time it is too late and difficult to make performance better.

    So I hope that I can use a better way to get better performance when it is not so complex.

    Of course, I just prompt problem and hope experience people can reply some useful suggestion, even so I don't stop to develop my app and keep doing.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    Not sure why you think that performance would be better if FMDB would put the values into a dictionary for you. FMDB is a thin layer over the sqlite database API. When you do a SELECT that results in multiple rows the values aren't really gotten from the database until you ask the FMResultSet for those values. FMResultSet isn't holding onto the values at all. And the database doesn't really fetch the values for row x until you ask it for them.

    If FMDB were to put the values from the SELECT for the current row into a dictionary this would be a convenience but I don't think it would affect performance. In fact since you know the best way to read the values out of the result set, whether by index or name, you can probably write slightly more efficient code for building the dictionary. Plus there's the question of the names of the keys. They would most naturally be the names of the columns in the database but it's possible to have joins that SELECT the same columns from multiple tables.

    FWIW, you have the complete source code to FMDB so you could add this ability if you want. Most naturally you could subclass FMResultSet to do what you're asking for. I've sent some code changes to the author of FMDB and he's accepted them, although they were mostly bug fixes.

    You already asked where to open the database, and I answered. In my app the databases are essentially documents. I have a scrolling list of documents. When the user chooses one a new view controller is pushed and I open the database in viewDidLoad of the document view controller, and close it in dealloc.
     
  8. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #8
    One performance issue that is real is that you might not want to fetch the data for rows that are never displayed. If you have a result set that has thousands of rows and you are going to display them in a tableview you might not want to fetch all the rows at one time. What I do is to fetch the rows in chunks of several hundred. If the user scrolls down then I fetch more rows. This was somewhat complicated to set up but the table view can display a database of 80000 rows with not much performance issues. The table view obviously has an index to allow the user to scroll down.
     

Share This Page