Skip to content

Commit 607458b

Browse files
committed
added dump export method and project example
1 parent d3d73dc commit 607458b

14 files changed

+3330
-8
lines changed

SQLiteManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ enum errorCodes {
3232
- (NSArray *) getRowsForQuery:(NSString *)sql;
3333
- (NSError *) closeDatabase;
3434

35+
- (NSString *)getDatabaseDump;
3536

3637
@end

SQLiteManager.m

Lines changed: 118 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ - (NSArray *)getRowsForQuery:(NSString *)sql {
146146

147147
while (sqlite3_step(statement) == SQLITE_ROW) {
148148
int columns = sqlite3_column_count(statement);
149-
NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:1];
149+
NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:columns];
150150

151151
for (int i = 0; i<columns; i++) {
152152
const char *name = sqlite3_column_name(statement, i);
@@ -178,7 +178,7 @@ - (NSArray *)getRowsForQuery:(NSString *)sql {
178178
case SQLITE_BLOB:
179179
break;
180180
case SQLITE_NULL:
181-
[result setObject:nil forKey:columnName];
181+
[result setObject:[NSNull null] forKey:columnName];
182182
break;
183183

184184
default:
@@ -200,6 +200,8 @@ - (NSArray *)getRowsForQuery:(NSString *)sql {
200200
} //end while
201201
sqlite3_finalize(statement);
202202

203+
[self closeDatabase];
204+
203205
return resultsArray;
204206

205207
}
@@ -215,17 +217,125 @@ - (NSError *) closeDatabase {
215217

216218
NSError *error = nil;
217219

218-
if (sqlite3_close(db) != SQLITE_OK){
219-
const char *errorMsg = sqlite3_errmsg(db);
220-
NSString *errorStr = [NSString stringWithFormat:@"The database could not be closed: %@",[NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding]];
221-
error = [self createDBErrorWithDescription:errorStr andCode:kDBFailAtClose];
222-
}
223220

224-
db = nil;
221+
if (db != nil) {
222+
if (sqlite3_close(db) != SQLITE_OK){
223+
const char *errorMsg = sqlite3_errmsg(db);
224+
NSString *errorStr = [NSString stringWithFormat:@"The database could not be closed: %@",[NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding]];
225+
error = [self createDBErrorWithDescription:errorStr andCode:kDBFailAtClose];
226+
}
227+
228+
db = nil;
229+
}
225230

226231
return error;
227232
}
228233

234+
235+
/**
236+
* Creates an SQL dump of the database.
237+
*
238+
* This method could get a csv format dump with a few changes.
239+
* But i prefer working with sql dumps ;)
240+
*
241+
* @return an NSString containing the dump.
242+
*/
243+
244+
- (NSString *)getDatabaseDump {
245+
246+
NSMutableString *dump = [[NSMutableString alloc] initWithCapacity:256];
247+
248+
// info string ;) please do not remove it
249+
[dump appendString:@";\n; Dump generated with SQLiteManager4iOS \n;\n; By Misato (2011)\n"];
250+
[dump appendString:[NSString stringWithFormat:@"; database %@;\n", databaseName]];
251+
252+
// first get all table information
253+
254+
NSArray *rows = [self getRowsForQuery:@"SELECT * FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"];
255+
// last sql query returns something like:
256+
// {
257+
// name = users;
258+
// rootpage = 2;
259+
// sql = "CREATE TABLE users (id integer primary key autoincrement, user text, password text)";
260+
// "tbl_name" = users;
261+
// type = table;
262+
// }
263+
264+
//loop through all tables
265+
for (int i = 0; i<[rows count]; i++) {
266+
267+
NSDictionary *obj = [rows objectAtIndex:i];
268+
//get sql "create table" sentence
269+
NSString *sql = [obj objectForKey:@"sql"];
270+
[dump appendString:[NSString stringWithFormat:@"%@;\n",sql]];
271+
272+
//get table name
273+
NSString *tableName = [obj objectForKey:@"name"];
274+
275+
//get all table content
276+
NSArray *tableContent = [self getRowsForQuery:[NSString stringWithFormat:@"SELECT * FROM %@",tableName]];
277+
278+
for (int j = 0; j<[tableContent count]; j++) {
279+
NSDictionary *item = [tableContent objectAtIndex:j];
280+
281+
//keys are column names
282+
NSArray *keys = [item allKeys];
283+
284+
//values are column values
285+
NSArray *values = [item allValues];
286+
287+
//start constructing insert statement for this item
288+
[dump appendString:[NSString stringWithFormat:@"insert into %@ (",tableName]];
289+
290+
//loop through all keys (aka column names)
291+
NSEnumerator *enumerator = [keys objectEnumerator];
292+
id obj;
293+
while (obj = [enumerator nextObject]) {
294+
[dump appendString:[NSString stringWithFormat:@"%@,",obj]];
295+
}
296+
297+
//delete last comma
298+
NSRange range;
299+
range.length = 1;
300+
range.location = [dump length]-1;
301+
[dump deleteCharactersInRange:range];
302+
[dump appendString:@") values ("];
303+
304+
// loop through all values
305+
// value types could be:
306+
// NSNumber for integer and floats, NSNull for null or NSString for text.
307+
308+
enumerator = [values objectEnumerator];
309+
while (obj = [enumerator nextObject]) {
310+
//if it's a number (integer or float)
311+
if ([obj isKindOfClass:[NSNumber class]]){
312+
[dump appendString:[NSString stringWithFormat:@"%@,",[obj stringValue]]];
313+
}
314+
//if it's a null
315+
else if ([obj isKindOfClass:[NSNull class]]){
316+
[dump appendString:@"null,"];
317+
}
318+
//else is a string ;)
319+
else{
320+
[dump appendString:[NSString stringWithFormat:@"'%@',",obj]];
321+
}
322+
323+
}
324+
325+
//delete last comma again
326+
range.length = 1;
327+
range.location = [dump length]-1;
328+
[dump deleteCharactersInRange:range];
329+
330+
//finish our insert statement
331+
[dump appendString:@");\n"];
332+
333+
}
334+
335+
}
336+
return dump;
337+
}
338+
229339
@end
230340

231341

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// UntitledAppDelegate.h
3+
// Untitled
4+
//
5+
// Created by Ester Sanchez on 10/03/11.
6+
// Copyright 2011 Dinamica Studios. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
@class UntitledViewController;
12+
13+
@interface UntitledAppDelegate : NSObject <UIApplicationDelegate> {
14+
UIWindow *window;
15+
UntitledViewController *viewController;
16+
}
17+
18+
@property (nonatomic, retain) IBOutlet UIWindow *window;
19+
@property (nonatomic, retain) IBOutlet UntitledViewController *viewController;
20+
21+
@end
22+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//
2+
// UntitledAppDelegate.m
3+
// Untitled
4+
//
5+
// Created by Ester Sanchez on 10/03/11.
6+
// Copyright 2011 Dinamica Studios. All rights reserved.
7+
//
8+
9+
#import "UntitledAppDelegate.h"
10+
#import "UntitledViewController.h"
11+
12+
@implementation UntitledAppDelegate
13+
14+
@synthesize window;
15+
@synthesize viewController;
16+
17+
18+
#pragma mark -
19+
#pragma mark Application lifecycle
20+
21+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
22+
23+
// Override point for customization after application launch.
24+
25+
// Add the view controller's view to the window and display.
26+
[self.window addSubview:viewController.view];
27+
[self.window makeKeyAndVisible];
28+
29+
return YES;
30+
}
31+
32+
33+
- (void)applicationWillResignActive:(UIApplication *)application {
34+
/*
35+
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
36+
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
37+
*/
38+
}
39+
40+
41+
- (void)applicationDidEnterBackground:(UIApplication *)application {
42+
/*
43+
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
44+
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
45+
*/
46+
}
47+
48+
49+
- (void)applicationWillEnterForeground:(UIApplication *)application {
50+
/*
51+
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
52+
*/
53+
}
54+
55+
56+
- (void)applicationDidBecomeActive:(UIApplication *)application {
57+
/*
58+
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
59+
*/
60+
}
61+
62+
63+
- (void)applicationWillTerminate:(UIApplication *)application {
64+
/*
65+
Called when the application is about to terminate.
66+
See also applicationDidEnterBackground:.
67+
*/
68+
}
69+
70+
71+
#pragma mark -
72+
#pragma mark Memory management
73+
74+
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
75+
/*
76+
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
77+
*/
78+
}
79+
80+
81+
- (void)dealloc {
82+
[viewController release];
83+
[window release];
84+
[super dealloc];
85+
}
86+
87+
88+
@end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// UntitledViewController.h
3+
// Untitled
4+
//
5+
// Created by Ester Sanchez on 10/03/11.
6+
// Copyright 2011 Dinamica Studios. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
#import "SQLiteManager.h"
11+
12+
13+
@interface UntitledViewController : UIViewController {
14+
15+
SQLiteManager *dbManager;
16+
17+
IBOutlet UITextView *textView;
18+
}
19+
20+
@property (nonatomic, retain) IBOutlet UITextView *textView;
21+
22+
- (IBAction) addTable;
23+
- (IBAction) addUser;
24+
25+
@end
26+

0 commit comments

Comments
 (0)