Skip to content

Instantly share code, notes, and snippets.

@Xliff
Created January 7, 2021 02:15
Show Gist options
  • Save Xliff/fcf214158ad5d9da0bf5ae25b9b72dc0 to your computer and use it in GitHub Desktop.
Save Xliff/fcf214158ad5d9da0bf5ae25b9b72dc0 to your computer and use it in GitHub Desktop.
Why is this Trait definition giving me this weird error…

This trait definition:

role Query                   { }
role DefaultQuery does Query { }
multi sub trait_mod:<is> (Method $m, :$default-query is required) {
  $m does DefaultQuery;
  $m.wrap(method (|c) {
    my $sth = $dbh.prepare( _getSQL($m) );
    $sth.execute;
    $sth.allrows;
  });
 }

Now when I use it on a method like this:

 #| SELECT url, name
 #| FROM control_records
 #| WHERE state = 1
 #| ORDER BY url, name
 multi method getActiveSites {
 
 }

It gives me the following error when I try to compile it using cro run:

Lexical with name '$m' does not exist in this frame
at /home/cbwood/Work/.../CountCollector/app/lib/MyApp/Queries.pm6 (MyApp::Queries):101
at /home/cbwood/Work/.../CountCollector/app/service.p6:3

Might someone familiar with Cro have some idea as to why this is occurring?

@Xliff
Copy link
Author

Xliff commented Jan 9, 2021

Here is the entire compunit:

use v6;

use DBIish;

my $dbh;

sub _getSQL ($r) { $r.WHY.leading }

role Query                   { }
role DefaultQuery does Query { }

multi sub trait_mod:<is> (Method $m is copy, :$query!) {
  $m does Query;
  my $r = $m;
  $m.wrap(method (|c) {
    say 'Wrap';
    my $*sth = $dbh.prepare( _getSQL($r) );
    $*sth.say;
    $*sth.execute(|c);
    nextsame;
  });
}
#
# multi sub trait_mod:<is> (Method $m, :$default-query is required) {
#   $m does DefaultQuery;
#   $m.wrap(method (|c) {
#     my $sth = $dbh.prepare( _getSQL($m) );
#     $*args ?? $sth.execute( |$*args ) !! $sth.execute;
#     $sth.allrows if $sth.rows;
#   });
# }

use Bizzell::Roles::Template;

class Bizzell::Queries {
  also does Bizzell::Roles::Template;

  has %!config;

  my $*args = Nil;

  submethod BUILD ( :$config ) {
    self.openCollectorDB( %!config = $config );
  }

  multi method new (%config) {
    self.bless( :%config );
  }

  method dispose {
    $dbh.dispose;
  }

  method openCollectorDB (%config) {
    $dbh = DBIish.connect(
      %config<engine>,
      database => %config<database>,
      user     => %config<user>,
      password => %config<password>,
      hostname => %config<hostname>
    );
  }

  #| SELECT id
  #| FROM control_records
  #| WHERE url = ? AND name = ?
  method checkSite ($url, $name) is query {
    #my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    #$*sth.execute($url, $name);
    my $r = $*sth.allrows;
    $r.elems ?? $r[0][0] !! Nil
  }

  #| INSERT INTO control_records (url, name, password, state)
  #| VALUES (?, ?, ?, 1)
  method registerSite ($url, $name, $password) is query {
    #my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    #$*sth.execute($url, $name, $password);
  }

  #| SELECT url, name
  #| FROM control_records
  #| WHERE state = 1
  #| ORDER BY url, name
  multi method getActiveSites {
    my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    $sth.execute;
    $sth.allrows;
  }

  #| SELECT url, name, password
  #| FROM control_records
  #| WHERE state = 1
  #| ORDER BY url, name
  multi method getActiveSites(:$password is required) {
    my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    $sth.execute;
    $sth.allrows;
  }

  #| SELECT date, count
  #| FROM site_counts
  #| WHERE url = ? AND name = ?
  #| ORDER BY date DESC
  method getCollectedCounts ($url, $name) {
    #my $*args = [$url, $name];
    #my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    #$sth.execute($url, $name);
    $*sth.allrows;
  }

  #| SELECT id
  #| FROM site_counts
  #| WHERE
  #|   url  = ? AND
  #|   date = ? AND
  #|   name = ?
  method getSiteCount ($url, $date, $name) is query {
    $*sth.allrows
  }

  method setCollectedCount ($url, $name, $date, $count) {
    my $r = self.getSiteCount($url, $date, $name);
    if $r.elems {
      self.updateCollectedCount($r[0][0], $count);
    } else {
      self.insertCollectedCount($url, $name, $date, $count);
    }
  }

  #| INSERT INTO site_counts (url, name, date, count)
  #| VALUES (?, ?, ?, ?)
  method insertCollectedCount ($url, $name, $date, $count) is query {
    #my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    #$sth.execute($url, $name, $date, $count);
  }

  #| UPDATE site_counts
  #| SET count = ?
  #| WHERE id = ?
  method updateCollectedCount ($id, $count) is query {
    # my $sth = $dbh.prepare( _getSQL(&?ROUTINE) );
    # $sth.execute($id, $count);
  }

}

@Xliff
Copy link
Author

Xliff commented Jan 9, 2021

So removing BRT solved the issue. All that was supposed to do would be to allow Cro::WebApp::Templates to come from strings rather than files. Here's that code:

use v6;

use Cro::WebApp::Template::ASTBuilder;
use Cro::WebApp::Template::Parser;
use Cro::WebApp::Template::Repository;

role Bizzell::Roles::Template {
  has $!template-repo;

  submethod TWEAK {
    $!template-repo = Cro::WebApp::Template::Repository.new
  }

  method render ($template, *%params) {
    my $*TEMPLATE-REPOSITORY = $!template-repo;
    my $ast = Cro::WebApp::Template::Parser.parse(
      $template,
      actions => Cro::WebApp::Template::ASTBuilder
    ).ast;

    Cro::WebApp::Template::Compiled.new(
      |$ast.compile,
      repository => $!template-repo
    ).render(%params);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment