node-mysqlでTEXT型使ってたら文字化けした


node-mysqlの0.9.6を使っていたら、TEXT型のカラムのデータが時々文字化けする現象に出くわした。
node-mysqlはJavaScriptだけで全部できてたので、ソースを追って調べてみた。

調査


mysql/lib/query.jsに

row[field.name] += buffer.toString('utf-8');

となっていて、BufferをUTF-8の文字列にしてから連結している部分を発見。ここが怪しい。

対応


Bufferをいったん保持しておいて、最終的に連結して文字列化するように変更してみた。
以下、差分。

5a6,19
> function joinBuffers(buffers) {
>     var i, len = buffers.length, size = 0;
>     for (i = 0; i < len; i++) {
>         size += buffers[i].length;
>     }
>     var result = new Buffer(size);
>     var buffer, from = 0;
>     while (buffer = buffers.shift()) {
>         buffer.copy(result, from, 0);
>         from += buffer.length;
>     } 
>     return result;
> }
> 
62c76
<           row[field.name] = '';
---
>           row[field.name] = [];
66,68c80
<           row[field.name] += buffer.toString('utf-8');
<         } else {
<           row[field.name] = null;
---
>           row[field.name].push(buffer);
72a85,90
>         }
> 
>         if (row[field.name].length > 0) {
>             row[field.name] = joinBuffers(row[field.name]).toString('utf-8');
>         } else {
>             row[field.name] = null;

結果


解決したっぽい。文字化けしなくなった。
githubでforkして修正をpull request投げてみようかと思ったけど、
なんか開発進んでだいぶ様変わりしてるみたいなので、そっとブラウザを閉じた。