<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Firmino Changani</title>
    <link>https://firmino.work/</link>
    <description>Recent content on Firmino Changani</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-UK</language>
    <managingEditor>hi&#43;blog@firmino.work (Firmino Changani)</managingEditor>
    <webMaster>hi&#43;blog@firmino.work (Firmino Changani)</webMaster>
    <copyright>Firmino Changani</copyright>
    <lastBuildDate>Tue, 18 Jun 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://firmino.work/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>About</title>
      <link>https://firmino.work/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/about/</guid>
      <description>Trial and error! Hi there, I&amp;rsquo;m Firmino Changani and I have been working as a Software Engineer since 2014.&#xA;I currently work as a Senior Software Engineer at GetHarley, a UK-based startup in the skincare space, but before that I worked for Mercedes Benz as a Software Engineer.&#xA;I enjoy working on product-oriented teams, building side projects, writing about subjects I find interesting and I do enjoy running 🏃‍♂️.</description>
      <content:encoded><![CDATA[<h2 id="trial-and-error">Trial and error!</h2>
<figure><img src="/images/self/IMG_2570.jpg" width="400">
</figure>

<p>Hi there, I&rsquo;m Firmino Changani and I have been working as a Software Engineer since 2014.</p>
<p>I currently work as a Senior Software Engineer at GetHarley, a UK-based startup in the skincare space, but before that I worked for Mercedes Benz as a Software Engineer.</p>
<p>I enjoy working on product-oriented teams, building side projects, writing about subjects I find interesting and I do enjoy running 🏃‍♂️.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Email validation in Golang</title>
      <link>https://firmino.work/blog/email-validation-in-golang/</link>
      <pubDate>Tue, 18 Jun 2024 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/email-validation-in-golang/</guid>
      <description>One shall not write from scratch an email syntax validator because it&amp;rsquo;s an activity that most likely has nothing to do with the domain of the system one is working on.&#xA;Moreover, often if/elses and regular expressions tend to be naive approaches to such a problem.&#xA;In Go, one shall avoid code such as the one written below because it&amp;rsquo;s ugly, complex, hard to maintain, and it isn&amp;rsquo;t even effective at validating perfectly valid email addresses.</description>
      <content:encoded><![CDATA[<p>One shall not write from scratch an email syntax validator because it&rsquo;s an activity that most likely has nothing to do with the domain of the system one is working on.</p>
<p>Moreover, often if/elses and regular expressions tend to be naive approaches to such a problem.</p>
<p>In Go, one shall avoid code such as the one written below because it&rsquo;s ugly, complex, hard to maintain, and it isn&rsquo;t even effective at validating perfectly valid email addresses.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">var</span> <span class="nx">pattern</span> <span class="p">=</span> <span class="nx">regexp</span><span class="p">.</span><span class="nf">MustCompile</span><span class="p">(</span><span class="s">&#34;^[a-zA-Z0-9.!#$%&amp;&#39;*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$&#34;</span><span class="p">)</span></span></span></code></pre></div><p>Instead one is provided with the package <a href="https://pkg.go.dev/net/mail">net/mail</a>, which has a function to parse email addresses based on the <a href="https://www.rfc-editor.org/rfc/rfc5322.html">RFC 5322</a>, and here is how one can leverage it:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">	<span class="s">&#34;net/mail&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">	<span class="nx">err</span> <span class="o">:=</span> <span class="nf">validateEmail</span><span class="p">(</span><span class="s">&#34;tim.cookapple.com&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">	<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">		<span class="k">return</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="kd">func</span> <span class="nf">validateEmail</span><span class="p">(</span><span class="nx">address</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">	<span class="nx">_</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">mail</span><span class="p">.</span><span class="nf">ParseAddress</span><span class="p">(</span><span class="nx">address</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">	<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">		<span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">	<span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="p">}</span></span></span></code></pre></div>




<pre tabindex="0"><code>&gt; mail: missing &#39;@&#39; or angle-addr</code></pre><h2 id="what-if-one-still-wants-to-write-an-email-validator-from-scratch">What if one still wants to write an email validator from scratch?</h2>
<p>That&rsquo;s a reasonable question for the sake of learning or any other reason one might have. That being said I recommend starting with the following resources:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Email_address">Email address</a>: this Wikipedia article is a good starting point because it&rsquo;s rather practical and succinct.</li>
<li><a href="https://www.rfc-editor.org/rfc/rfc5322.html">RFC 5322</a>: in this RFC one should expect to learn about the formal specification about the standard syntax of an email address.</li>
<li><a href="https://github.com/golang/go/tree/master/src/net/mail">net/mail&rsquo;s implementation</a>: implementation details matter.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Inline conversion of anything to a pointer - Golang</title>
      <link>https://firmino.work/blog/golang-inline-conversion-of-anything-to-a-pointer/</link>
      <pubDate>Sun, 03 Dec 2023 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/golang-inline-conversion-of-anything-to-a-pointer/</guid>
      <description>In Go, unless one is initialising a struct, one cannot outright create a pointer out of something without first initialising it to a variable:&#xA;1package main 2 3type User struct { 4 lastUpdatedAt *time.Time 5} 6 7func main() { 8 lastUpdatedAt := time.Now() 9 user := User{ 10 lastUpdatedAt: &amp;amp;lastUpdatedAt 11 } 12}Even though the approach displayed above works just fine it still ends up requiring the initialisation of a variable that potentially won&amp;rsquo;t be used anywhere, and perhaps for the use-case above one would be better off by performing an inline conversion of the intended value to a pointer.</description>
      <content:encoded><![CDATA[<p>In Go, unless one is initialising a <code>struct</code>, one cannot outright create a pointer out of something without first initialising it to a variable:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kd">type</span> <span class="nx">User</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nx">lastUpdatedAt</span> <span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Time</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="nx">lastUpdatedAt</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nf">Now</span><span class="p">()</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="nx">user</span> <span class="o">:=</span> <span class="nx">User</span><span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">        <span class="nx">lastUpdatedAt</span><span class="p">:</span> <span class="o">&amp;</span><span class="nx">lastUpdatedAt</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>Even though the approach displayed above works just fine it still ends up requiring the initialisation of a variable that potentially won&rsquo;t be used anywhere, and perhaps for the use-case above one would be better off by performing an inline conversion of the intended value to a pointer.</p>
<p>What I do and rather often, is to write a function that will receive <strong>anything</strong> and return that same <strong>thing</strong> as a pointer, here is how I express it in code:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="kd">func</span> <span class="nx">ToPtr</span><span class="p">[</span><span class="nx">T</span> <span class="nx">any</span><span class="p">](</span><span class="nx">value</span> <span class="nx">T</span><span class="p">)</span> <span class="o">*</span><span class="nx">T</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">	<span class="k">return</span> <span class="o">&amp;</span><span class="nx">value</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>Here is the initial example rewritten with such a function:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kd">type</span> <span class="nx">User</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nx">lastUpdatedAt</span> <span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Time</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="nx">user</span> <span class="o">:=</span> <span class="nx">User</span><span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        <span class="nx">lastUpdatedAt</span><span class="p">:</span> <span class="nf">ToPtr</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Now</span><span class="p">())</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>And that&rsquo;s all, thanks for passing by.</p>
]]></content:encoded>
    </item>
    <item>
      <title>How to skip rows locked in a transaction (skip locked)</title>
      <link>https://firmino.work/blog/skip-locked-how-to-skip-rows-locked-in-a-transaction/</link>
      <pubDate>Sun, 17 Sep 2023 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/skip-locked-how-to-skip-rows-locked-in-a-transaction/</guid>
      <description>If you&amp;rsquo;ve landed on this post, you probably know what you are looking for, so here is how to skip rows locked in another transaction (PostgreSQL):&#xA;1BEGIN; 2 3SELECT * FROM urls 4FOR UPDATE 5SKIP LOCKED 6LIMIT 100; 7 8END;The key to achieve such skip, is to first ensure that the rows to be queried will actually be locked, hence the FOR UPDATE clause, and then the SKIP LOCKED clause to prevent the query from waiting for the RDBMS to release the locks that another query might have acquired.</description>
      <content:encoded><![CDATA[<p>If you&rsquo;ve landed on this post, you probably know what you are looking for, so here is how to skip rows locked in another transaction (PostgreSQL):</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">BEGIN</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">urls</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="k">FOR</span><span class="w"> </span><span class="k">UPDATE</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="n">SKIP</span><span class="w"> </span><span class="n">LOCKED</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w"></span><span class="k">LIMIT</span><span class="w"> </span><span class="mi">100</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="w"></span><span class="k">END</span><span class="p">;</span></span></span></code></pre></div><p>The key to achieve such skip, is to first ensure that the rows to be queried will actually be locked, hence the <code>FOR UPDATE</code> clause, and then the <code>SKIP LOCKED</code> clause to prevent the query from waiting for the RDBMS to release the locks that another query might have acquired.</p>
<blockquote>
<p>With SKIP LOCKED, any selected rows that cannot be immediately locked are skipped. Skipping locked rows provides an inconsistent view of the data, so this is not suitable for general purpose work, but can be used to avoid lock contention with multiple consumers accessing a queue-like table - <a href="https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE">PostgreSQL Documentation: The Locking Clause</a></p>
</blockquote>
<h2 id="how-was-this-useful-to-me">How was this useful to me?</h2>
<p>I am working on a monitoring tool architected with the Leader-follower model where the service acting as the leader, and the service acting as a worker needs to be capable of working with multiple replicas of themselves. The leader needs to query data on an interval basis and publish events/messages to a queue to be consumed by the workers.</p>
<p>Due to the potential volume of data, and to prevent having a single point of failure I needed to foresee having multiple leaders running in a replicated fashion, which without proper concurrency control would have led to issues such as multiple leaders accessing the same rows for the same purpose.</p>
<p><img alt="/images/posts/skip-locked-arch-overview.png" src="/images/posts/skip-locked-arch-overview.png"></p>
<p>That&rsquo;s it for this post, thank you.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Shipping a Golang service as a Docker container</title>
      <link>https://firmino.work/blog/shipping-go-as-a-docker-container/</link>
      <pubDate>Tue, 15 Aug 2023 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/shipping-go-as-a-docker-container/</guid>
      <description>At this day and age Docker has established itself as the de facto tool for containerisation, it is deserved given how well it abstract its complexity away from its users. In the cloud it allows us to run containerised services as if the programming language those services have been written on don&amp;rsquo;t really matter, and in fact it doesn&amp;rsquo;t, provided that the service are exposed on a port.&#xA;On this blog post I will my preferred set up to Dockerize Go services.</description>
      <content:encoded><![CDATA[<p>At this day and age Docker has established itself as the de facto tool for containerisation, it is deserved given how well it abstract its complexity away from its users.
In the cloud it allows us to run containerised services as if the programming language those services have been written on don&rsquo;t really matter, and in fact it doesn&rsquo;t, provided that the service are exposed on a port.</p>
<p>On this blog post I will my preferred set up to Dockerize Go services.</p>
<h2 id="binary-binary-binary">Binary, Binary, Binary</h2>
<blockquote>
<p>Binary, Binary, Binary - <a href="https://www.youtube.com/watch?v=Vhh_GeBPOhs&ab_channel=MrWueb007">Steve Balmer</a></p>
</blockquote>
<p>The command <code>go build</code> generates a binary, and this is a relevant and non-trivial fact that is going to impact how I am going to set up the Dockerfile, but I am going to come back at this later, for now here is the code snippet:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dockerfile" data-lang="dockerfile"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c">##</span><span class="err">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="err"></span><span class="c">## Builder stage</span><span class="err">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="err"></span><span class="c">##</span><span class="err">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> golang:1.20 AS builder</span><span class="err">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="err"></span><span class="k">ARG</span> VERSION<span class="err">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /usr/app</span><span class="err">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="err"></span><span class="k">COPY</span> . ./<span class="err">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="err"></span><span class="k">ENV</span> <span class="nv">CGO_ENABLED</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">RUN</span> go build -buildvcs<span class="o">=</span><span class="nb">false</span> -o bin/service -ldflags<span class="o">=</span><span class="s2">&#34;-X main.Version=</span><span class="si">${</span><span class="nv">VERSION</span><span class="si">}</span><span class="s2">&#34;</span> ./<span class="err">
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="err"></span><span class="c">##</span><span class="err">
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="err"></span><span class="c">## Final stage</span><span class="err">
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="err"></span><span class="c">##</span><span class="err">
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /usr/app</span><span class="err">
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="err"></span><span class="k">COPY</span> --from<span class="o">=</span>builder /usr/app/bin/service ./service<span class="err">
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;./service&#34;</span><span class="p">]</span></span></span></code></pre></div><p><a href="https://github.com/flowck/blog_code_snippets/blob/cb7c95b57e2b5ace9574d094e4613968b3d54359/go_docker/Dockerfile#L1">Source</a></p>
<p>The Dockerfile above has two stages where the first stage is solely focused on building a binary from the <a href="https://github.com/flowck/blog_code_snippets/tree/cb7c95b57e2b5ace9574d094e4613968b3d54359/go_docker">source code</a>:</p>
<ul>
<li>It relies on the base image <code>golang:1.20</code> and it is aliased as <code>builder</code> because it&rsquo;s referenced further down</li>
<li>Defines docker argument <code>VERSION</code>, which is used to specify the image&rsquo;s and the binary&rsquo;s version during build time</li>
<li>It sets a workdir, and copy everything from the project root to the root of the working directory set as <code>/usr/app</code></li>
<li>CGO is disabled because the source code doesn&rsquo;t rely on any library written in <code>C</code>. <a href="https://stackoverflow.com/questions/61515186/when-using-cgo-enabled-is-must-and-what-happens">Read more here</a></li>
<li>Builds the binary:
<ul>
<li>Omitting the version control metadata with <code>-buildvcs</code> set to false</li>
<li>Defines the output directory and binary filename to <code>bin/service</code></li>
<li>Sets the docker argument <code>VERSION</code> to the <a href="https://github.com/flowck/blog_code_snippets/blob/cb7c95b57e2b5ace9574d094e4613968b3d54359/go_docker/main.go#L14">variable</a> <code>Version</code> defined in <code>main.go</code></li>
</ul>
</li>
</ul>
<p>After the binary gets built on the state named <code>builder</code>, Docker jumps into the second stage and does the following:</p>
<ul>
<li>It uses a very small Docker image based on Linux named <a href="https://hub.docker.com/_/alpine">alpine</a>, which is as big as ~5 MB in size, and that is possible because the newly built binary doesn&rsquo;t rely on an external runtime such as Node.js or JVM</li>
<li>The working directory is set to <code>/usr/app</code></li>
<li>The binary generated in the previous stage gets copied thanks to <code>COPY --from=builder</code></li>
<li>Finally, the entrypoint is a call to the binary <code>./service</code>, just like you would do if you were running it locally</li>
</ul>
<h2 id="how-to-build-it-and-run-it">How to build it, and run it</h2>
<p>To build a new Docker image versioned 0.0.1, run the following command:</p>





<pre tabindex="0"><code>docker build --build-arg VERSION=0.0.1 -t go-docker-demo:0.0.1 .</code></pre><p>And to run the image newly built run the following command:</p>





<pre tabindex="0"><code>docker run -p 8080:8080 go-docker-demo:0.0.1</code></pre><h2 id="conclusion">Conclusion</h2>
<p>That&rsquo;s the end of this post, and perhaps to I would like to conclude that the fact that Go generates a binary that can be executed without an external runtime helps to build Docker images based in lightweight images such as <code>alpine</code>, which makes the build faster, and very cheap to host it on an Images Registry provided by a Cloud vendor, which tend to <a href="https://aws.amazon.com/ecr/pricing/">charge</a> by data transferred in and out.</p>
<p>Cheers,<!-- raw HTML omitted -->
Firmino</p>
]]></content:encoded>
    </item>
    <item>
      <title>I shall recover - Golang</title>
      <link>https://firmino.work/blog/i-shall-recover-go/</link>
      <pubDate>Wed, 05 Jul 2023 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/i-shall-recover-go/</guid>
      <description>In this blog post, I intend to demonstrate the usage of Go&amp;rsquo;s built-in function recover() used to gracefully handle panics.&#xA;The example I prepared is effectively a function that takes another function as an argument and repeatedly executes it based on the time interval passed in the first parameter.&#xA;1package main 2 3import &amp;#34;time&amp;#34; 4 5func main() { 6&#x9;runOnInterval(time.Millisecond*500, func(ranAt time.Time) { 7&#x9;iWillPanic() 8&#x9;}) 9} 10 11func iWillPanic() { 12&#x9;panic(&amp;#34;something went wrong&amp;#34;) 13}The implementation of runOnInterval() is rather simple, it makes use of a for/loop that blocks on every iteration based in the time interval provided.</description>
      <content:encoded><![CDATA[<p>In this blog post, I intend to demonstrate the usage of Go&rsquo;s built-in function <code>recover()</code> used to gracefully handle panics.</p>
<p>The example I prepared is effectively a function that takes another function as an argument and repeatedly executes it based on the time interval passed in the first parameter.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">	<span class="nf">runOnInterval</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="o">*</span><span class="mi">500</span><span class="p">,</span> <span class="kd">func</span><span class="p">(</span><span class="nx">ranAt</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">		<span class="nf">iWillPanic</span><span class="p">()</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">	<span class="p">})</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="kd">func</span> <span class="nf">iWillPanic</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">	<span class="nb">panic</span><span class="p">(</span><span class="s">&#34;something went wrong&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>The implementation of <code>runOnInterval()</code> is rather simple, it makes use of a for/loop that blocks on every iteration based in the time interval provided.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">func</span> <span class="nf">runOnInterval</span><span class="p">(</span><span class="nx">interval</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">,</span> <span class="nx">handler</span> <span class="kd">func</span><span class="p">(</span><span class="nx">ranAt</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">	<span class="nx">ticker</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nf">NewTicker</span><span class="p">(</span><span class="nx">interval</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">	<span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">		<span class="nf">handler</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Now</span><span class="p">())</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">		<span class="o">&lt;-</span><span class="nx">ticker</span><span class="p">.</span><span class="nx">C</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>Such a small program panics every time it&rsquo;s ran, and it outputs the following information on the terminal:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">panic: something went wrong
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">goroutine <span class="m">1</span> <span class="o">[</span>running<span class="o">]</span>:
</span></span><span class="line"><span class="ln">4</span><span class="cl">main.iWillPanic<span class="o">(</span>...<span class="o">)</span></span></span></code></pre></div><h2 id="a-naive-assumption">A naive assumption&hellip;</h2>
<p>What if the function passed in <code>runOnInterval()</code> is not meant to panic? And that perhaps if something unexpected were to happen <code>runOnInterval()</code> should at least retry it three times before stopping the execution altogether. That&rsquo;s when the <code>recover()</code> function enters the conversation, and its basic syntax can be defined as such:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kd">func</span> <span class="nf">iWillPanic</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">	<span class="nb">panic</span><span class="p">(</span><span class="s">&#34;Yeah, I refuse to run&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">	<span class="k">defer</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">		<span class="k">if</span> <span class="nx">r</span> <span class="o">:=</span> <span class="nb">recover</span><span class="p">();</span> <span class="nx">r</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">			<span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Oops, something went wrong: &#34;</span><span class="p">,</span> <span class="nx">r</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">	<span class="nf">iWillPanic</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><blockquote>
<p><code>recover</code> must be called within a deferred function. When the enclosing function panics, the defer will activate and a recover call within it will catch the panic. - <a href="https://gobyexample.com/recover">Go by Example: Recover</a></p>
</blockquote>
<h2 id="now-lets-recover">Now let&rsquo;s recover</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">	<span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">	<span class="s">&#34;log&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="kd">func</span> <span class="nf">runOnInterval</span><span class="p">(</span><span class="nx">interval</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">,</span> <span class="nx">handler</span> <span class="kd">func</span><span class="p">(</span><span class="nx">ranAt</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">	<span class="nx">ticker</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nf">NewTicker</span><span class="p">(</span><span class="nx">interval</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">	<span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">		<span class="kd">func</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">			<span class="k">defer</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">				<span class="k">if</span> <span class="nx">r</span> <span class="o">:=</span> <span class="nb">recover</span><span class="p">();</span> <span class="nx">r</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">					<span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;The handler has panicked: %v&#34;</span><span class="p">,</span> <span class="nx">r</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">				<span class="p">}</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">			<span class="p">}()</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">			<span class="nf">handler</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Now</span><span class="p">())</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">		<span class="p">}()</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">		<span class="o">&lt;-</span><span class="nx">ticker</span><span class="p">.</span><span class="nx">C</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>The use of <code>defer</code> inside a loop is discouraged, but <code>runOnInterval</code> still needs to check whether the <code>handler</code> has panicked and to do that I wrapped both the <code>recover</code> and the handler inside an anonymous function that is going check whether the <code>handler</code> has panicked or not. Here are the logs shown in the terminal after the change made above:</p>





<pre tabindex="0"><code>2023/07/05 08:25:39 The handler has panicked: something went wrong
2023/07/05 08:25:40 The handler has panicked: something went wrong
2023/07/05 08:25:40 The handler has panicked: something went wrong
2023/07/05 08:25:41 The handler has panicked: something went wrong
2023/07/05 08:25:41 The handler has panicked: something went wrong
2023/07/05 08:25:42 The handler has panicked: something went wrong
2023/07/05 08:25:42 The handler has panicked: something went wrong
2023/07/05 08:25:43 The handler has panicked: something went wrong
2023/07/05 08:25:43 The handler has panicked: something went wrong</code></pre><p>It works, but the implementation is rather incomplete because <code>runOnInterval</code> will attempt to recover forever, which is not ideal because there is no guarantee that whatever is making the <code>handler</code> panic will ever change. As a countermeasure, a counter - no pun intended - comes in quite handy:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">	<span class="s">&#34;time&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">	<span class="s">&#34;log&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="kd">func</span> <span class="nf">runOnInterval</span><span class="p">(</span><span class="nx">interval</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">,</span> <span class="nx">handler</span> <span class="kd">func</span><span class="p">(</span><span class="nx">ranAt</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">	<span class="nx">panicCounter</span> <span class="o">:=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">	<span class="nx">ticker</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nf">NewTicker</span><span class="p">(</span><span class="nx">interval</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">	<span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">		<span class="k">if</span> <span class="nx">panicCounter</span> <span class="o">==</span> <span class="mi">3</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">			<span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;The handler has panicked %d times. Ending execution&#34;</span><span class="p">,</span> <span class="nx">panicCounter</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">			<span class="k">break</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">		<span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">			<span class="k">defer</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">				<span class="k">if</span> <span class="nx">r</span> <span class="o">:=</span> <span class="nb">recover</span><span class="p">();</span> <span class="nx">r</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">					<span class="nx">panicCounts</span><span class="o">++</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">					<span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;The handler has panicked. Panic count: %d&#34;</span><span class="p">,</span> <span class="nx">panicCounter</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">				<span class="p">}</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">			<span class="p">}()</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">			<span class="nf">handler</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Now</span><span class="p">())</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">		<span class="p">}()</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl">		<span class="o">&lt;-</span><span class="nx">ticker</span><span class="p">.</span><span class="nx">C</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">	<span class="nf">runOnInterval</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="o">*</span><span class="mi">500</span><span class="p">,</span> <span class="kd">func</span><span class="p">(</span><span class="nx">ranAt</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">		<span class="nf">iWillPanic</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">	<span class="p">})</span>
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="kd">func</span> <span class="nf">iWillPanic</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl">	<span class="nb">panic</span><span class="p">(</span><span class="s">&#34;something went wrong&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>Here are the logs that the program outputs with the introduction of the counter:</p>





<pre tabindex="0"><code>2023/07/05 08:29:33 The handler has panicked. Panic count: 1
2023/07/05 08:29:34 The handler has panicked. Panic count: 2
2023/07/05 08:29:34 The handler has panicked. Panic count: 3
2023/07/05 08:29:35 The handler has panicked 3 times. Ending execution</code></pre><p>That&rsquo;s it for this blog post, and thank you for passing by.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Pointers in Golang</title>
      <link>https://firmino.work/blog/golang-pointers/</link>
      <pubDate>Wed, 05 Jul 2023 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/golang-pointers/</guid>
      <description>A pointer holds a variable&amp;rsquo;s address in the computer&amp;rsquo;s memory. One can say that once a pointer is created, its value is just an address that lead you to where in the computer&amp;rsquo;s memory the program will store the actual data.&#xA;Example 1package main 2 3import &amp;#34;fmt&amp;#34; 4 5func main() { 6 7&#x9;// Creating a pointer 8&#x9;var fullNamePtr *string = new(string) 9&#x9;fmt.Println(fullNamePtr) // Prints the address: 0x14000110230 10 11&#x9;// Storing value in the pointer&amp;#39;s address by dereferencing it 12&#x9;*fullNamePtr = &amp;#34;John Doe&amp;#34; 13&#x9;fmt.</description>
      <content:encoded><![CDATA[<p>A pointer holds a variable&rsquo;s address in the computer&rsquo;s memory. One can say that once a pointer is created, its value is just an address that lead you to where in the computer&rsquo;s memory the program will store the actual data.</p>
<h2 id="example">Example</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">	<span class="c1">// Creating a pointer
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>	<span class="kd">var</span> <span class="nx">fullNamePtr</span> <span class="o">*</span><span class="kt">string</span> <span class="p">=</span> <span class="nb">new</span><span class="p">(</span><span class="kt">string</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">fullNamePtr</span><span class="p">)</span> <span class="c1">// Prints the address: 0x14000110230
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">	<span class="c1">// Storing value in the pointer&#39;s address by dereferencing it
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"></span>	<span class="o">*</span><span class="nx">fullNamePtr</span> <span class="p">=</span> <span class="s">&#34;John Doe&#34;</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">fullNamePtr</span><span class="p">,</span> <span class="o">*</span><span class="nx">fullNamePtr</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">	<span class="c1">// Getting the pointer of an existing variable
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="c1"></span>	<span class="nx">country</span> <span class="o">:=</span> <span class="s">&#34;Brazil&#34;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">country</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h2 id="when-to-use-pointers">When to use pointers</h2>
<p>Since I come from the Javascript world, despite learning the syntax to create a pointer, learning when to use them wasn&rsquo;t that obvious.</p>
<p>For instance, in Javascript, it is possible to mutate a property from literal object inside a function by just updating the argument passed:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kr">const</span> <span class="nx">person</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;John Doe&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="kd">function</span> <span class="nx">updateName</span><span class="p">(</span><span class="nx">person</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  <span class="nx">person</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nx">updateName</span><span class="p">(</span><span class="nx">person</span><span class="p">,</span> <span class="s2">&#34;Jane Smith&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">person</span><span class="p">);</span> <span class="c1">// { name: &#34;Jane Smith&#34; }
</span></span></span></code></pre></div><p>In Go, such operation wouldn&rsquo;t mutate the struct passed as argument, unless the function <code>updateName</code> was declared with an interface ready to receive a pointer, rather than an actual value.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="kd">type</span> <span class="nx">Person</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">	<span class="nx">Name</span> <span class="kt">string</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="kd">func</span> <span class="nf">updatePersonName</span><span class="p">(</span><span class="nx">person</span> <span class="o">*</span><span class="nx">Person</span><span class="p">,</span> <span class="nx">name</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">	<span class="nx">person</span><span class="p">.</span><span class="nx">Name</span> <span class="p">=</span> <span class="nx">name</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Go fundamentals&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">	<span class="nx">person</span> <span class="o">:=</span> <span class="nx">Person</span><span class="p">{</span><span class="nx">Name</span><span class="p">:</span> <span class="s">&#34;John Doe&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="c1">// {John Doe}
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">	<span class="nf">updatePersonName</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">person</span><span class="p">,</span> <span class="s">&#34;Jane Smith&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">person</span><span class="p">)</span> <span class="c1">// {Jane Smith}
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="c1"></span><span class="p">}</span></span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Golang/PostgreSQL - Custom LastInsertId</title>
      <link>https://firmino.work/blog/go-sql-postgres-last-insert-id/</link>
      <pubDate>Fri, 01 Jul 2022 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/go-sql-postgres-last-insert-id/</guid>
      <description>I&amp;rsquo;ve just stumbled upon a challenge, where I needed a query to return the ID of the last inserted row, and I was querying using ExecContext and the method LastInsertId() to retrieve the id:&#xA;1result, err := Db.ExecContext(ctx, `INSERT INTO tenants (name) VALUES ($1)`, &amp;#34;My Awesome, Inc.&amp;#34;) 2 3if err != nil { 4&#x9;// do something with the error 5} 6 7id, _ := result.LastInsertId() 8 9fmt.Println(id) // 0 However, the id returned was always 0, despite the id type being set as a VARCHAR.</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve just stumbled upon a challenge, where I needed a query to return the ID of the last inserted row, and I was querying using <code>ExecContext</code> and the method <code>LastInsertId()</code> to retrieve the <code>id</code>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">result</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">Db</span><span class="p">.</span><span class="nf">ExecContext</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">`INSERT INTO tenants (name) VALUES ($1)`</span><span class="p">,</span> <span class="s">&#34;My Awesome, Inc.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">	<span class="c1">// do something with the error
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nx">id</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">result</span><span class="p">.</span><span class="nf">LastInsertId</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="c1">// 0
</span></span></span></code></pre></div><p>However, the <code>id</code> returned was always 0, despite the <code>id</code> type being set as a <code>VARCHAR</code>. After a quick digging I learned that unless the table&rsquo;s <code>id</code> has been created with a <a href="https://www.postgresql.org/docs/9.5/sql-createsequence.html"><code>SEQUENCE</code></a> generator, PostgreSQL won&rsquo;t return the <code>id</code> upon row insertion.</p>
<p>To overcome the challenge I&rsquo;ve just described above, I&rsquo;ve used the <a href="https://www.postgresql.org/docs/9.5/dml-returning.html"><code>RETURNING</code></a> clause, and replaced Go&rsquo;s <code>Db.ExecContext()</code> with <code>Db.QueryRowContext()</code> to gain access to the modified row.</p>
<p>Take a look at the full script:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kd">func</span> <span class="nf">FindTenantById</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span> <span class="nx">id</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">Tenant</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">	<span class="nx">tenant</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">Tenant</span><span class="p">{}</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="c1">// Use QueryRowContext instead of ExecContext() to perform an INSERT
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span>	<span class="nx">row</span> <span class="o">:=</span> <span class="nx">Db</span><span class="p">.</span><span class="nf">QueryRowContext</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">`INSERT INTO tenants (name) VALUES($1) RETURNING id`</span><span class="p">,</span> <span class="nx">id</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">	<span class="nx">err</span> <span class="o">:=</span> <span class="nx">row</span><span class="p">.</span><span class="nf">Scan</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">tenant</span><span class="p">.</span><span class="nx">Id</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">tenant</span><span class="p">.</span><span class="nx">Name</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">	<span class="k">if</span> <span class="nx">row</span><span class="p">.</span><span class="nf">Err</span><span class="p">()</span> <span class="o">==</span> <span class="nx">sql</span><span class="p">.</span><span class="nx">ErrNoRows</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">		<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">	<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">		<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">	<span class="k">return</span> <span class="nx">tenant</span><span class="p">,</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>That will be all for now, and don&rsquo;t forget to take a look at the links I&rsquo;ve listed under references.</p>
<p>Cheers.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.postgresql.org/docs/9.5/sql-createsequence.html">https://www.postgresql.org/docs/9.5/sql-createsequence.html</a></li>
<li><a href="https://stackoverflow.com/questions/33382981/go-how-to-get-last-insert-id-on-postgresql-with-namedexec">https://stackoverflow.com/questions/33382981/go-how-to-get-last-insert-id-on-postgresql-with-namedexec</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Golang/SQL - Fixing the error - Converting NULL to string is unsupported error</title>
      <link>https://firmino.work/blog/go-sql-converting-null-to-string-is-unsupported/</link>
      <pubDate>Sun, 26 Jun 2022 00:00:00 +0000</pubDate><author>hi&#43;blog@firmino.work (Firmino Changani)</author>
      <guid>https://firmino.work/blog/go-sql-converting-null-to-string-is-unsupported/</guid>
      <description>Converting NULL to string is unsupported errorThe error above is thrown whenever a Go program tries to scan a query result that contains at least one column whose value is NULL to a struct defined with primitive types instead of sql.NullString type.&#xA;To solve this issue at the query level, the SQL function COALESCE comes in handy.&#xA;1package demo 2 3type User struct { 4 Id string 5 FirstName string 6 LastName string 7} 8 9func findUserByEmail(ctx context.</description>
      <content:encoded><![CDATA[




<pre tabindex="0"><code>Converting NULL to string is unsupported error</code></pre><p>The error above is thrown whenever a Go program tries to scan a query result that contains at least one column whose value is <code>NULL</code> to a struct defined with primitive types instead of <code>sql.NullString</code> type.</p>
<p>To solve this issue at the query level, the SQL function <a href="https://www.postgresql.org/docs/14/functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL"><code>COALESCE</code></a> comes in handy.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span> <span class="nx">demo</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kd">type</span> <span class="nx">User</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nx">Id</span> <span class="kt">string</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="nx">FirstName</span> <span class="kt">string</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="nx">LastName</span> <span class="kt">string</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="kd">func</span> <span class="nf">findUserByEmail</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span> <span class="nx">email</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="nx">user</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">User</span><span class="p">{}</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">	<span class="nx">row</span> <span class="o">:=</span> <span class="nx">DbConn</span><span class="p">.</span><span class="nf">QueryRowContext</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">`
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="s">		SELECT id, COALESCE(first_name, &#39;&#39;) as first_name, COALESCE(last_name, &#39;&#39;) as last_name
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="s">		FROM users
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="s">		WHERE email = $1
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="s">	`</span><span class="p">,</span> <span class="nx">email</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">	<span class="nx">err</span> <span class="o">:=</span> <span class="nx">row</span><span class="p">.</span><span class="nf">Scan</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">user</span><span class="p">.</span><span class="nx">Id</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">user</span><span class="p">.</span><span class="nx">FirstName</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">user</span><span class="p">.</span><span class="nx">LastName</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"></span><span class="p">}</span></span></span></code></pre></div><p>When the query above is executed, the function COALESCE will replace the <code>NULL</code> value of the columns <code>first_name</code> and <code>last_name</code> returned by the database for the value passed as second argument, which is an empty string.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/go-sql-driver/mysql/issues/34#issuecomment-158391340">https://github.com/go-sql-driver/mysql/issues/34#issuecomment-158391340</a></li>
<li><a href="https://www.postgresql.org/docs/14/functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL">https://www.postgresql.org/docs/14/functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL</a></li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
