Skip to content

Instantly share code, notes, and snippets.

@jberger
Last active August 29, 2015 14:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jberger/e9ce5820066d4afd17f4 to your computer and use it in GitHub Desktop.
Save jberger/e9ce5820066d4afd17f4 to your computer and use it in GitHub Desktop.
Updated WebSocket DBI Example
#!/usr/bin/env perl
use Mojolicious::Lite;
use DBIx::Connector;
my $dbname = $ENV{MOJO_DBNAME} || 'database.db';
# add helper methods for interacting with database
helper connector => sub {
state $db = DBIx::Connector->new("dbi:SQLite:$dbname","","") or die "Could not connect";
};
helper db => sub { shift->connector->dbh };
helper create_table => sub {
my $self = shift;
$self->app->log->info("Creating table 'people'");
$self->db->do('CREATE TABLE people (name varchar(255), age int);');
};
helper empty_table => sub {
my $self = shift;
$self->app->log->info("Emptying table 'people'");
$self->db->do('DELETE FROM people');
};
helper select => sub {
my $self = shift;
my $sth = eval { $self->db->prepare('SELECT * FROM people') } || return undef;
$sth->execute;
return $sth->fetchall_arrayref;
};
helper insert => sub {
my $self = shift;
my ($name, $age) = @_;
my $sth = eval { $self->db->prepare('INSERT INTO people VALUES (?,?)') } || return undef;
$sth->execute($name, $age);
return 1;
};
# if statement didn't prepare, assume its because the table doesn't exist
app->select || app->create_table;
# setup base route
any '/' => sub {
my $self = shift;
my $rows = $self->select;
$self->render('index', rows => $rows );
};
# setup websocket message handler
websocket '/insert' => sub {
my $self = shift;
$self->on( json => sub {
my ($ws, $row) = @_;
$self->insert(@$row);
my $html = $ws->render_to_string( 'table', rows => [$row] );
$ws->send({ json => {row => $html} });
});
};
app->start;
__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html>
<head>
<title>People</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div class="form-inline" role="form">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name">
</div>
<div class="form-group">
<label for="age">Age</label>
<input type="text" class="form-control" id="age" >
</div>
<input type="submit" value="Add" onclick="insert()">
</div>
<p>Data:</p>
<div class="row"><div class="col-md-6">
<table class="table table-bordered table-condensed">
<thead>
<tr><th>Name</th><th>Age</th></tr>
</thead>
<tbody id="table">
%= include 'table'
</tbody>
</table>
</div></div>
</div>
%= javascript begin
function insert () {
if (!("WebSocket" in window)) {
alert('Your browser does not support WebSockets!');
return;
}
var ws = new WebSocket("<%= url_for('insert')->to_abs %>");
ws.onopen = function () {
var name = $('#name');
var age = $('#age');
ws.send(JSON.stringify([name.val(),age.val()]));
name.val('');
age.val('');
};
ws.onmessage = function (evt) {
var data = JSON.parse(evt.data);
$('#table').append(data.row);
};
}
%= end
</body>
</html>
@@ table.html.ep
% foreach my $row (@$rows) {
<tr>
% foreach my $text (@$row) {
<td><%= $text %></td>
% }
</tr>
% }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment