fixed a problemo which kept it from compiling on the iphone.
[fmdb.git] / src / FMResultSet.m
blob04455823bad52f3f13911bc324f6b06a2bfb180e
1 #import "FMResultSet.h"
2 #import "FMDatabase.h"
4 @interface FMResultSet (Private)
5 - (NSMutableDictionary *)columnNameToIndexMap;
6 - (void)setColumnNameToIndexMap:(NSMutableDictionary *)value;
7 @end
9 @implementation FMResultSet
11 + (id) resultSetWithStatement:(FMStatement *)statement usingParentDatabase:(FMDatabase*)aDB {
12     
13     FMResultSet *rs = [[FMResultSet alloc] init];
14     
15     [rs setStatement:statement];
16     [rs setParentDB:aDB];
17     
18     return [rs autorelease];
21 - (id)init {
22         self = [super init];
23     if (self) {
24         [self setColumnNameToIndexMap:[NSMutableDictionary dictionary]];
25     }
26         
27         return self;
31 - (void)dealloc {
32     [self close];
33     
34     [query release];
35     query = nil;
36     
37     [columnNameToIndexMap release];
38     columnNameToIndexMap = nil;
39     
40         [super dealloc];
43 - (void) close {
44     
45     [statement reset];
46     [statement release];
47     statement = nil;
48     
49     [parentDB setInUse:NO];
52 - (void) setupColumnNames {
53     
54     int columnCount = sqlite3_column_count(statement.statement);
55     
56     int columnIdx = 0;
57     for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
58         [columnNameToIndexMap setObject:[NSNumber numberWithInt:columnIdx]
59                                  forKey:[[NSString stringWithUTF8String:sqlite3_column_name(statement.statement, columnIdx)] lowercaseString]];
60     }
61     columnNamesSetup = YES;
64 - (void) kvcMagic:(id)object {
65     
66     
67     int columnCount = sqlite3_column_count(statement.statement);
68     
69     int columnIdx = 0;
70     for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
71         
72         
73         const char *c = (const char *)sqlite3_column_text(statement.statement, columnIdx);
74         
75         // check for a null row
76         if (c) {
77             NSString *s = [NSString stringWithUTF8String:c];
78             
79             [object setValue:s forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement.statement, columnIdx)]];
80         }
81     }
84 - (BOOL) next {
85     
86     int rc;
87     BOOL retry;
88     int numberOfRetries = 0;
89     do {
90         retry = NO;
91         
92         rc = sqlite3_step(statement.statement);
93         
94         if (SQLITE_BUSY == rc) {
95             // this will happen if the db is locked, like if we are doing an update or insert.
96             // in that case, retry the step... and maybe wait just 10 milliseconds.
97             retry = YES;
98             usleep(20);
99             
100             if ([parentDB busyRetryTimeout] && (numberOfRetries++ > [parentDB busyRetryTimeout])) {
101                 
102                 NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [parentDB databasePath]);
103                 NSLog(@"Database busy");
104                 break;
105             }
106         }
107         else if (SQLITE_DONE == rc || SQLITE_ROW == rc) {
108             // all is well, let's return.
109         }
110         else if (SQLITE_ERROR == rc) {
111             NSLog(@"Error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([parentDB sqliteHandle]));
112             break;
113         } 
114         else if (SQLITE_MISUSE == rc) {
115             // uh oh.
116             NSLog(@"Error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([parentDB sqliteHandle]));
117             break;
118         }
119         else {
120             // wtf?
121             NSLog(@"Unknown error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([parentDB sqliteHandle]));
122             break;
123         }
124         
125     } while (retry);
126     
127     
128     if (rc != SQLITE_ROW) {
129         [self close];
130     }
131     
132     return (rc == SQLITE_ROW);
135 - (int) columnIndexForName:(NSString*)columnName {
136     
137     if (!columnNamesSetup) {
138         [self setupColumnNames];
139     }
140     
141     columnName = [columnName lowercaseString];
142     
143     NSNumber *n = [columnNameToIndexMap objectForKey:columnName];
144     
145     if (n) {
146         return [n intValue];
147     }
148     
149     NSLog(@"Warning: I could not find the column named '%@'.", columnName);
150     
151     return -1;
156 - (int) intForColumn:(NSString*)columnName {
157     
158     if (!columnNamesSetup) {
159         [self setupColumnNames];
160     }
161     
162     int columnIdx = [self columnIndexForName:columnName];
163     
164     if (columnIdx == -1) {
165         return 0;
166     }
167     
168     return sqlite3_column_int(statement.statement, columnIdx);
170 - (int) intForColumnIndex:(int)columnIdx {
171     return sqlite3_column_int(statement.statement, columnIdx);
174 - (long) longForColumn:(NSString*)columnName {
175     
176     if (!columnNamesSetup) {
177         [self setupColumnNames];
178     }
179     
180     int columnIdx = [self columnIndexForName:columnName];
181     
182     if (columnIdx == -1) {
183         return 0;
184     }
185     
186     return sqlite3_column_int64(statement.statement, columnIdx);
189 - (long) longForColumnIndex:(int)columnIdx {
190     return sqlite3_column_int64(statement.statement, columnIdx);
193 - (BOOL) boolForColumn:(NSString*)columnName {
194     return ([self intForColumn:columnName] != 0);
197 - (BOOL) boolForColumnIndex:(int)columnIdx {
198     return ([self intForColumnIndex:columnIdx] != 0);
201 - (double) doubleForColumn:(NSString*)columnName {
202     
203     if (!columnNamesSetup) {
204         [self setupColumnNames];
205     }
206     
207     int columnIdx = [self columnIndexForName:columnName];
208     
209     if (columnIdx == -1) {
210         return 0;
211     }
212     
213     return sqlite3_column_double(statement.statement, columnIdx);
216 - (double) doubleForColumnIndex:(int)columnIdx {
217     return sqlite3_column_double(statement.statement, columnIdx);
221 #pragma mark string functions
223 - (NSString*) stringForColumnIndex:(int)columnIdx {
224     
225     const char *c = (const char *)sqlite3_column_text(statement.statement, columnIdx);
226     
227     if (!c) {
228         // null row.
229         return nil;
230     }
231     
232     return [NSString stringWithUTF8String:c];
235 - (NSString*) stringForColumn:(NSString*)columnName {
236     
237     if (!columnNamesSetup) {
238         [self setupColumnNames];
239     }
240     
241     int columnIdx = [self columnIndexForName:columnName];
242     
243     if (columnIdx == -1) {
244         return nil;
245     }
246     
247     return [self stringForColumnIndex:columnIdx];
253 - (NSDate*) dateForColumn:(NSString*)columnName {
254     
255     if (!columnNamesSetup) {
256         [self setupColumnNames];
257     }
258     
259     int columnIdx = [self columnIndexForName:columnName];
260     
261     if (columnIdx == -1) {
262         return nil;
263     }
264     
265     return [NSDate dateWithTimeIntervalSince1970:[self doubleForColumn:columnName]];
268 - (NSDate*) dateForColumnIndex:(int)columnIdx {
269     return [NSDate dateWithTimeIntervalSince1970:[self doubleForColumnIndex:columnIdx]];
273 - (NSData*) dataForColumn:(NSString*)columnName {
274     
275     if (!columnNamesSetup) {
276         [self setupColumnNames];
277     }
278     
279     int columnIdx = [self columnIndexForName:columnName];
280     
281     if (columnIdx == -1) {
282         return nil;
283     }
284     
285     int dataSize = sqlite3_column_bytes(statement.statement, columnIdx);
286     
287     NSMutableData *data = [NSMutableData dataWithLength:dataSize];
288     
289     memcpy([data mutableBytes], sqlite3_column_blob(statement.statement, columnIdx), dataSize);
290     
291     return data;
294 - (NSData*) dataForColumnIndex:(int)columnIdx {
295     
296     int dataSize = sqlite3_column_bytes(statement.statement, columnIdx);
297     
298     NSMutableData *data = [NSMutableData dataWithLength:dataSize];
299     
300     memcpy([data mutableBytes], sqlite3_column_blob(statement.statement, columnIdx), dataSize);
301     
302     return data;
306 - (void)setParentDB:(FMDatabase *)newDb {
307     parentDB = newDb;
311 - (NSString *)query {
312     return query;
315 - (void)setQuery:(NSString *)value {
316     [value retain];
317     [query release];
318     query = value;
321 - (NSMutableDictionary *)columnNameToIndexMap {
322     return columnNameToIndexMap;
325 - (void)setColumnNameToIndexMap:(NSMutableDictionary *)value {
326     [value retain];
327     [columnNameToIndexMap release];
328     columnNameToIndexMap = value;
331 - (FMStatement *) statement {
332     return statement;
335 - (void)setStatement:(FMStatement *)value {
336     if (statement != value) {
337         [statement release];
338         statement = [value retain];
339     }
344 @end