土曜日, 1月 07, 2017

初Mojolicious::Liteアプリサンプル

OS: CentOS 7.3
Perl: 5.24.0
Mojolicious: 7.14
DBI: 1.636
DBIx::Connector: 0.56
DBD::ODBC: 1.56

----- ここから -----
#!/usr/bin/env perl

use strict;
use warnings;

use Mojolicious::Lite;
use DBIx::Connector;

my $db_host   = 'db1';
my $dsn       = 'dbi:ODBC:' . $db_host;
my $db_name   = 'sample';
my $db_user   = 'db_user_name';
my $db_passwd = 'db_user_passwd';

# DB接続
my $conn = DBIx::Connector->new($dsn, $db_user, $db_passwd) or die $!;
helper db => sub { return $conn->dbh; };

# サイトID取得
helper get_site_id => sub {
    my $self = shift;
    my $stmt = "SELECT [site_id] FROM $db_name.$db_user.site";
    my $sth = $self->db->prepare($stmt) or die $self->db->errstr;
    $sth->{LongTruncOk}=1;
    $sth->{LongReadLen}=2000000;
    $sth->execute or die $self->db->errstr;
    my @site_ids = ();
    while (my @row = $sth->fetchrow_array) {
        push @site_ids, $row[0];
    }
    $sth->finish;
    return \@site_ids;
};

# サイトプロパティ取得
helper get_site_properties => sub {
    my $self = shift;
    $site_id = $_[0];
   
    if ($site_id) {
        my $stmt = "SELECT [property_key], [property_value], [description] FROM $db_name.$db_user.site_properties WHERE site_id = ?";
        my $sth = $self->db->prepare($stmt) or die $self->db->errstr;
        $sth->{LongTruncOk}=1;
        $sth->{LongReadLen}=2000000;
        $sth->execute($site_id) or die $self->db->errstr;
        my @properties = ();
        while (my @row = $sth->fetchrow_array) {
            push @properties, {'property_key' => $row[0], 'property_value' => $row[1], 'description' => $row[2]};
        }
        $sth->finish;
        return \@properties;
    }
};

# ベースルートの設定
any '/' => sub {
    my $self = shift;
    my $site_ids = $self->get_site_id();
    $self->stash( site_ids => $site_ids );
    $self->render('index');
};

# サイトプロパティ取得用ルートの設定
any '/site_properties' => sub {
    my $self = shift;
    my $site_id = $self->param('site_id');
    my $properties = $self->get_site_properties($site_id);
    $self->render(json => $properties);
};

app->start;

__DATA__

@@ index.html.ep

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="robots" content="noindex,nofollow" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>e2R Utilities</title>
<%= stylesheet '//www.foobar.com/common/css/bootstrap.min.css' %>
<%= stylesheet '//www.foobar.com/common/css/bootstrap-theme.min.css' %>
</head>
<body>
<div class="container">

<div class="row">
<div class="col-md-12">
<h3>ユーティリティ</h3>
</div>
</div>
<br />

<div class="row">
<div class="col-md-12">

<div class="well well-sm">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="site_id" class="col-sm-2 control-label">サイトID</label>
<div class="col-sm-6">
<select name="site_id" class="form-control">
<option value=""></option>
% foreach my $site_id (@$site_ids) {
<option value="<%= $site_id %>"><%= $site_id %></option>
% }
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" id="site-property-btn" class="btn btn-primary">サイトプロパティ表示</button>
</div>
</div>
</form>
</div>

</div>
</div>
<br />

<div class="row">
<div class="col-md-12">
<div id="site-property-block">
<strong>サイトプロパティ</strong><br />
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th>キー</th>
<th>値</th>
<th>説明</th>
</tr>
</thead>
<tbody id="site-property-list"></tbody>
</table>
</div>
</div>
</div>

</div>

<!-- template -->
<script type="text/template" id="property-list-template">
<tr>
<td>{{ property_key }}</td>
<td>{{ property_value }}</td>
<td>{{ description }}</td>
</tr>
</script>

<!-- javascript -->
%= javascript '//www.foobar.com/common/js/underscore.min.js';
%= javascript '//www.foobar.com/common/js/jquery.min.js';
%= javascript begin
(function() {

var root = this,
    _    = root._,
    $    = root.jQuery;

_.templateSettings = {
  interpolate: /\{\{(.+?)\}\}/g
};

$.ajaxSettings.contentType
  = 'application/x-www-form-urlencoded; charset=UTF-8';

var propertyListTemplate
  = _.template($("#property-list-template").html());

var escapeHtml = function(string) {
  if (typeof string !== 'string') {
    return string;
  }
  return string.replace(/[&'`"<>]/g, function(match) {
    return {
      '&': '&amp;',
      "'": '&#x27;',
      '`': '&#x60;',
      '"': '&quot;',
      '<': '&lt;',
      '>': '&gt;',
    }[match]
  });
};

$(function() {
  $('#site-property-block').hide();

  $('#site-property-btn').on('click', function() {
    $('#site-property-block').hide();

    if (!$('[name=site_id]').val()) {
      alert('サイトIDを選択してください。');
      return false;
    }

    $.ajax({
      url : '/app/site_properties',
      type : "POST",
      cache : false,
      dataType : "json",
      data : {
        "site_id" : $('[name=site_id]').val()
      }
    }).done(function(json) {
      var propertyListHtml = "";
      _.each(json, function(value) {
        propertyListHtml
          += propertyListTemplate({
               property_key : value["property_key"],
               property_value : escapeHtml(value["property_value"]),
               description : value["description"]
             });
      });
      $('#site-property-list').html(propertyListHtml);
      $('#site-property-block').show();
    }).fail(function() {
      alert("サイトプロパティの取得に失敗しました。");
      return false;
    });
  });
});

}).call(this);
% end

</body>
</html>
----- ここまで -----

0 件のコメント: