본문 바로가기

프로그래밍/아이폰 프로그래밍

23. SQLite 쿼리문 사용하기

 
 

♨ 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);

}