I need to read an sqlite database generated by others. So I wrote an outer loop which steps through the rows of a table using sqlite3_step, and an inner loop which steps through the columns. The inner loop finds the type using sqlite3_column_type(), then 'switches' to get the value using the appropriate sqlite3_column_XXXXX() function.

It works fine if, when encountering an SQLITE_INTEGER type, I use sqlite_column_int64() to get the data.

I don't know whether or not I'm just "lucky" that the application which wrote the database uses 64 bit for all of its integers? If so, what if someone throws a 32-bit integer at me someday? How can I tell whether integer data objects in a table are 32 or 64 bit? The column specifications I get from pragma_table_info() are likewise uninformative, saying simply type=INTEGER.

Thanks again,

Jerry Krinock


// Method Implementation (Objective-C for Mac OS X)

- (NSArray*)dicsOfRowsInTable:(NSString*)table {
    // Will return nil if fails, empty array if no rows
    void* db = [self db] ;
    //char* errMsg = NULL ;
    int result ;

NSString* statement = [[NSString alloc] initWithFormat:@"SELECT * FROM '%@'", table] ;

    // Compile the statement into a virtual machine
    sqlite3_stmt* preparedStatement ;
result = sqlite3_prepare(db, [statement UTF8String], -1, &preparedStatement, NULL) ;
    [statement release] ;

    NSArray* output = nil ;
    if (result != SQLITE_OK) {
        [self showError:"prepare" from:11 code:result] ;
    }
    else {
        NSMutableArray* rowDics = [[NSMutableArray alloc] init] ;
        NSArray* keys = [self keysInTable:table] ;
        int nColumns = [keys count] ;
while (result = sqlite3_step(preparedStatement) == SQLITE_ROW) { NSMutableDictionary* rowDic = [[NSMutableDictionary alloc] init] ;

            int iColumn  ;
            for (iColumn= 0; iColumn<nColumns; iColumn++) {
int type = sqlite3_column_type(preparedStatement, iColumn) ; // The sqlite3_column_type() routine returns datatype code
                // for the initial data type of the result column.
                // The returned value is one of SQLITE_INTEGER,
// SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL

                // Initialize to null in case object is not found
                const void* pFirstByte = NULL ;
                int nBytes = 0 ;
                id object = nil ;
                long long int intValue ;
                const unsigned char* utf8String ;
                double doubleValue ;
                switch(type) {
                    case SQLITE_BLOB:
nBytes = sqlite3_column_bytes(preparedStatement, iColumn) ; // "The return value from sqlite3_column_blob() for a zero-length // blob is an arbitrary pointer, possibly even a NULL pointer."
                        // Therefore, we qualify...
                        if (nBytes > 0) {
pFirstByte = sqlite3_column_blob(preparedStatement, iColumn) ; object = [[NSData alloc] initWithBytes:pFirstByte length:nBytes] ;
                        }
                        break ;
                    case SQLITE_INTEGER:
intValue = sqlite3_column_int64(preparedStatement, iColumn) ; object = [NSNumber numberWithLongLong:intValue] ;
                        break ;
                    case SQLITE_TEXT:
// "Strings returned by sqlite3_column_text() and sqlite3_column_text16(), // even zero-length strings, are always zero terminated."
                        // So, we ignore the length and just convert it
utf8String = sqlite3_column_text(preparedStatement, iColumn) ; object = [NSString stringWithUTF8String: (char*)utf8String] ;
                        break ;
                    case SQLITE_FLOAT:
doubleValue = sqlite3_column_double(preparedStatement, iColumn) ; object = [NSNumber numberWithDouble:doubleValue] ;
                        break ;
                    case SQLITE_NULL:
                    default:
// Just leave object nil, will replace with [NSNull null] soon.
                        ;
                }

                if (object == nil) {
                    object = [NSNull null] ;
                }

[rowDic setObject:object forKey:[keys objectAtIndex:iColumn]] ;
            }

            NSDictionary* rowDicCopy = [rowDic copy] ;
            [rowDics addObject:rowDicCopy] ;
            [rowDicCopy release] ;
        }

        output = [rowDics copy] ;
        [rowDics release] ;
    }

// Finalize the statement (this releases resources allocated by sqlite3_prepare()
    result = sqlite3_finalize(preparedStatement) ;
    if (result != SQLITE_OK) {
        [self showError:"finalize" from:13 code:result] ;
    }

    return [output autorelease] ;
}


-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to