DirTy™의 하루일과/DirTy™의 가당찮은iOS

[IOS] sqlite 사용하기

DirTy™ 2015. 1. 12. 15:06

처음 아이폰 프로그래밍을 접하고 가장 많이 하는것이 아마도 네비게이션 컨트롤러 위에 테이블뷰를 넣고 테이블뷰위에 데이터를 뿌리는 걸 가장 많이 하는것 같다.


실무에서도 많이쓰이고 구조를 이해하는데 이것만큼 좋은것이 없다고 생각된다.

테이블뷰위에 뿌려지는 데이터를 어딘가에 저장하고 싶어지기 마련인데 가장 많이 사용되는것이 sqlite일것 이라 판단된다.(나도 이것밖에 사용해본적이 없다.)


아래와같이 구현하였고 현재 이렇게 상용앱에서도 사용중이다.

일단 libraries 에 libsqlite3.dylib 을 추가해준다.


// 데이터베이스를 확인하고 없다면 생성한다.

- (void)checkAndCreateDatabase {

    NSString *docsDir;

    NSArray *dirPaths;

    

    // Get the documents directory

    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    

    docsDir = [dirPaths objectAtIndex:0];

    

    // Build the path to the database file

    databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];

    

    NSFileManager *filemgr = [NSFileManager defaultManager];

    

    if ([filemgr fileExistsAtPath: databasePath ] == NO) {

const char *dbpath = [databasePath UTF8String];

        

        if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {

            char *errMsg;

            const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, MESSAGE TEXT, TYPE TEXT, BSEQNO TEXT, SCHOOLNUMBER TEXT, SENDTIME TEXT, IID INTEGER)";

            

            if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) {

                if(USE_DEGUG) {

                    NSLog(@"Failed to create table");

                }

            }

            

            sqlite3_close(contactDB);

            

        } else {

            if(USE_DEGUG) {

                NSLog(@"Failed to open/create database");

            }

        }

    }

}


// 데이터 베이스가 있다면 읽어온다.

- (void)readMemoFromDatabase {

// 데이터를 담을 오브젝트인 DBData 초기화

// 데이터베이스에 처음 엑세스하는 것이라면 alloc으로 메모리를 할당

if (self.isFirstTimeAccess == YES) {

self.DBData = [[NSMutableArray alloc] init];

self.isFirstTimeAccess = NO;

    } else { // 처음 엑세스하는 것이 아니면 removeAllObject DBData 초기화

        [self.DBData removeAllObjects];

    }

    const char *dbpath = [databasePath UTF8String];

    

// 데이터 베이스 파일을 연다.

if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {

// SQL명령을 실행한다.

//const char *sqlStatement = "SELECT * FROM nmpData ORDER BY Nmp_Index DESC";

        const char *sqlStatement = "SELECT * FROM CONTACTS ORDER BY ID DESC";

sqlite3_stmt *compiledStatement;

        

if (sqlite3_prepare_v2(contactDB, sqlStatement, -1, &compiledStatement, NULL) ==SQLITE_OK) {

// SQL 명령어를 실행하여 얻은 결과를 하나씩 읽는다.

while (sqlite3_step(compiledStatement) == SQLITE_ROW) {

NSInteger aIndex = sqlite3_column_int(compiledStatement, 0);

NSString *aMessage = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 1)];

                NSString *aType = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 2)];

                NSString *abseqno = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 3)];

                NSString *aSchoolNumber = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 4)];

                NSString *aSendtime = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 5)];

                NSInteger aIid = sqlite3_column_int(compiledStatement, 6);

                                                     

                // 읽어온 데이터를 사용하여 DataModel 오브젝트를 생성한다.

                DataModel *md = [[DataModel alloc] initWithData:aIndex message:aMessage type:aType bseqno:abseqno schoolnumber:aSchoolNumber sendtime:aSendtime iid:aIid];

                if(USE_DEGUG) {

                    NSLog(@"%ld / %@ / %@ / %@ / %@ / %@ / %ld", (long)aIndex, aMessage, aType, abseqno, aSchoolNumber, aSendtime, (long)aIid);

                }

                // DataModel 오브젝트를 DBData 배열에 추가한다.

                [self.DBData addObject:md];

}

        } else {

            printf("could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        }

// SQL 명령을 종료

sqlite3_finalize(compiledStatement);

}

// 데이터베이스를 닫는다.

sqlite3_close(contactDB);

}


// 데이터를 저장한다.

- (void)saveData:(NSString *)pmessage type:(NSString *)ptype bseqno:(NSString *)pbseqno schoolnumber:(NSString *)pschoolnumber sendtime:(NSString *)psendtime iid:(NSString *)piid {

    sqlite3_stmt    *statement;

    const char *dbpath = [databasePath UTF8String];

    

    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {

        NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO CONTACTS (MESSAGE, TYPE, BSEQNO, SCHOOLNUMBER, SENDTIME, IID) VALUES (\"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%ld\")", pmessage, ptype, pbseqno, pschoolnumber, psendtime, (long)[piid integerValue]];


        const char *insert_stmt = [insertSQL UTF8String];

        

        sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);

        if (sqlite3_step(statement) == SQLITE_DONE) {

            if(USE_DEGUG) {

                NSLog(@"SQLITE_DONE : %@", insertSQL);

            }

        } else {

            if(USE_DEGUG) {

                NSLog(@"SQLITE_FAILED : %@", insertSQL);

            }

        }

        

        sqlite3_finalize(statement);

        sqlite3_close(contactDB);

    }

}


// pUserID로 데이터를 검색!

- (void)findContact:(NSString *)pSchool UserID:(NSString *)pUserID UserPass:(NSString *)pUserPass {

    sqlite3_stmt    *statement;

    const char *dbpath = [databasePath UTF8String];

    

    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {

        NSString *querySQL = [NSString stringWithFormat: @"SELECT MESSAGE FROM CONTACTS WHERE SCHOOLNUMBER=\"%@\"", pUserID];

        

        const char *query_stmt = [querySQL UTF8String];

        

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK) {

            if (sqlite3_step(statement) == SQLITE_ROW) {

                if(USE_DEGUG) {

                    NSLog(@"Match found : %@", querySQL);

                }

            } else {

                if(USE_DEGUG) {

                    NSLog(@"Match Not found : %@", querySQL);

                }

            }

            sqlite3_finalize(statement);

        }

        sqlite3_close(contactDB);

    }

}