Tistory로 옮깁니다

정들었던 이글루를 버리고... 훌쩍 ㅜㅡ
티스토리로 옮깁니다. 머 큰 이유는 없고요. 훨씬 기능적으로 우수하다는 판단이 서서랄까...

태터툴즈 때부터 쓰고 싶었지만 설치형 웹 어플리케이션은 서버도 없고 해서 안 썼는데 티스토리가 나오고 이제 시간도 좀 흐른 거 같고 해서 그냥 옮깁니다.

많이들 들러주세요 (__)

http://jeminency.tistory.com

by eminency | 2007/08/09 16:27 | Life | 트랙백 | 덧글(2)

SQLite C API 소개

꽤 간단한 내용이지만, SQLite는 한글 매뉴얼이 별로 없는 탓에 끄적여 봅니다.

그간 C API를 써 본 DB들을 보면, ODBC와 비슷한 형태를 갖고 있는 경우가 많습니다. 오라클은 C API보다는 Pro*C를 쓰니 예외로 하고요.. 오라클 C API가 어떻게 되어 있는 지도 모르겠네요 -_-;

대략 Open-Prepare-Bind-Execute-(Fetch)-Close의 과정을 거치는데 open-close는 당연히 DB를 열고 핸들러(DB 정보 구조체)를 초기화하는 것과 종료하는 것이니 어려울 것 없고요.

Prepare는 DB에게 자기가 실행할 SQL 문장을 던져주고 미리 실행 플랜을 준비하도록 합니다. binding 할 값이 없다면 prepare 하지 않고 곧바로 execute도 가능합니다만, 예를 들어 문장은 동일한데 값만 바뀌는 쿼리를 여러 번 실행할 경우에 다이렉트로 그 때마다 실행을 한다면, 매번 DB 엔진은 SQL 문장을 해석하고 어떻게 실행할 지를 결정하고, 값에 따라 실행하게 되겠죠. 값만 달라진다면, 문장을 해석하고 실행할 지 결정하는 부분은 사실 한 번만 해도 되는데 말이죠.

그리고 bind는 실행하기 전 쿼리에 값을 할당하는 것입니다. 바인딩할 부분은 보통 '?'으로 표현하는데 'SELECT * FROM test WHERE id = ?' 이런 식으로 쿼리 문장을 표현할 수 있습니다. 이 문장 그대로 prepare를 딱 한 번만 한 다음 실행할 때는 '?'위치에 integer 변수를 binding 하여 여러 가지로 id 값을 주어서 결과를 가져올 수 있습니다.

Execute는 말 그대로 문장을 실행하는 것인데 DB에서는 select 쿼리가 실행 되었을 경우 result set 공간에 결과값을 저장해 놓습니다.
Fetch는 그런 result set의 값을 가져오는 과정입니다. insert-update-delete를 실행했을 경우는 당연히 필요없는 과정이죠.

상당히 대충 설명했는데 -_- 직접 예를 보겠습니다.
testtbl의 스키마는 'CREATE TABLE testtbl(id int, value text);' 입니다.

예제 프로그램은 id를 1부터 3까지 돌리며 해당되는 레코드를 긁어오는 것입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sqlite3.h>

#define EXIT_WITH_ERROR(func, dbh) \
do { \
    if (func != SQLITE_OK) \
    { \
        fprintf(stderr, "line %d: %s \n: %s\n", __LINE__ \
            , #func ,sqlite3_errmsg(dbh)); \
        exit(sqlite3_errcode(dbh)); \
    } \
} while(0)

int main()
{
    sqlite3 *dbh;
    sqlite3_stmt *stmt;
    int i, j;
    const char *tail;
    char *errmsg;

    char *sql = "select * from testtbl where id=?";

    /* "testdb"라는 DB 파일을 연다 */
    EXIT_WITH_ERROR(sqlite3_open("testdb", &dbh), dbh);

    /* sql 문장에 대해 질의 플랜을 준비한다 */
    EXIT_WITH_ERROR(sqlite3_prepare(dbh, sql, strlen(sql), &stmt, NULL, dbh);

    for (i=1; i<=3; i++)
    {
        /* '?' 위치에 i 값을 바인딩한다 */
        EXIT_WITH_ERROR(sqlite3_bind_int(stmt, 1, i) , dbh);

        /* sql 쿼리 실행 */
        while (sqlite3_step(stmt) != SQLITE_DONE)
        {
            /* 실행된 결과값을 받아와 출력 */
            printf("%d : %s\n" , sqlite3_column_int(stmt, 0)
                , sqlite3_column_text(stmt, 1));
        }

        sqlite3_reset(stmt);
    }
    sqlite3_finalize(stmt);
}


EXIT_WITH_ERROR는 에러 체크를 위해 제가 작성한 매크로입니다. 실제 sqlite3_ 로 시작하는 함수들만 보시면 됩니다.

처음에 DB 오픈을 하고 sql 문장에 대해 prepare를 수행하죠?
prepare의 마지막 NULL 인자는 원래 char *가 들어가는 곳입니다. sql 문장이 하나가 아니라 여러 개일 경우는 첫번째 것만 prepare하고 마지막 인자의 포인터 변수에 두번째 문장이 시작하는 위치를 가리키도록 되어 있습니다.
순차적으로 수행되어야 할 sql 문이라면 변수를 따로 안 두고 실행 단위별로 sql 문을 선언하여 쓸 수 있다는 장점이 있습니다(자세한 설명은 sqlite3_prepare()의 매뉴얼 페이지를..).

그 다음에는 for 문을 돌며 바인딩-실행-결과 페치를 반복합니다.
바인딩은 for 문의 변수인 i를 그대로 이용합니다. 바인딩 함수의 두번째 인자는 binding variable의 순서입니다. 첫번째니까 '1'이죠. 여러 개 있으면 앞에서부터 1,2,3,..이 됩니다. 숫자이므로 sqlite3_bind_int를 썼고, 그 외에 _null, _text 등 다양한 바인딩 함수가 있습니다.

그리고 sqlite3_step()을 써서 실행을 하는데 특이한 점은 이 함수가 실행과 페치를 동시에 수행한다는 점입니다.

예를 들어 MySQL이라면, mysql_query()로 실행하고, mysql_store_result()로 결과 셋을 가져 온 후, mysql_fetch_row()을 반복 실행하여 한 건씩 긁어오는 과정을 거칩니다.

반면 SQLite는 sqlite3_step을 실행하면 실행하고 결과 셋의 첫번째 레코드를 가져오는 과정까지 거칩니다.
그 다음은 각 컬럼을 sqlite3_column_* 함수들을 써서 가져오면 됩니다(컬럼 번호는 0부터 시작합니다).
그리고, 두번째 이후로 sqlite3_step()을 실행하면 sql을 실행하지는 않고 결과 셋의 다음 레코드들을 가져오게 되는 것이죠. 만약 가져올 결과 레코드가 없으면 SQLITE_DONE을 리턴합니다.
즉, 만약 결과가 실행할 때마다 한 건씩만 있다면 굳이 while 문을 돌릴 필요는 없습니다. 실행 결과는 다음과 같습니다.

1 : aaa
1 : ddd
2 : bbb
3 : ccc

만약 while 문을 쓰지 않았다면 결과에는 1:ddd가 나오지 않을 것입니다. id 컬럼이 unique 하다면 while문을 쓰지 않아도 되겠지만, 방어적인 프로그래밍을 위해서는 while을 사용하는 스타일이 나을 듯 합니다 ^^

그리고 결과셋을 다 긁어왔다면 sqlite3_reset을 실행해서 바인딩 된 변수들을 초기화 해 주어야 합니다.
그렇지 않을 경우 두번째 bind를 할 때에 에러가 납니다.

이상으로 간단히 SQLite의 C API에 대해 살펴 보았습니다, 간단하죠? ^^
개인적으로는 다른 DB에 비해 비교적 API 사용법이 쉽다는 느낌이 듭니다. DB 데몬이 없기 때문에 API를 더욱 간략하게 만들 수 있었는 지도 모르겠습니다.

하지만 C를 쓸 경우는 아무래도 다른 언어보다는 조금 번거롭죠.
pysqlite 같은 걸 쓸 경우는 훨씬 편합니다. 이후에는 C언어 이외의 SQLite API에 대해 한 번 보도록 하겠습니다.

by eminency | 2007/08/08 15:19 | Programming Story | 트랙백 | 덧글(5)

라따뚜이 & D-war 논란에 대해...

어제 라따뚜이 봤습니다. 작년에 쓴 카(Cars)에 대한 평과 비슷하게 될 지도 모르겠네요.
픽사 애니메이션 하나도 안 빼놓고 다 봤다는 거나... 스토리가 뻔하다는 거나... 애니메이션임에도 현실감 있게 만드는 능력이 놀랍다거나...-_-

하지만 반대로 이렇게 말하고도 싶습니다. 픽사 애니메이션 보러 가서 실망한 적은 없다고요(실망까지는 아니지만 가장 아쉬웠던 작품은 '인크레더블'이었던 듯 하군요).

어제 보러 가기 전에 직장 동료가 재미없다고 해서 걱정을 좀 했는데 알고 보니 다운 받아서 본 거였다는군요.
영화에 따라 정도 차이가 있겠지만, 다운받아 보고 혹평을 하는 것은 일면 옳지 못하다고 생각합니다. 다운받아서 제대로 알 수 있는 것은 영화의 스토리 라인 정도가 아닐까 생각합니다. 영화의 재미에는 비단 액션 영화가 아니더라도 큰 화면과 화질과, 웅장한 사운드가 중요한 역할을 합니다. 게다가 외국 영화라면 다운받은 자막의 번역 수준이 미흡하여 영화의 재미를 해치는 경우도 있지요.
영화를 보기 위해 내는 돈에는 그만한 가치가 있다는게 개인적인 의견입니다.
물론 단점도 있지요, 재수없으면 시끄럽게 떠드는 초딩 색히들이 영화 관람을 방해하기도 하고 뒷사람이 의자에 로우킥을 날리기도 하지만, 혼자 볼 때는 웃지 않을 장면이 여러 사람이 보면서 웃게 되는 경우도 많으니 일장일단이랄까요(애들이 있는 건 확실히 단점입니다만).

아시다시피(?) 이번 영화는 요리에 대한 영화입니다.
주인공인 레미는 쥐인데 미각과 후각이 예민하여 인간의 집에 들어가 TV와 책을 보며 요리를 배우게 되지요. 하지만 쥐의 몸으로는 요리를 할 수 없는데 하늘이 도우셨는지 요리사 지망생인 -하지만 솜씨는 없는- 링귀니를 만나게 되어 그를 도와 요리를 하게 됩니다.


늘 그렇듯 이번에도 픽사의 직원들은 파리의 경치, 요리의 질감, 요리사들의 손놀림을 구현하기 위해 많은 애를 썼다고 합니다. 이 작품을 위해 전 직원이 프랑스 요리강좌를 수강했다더군요 -_- 현대적인 장인정신이랄까요. 그래서 실제 요리사들이 애니메이션을 보고 캐릭터들의 요리할 때의 손놀림에 감탄을 했다고도 합니다(전 모르겠던데요).

CG도 역시 탁월한 수준인데 볼 때마다 느끼는 거지만 픽사는 실제처럼 CG를 구현할 능력이 있으면서도 일부러 애니메이션틱하게 보이는 데에 일가견이 있는 듯합니다. 주인공 레미만 해도 눈과 입을 제외하면 실제 생쥐와 다를 바가 없어 보일 정도니까요(특히 털).

카(Cars)에서부터 그들의 CG에 대해 감탄을 내뱉게 하는 것은 '경치'입니다. 카 이전까지의 작품들에는 현실의 경치를 CG로 구현한 부분은 제 기억에 드물었던 것 같은데 카(Cars)에서부터는 실제 지명을 배경으로 하다 보니 현실의 경치 또한 애니메이션 안에 들어가게 된 것이 아닐까 싶은데요.
라따뚜이에서는 파리의 경치를 정말 멋있게 보여줍니다.


실제 파리보다도 사람들의 마음 속에 있는 '파리'라는 도시에 대한 풍경을 그대로 그려놓은 듯 합니다.
경치 뿐만 아니라 레미가 도망다닐 때 보여주는 파리 시내의 구석구석도 현실감 넘칩니다.
(개인적으로 재미있었던 명장면은 초반의 생쥐들의 대탈출 부분과 후반의 생쥐들이 단체로 요리하는 장면이었던 듯)


음... 그리고 요새 D-war 때문에 말이 많은데 이렇게 논란이 많았던 영화도 흔치 않았을 듯 합니다. 저는 보지는 않았지만...
그저 제가 하고 싶은 말은 영화에 대한 평은 역시 관객들의 몫이고 자신에게 재미있었다면 남이 하는 평가에 휘둘릴 필요는 없다는 것입니다.

자신의 블로그에 영화에 대한 평을 올리는 것도 개인의 자유이고 평이 옳든 그르든 논리적인 반박은 몰라도 욕설 테러를 가한다는 건 곤란하죠 -_-; 블로그가 언론의 대체 역할을 점점 해 나가고 있는 건 사실이지만 여전히 블로그는 블로그일 뿐입니다.
'니가 만들어 봐라, 저만큼 만드나 보자'라는 식의 고전적인 억지는 정당하지 못합니다. 돈을 내고 영화를 봤다면 비판할 권리도 당연히 있습니다. 비싼 돈 주고 산 전자제품이 잘 고장난다고 불평하는 사람에게 '니가 만들어 봐라'하는 건 옳지 못하지요.

D-war에 대한 논란은 우리나라 사람이 만든 헐리우드 스케일(그리고 스타일)의 영화라는 것에 기인한다고 보여집니다. 그리고 심형래 감독의 동정심 혹은 애국심 마케팅(으로 보여집니다)이 큰 역할을 했구요.
하지만 헐리우드 영화와 D-war를 비교하는 것은 당연합니다. 애국심이든 뭐든 영화는 영화니까요. 아무리 제작비나 제작 환경의 문제를 들먹이더라도 시청자가 미국 드라마를 보며 눈이 높아지는 것이 어쩔 수 없듯이요.

D-war와 용가리와 다른 결정적인 점은 이미 많은 사람들이 봤다는 것입니다. 그리고 당연한 사실이지만 -D-war를 보지는 않았지만- 들리는 평대로라면 D-war보다 못 만든 헐리우드 영화들도 무지 많을 겁니다.
값싼 애국심이나 값싼 동정심으로 D-war가 한국형 블록버스터의 새로운 장을 열어주는 영화이길 기원하는 입장은 아니지만, 제가 보기엔 이미 절반의 성공은 거두고 있는 듯 보이네요.
그리고 스토리가 빈약하단 논란은 다이하드 4.0이나 트랜스포머도 마찬가지인 거 같은데 D-war에 대해서는 유독 가혹한 듯 보이는 것도 사실입니다.

고로 결론은... 비판을 위한 비판은 자제하자... 인가? -_-
근데 왜 저는 볼 생각이 없냐고 물으신다면... 이미 예전의 우뢰매나 슈퍼 홍길동의 인상이 강해서(심형래가 만든 영화는 아니지만) 선입견을 이미 갖고 있기 때문에 안 보는게 낫다고 생각해서입니다.
애초에 '한국 사람이 만든 블록버스터 대작'이라는 식의 카피에 반감을 갖게 되었기 때문이기도 하구요 - 실제로 이렇게 광고했는지는 모르겠지만 열이면 여덟아홉은 저런 인상을 갖게 되는게 당연하지 않습니까.

D-war가 다이하드 같은 시리즈물이 된다거나 하는 식으로 탄탄한 기반을 나중에 갖게 된다면 얘기는 또 달라지겠지요.

by eminency | 2007/08/07 14:14 | Hobby | 트랙백 | 덧글(0)

◀ 이전 페이지다음 페이지 ▶