シェルスクリプトマガジン

香川大学SLPからお届け!(Vol.59掲載)

著者:竹原一駿

USB接続のバーコードリーダーを用いてバーコード化されたデータを読み取り、その結果をサーバーに送って集計するデータ収集システムを開発しました。今回は、同システムについて紹介します。クライアントはGo、集計サーバーは主にPerlで記述しています。クライアントもサーバーもDocker環境で簡単に動かせますので、ぜひ試してみてください。

シェルスクリプトマガジン Vol.59は以下のリンク先でご購入できます。

図8 バーコードリーダーで読み取ったデータを取得する関数

func ScanStdin() string {
  stdin := bufio.NewScanner(os.Stdin)
  stdin.Scan()
  return stdin.Text()
}

図9 意見を示す数値を文字列に変換するコード

const AGREE = "100" // 賛成
 const OPPOSITE = "200" // 反対
 const NEUTRAL = "300" // 中立

 if sData == AGREE {
   sData = "agree" // 意見の文字列を代入
 } else if sData == OPPOSITE {
   sData = "opposite"
 } else if sData == NEUTRAL {
   sData = "neutral"
 }

図10 データを集計サーバーに送るためのコード

resp, err := http.Get(baseurl)
if err != nil {
  fmt.Println(err)
  return err
}
defer resp.Body.Close()

図11 HTTPサーバー機能を提供するMyWebServerパッケージの記述

#!/usr/bin/perl
{
  package MyWebServer;
  use HTTP::Server::Simple::CGI;
  use base qw(HTTP::Server::Simple::CGI); #継承
  use strict;
  use warnings;
  # 以降の処理はここに書く.
}
my $pid = MyWebServer->new(80)->run();

図12 CGIで日本語を表示するための記述

print $cgi->header(-charset=>"utf-8"),
      $cgi->start_html(-lang => 'ja','Not found'),
      $cgi->h1('Not found'),
      $cgi->end_html;

図13 ハッシュ変数にサブルーチンのリファレンスを保存

my %dispatch = (
  '/index' => \&resp_index, # index
  '/insert' => \&resp_insert, # データの挿入
  '/operate' => \&resp_operate, # 質問番号の調整
  '/analy' => \&resp_analy, # 解析
);

図14 insertページを表示するコード

sub resp_insert {
  my $cgi = shift;
  return if !ref $cgi;

  my $user = $cgi->param('user'); # ユーザーID
  my $opi = $cgi->param('opi'); # 意見
  my $dbh = DBI->connect(
            "dbi:mysql:database=opinidb;".
            "host=mysql;port=3306",
            'user','password'
            ); #データベースの接続
  my $sth = $dbh->prepare(
            "INSERT INTO
            opinidb.opinion(USER,NUM,OPI)".
            " VALUES (?,?,?);"
            );
  $sth->execute($user,$ques_num,$opi); # SQL生成,実行
  $sth->finish;
  $dbh->disconnect; #接続終了
  print $cgi->header(-charset=>"utf-8"),
        $cgi->start_html("insert"),
        $cgi->h1("Question number is $ques_num"),
        "ユーザ:$user, 意見$opi",
        $cgi->end_html;
  }

図15 analyページを表示するコード

my @opilist = ('agree','opposite','neutral');

print $cgi->header(-charset=>"utf-8");
print $cgi->start_html(-lang => 'ja',"analy");
foreach(@opilist){
  print $cgi->h2("count : ".$_);
  my $sth = $dbh->prepare(
              "SELECT NUM AS ques_num , ".
              "COUNT(*) AS countopi ".
              "FROM opinidb.opinion ".
              "WHERE OPI LIKE '\%".$_."\%' ".
              "GROUP BY ques_num"
            );
  $sth->execute(); # SQL生成,実行
  print '<table border=1>';
  print '<tr><th>質問番号</th><th>選んだ人数</th></tr>';
  while(my $datahash = $sth->fetchrow_hashref){
    print '<tr><td>'.
    $datahash->{'ques_num'}.'</td><td>'.
    $datahash->{'countopi'}.'</td></tr>';
  }
  print '</table>';
  $sth->finish;
}