summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2016-08-13 13:45:12 -0400
committerJesse Luehrs <doy@tozt.net>2016-08-13 13:45:12 -0400
commit3214feb89ffca3e8432805c048b3879d0146b0c0 (patch)
tree18f842cdccbb7edeaebf1270108089913f17f056 /lib
parentd12114019f91718f26a32012f610a249e0f359ff (diff)
downloadchart-clicker-sql-3214feb89ffca3e8432805c048b3879d0146b0c0.tar.gz
chart-clicker-sql-3214feb89ffca3e8432805c048b3879d0146b0c0.zip
start working on a simple repl
Diffstat (limited to 'lib')
-rw-r--r--lib/Chart/Clicker/SQL/REPL.pm146
1 files changed, 146 insertions, 0 deletions
diff --git a/lib/Chart/Clicker/SQL/REPL.pm b/lib/Chart/Clicker/SQL/REPL.pm
new file mode 100644
index 0000000..dca39f9
--- /dev/null
+++ b/lib/Chart/Clicker/SQL/REPL.pm
@@ -0,0 +1,146 @@
+package Chart::Clicker::SQL::REPL;
+use Moose;
+use 5.020;
+use feature 'signatures', 'postderef';
+no warnings 'experimental::signatures';
+no warnings 'experimental::postderef';
+
+use Browser::Open;
+use File::HomeDir;
+use File::Spec;
+use File::Temp;
+use Module::Runtime;
+use Path::Class;
+use Term::ReadLine;
+
+use Chart::Clicker::SQL;
+
+has sql => (
+ is => 'rw',
+ isa => 'Chart::Clicker::SQL',
+ predicate => 'initialized',
+);
+
+has history_file => (
+ is => 'ro',
+ isa => 'Str',
+ default => sub {
+ my $filename = File::Spec->catfile(
+ File::HomeDir->my_data,
+ '.ccsql_history'
+ );
+ file($filename)->touch;
+ return $filename;
+ },
+);
+
+has rl => (
+ is => 'ro',
+ isa => 'Term::ReadLine',
+ lazy => 1,
+ default => sub ($self) {
+ my $rl = Term::ReadLine->new(__PACKAGE__);
+ for my $line (file($self->history_file)->slurp(chomp => 1)) {
+ $rl->addhistory($line);
+ }
+ return $rl;
+ },
+);
+
+has chart_options => (
+ is => 'ro',
+ isa => 'HashRef',
+ default => sub {
+ {
+ width => 1000,
+ height => 600,
+ set_renderer => Chart::Clicker::Renderer::Line->new,
+ }
+ },
+);
+
+has last_query => (
+ is => 'rw',
+ isa => 'Str',
+ predicate => 'has_last_query',
+);
+
+sub dsn ($self, $dsn) {
+ $self->sql(Chart::Clicker::SQL->new(dsn => $dsn));
+}
+
+sub select ($self, $query) {
+ $query = "select $query";
+ $self->last_query($query);
+ $self->_draw;
+}
+
+sub _draw ($self) {
+ if (!$self->initialized) {
+ warn "not initialized";
+ return;
+ }
+ if (!$self->has_last_query) {
+ warn "no active query";
+ return;
+ }
+ my $chart = $self->sql->render($self->last_query);
+ $self->_configure_chart($chart);
+ my ($fh, $filename) = File::Temp::tempfile(SUFFIX => '.png', UNLINK => 1);
+ $chart->draw;
+ $fh->write($chart->rendered_data);
+ $fh->flush;
+ Browser::Open::open_browser("file://$filename");
+}
+
+sub size ($self, $size) {
+ my ($width, $height) = split ' ', $size;
+ $self->chart_options->{width} = $width;
+ $self->chart_options->{height} = $height;
+}
+
+sub title ($self, $title) {
+ $self->chart_options->{title} = $title;
+}
+
+for my $renderer (qw(Line StackedLine Bar StackedBar Area StackedArea Point)) {
+ __PACKAGE__->meta->add_method(lc($renderer) => sub ($self, $args) {
+ my $renderer_class = "Chart::Clicker::Renderer::$renderer";
+ Module::Runtime::require_module($renderer_class);
+ $self->chart_options->{set_renderer} = $renderer_class->new;
+ $self->_draw;
+ })
+}
+
+sub _configure_chart ($self, $chart) {
+ $chart->get_context('default')->range_axis->tick_division_type("LinearRounded");
+ for my $opt (keys $self->chart_options->%*) {
+ $chart->$opt($self->chart_options->{$opt})
+ if $chart->can($opt);
+ }
+}
+
+sub run ($self) {
+ while (1) {
+ if (defined(my $input = $self->rl->readline("> "))) {
+ next unless length($input);
+ chomp($input);
+ last if $input eq 'exit';
+ my ($command, $args) = split(' ', $input, 2);
+ $self->$command($args);
+ }
+ else {
+ print "\n";
+ last;
+ }
+ }
+}
+
+sub DEMOLISH ($self, $igd) {
+ $self->rl->WriteHistory($self->history_file);
+}
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;