MOBILE

iphone SDK 3 : Working with Databases - Retrieving BLOBs

1/19/2014 8:40:49 PM

In the previous section, we saw how we can populate a table with records containing BLOB columns. In this section, we will learn how we can retrieve these BLOB columns. The presentation will use the same companies table populated before.

Listing 1 shows the main() function used to demonstrate the retrieval of BLOBs. What we would like to do is to retrieve these images and write them to the file system with a different name. The main() function opens the database and retrieves the images by invoking the retrieveCompany() function shown in Listing 2.

Example 1. The main() function demonstrating the retrieval of BLOB columns from a database.
int main(int argc, char* argv[]) {
sqlite3 *pDb;
int returnCode;
char *databaseName;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
databaseName = "financial.db";
returnCode = sqlite3_open(databaseName, &pDb);
if(returnCode!=SQLITE_OK) {
fprintf(stderr,"Error in opening the database. Error: %s",
sqlite3_errmsg(pDb));
sqlite3_close(pDb);
return −1;

}
retrieveCompany(pDb, "ALU");
retrieveCompany(pDb, "GOOG");
retrieveCompany(pDb, "MSFT");
retrieveCompany(pDb, "NT");
sqlite3_close(pDb);
[pool release];
return 0;
}

We start by preparing the following parametrized SQL statement:

SELECT image FROM companies WHERE symbol = ?

After that, we bind the sole parameter with the symbol parameter of the function. Note that we could have just used sqlite3_mprintf() to do that job without using parametrized queries. We then execute the query and check for a row result. Since there should be at most one record (the symbol is a primary key), we retrieve the BLOB column value at most once. We use NSData as a wrapper of the image bytes as in the following statement:

NSData * pData =
[NSData dataWithBytes:sqlite3_column_blob(pStmt, 0)
length:sqlite3_column_bytes(pStmt, 0)];

The class method dataWithBytes:length: is declared as follows:

+(id)dataWithBytes:(const void* )bytes length:(NSUInteger)length

It takes the bytes and length as two parameters. To retrieve the BLOB bytes from the column result, we use the function sqlite3_column_blob(). This function takes a pointer to the statement handle we received when we invoked the sqlite3_prepare_v2() function and the column index (starting from 0). The length of the BLOB bytes can be retrieved by the function sqlite3_column_bytes().

Once we have retrieved the image from the database and have used an NSData instance as a wrapper around it, we can use the NSData's instance method writeToFile:atomically: to write the contents of this data to a file. The method is declared as:

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile

In addition to the file path, the useAuxiliaryFile is used to specify whether a temporary file should be used. If the value is YES, the data will be written first to a temporary file and then that temporary file will be renamed to the new name. Once we have written the file, we finalize the statement and return from the function.

Example 2. The retrieveCompany() function used to retrieve BLOB images from the database and write them back to the file system.
#import "/usr/include/sqlite3.h"
void retrieveCompany(sqlite3 *pDb, const char* symbol){


int             returnCode;
sqlite3_stmt *pStmt;
char *st = "SELECT image FROM companies WHERE symbol = ?";
returnCode = sqlite3_prepare_v2(pDb, st, −1, &pStmt, 0);
if(returnCode!=SQLITE_OK) {
fprintf(stderr, "Error retrieving image from companies.");
return;
}
sqlite3_bind_text(pStmt, 1, symbol, −1, SQLITE_STATIC);
returnCode = sqlite3_step(pStmt);
if(returnCode == SQLITE_ROW){
NSData * pData =
[NSData dataWithBytes:sqlite3_column_blob(pStmt, 0)
length:sqlite3_column_bytes(pStmt, 0)];
NSMutableString *imageFileName =
[NSMutableString stringWithCString:symbol];
[imageFileName appendString:@"−2.png"];
[pData writeToFile:imageFileName atomically:YES];
}
returnCode = sqlite3_finalize(pStmt);
if(returnCode != SQLITE_OK) {
fprintf(stderr, "Error inserting into companies.");
}
}


Other  
 
Video
PS4 game trailer XBox One game trailer
WiiU game trailer 3ds game trailer
Top 10 Video Game
-   Forza Horizon 2 [X360/XOne] Porsche Expansion
-   NBA Live 16 [PS4/XOne] Cover Athlete
-   Tom Clancy’s The Division | Community Q&A
-   Victor Vran [PC] Race To Release
-   GTA 5 Skyfall Cheat Demo
-   GTA 5 Moon Gravity Cheat Demo
-   GTA 5 Spawn Buzzard Cheat Demo
-   GTA 5 Super Jump Cheat Demo
-   GTA 5 Explosive Melee Attacks Cheat Demo
-   Blood Bowl II [PS4/XOne/PC] Campaign
-   verybody's Gone to the Rapture I Launch Date Announcement
-   Halo 5: Guardians | Master Chief Teaser