♨ SQLite를 사용하기 위해서는 헤더파일에 #import <sqlite3.h> 를 임포트 해야합니다.
#import <UIKit/UIKit.h>
#import <sqlite3.h> // SQLite 를 사용하기 위한 헤더 파일을 임포트
@interface MemoPadAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
NSString *DBName; // 데이터 베이스 이름
NSString *DBPath; // 데이터 베이스 경로
NSMutableArray *DBData; // 데이터 베이스에서 읽은 데이터를 가져온다.
BOOL isFirstTimeAccess; // 데이터 베이스에 처음으로 접속하는지 여부
NSInteger currentMemoSQLIndex;
NSInteger currentMemoRowIndex;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSString *DBName;
@property (nonatomic, retain) NSString *DBPath;
@property (nonatomic, retain) NSMutableArray *DBData;
@property (nonatomic, assign) BOOL isFirstTimeAccess;
@property (nonatomic, assign) NSInteger currentMemoSQLIndex;
@property (nonatomic, assign) NSInteger currentMemoRowIndex;
- (void)checkAndCreateDatabase; // 파일이 있는지 체크하고 없으면 생성하는 메소드
- (void)readMemoFromDatabase; // 데이터베이스에서 데이터를 읽어오는 메소드
// 데이터베이스에 메모를 저장하는 메소드
- (void)writeMemoToDatabaseWithTitle:(NSString*)inputTitle Content:(NSString*)inputContent;
// 데이터베이스의 메모를 업데이트하는 메소드
- (void)updateMemoToDatabaseWithTitle:(NSString*)inputTitle Content:(NSString*)inputContent;
// 데이터베이스에서 메모를 삭제하는 메소드
- (void)deleteMemoFromDatabase;
@end
SQLite 초기화
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 최초 엑세스 인가?
self.isFirstTimeAccess = YES;
// 앱의 파일 시스템 경로를 구한다.
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
// 데인터베이스 이름과 경로를 저장한다.
self.DBName = @"MemoPad.db";
self.DBPath = [documentsDir stringByAppendingPathComponent:self.DBName];
[self checkAndCreateDatabase];
//[self readMemoFromDatabase];
// Add the navigation controller's view to the window and display.
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
SQLite 생성
- (void)checkAndCreateDatabase {
NSFileManager *fileManager = [NSFileManager defaultManager];
// 해당 경로에 데이터 베이스 파일이 존재하는지 확인한다.
if ([fileManager fileExistsAtPath:self.DBPath]) {
return;
}
// 데이터 베이스 파일이 없다면 번들(앱에 포함된 리소스)에서 데이터 베이스 파일을 복사한다.
else {
NSString *databasePathFromApp = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:self.DBName];
[fileManager copyItemAtPath:databasePathFromApp toPath:self.DBPath error:nil];
[fileManager release];
}
}
SQLite : SELECT
- (void)readMemoFromDatabase {
sqlite3 *database;
// 데이터를 담을 오브젝트인 DBData를 초기화한다.
// 데이터베이스에 처음 엑세스하는 것이라면 alloc으로 메모리를 할당한다.
if (self.isFirstTimeAccess == YES) {
self.DBData = [[NSMutableArray alloc] init];
self.isFirstTimeAccess == NO;
}
// 처음 엑세스하는 것이 아니면 removeAllObject로 DBData를 초기화 한다.
else {
[self.DBData removeAllObjects];
}
// 데이터 베이스 파일을 연다.
if (sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {
// SQL명령을 실행한다.
const char *sqlStatement = "SELECT * FROM tblMemoPad ORDER BY MP_Index DESC";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// SQL 명령어를 실행하여 얻은 결과를 하나씩 읽는다.
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSInteger aIndex = sqlite3_column_int(compiledStatement, 0);
NSString *aTitle = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aContent = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aDate = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// 읽어온 데이터를 사용하여 MemoData 오브젝트를 생성한다.
MemoData *md = [[MemoData alloc] initWithData:aIndex Title:aTitle Content:aContent Date:aDate];
NSLog(@"%d / %@ / %@ / %@", aIndex, aTitle, aContent, aDate);
// MemoData 오브젝트를 DBData 배열에 추가한다.
[self.DBData addObject:md];
[md release];
}
}
else {
printf("could not prepare statement: %s\n", sqlite3_errmsg(database));
}
// SQL 명령을 종료한다.
sqlite3_finalize(compiledStatement);
}
// 데이터베이스를 닫는다.
sqlite3_close(database);
}
SQLite : INSERT
- (void)writeMemoToDatabaseWithTitle:(NSString *)inputTitle Content:(NSString *)inputContent {
sqlite3 *database;
// 데이터베이스 파일을 연다.
if (sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {
// SQL 명령어
const char *sqlStatement = "INSERT INTO tblMemoPad(MP_Title, MP_Content, MP_Date) VALUES(?,?,?)";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// 현재의 날짜와 시각을 얻는다.
NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *comp = [calendar components:unitFlags fromDate:date];
NSString *yearOfCommonEra = [NSString stringWithFormat:@"%02d", [comp year]];
NSString *monthOfYear = [NSString stringWithFormat:@"%02d", [comp month]];
NSString *dayOfMonth = [NSString stringWithFormat:@"%02d", [comp day]];
NSString *hourOfDay = [NSString stringWithFormat:@"%02d", [comp hour]];
NSString *minuteOfHour = [NSString stringWithFormat:@"%02d", [comp minute]];
NSString *secondOfMinute = [NSString stringWithFormat:@"%02d", [comp second]];
NSString *dateStringConcat = [NSString stringWithFormat:@"%@-%@-%@", yearOfCommonEra, monthOfYear, dayOfMonth];
NSString *timeStringConcat = [NSString stringWithFormat:@"%@:%@:%@", hourOfDay, minuteOfHour, secondOfMinute];
// 얻어낸 날짜와 시각 문자열들을 합쳐 최종적으로 하나의 문자열로 만든다.
NSString *dateTimeString = [NSString stringWithFormat:@"%@ %@", dateStringConcat, timeStringConcat];
// 전달 받은 inputTitle을 SQL 명령의 첫 번째 인자로 바인딩한다.
sqlite3_bind_text(compiledStatement, 1, [inputTitle UTF8String], -1, SQLITE_TRANSIENT);
// 전달 받은 inputContent를 SQL 명령의 두 번째 인자로 바인딩한다.
sqlite3_bind_text(compiledStatement, 2, [inputContent UTF8String], -1, SQLITE_TRANSIENT);
// 위에서 만들어낸 현재 시각 문자열을 SQL 명령의 세 번째 인자로 바인딩한다.
sqlite3_bind_text(compiledStatement, 3, [dateTimeString UTF8String], -1, SQLITE_TRANSIENT);
// SQL 명령을 실행한다.
if (SQLITE_DONE != sqlite3_step(compiledStatement)) {
NSAssert1(0, @"Error while inserting into tblMemoPad. '%s'", sqlite3_errmsg(database));
}
sqlite3_reset(compiledStatement);
// 데이터베이스를 닫는다.
sqlite3_close(database);
}
else {
printf("could not prepare statemnt: %s\n", sqlite3_errmsg(database));
}
}
else {
sqlite3_close(database);
NSAssert1(0, @"Error opening database in tblMemoPad. '%s'", sqlite3_errmsg(database));
}
}
SQLite : UPDATE
- (void)updateMemoToDatabaseWithTitle:(NSString *)inputTitle Content:(NSString *)inputContent {
sqlite3 *database;
// 데이터베이스 파일을 연다.
if (sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {
// SQL 명령어
NSString* sqlStatementNS = [[NSString alloc] initWithString:[NSString stringWithFormat:@"UPDATE tblMemoPad SET MP_Title=?, MP_Content=?, MP_Date=? WHERE MP_Index = '%d'", self.currentMemoSQLIndex]];
const char *sqlStatement = [sqlStatementNS UTF8String];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// 현재의 날짜와 시각을 얻는다.
NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *comp = [calendar components:unitFlags fromDate:date];
NSString *yearOfCommonEra = [NSString stringWithFormat:@"%02d", [comp year]];
NSString *monthOfYear = [NSString stringWithFormat:@"%02d", [comp month]];
NSString *dayOfMonth = [NSString stringWithFormat:@"%02d", [comp day]];
NSString *hourOfDay = [NSString stringWithFormat:@"%02d", [comp hour]];
NSString *minuteOfHour = [NSString stringWithFormat:@"%02d", [comp minute]];
NSString *secondOfMinute = [NSString stringWithFormat:@"%02d", [comp second]];
NSString *dateStringConcat = [NSString stringWithFormat:@"%@-%@-%@", yearOfCommonEra, monthOfYear, dayOfMonth];
NSString *timeStringConcat = [NSString stringWithFormat:@"%@:%@:%@", hourOfDay, minuteOfHour, secondOfMinute];
// 얻어낸 날짜와 시각 문자열들을 합쳐 최종적으로 하나의 문자열로 만든다.
NSString *dateTimeString = [NSString stringWithFormat:@"%@ %@", dateStringConcat, timeStringConcat];
// 전달 받은 inputTitle을 SQL 명령의 첫 번째 인자로 바인딩한다.
sqlite3_bind_text(compiledStatement, 1, [inputTitle UTF8String], -1, SQLITE_TRANSIENT);
// 전달 받은 inputContent를 SQL 명령의 두 번째 인자로 바인딩한다.
sqlite3_bind_text(compiledStatement, 2, [inputContent UTF8String], -1, SQLITE_TRANSIENT);
// 위에서 만들어낸 현재 시각 문자열을 SQL 명령의 세 번째 인자로 바인딩한다.
sqlite3_bind_text(compiledStatement, 3, [dateTimeString UTF8String], -1, SQLITE_TRANSIENT);
// SQL 명령을 실행한다.
if (SQLITE_DONE != sqlite3_step(compiledStatement)) {
NSAssert1(0, @"Error while inserting into tblMemoPad. '%s'", sqlite3_errmsg(database));
}
sqlite3_reset(compiledStatement);
// 데이터베이스를 닫는다.
sqlite3_close(database);
}
else {
printf("could not prepare statemnt: %s\n", sqlite3_errmsg(database));
}
}
else {
sqlite3_close(database);
NSAssert1(0, @"Error opening database in tblLocationHistory. '%s'", sqlite3_errmsg(database));
}
}
SQLite : DELETE
- (void)deleteMemoFromDatabase {
sqlite3 *database;
// 데이터베이스 파일을 연다.
if(sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {
// SQL 명령어
NSString* sqlStatementNS = [[NSString alloc] initWithString:[NSString stringWithFormat:@"DELETE FROM tblMemoPad WHERE MP_Index = '%d'", self.currentMemoSQLIndex]];
const char *sqlStatement = [sqlStatementNS UTF8String];
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
if (SQLITE_DONE != sqlite3_step(compiledStatement)) {
NSAssert1(0,@"Error while inserting into tblMemoPad. '%s'", sqlite3_errmsg(database));
}
sqlite3_reset(compiledStatement);
}
sqlite3_finalize(compiledStatement);
[sqlStatementNS release];
}
sqlite3_close(database);
}