鈍足ランナーのIT日記

走るのが好きな5流のITエンジニアのブログ。

趣味の範囲は広いけど、どれも中途半端なクソブロガー楽しめるWebアプリを作ってあっと言わせたい。サーバーサイドPerl(Mojolicious)、クライアントサイドVue.js。Arduinoにも触手を伸ばす予定。

TengでMySQLのLINESTRING型にinsert

Teng->insertを使う

my $marker = $teng->insert('Route',
{g=> "GeomFromText('LINESTRING" . $path . "')", name => $name, create_user=> "test_user", create_at => $dt});

今のところ、エラーとなった。

@@@@@ Teng 's Exception @@@@@
Reason  : DBD::mysql::st execute failed: Cannot get geometry object from data you send to the GEOMETRY field at /usr/lib/perl5/site_perl/5.14/Teng.pm line 236.

SQL     : INSERT INTO `Route`
          (`create_at`, `g`, `name`, `create_user`)
          VALUES (?, ?, ?, ?)
BIND    : $VAR1 = [
          [
            '2013-05-14 05:44:20',
            undef
          ],
          [
            'GeomFromText(\'LINESTRING(35.69034569127357 139.75294947624206,35.690380000000005 139.75302000000002,35.689890000000005 139.75341)\')',
            undef
          ],
          [
            'test',
            undef
          ],
          [
            'test_user',
            undef
          ]
        ];

さて、どうするか・・・

Teng->doを使う

では、Teng->doをつかえば、生SQLを発行できるようなので・・・

$teng->do(qq{
    Insert into Route 
    (g, name, create_user, create_at)
    values
     (GeomFromText('LINESTRING $path '), '$name', 'test_user', NOW())
});

でも、なんかかっこ悪いな。変数をSQLに入れるのは。 $pathに渡す値を"LINESTRING (11 22,22 33)"のように変えて ソースを以下のようにした。

$teng->do(qq{
    Insert into Route 
    (g, name, create_user, create_at)
    values
     (GeomFromText(?), ?, ?, NOW())
},undef,($path,$name,'test_user'));

一応これでインサートできた!。一件落着。doは便利だなぁ。(ほぼ生SQLですが・・・) teng力++

Teng->insertでSQL関数を呼ぶ方法がありました。

@tsucchi1022さんから、コメントいただきました。ありがとうございます。 コメントを参考に、ソースを以下のよう変更しました。

my $route = $teng->insert('Route',
{g=> \["GeomFromText(?)", $path],
name => $name, 
create_user=> "test_user", 
create_at => \"Now()"});

それと、スキーマ定義のcreate_atのdeflateをコメント化しました。

table {
    name 'Route';
    pk id;
    columns qw( id name g create_user create_at );

    inflate 'create_at' => sub {
        DateTime::Format::MySQL->parse_datetime(shift);
    };
#    deflate 'create_at' => sub {
#        DateTime::Format::MySQL->format_datetime(shift);
#    };
};

うまく、関数がよばれるようになりましたw。 文字列をリファレンスで渡すんですね。 今まで、Perlで現在日付を渡していたのが、コーディング量が減らせる。 これは、便利だぁ。Teng力++。 tsucchi1022さんに重ね重ね、感謝です。

まだまだ、手探り状態

今回作っている地図系アプリは、以前作ったゲリライベントを 元にもう少し複雑なものに挑戦しています。 一歩踏み込むと分からないことって結構 あるんで、その辺のノウハウを書き留めていければなと思います。