more clang fixes
[fmdb.git] / src / fmdb.m
blobb9d181bd83d1934155a8edc5ed3f8d421c0be29b
1 #import <Foundation/Foundation.h>
2 #import "FMDatabase.h"
3 #import "FMDatabaseAdditions.h"
5 int main (int argc, const char * argv[]) {
6     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
7     
8     // delete the old db.
9     NSFileManager *fileManager = [NSFileManager defaultManager];
10     [fileManager removeFileAtPath:@"/tmp/tmp.db" handler:nil];
11     
12     FMDatabase* db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
13     if (![db open]) {
14         NSLog(@"Could not open db.");
15         [pool release];
16         return 0;
17     }
18     
19     // kind of experimentalish.
20     [db setShouldCacheStatements:YES];
21     
22     // create a bad statement, just to test the error code.
23     [db executeUpdate:@"blah blah blah"];
24     if ([db hadError]) {
25         NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
26     }
27     
28     // but of course, I don't bother checking the error codes below.
29     // Bad programmer, no cookie.
30     
31     [db executeUpdate:@"create table test (a text, b text, c integer, d double, e double)"];
32     
33     
34     [db beginTransaction];
35     int i = 0;
36     while (i++ < 20) {
37         [db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,
38             @"hi'", // look!  I put in a ', and I'm not escaping it!
39             [NSString stringWithFormat:@"number %d", i],
40             [NSNumber numberWithInt:i],
41             [NSDate date],
42             [NSNumber numberWithFloat:2.2f]];
43     }
44     [db commit];
45     
46     
47     
48     // do it again, just because
49     [db beginTransaction];
50     i = 0;
51     while (i++ < 20) {
52         [db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,
53          @"hi again'", // look!  I put in a ', and I'm not escaping it!
54          [NSString stringWithFormat:@"number %d", i],
55          [NSNumber numberWithInt:i],
56          [NSDate date],
57          [NSNumber numberWithFloat:2.2f]];
58     }
59     [db commit];
60     
61     
62     
63     
64     
65     FMResultSet *rs = [db executeQuery:@"select rowid,* from test where a = ?", @"hi'"];
66     while ([rs next]) {
67         // just print out what we've got in a number of formats.
68         NSLog(@"%d %@ %@ %@ %@ %f %f",
69               [rs intForColumn:@"c"],
70               [rs stringForColumn:@"b"],
71               [rs stringForColumn:@"a"],
72               [rs stringForColumn:@"rowid"],
73               [rs dateForColumn:@"d"],
74               [rs doubleForColumn:@"d"],
75               [rs doubleForColumn:@"e"]);
76     }
77     // close the result set.
78     // it'll also close when it's dealloc'd, but we're closing the database before
79     // the autorelease pool closes, so sqlite will complain about it.
80     [rs close];  
81     
82     // ----------------------------------------------------------------------------------------
83     // blob support.
84     [db executeUpdate:@"create table blobTable (a text, b blob)"];
85     
86     // let's read in an image from safari's app bundle.
87     NSData *d = [NSData dataWithContentsOfFile:@"/Applications/Safari.app/Contents/Resources/compass.icns"];
88     if (d) {
89         [db executeUpdate:@"insert into blobTable (a, b) values (?,?)", @"safari's compass", d];
90         
91         rs = [db executeQuery:@"select b from blobTable where a = ?", @"safari's compass"];
92         if ([rs next]) {
93             d = [rs dataForColumn:@"b"];
94             [d writeToFile:@"/tmp/compass.icns" atomically:NO];
95             
96             // let's look at our fancy image that we just wrote out..
97             system("/usr/bin/open /tmp/compass.icns");
98         }
99         else {
100             NSLog(@"Could not select image.");
101         }
102         
103         [rs close];
104         
105     }
106     else {
107         NSLog(@"Can't find compass image..");
108     }
109     
110     
111     // test out the convenience methods in +Additions
112     [db executeUpdate:@"create table t1 (a integer)"];
113     [db executeUpdate:@"insert into t1 values (?)", [NSNumber numberWithInt:5]];
114     int a = [db intForQuery:@"select a from t1 where a = ?", [NSNumber numberWithInt:5]];
115     if (a != 5) {
116         NSLog(@"intForQuery didn't work (a != 5)");
117     }
118     
119     // test the busy rety timeout schtuff.
120     
121     [db setBusyRetryTimeout:50000];
122     
123     FMDatabase *newDb = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
124     [newDb open];
125     
126     rs = [newDb executeQuery:@"select rowid,* from test where a = ?", @"hi'"];
127     [rs next]; // just grab one... which will keep the db locked.
128     
129     NSLog(@"Testing the busy timeout");
130     
131     BOOL success = [db executeUpdate:@"insert into t1 values (5)"];
132     
133     if (success) {
134         NSLog(@"Whoa- the database didn't stay locked!");
135         return 7;
136     }
137     else {
138         NSLog(@"Hurray, our timeout worked");
139     }
140     
141     [rs close];
142     [newDb close];
143     
144     success = [db executeUpdate:@"insert into t1 values (5)"];
145     if (!success) {
146         NSLog(@"Whoa- the database shouldn't be locked!");
147         return 8;
148     }
149     else {
150         NSLog(@"Hurray, we can insert again!");
151     }
152     
153     
154     
155     // test some nullness.
156     [db executeUpdate:@"create table t2 (a integer, b integer)"];
157     
158     if (![db executeUpdate:@"insert into t2 values (?, ?)", nil, [NSNumber numberWithInt:5]]) {
159         NSLog(@"UH OH, can't insert a nil value for some reason...");
160     }
161     
162     
163     
164     
165     rs = [db executeQuery:@"select * from t2"];
166     while ([rs next]) {
167         NSString *a = [rs stringForColumnIndex:0];
168         NSString *b = [rs stringForColumnIndex:1];
169         
170         if (a != nil) {
171             NSLog(@"%s:%d", __FUNCTION__, __LINE__);
172             NSLog(@"OH OH, PROBLEMO!");
173             return 10;
174         }
175         else {
176             NSLog(@"YAY, NULL VALUES");
177         }
178         
179         if (![b isEqualToString:@"5"]) {
180             NSLog(@"%s:%d", __FUNCTION__, __LINE__);
181             NSLog(@"OH OH, PROBLEMO!");
182             return 10;
183         }
184     }
185     
186     
187     
188     
189     
190     
191     
192     
193     
194     
195     // test some inner loop funkness.
196     [db executeUpdate:@"create table t3 (a somevalue)"];
197     
198     
199     // do it again, just because
200     [db beginTransaction];
201     i = 0;
202     while (i++ < 20) {
203         [db executeUpdate:@"insert into t3 (a) values (?)" , [NSNumber numberWithInt:i]];
204     }
205     [db commit];
206     
207     
208     
209     
210     rs = [db executeQuery:@"select * from t3"];
211     while ([rs next]) {
212         int foo = [rs intForColumnIndex:0];
213         
214         int newVal = foo + 100;
215         
216         [db executeUpdate:@"update t3 set a = ? where a = ?" , [NSNumber numberWithInt:newVal], [NSNumber numberWithInt:foo]];
217         
218         
219         FMResultSet *rs2 = [db executeQuery:@"select a from t3 where a = ?", [NSNumber numberWithInt:newVal]];
220         [rs2 next];
221         
222         if ([rs2 intForColumnIndex:0] != newVal) {
223             NSLog(@"Oh crap, our update didn't work out!");
224             return 9;
225         }
226         
227         [rs2 close];
228     }
229     
230     
231     
232     
233     
234     
235     
236     
237     
238     
239     // NSNull tests
240     [db executeUpdate:@"create table nulltest (a text, b text)"];
241     
242     [db executeUpdate:@"insert into nulltest (a, b) values (?, ?)" , [NSNull null], @"a"];
243     [db executeUpdate:@"insert into nulltest (a, b) values (?, ?)" , nil, @"b"];
244     
245     rs = [db executeQuery:@"select * from nulltest"];
246     
247     while ([rs next]) {
248         
249         NSString *a = [rs stringForColumnIndex:0];
250         NSString *b = [rs stringForColumnIndex:1];
251         
252         if (!b) {
253             NSLog(@"Oh crap, the nil / null inserts didn't work!");
254             return 10;
255         }
256         
257         if (a) {
258             NSLog(@"Oh crap, the nil / null inserts didn't work (son of error message)!");
259             return 11;
260         }
261         else {
262             NSLog(@"HURRAH FOR NSNULL (and nil)!");
263         }
264     }
265     
266     
267     
268     
269     
270     
271     
272     
273     
274     
275     
276     
277     
278     
279     
280     // print out some stats if we are using cached statements.
281     if ([db shouldCacheStatements]) {
282         
283         NSEnumerator *e = [[db cachedStatements] objectEnumerator];;
284         FMStatement *statement;
285         
286         while ((statement = [e nextObject])) {
287                 NSLog(@"%@", statement);
288         }
289     }
290     
291     
292     
293     
294     
295     
296     
297     
298     
299     
300     
301     
302     
303     
304     [db close];
305     
306     [pool release];
307     return 0;