Red.git | docs/coverage/report-data/ | Red-Driver-Pg.html


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>RaCoCo result: Red::Driver::Pg</title>
	<link rel="stylesheet"
				href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
				integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
				crossorigin="anonymous">
	<style>
      pre.code::before {
          counter-reset: listing;
      }

      pre.code span {
          counter-increment: listing;
      }

      pre.code span::before {
          content: counter(listing) ". ";
      }

      .coverage-green {
          background-color: #32CD32;
          /*color-blind
          background-color: #00CED1;
          /**/
      }

      .coverage-red {
          background-color: #fa8072;
      }

      .coverage-purple {
          background-color: #9370DB;
      }
	</style>
</head>
<body>
<div class="container">
	<div class="row mt-5 mb-3">
		<div class="col-12">
			<div class="page-header">
				<h1>Red::Driver::Pg 2.3%</h1>
			</div>
		</div>
	</div>
	<div class="row justify-content-md-center">
		<div class="col-md-10">
			<pre class="code">
<span class="coverage-green">use DB::Pg;</span>
<span class="coverage-no">use Red::Driver;</span>
<span class="coverage-no">use Red::Driver::CommonSQL;</span>
<span class="coverage-no">use Red::Statement;</span>
<span class="coverage-no">use Red::AST::Unary;</span>
<span class="coverage-no">use Red::AST::Infixes;</span>
<span class="coverage-no">use X::Red::Exceptions;</span>
<span class="coverage-no">use Red::AST::TableComment;</span>
<span class="coverage-no">use Red::Type::Json;</span>
<span class="coverage-no">need UUID;</span>
<span class="coverage-no"></span>
<span class="coverage-green">unit class Red::Driver::Pg does Red::Driver::CommonSQL;</span>
<span class="coverage-no"></span>
<span class="coverage-no">has Str $!user;</span>
<span class="coverage-no">has Str $!password;</span>
<span class="coverage-no">has Str $!host;</span>
<span class="coverage-no">has Int $!port;</span>
<span class="coverage-no">has Str $!dbname;</span>
<span class="coverage-no">has $.dbh;</span>
<span class="coverage-no"></span>
<span class="coverage-no"></span>
<span class="coverage-red">method schema-reader {}</span>
<span class="coverage-no">#| Data accepted by the Pg driver constructor:</span>
<span class="coverage-no">#| dbh     : DB::Pg object</span>
<span class="coverage-no">#| user    : User to be used to connect to the database</span>
<span class="coverage-no">#| password: Password to be used to connect to the database</span>
<span class="coverage-no">#| host    : To be connected to</span>
<span class="coverage-no">#| port    : What port to connect</span>
<span class="coverage-no">#| dbname  : Database name</span>
<span class="coverage-red">submethod BUILD(:$!dbh, Str :$!user, Str :$!password, Str :$!host = &quot;127.0.0.1&quot;, Int :$!port = 5432, Str :$!dbname) {</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">submethod TWEAK() {</span>
<span class="coverage-red">    $!dbh //= DB::Pg.new:</span>
<span class="coverage-red">        conninfo =&gt; &quot;{</span>
<span class="coverage-red">            &quot;user=$_&quot; with $!user</span>
<span class="coverage-red">        } {</span>
<span class="coverage-red">            &quot;password=$_&quot; with $!password</span>
<span class="coverage-red">        } {</span>
<span class="coverage-red">            &quot;host=$_&quot; with $!host</span>
<span class="coverage-red">        } {</span>
<span class="coverage-red">            &quot;port=$_&quot; with $!port</span>
<span class="coverage-red">        } {</span>
<span class="coverage-red">            &quot;dbname=$_&quot; with $!dbname</span>
<span class="coverage-no">        }&quot;</span>
<span class="coverage-no">    ;</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">method new-connection($dbh = $!dbh) {</span>
<span class="coverage-red">    self.clone: dbh =&gt; $dbh</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">method begin {</span>
<span class="coverage-red">    my $dbh = $!dbh.db;</span>
<span class="coverage-red">    $dbh.begin;</span>
<span class="coverage-red">    self.new-connection: $dbh</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">method commit {</span>
<span class="coverage-no">    #die &quot;Not in a transaction!&quot; unless $*RED-TRANSCTION-RUNNING;</span>
<span class="coverage-red">    $!dbh.commit.finish;</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">method rollback {</span>
<span class="coverage-no">    #die &quot;Deu ruim!!!&quot;;</span>
<span class="coverage-no">    #die &quot;Not in a transaction!&quot; unless $*RED-TRANSCTION-RUNNING;</span>
<span class="coverage-red">    $!dbh.rollback;</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">method wildcard { &quot;\${ ++$*bind-counter }&quot; }</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Not $_ where .value ~~ Red::Column, $context?) {</span>
<span class="coverage-red">    self.translate: Red::AST::Cast.new(.value, &quot;boolean&quot;).not</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::AND $_ where .left ~~ Red::Column, $context?) {</span>
<span class="coverage-red">    self.translate: Red::AST::AND.new: Red::AST::Cast.new(.left, &quot;boolean&quot;), .right</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::AND $_ where .right ~~ Red::Column, $context?) {</span>
<span class="coverage-red">    self.translate: Red::AST::AND.new: .left, Red::AST::Cast.new(.right, &quot;boolean&quot;)</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::OR $_ where .left ~~ Red::Column, $context?) {</span>
<span class="coverage-red">    self.translate: Red::AST::OR.new: Red::AST::Cast.new(.left, &quot;boolean&quot;), .right</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::OR $_ where .right ~~ Red::Column, $context?) {</span>
<span class="coverage-red">    self.translate: Red::AST::OR.new: .left, Red::AST::Cast.new(.right, &quot;boolean&quot;)</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Cast $_ where { .type eq &quot;boolean&quot; &amp;&amp; .value.?returns ~~ DateTime }, $context?) {</span>
<span class="coverage-red">    self.translate: Red::AST::IsDefined.new: .value;</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::Column $_, &quot;column-auto-increment&quot;) {}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Select $_, $context?, :$gambi where !*.defined) {</span>
<span class="coverage-red">    my $bind-counter = $*bind-counter // 0;</span>
<span class="coverage-red">    {</span>
<span class="coverage-red">        my Int $*bind-counter = $bind-counter;</span>
<span class="coverage-red">        self.Red::Driver::CommonSQL::translate($_, $context, :gambi);</span>
<span class="coverage-no">    }</span>
<span class="coverage-no">}</span>
<span class="coverage-red">multi method translate(Red::AST::Update $_, $context?, :$gambi where !*.defined) {</span>
<span class="coverage-red">    my Int $*bind-counter;</span>
<span class="coverage-red">    self.Red::Driver::CommonSQL::translate($_, $context, :gambi);</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method wildcard-value(@val) { @val.map: { self.wildcard-value: $_ } }</span>
<span class="coverage-red">multi method wildcard-value($_ where { .HOW ~~ Metamodel::EnumHOW }) { .value }</span>
<span class="coverage-red">multi method wildcard-value(Red::AST::Value $_) {</span>
<span class="coverage-red">    self.wildcard-value: .get-value</span>
<span class="coverage-no">}</span>
<span class="coverage-red">multi method wildcard-value(Bool $_) { .Int }</span>
<span class="coverage-red">multi method wildcard-value($_) { $_ }</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::RowId $_, $context?) { &quot;OID&quot; =&gt; [] }</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Delete $_, $context?, :$gambi where !*.defined) {</span>
<span class="coverage-red">    my Int $*bind-counter;</span>
<span class="coverage-red">    self.Red::Driver::CommonSQL::translate($_, $context, :gambi);</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Insert $_, $context?) {</span>
<span class="coverage-red">    my Int $*bind-counter;</span>
<span class="coverage-red">    my @values = .values.grep({ .value.value.defined });</span>
<span class="coverage-red">    return &quot;INSERT INTO { self.table-name-wrapper: .into.^table } DEFAULT VALUES RETURNING *&quot; =&gt; [] unless @values;</span>
<span class="coverage-no"></span>
<span class="coverage-no">    # TODO: User translation</span>
<span class="coverage-red">    my @bind = @values.map: { self.wildcard-value: .value }</span>
<span class="coverage-red">    &quot;INSERT INTO {</span>
<span class="coverage-red">        self.table-name-wrapper: .into.^table</span>
<span class="coverage-red">    }(\n{</span>
<span class="coverage-red">        @values&gt;&gt;.key.join(&quot;,\n&quot;).indent: 3</span>
<span class="coverage-red">    }\n)\nVALUES(\n{</span>
<span class="coverage-red">        (self.wildcard xx @values).join(&quot;,\n&quot;).indent: 3</span>
<span class="coverage-no">    }\n) RETURNING *&quot; =&gt; @bind</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Mod $_, $context?) {</span>
<span class="coverage-red">    my ($ls, @lb) := self.translate: .left,  $context;</span>
<span class="coverage-red">    my ($rs, @rb) := self.translate: .right, $context;</span>
<span class="coverage-red">    &quot;mod($ls, $rs)&quot; =&gt; [|@lb, |@rb]</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Value $_ where .type ~~ Bool, $context?) {</span>
<span class="coverage-red">    (.value ?? &quot;'t'&quot; !! &quot;'f'&quot;) =&gt; []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Value $_ where .type ~~ UUID, $context?) {</span>
<span class="coverage-red">    &quot;'{ .value.Str }'&quot; =&gt; []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Value $_ where .type ~~ Rat, $context?) {</span>
<span class="coverage-red">    &quot;'{ .value }'::{ self.default-type-for-type: .type }&quot; =&gt; []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::Column $_, &quot;column-comment&quot;) {</span>
<span class="coverage-red">    (.comment ?? &quot;COMMENT ON COLUMN { self.translate: $_, &quot;table-dot-column&quot; } IS '{ .comment }'&quot; !! &quot;&quot;) =&gt; []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::Column $_, &quot;column-type&quot;)           {</span>
<span class="coverage-red">    if !.auto-increment &amp;&amp; .attr.type =:= Mu &amp;&amp; !.type.defined {</span>
<span class="coverage-red">        return self.type-by-name(&quot;string&quot;) =&gt; []</span>
<span class="coverage-no">    }</span>
<span class="coverage-red">    (.type.defined ?? self.type-by-name(.type) !! self.default-type-for: $_) =&gt; []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::TableComment $_, $context?) {</span>
<span class="coverage-red">    &quot;COMMENT ON TABLE { .table } IS '{ .msg }'&quot; =&gt; []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-green">class Statement does Red::Statement {</span>
<span class="coverage-red">    has Str $.query;</span>
<span class="coverage-red">    method stt-exec($stt, *@bind) {</span>
<span class="coverage-red">        $!driver.debug: $!query, @bind || @!binds;</span>
<span class="coverage-red">        my $db = $stt ~~ DB::Pg ?? $stt.db !! $stt;</span>
<span class="coverage-red">        my $sth = $db.prepare($!query);</span>
<span class="coverage-red">        my $s = $sth.execute(|(@bind or @!binds));</span>
<span class="coverage-red">        $db.finish if $stt ~~ DB::Pg;</span>
<span class="coverage-red">        do if $s ~~ DB::Pg::Results {</span>
<span class="coverage-red">            $s.hashes</span>
<span class="coverage-no">        } else {</span>
<span class="coverage-red">            []</span>
<span class="coverage-no">        }.iterator</span>
<span class="coverage-no">    }</span>
<span class="coverage-red">    method stt-row($stt) { $stt.pull-one }</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">method comment-on-same-statement { False }</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method prepare(Str $query) {</span>
<span class="coverage-red">    CATCH {</span>
<span class="coverage-red">        default {</span>
<span class="coverage-red">            self.map-exception($_).throw</span>
<span class="coverage-no">        }</span>
<span class="coverage-no">    }</span>
<span class="coverage-red">    Statement.new: :driver(self), :statement($!dbh), :$query</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method default-type-for(Red::Column $ where .auto-increment --&gt; Str:D) {&quot;serial&quot;}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method default-type-for-type(Positional $_ --&gt; Str:D) {&quot;{ self.default-type-for-type: .of }[]&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(Json          --&gt; Str:D) {&quot;jsonb&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(DateTime      --&gt; Str:D) {&quot;timestamp&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(Instant       --&gt; Str:D) {&quot;timestamp&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(Bool          --&gt; Str:D) {&quot;boolean&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(Int           --&gt; Str:D) {&quot;integer&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(UUID          --&gt; Str:D) {&quot;uuid&quot;}</span>
<span class="coverage-red">multi method default-type-for-type(Red::Column $ --&gt; Str:D) {&quot;varchar(255)&quot;}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method type-for-sql(&quot;jsonb&quot;     --&gt; &quot;Json&quot;    ) {}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method inflate(Str $value, DateTime :$to!) { DateTime.new: $value }</span>
<span class="coverage-red">multi method deflate(Instant  $value) { ~$value.DateTime.utc }</span>
<span class="coverage-red">multi method deflate(DateTime $value) { ~$value.utc }</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method map-exception(DB::Pg::Error::FatalError $x where .?message ~~ /&quot;duplicate key value violates unique constraint &quot; \&quot;$&lt;field&gt;=(\w+)\&quot;/) {</span>
<span class="coverage-red">    X::Red::Driver::Mapped::Unique.new:</span>
<span class="coverage-no">            :driver&lt;Pg&gt;,</span>
<span class="coverage-no">            :orig-exception($x),</span>
<span class="coverage-no">            :fields($&lt;field&gt;.Str)</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method map-exception(DB::Pg::Error::FatalError $x where /&quot;duplicate key value violates unique constraint&quot;/) {</span>
<span class="coverage-red">    $x.?message-detail ~~ /&quot;Key (&quot; \s* (\w+)+ % [\s* &quot;,&quot; \s*] \s* &quot;)=(&quot; .*? &quot;) already exists.&quot;/;</span>
<span class="coverage-red">    my @fields = $0 ?? $0&gt;&gt;.Str !! &quot;&quot;;</span>
<span class="coverage-red">    X::Red::Driver::Mapped::Unique.new:</span>
<span class="coverage-no">        :driver&lt;Pg&gt;,</span>
<span class="coverage-no">        :orig-exception($x),</span>
<span class="coverage-no">        :@fields,</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method map-exception(DB::Pg::Error::FatalError $x where /&quot;duplicate key value violates unique constraint&quot;/) {</span>
<span class="coverage-red">    $x.?message ~~ /&quot;DETAIL:  Key (&quot; \s* (\w+)+ % [\s* &quot;,&quot; \s*] \s* &quot;)=(&quot; .*? &quot;) already exists.&quot;/;</span>
<span class="coverage-red">    X::Red::Driver::Mapped::Unique.new:</span>
<span class="coverage-no">        :driver&lt;Pg&gt;,</span>
<span class="coverage-no">        :orig-exception($x),</span>
<span class="coverage-no">        :fields($0&gt;&gt;.Str)</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method map-exception(DB::Pg::Error::FatalError $x where .?message ~~ /relation \s+ \&quot;$&lt;table&gt;=(\w+)\&quot; \s+ already \s+ exists/) {</span>
<span class="coverage-red">    X::Red::Driver::Mapped::TableExists.new:</span>
<span class="coverage-no">            :driver&lt;Pg&gt;,</span>
<span class="coverage-no">            :orig-exception($x),</span>
<span class="coverage-no">            :table($&lt;table&gt;.Str)</span>
<span class="coverage-no">}</span>
			</pre>
		</div>
	</div>
</div>
</body>
</html>