iOS
아이폰 SQLite3 샘플
cocoadev
2008. 11. 25. 14:18
이와함께 애플의 iPhoneDev Center에 SQLite Book List란 샘플을 보시면, 아이폰 SDK에서 사용하는 방법이 잘 나와있습니다. SQLite의 개발자인 Richard Hipp이 구글 테크토크에서 직접 SQLite에 대해서 설명하는 'An Introducion to SQLite'란 동영상도 참고하면 좋습니다.
* SQLiteTestAppDelegate.h
#import <UIKit/UIKit.h>
#import <sqlite3.h>
@interface SQLiteTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
sqlite3 *db;
NSMutableArray *dataList;
IBOutlet UITextField *newString;
IBOutlet UITableView *dataTable;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
- (void)updateDataList;
- (IBAction)addRow:(id)sender;
@end
#import <sqlite3.h>
@interface SQLiteTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
sqlite3 *db;
NSMutableArray *dataList;
IBOutlet UITextField *newString;
IBOutlet UITableView *dataTable;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
- (void)updateDataList;
- (IBAction)addRow:(id)sender;
@end
SQLiteTestAppDelegate.m
#import "SQLiteTestAppDelegate.h"
@implementation SQLiteTestAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window makeKeyAndVisible];
/* 어플리케이션 패스를 구한다. */
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"mydata.db"];
/* 데이터베이스를 오픈한다 */
if(sqlite3_open([path UTF8String], &db) == SQLITE_OK) {
char *error = NULL;
const char* query = "SELECT count(*) from mytable";
/* mytable을 쿼리해보고 오류가 있으면 mytable을 생성한다. */
if (sqlite3_exec(db, query, NULL, 0, &error) != SQLITE_OK) {
sqlite3_free(error);
/* 테이블 생성 */
if (sqlite3_exec(db, "CREATE TABLE mytable ('name' CHAR(16))", NULL, 0, &error) != SQLITE_OK) {
NSLog(@"TABLE CREATE ERROR: %s", error);
sqlite3_free(error);
}
}
} else {
/* DB 오픈 에러 */
sqlite3_close(db);
db = NULL;
NSLog(@"DB OPEN ERROR: '%s'", sqlite3_errmsg(db));
}
dataList = [[NSMutableArray alloc] initWithCapacity:100];
[self updateDataList];
}
- (void)applicationWillTerminate:(UIApplication *)application {
if (db) {
sqlite3_close(db);
}
}
- (void)dealloc {
[dataList release];
[window release];
[super dealloc];
}
/** 현재 DB에 있는 데이터를 dataList에 등록 */
- (void)updateDataList {
/* 이전 데이터를 모두 삭제 */
[dataList removeAllObjects];
const char *query = "SELECT name FROM mytable";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, query, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
/* dataList에 쿼리결과 등록 */
NSString* str = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
[dataList addObject:str];
[str release];
}
}
sqlite3_finalize(statement);
[dataTable reloadData];
}
#pragma mark IBACTION
- (IBAction)addRow:(id)sender {
char *error = NULL;
/* 사용자가 입력한 값을 DB에 추가한다 */
NSString *query = [NSString stringWithFormat:@"INSERT INTO mytable VALUES ('%@')", [newString text]];
sqlite3_exec(db, [query UTF8String], NULL, 0, &error);
[self updateDataList];
}
#pragma mark TextField Delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#pragma mark TableView Delegate method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return @"Table Items";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
}
cell.text = [dataList objectAtIndex:indexPath.row];
return cell;
}
@end
@implementation SQLiteTestAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window makeKeyAndVisible];
/* 어플리케이션 패스를 구한다. */
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"mydata.db"];
/* 데이터베이스를 오픈한다 */
if(sqlite3_open([path UTF8String], &db) == SQLITE_OK) {
char *error = NULL;
const char* query = "SELECT count(*) from mytable";
/* mytable을 쿼리해보고 오류가 있으면 mytable을 생성한다. */
if (sqlite3_exec(db, query, NULL, 0, &error) != SQLITE_OK) {
sqlite3_free(error);
/* 테이블 생성 */
if (sqlite3_exec(db, "CREATE TABLE mytable ('name' CHAR(16))", NULL, 0, &error) != SQLITE_OK) {
NSLog(@"TABLE CREATE ERROR: %s", error);
sqlite3_free(error);
}
}
} else {
/* DB 오픈 에러 */
sqlite3_close(db);
db = NULL;
NSLog(@"DB OPEN ERROR: '%s'", sqlite3_errmsg(db));
}
dataList = [[NSMutableArray alloc] initWithCapacity:100];
[self updateDataList];
}
- (void)applicationWillTerminate:(UIApplication *)application {
if (db) {
sqlite3_close(db);
}
}
- (void)dealloc {
[dataList release];
[window release];
[super dealloc];
}
/** 현재 DB에 있는 데이터를 dataList에 등록 */
- (void)updateDataList {
/* 이전 데이터를 모두 삭제 */
[dataList removeAllObjects];
const char *query = "SELECT name FROM mytable";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, query, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
/* dataList에 쿼리결과 등록 */
NSString* str = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
[dataList addObject:str];
[str release];
}
}
sqlite3_finalize(statement);
[dataTable reloadData];
}
#pragma mark IBACTION
- (IBAction)addRow:(id)sender {
char *error = NULL;
/* 사용자가 입력한 값을 DB에 추가한다 */
NSString *query = [NSString stringWithFormat:@"INSERT INTO mytable VALUES ('%@')", [newString text]];
sqlite3_exec(db, [query UTF8String], NULL, 0, &error);
[self updateDataList];
}
#pragma mark TextField Delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#pragma mark TableView Delegate method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return @"Table Items";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
}
cell.text = [dataList objectAtIndex:indexPath.row];
return cell;
}
@end