Please Enable JavaScript!
Gon[ Enable JavaScript ]

iPhone(아이폰) DB 개발시 Sqlite3 용 클래스 FMDB

안드로이드 개발
반응형

iPhone(아이폰) DB 개발시 Sqlite3 용 클래스 FMDB

 

개발환경 : Mac OS X 10.6.3, Simulator - 3.1.3

 

FMDB 를 사용하기 위한 클래스를 다운받아야 하는데 기존 링크는 전부

깨져서 받을 수가 없었다. 검색해보니 누군가 구글코드 프로젝트에 올려놓은

곳이 있었다. 여기서 소스를 다운받는다. fmdb클래스는 예제를 실행한

내용으로 유용한 소스가 많이 들어가 있다. 참고 하기 바란다.

http://code.google.com/p/flycode/source/browse/trunk/fmdb#fmdb/src


받은 파일은 Classes 폴더에 넣어둔다. FMDB 에서 제일 중요한 파일은 FMDatabase,

FMResultSet 이다. 클래스 이름에서도 알수 있듯이 FMDatabase 는 데이터베이스

접속을 유지하고 SQL문장을 실행시켜준다. 그리고  FMResultSet SELECT 쿼리를

수행한 결과를 담을 그릇이다. 이 객체에 데이터를 담은후에 소스에서는

하나하나 꺼내어 쓰게 된다.

 

간단한 사용법 예제를 보고 구현한 소스를 보는 것이 이해하기 편할 것 같다.

데이터베이스 수행의 기본은 CRUD 이다. CRUD 에 대한 간단한 예제들을

어떻게 수행하는지 볼텐데 데이터베이스 구현을 위한 함수는 크게 세가지로 보면

된다. 먼저 DB 접속을위한 FMDatabase 객체생성, 데이터를 읽어오는 executeQuery,

삭제, 업데이트, 입력을 수행하는 executeUpdate 가 그것이다.

 

위에 flycode 구글 프로젝트에서 fmdb.m FMDB 를 어떻게 사용하는지에 대한

구체적인 예제 코드를 구현해놓았다.

처음 DB 를 열때는 NSAutoreleasePool DB pool 을 생성한다. 그리고 FMDatabase

객체를 사용하여 DB 열고 Open 에 실패 했을때는 Pool release 하고 리턴한다.

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

FMDatabase* db = [FMDatabase databaseWithPath:@"success.sqlite"];

if (![db open]) {

           NSLog(@"Could not open db.");

           [pool release];

           return 0;

}

 

쿼리를 제대로 작성해서 실행을 했는지도 체크가 가능하다. FMDatabase

hadError 함수로 제대로 수행되었는지에 대한 내용을 Bool 값으로 리턴하게

되는데 false 일 경우 lastErrorCode  함수로 그 내용을 알수 있다.

// create a bad statement, just to test the error code.

[db executeUpdate:@"blah blah blah"];

          

FMDBQuickCheck([db hadError]);

 

if ([db hadError]) {

           NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);

}

 

아래 예제는 테이블 생성과 여러 입력 쿼리 실행시 트랜잭션을 걸수 있는 내용이

포함 되어있다.

[db executeUpdate:@"CREATE TABLE quiz (no INTEGER PRIMARY KEY  AUTOINCREMENT  NOT

NULL , title VARCHAR, question VARCHAR, answer VARCHAR, level VARCHAR)"];

          

[db beginTransaction];

int count = 0;

while (count++ < 3) {

[db executeUpdate:@"insert into quiz (title, question, answer, level) values (?, ?, ?, ?)" ,

                      @"hi again'", // look!  I put in a ', and I'm not escaping it!

                      @"dadfasdfasdf",

                      @"sdfasfasdf",

                      @"1"];

}

[db commit];

 

다음은 데이터를 select 했을때 가져와서 어떻게 꺼내 사용할지에 대한 예제이다.

FMResultSet *rs = [db executeQuery:@"select rowid,* from test where a = ?", @"hi'"];

while ([rs next]) {

           // just print out what we've got in a number of formats.

           NSLog(@"%d %@ %@ %@ %@ %f %f",

                       [rs intForColumn:@"c"],

                       [rs stringForColumn:@"b"],

                       [rs stringForColumn:@"a"],

                       [rs stringForColumn:@"rowid"],

                       [rs dateForColumn:@"d"],

                       [rs doubleForColumn:@"d"],

                       [rs doubleForColumn:@"e"]);

          

          

           if (!([[rs columnNameForIndex:0] isEqualToString:@"rowid"] &&

                       [[rs columnNameForIndex:1] isEqualToString:@"a"])

           ) {

                     NSLog(@"WHOA THERE BUDDY, columnNameForIndex ISN'T WORKING!");

                                return 7;

           }

}

// close the result set.

// it'll also close when it's dealloc'd, but we're closing the database before

// the autorelease pool closes, so sqlite will complain about it.

[rs close];

 

이것은 테이블에 BLOB 형태로 이미지를 넣는 예제이다. 어플리케이션의 특정아이콘

이미지를 집어넣는것이다.

[db executeUpdate:@"create table blobTable (a text, b blob)"];

// let's read in an image from safari's app bundle.

NSData *safariCompass =

[NSData dataWithContentsOfFile:@"/Applications/Safari.app/Contents/Resources/compass.icns"];

if (safariCompass) {

           [db executeUpdate:@"insert into blobTable (a, b) values (?,?)", @"safari's compass",

safariCompass];

 

           rs = [db executeQuery:@"select b from blobTable where a = ?",

@"safari's compass"];

           if ([rs next]) {

                     safariCompass = [rs dataForColumn:@"b"];

                     [safariCompass writeToFile:@"/tmp/compass.icns" atomically:NO];

                    

                     // let's look at our fancy image that we just wrote out..

                     system("/usr/bin/open /tmp/compass.icns");

                               

                     // ye shall read the header for this function, or suffer the consequences.

                     safariCompass = [rs dataNoCopyForColumn:@"b"];

                     [safariCompass writeToFile:@"/tmp/compass_data_no_copy.icns"

 atomically:NO];

                                system("/usr/bin/open /tmp/compass_data_no_copy.icns");

                     }

           else {

                     NSLog(@"Could not select image.");

           }

           [rs close];

}

else {

           NSLog(@"Can't find compass image..");

}

 

이외에도 몇가지 더 있는데 비슷한 내용이라 생략한다.

fmdb.m 클래스를 참고 하게 되면 왠만한 DB 관련로직은 쉽게 구현하리라 생각된다.

트랜잭션처리와 DB 풀을 유지하며 작업을 할수 있다는점, 여러가지 에러체크 함수등은

FMDB 를 사용할 수밖에 없는 중요한 요소이다.

반응형
Posted by 녹두장군1
,