Skip to main content

C++ of the Day #45 - SQLite3 C++ wrapper #3

이번엔 sqlite3++를 소개하는 마지막 시간으로 SQLite3의 extension 기능에 대한 부분을 살펴 보겠습니다.

SQLite3는 사용자가 정의할 수 있는 function과 aggregate들을 통해 기본 기능을 확장할 수 있도록 하고 있습니다. ((이외에 collation sequence라는 확장 기능도 있습니다만 sqlite3++에서는 지원하지 않습니다. 아직까지는...))

예를 들어 A라는 column의 정보를 가지고 B와 C의 데이터 중 선택할 수 있는 cond(A, B, C)라는 function을 사용자가 정의할 수 있다면 복잡한 SQL 구문 대신 다음과 같이 간단하게 사용할 수 있을 것입니다.

SELECT cond(A, B, C) FROM ...;


그리고 특정 규칙을 적용한 filter를 사용하여 해당 filter에 의해 선택된 항목들의 개수만 세고 싶다면 다음과 같은 aggregate를 만들어 사용할 수도 있습니다. 아래 코드에서는 count_of가 사용자가 정의한 filter라고 가정합니다.

SELECT count_of(A, B, C) FROM ...;


이처럼 function이나 aggregate는 SQLite3가 기본적으로 제공하지 않거나 SQL만으로 작성하기에는 복잡한 기능들을 사용자가 정의할 수 있도록 해줍니다.

그럼 sqlite3++을 사용하여 간단하게 이런 function이나 aggregate를 만들 수 있는 방법을 알아보겠습니다.

먼저 ext::function의 경우에는 function pointer나 functor, boost::binder 그리고 boost::lambda등을 function으로 등록하여 사용할 수 있습니다. 예를 들면 다음과 같습니다.

int plus100(int val) {
return val + 100;
}
// ...
sqlite3pp::ext::function func(db);
func.create("plus100", &plus100);

// SELECT plus100(id) FROM ...;


위의 plus100()은 단순히 입력된 값에 100이라는 값을 더하여 리턴하는 함수입니다. 등록은 ext::function 객체의 create 함수를 사용하며 template 인자의 문법은 boost::function과 유사하게 function type이 사용됩니다. :-)

이처럼 간단한 코드는 boost::lambda로도 등록하여 사용할 수 있습니다.

using namespace boost::lambda;
func.create("plus100", _1 + 100);


물론 다음과 같이 입력과 출력의 타입은 서로 다를 수 있으며 입력의 개수는 현재 0~5개까지 지원합니다.

int strlen_3(std::string const& s1, std::string const& s2, std::string const& s3)
{
return (s1 + s2 + s3).size();
}
// ...
func.create_function("strlen_3", &strlen_3);

// SELECT strlen_3(A, B, C) FROM ...;


위에서 본 코드와 같이 ext::function은 비교적 간단히 사용할 수 있습니다만 ext::aggregate의 경우에는 약간 복잡합니다. ext::aggregate는 하나의 함수가 아니라 해당 입력값을 하나씩 받아들이는 step()함수와 모든 입력이 끝난 뒤에 리턴값을 처리하는 finish()함수로 구성됩니다.

ext::function보다 복잡하다고는 하지만 실제 사용 방법은 간단하게 step()함수와 finish()함수를 가지는 클래스를 구현하는 것입니다.

struct strlen_all
{
strlen_all() : n_(0) {
}
void step(std::string const& s) {
n_ += s.size();
}
int finish() {
return n_;
}
int n_;
};
// ...
sqlite3pp::ext::aggregate aggr(db);
aggr.create("strlen_all");

// SELECT strlen_all(name) FROM table;


위의 ext::aggregate는 해당 column에 있는 문자열의 길이의 합을 리턴합니다.

등록시에 사용되는 create 함수의 template 인자의 구성은 가 됩니다. aggregate의 리턴 타입은 자동으로 finish() 함수의 리턴 타입으로 결정됩니다. 여기서도 입력의 개수는 현재 0~5개까지로 구현되어 있습니다.

이것으로 구현한 sqlite3++의 사용 방법에 대한 설명을 마치겠습니다. 오랫만에 코드에 template을 좀 썼더니 재밌네요. 기회가 되면 sqlite3++에 사용된 template 구현 방법에 대해 설명해 보도록 하겠습니다. :-)

sqlite3pp - Google Code에서 코드들과 간단한 사용 예제들을 보실 수 있습니다.

Comments

Popular posts from this blog

CodeHighlighter plugin test page.

This post is for testing CodeHighlighter plugin which uses GeSHi as a fontifier engine. ((Those code blocks are acquired from Google Code Search .)) ((For more supported languages, go CodeHighlighter plugin or GeSHi homepage.)) C++ (<pre lang="cpp" lineno="1">) class nsScannerBufferList { public: /** * Buffer objects are directly followed by a data segment. The start * of the data segment is determined by increment the |this| pointer * by 1 unit. */ class Buffer : public PRCList { public: Buffer() { ++index_; } PHP (<pre lang="php" lineno="4">) for ($i = 0; $i $value = ord( $utf8_string[ $i ] ); if ( $value < 128 ) { // ASCII $unicode .= chr($value); } else { if ( count( $values ) == 0 ) { $num_octets = ( $value } $values[] = $value; Lisp (<pre lang="lisp">) ;;; Assignment (define-caller-pattern setq ((:star var fo...

Textiler plugin test page

This post is for testing Textiler plugin . This plugin uses Textile engine (version 2.0.0). The sample text is come from Textile test page. (Note that the result will be vary according to your CSS options.) Supported wiki syntax Rendering result h2{color:green}. This is a title h3. This is a subhead p{color:red}. This is some text of dubious character. Isn't the use of "quotes" just lazy writing -- and theft of 'intellectual property' besides? I think the time has come to see a block quote. bq[fr]. This is a block quote. I'll admit it's not the most exciting block quote ever devised. Simple list: #{color:blue} one # two # three Multi-level list: # one ## aye ## bee ## see # two ## x ## y # three Mixed list: * Point one * Point two ## Step 1 ## Step 2 ## Step 3 * Point three ** Sub point 1 ** Sub point 2 Well, that went well. How about we insert an <a href="/" title="watch out">old-fashioned hypertext link</a>? Will the quo...

BookCover plugin test page

This post is for testing BookCover plugin . (( The previous test page has some comments from users.)) The 'Books Reading' section in the sidebar is also using this plugin. [ bookcover:1932394613] [bookcover:1932394613] [ bookcover:1590598385(Smart and Gets Things Done)] [bookcover:1590598385(Smart and Gets Things Done)] [ bookcover:1591841380(Wikinomics : How Mass Collaboration Changes Everything)] [bookcover:1591841380(Wikinomics : How Mass Collaboration Changes Everything)] [ bookcover:8995856408] [bookcover:8995856408] [ bookcover:8831793721] [bookcover:8831793721] [ bookcover:9788831793728] [bookcover:9788831793728]