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 = "127.0.0.1", 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 => "{</span>
<span class="coverage-red"> "user=$_" with $!user</span>
<span class="coverage-red"> } {</span>
<span class="coverage-red"> "password=$_" with $!password</span>
<span class="coverage-red"> } {</span>
<span class="coverage-red"> "host=$_" with $!host</span>
<span class="coverage-red"> } {</span>
<span class="coverage-red"> "port=$_" with $!port</span>
<span class="coverage-red"> } {</span>
<span class="coverage-red"> "dbname=$_" with $!dbname</span>
<span class="coverage-no"> }"</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 => $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 "Not in a transaction!" 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 "Deu ruim!!!";</span>
<span class="coverage-no"> #die "Not in a transaction!" 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 { "\${ ++$*bind-counter }" }</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, "boolean").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, "boolean"), .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, "boolean")</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, "boolean"), .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, "boolean")</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::AST::Cast $_ where { .type eq "boolean" && .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 $_, "column-auto-increment") {}</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?) { "OID" => [] }</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 "INSERT INTO { self.table-name-wrapper: .into.^table } DEFAULT VALUES RETURNING *" => [] 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"> "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>>.key.join(",\n").indent: 3</span>
<span class="coverage-red"> }\n)\nVALUES(\n{</span>
<span class="coverage-red"> (self.wildcard xx @values).join(",\n").indent: 3</span>
<span class="coverage-no"> }\n) RETURNING *" => @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"> "mod($ls, $rs)" => [|@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 ?? "'t'" !! "'f'") => []</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"> "'{ .value.Str }'" => []</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"> "'{ .value }'::{ self.default-type-for-type: .type }" => []</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 $_, "column-comment") {</span>
<span class="coverage-red"> (.comment ?? "COMMENT ON COLUMN { self.translate: $_, "table-dot-column" } IS '{ .comment }'" !! "") => []</span>
<span class="coverage-no">}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method translate(Red::Column $_, "column-type") {</span>
<span class="coverage-red"> if !.auto-increment && .attr.type =:= Mu && !.type.defined {</span>
<span class="coverage-red"> return self.type-by-name("string") => []</span>
<span class="coverage-no"> }</span>
<span class="coverage-red"> (.type.defined ?? self.type-by-name(.type) !! self.default-type-for: $_) => []</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"> "COMMENT ON TABLE { .table } IS '{ .msg }'" => []</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 --> Str:D) {"serial"}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method default-type-for-type(Positional $_ --> Str:D) {"{ self.default-type-for-type: .of }[]"}</span>
<span class="coverage-red">multi method default-type-for-type(Json --> Str:D) {"jsonb"}</span>
<span class="coverage-red">multi method default-type-for-type(DateTime --> Str:D) {"timestamp"}</span>
<span class="coverage-red">multi method default-type-for-type(Instant --> Str:D) {"timestamp"}</span>
<span class="coverage-red">multi method default-type-for-type(Bool --> Str:D) {"boolean"}</span>
<span class="coverage-red">multi method default-type-for-type(Int --> Str:D) {"integer"}</span>
<span class="coverage-red">multi method default-type-for-type(UUID --> Str:D) {"uuid"}</span>
<span class="coverage-red">multi method default-type-for-type(Red::Column $ --> Str:D) {"varchar(255)"}</span>
<span class="coverage-no"></span>
<span class="coverage-red">multi method type-for-sql("jsonb" --> "Json" ) {}</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 ~~ /"duplicate key value violates unique constraint " \"$<field>=(\w+)\"/) {</span>
<span class="coverage-red"> X::Red::Driver::Mapped::Unique.new:</span>
<span class="coverage-no"> :driver<Pg>,</span>
<span class="coverage-no"> :orig-exception($x),</span>
<span class="coverage-no"> :fields($<field>.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 /"duplicate key value violates unique constraint"/) {</span>
<span class="coverage-red"> $x.?message-detail ~~ /"Key (" \s* (\w+)+ % [\s* "," \s*] \s* ")=(" .*? ") already exists."/;</span>
<span class="coverage-red"> my @fields = $0 ?? $0>>.Str !! "";</span>
<span class="coverage-red"> X::Red::Driver::Mapped::Unique.new:</span>
<span class="coverage-no"> :driver<Pg>,</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 /"duplicate key value violates unique constraint"/) {</span>
<span class="coverage-red"> $x.?message ~~ /"DETAIL: Key (" \s* (\w+)+ % [\s* "," \s*] \s* ")=(" .*? ") already exists."/;</span>
<span class="coverage-red"> X::Red::Driver::Mapped::Unique.new:</span>
<span class="coverage-no"> :driver<Pg>,</span>
<span class="coverage-no"> :orig-exception($x),</span>
<span class="coverage-no"> :fields($0>>.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+ \"$<table>=(\w+)\" \s+ already \s+ exists/) {</span>
<span class="coverage-red"> X::Red::Driver::Mapped::TableExists.new:</span>
<span class="coverage-no"> :driver<Pg>,</span>
<span class="coverage-no"> :orig-exception($x),</span>
<span class="coverage-no"> :table($<table>.Str)</span>
<span class="coverage-no">}</span>
</pre>
</div>
</div>
</div>
</body>
</html>