mysqlにユーザ定義関数curlを追加してみる

なんか結構今更なのだけども折角なのでとりあえず。
13.2. MySQL への新しい関数の追加

mysqlのインストール

省略。

curlのインストール

curl(ってかlibcurl)yumでインストール。

# yum install curl curl-devel

ちなみにcurlってHTTPやFTPプロトコルでアクセスできるライブラリ。

コード作成

こことかを参考にしつつ。
でもまだ怪しい。 [c num=1]#include <stdlib.h>

include <stdio.h>

include <string.h>

include <mysql/mysql.h>

include <ctype.h>

include <curl/curl.h>

define BLOCKSIZE 1024

my_bool curl_init(UDF_INIT initid, UDF_ARGS args, char message); void curl_deinit(UDF_INIT initid); char curl(UDF_INIT initid, UDF_ARGS args, char result, unsigned long length, char is_null, char *error);

my_bool curl_init(UDF_INIT initid, UDF_ARGS args, char *message) { if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) { strcpy(message,"Wrong arguments to metaphon; Use the source"); return 1; } return 0; }

void curl_deinit(UDF_INIT *initid) { free(initid->ptr); }

char curl(UDF_INIT initid, UDF_ARGS args, char result, unsigned long length, char is_null, char error attribute*1 == BLOCKSIZE) { n = 0; p += BLOCKSIZE; nbuf = realloc(buf, p+BLOCKSIZE); if (!nbuf) { break; } buf = nbuf; } fclose(file);

*length = n + p; initid->ptr = buf;

return buf; }[/c]

コンパイルして、/usr/libにコピー

# gcc  -lcurl  -shared -fPIC my_curl.c -o my_curl.so
# cp my_curl.so /usr/lib/

mysqlからの使用

とりあえず、「http://www.yahoo.co.jp/」にアクセスして、コンテンツをひろってくる。

mysql> create table t2(id integer auto_increment, url text, primary key(id));
mysql> insert into t2 set url = 'http://www.yahoo.co.jp/';
mysql> create function curl returns string soname 'my_curl.so';
mysql> select length(curl(url))  from t2;
+-------------------+
| length(curl(url)) |
+-------------------+
|             67649 |
+-------------------+
1 row in set (2.74 sec)


面白いかなと思ったけど大したことなかったな。
しかもちょっと遅いし。
あとポインタ殆ど忘れていたことが判明した。

*1:unused))) { const char url=args->args[0]; int n,p=0; char buf,nbuf; FILE *file; file = tmpfile();

CURL *h = curl_easy_init(); curl_easy_setopt(h, CURLOPT_VERBOSE, 0); curl_easy_setopt(h, CURLOPT_URL, url); curl_easy_setopt(h, CURLOPT_WRITEDATA, file); curl_easy_perform(h); curl_easy_cleanup(h);

rewind(file); buf = (char )malloc(BLOCKSIZE); if (!buf) { fclose(file); is_null = 1; return 0; } while ((n=fread(buf+p, 1, BLOCKSIZE, file