<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rogério Ramos</title>
    <description>The latest articles on DEV Community by Rogério Ramos (@habutre).</description>
    <link>https://dev.to/habutre</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F169600%2Fdf55b187-6e4f-467e-a890-f13af20393cd.jpg</url>
      <title>DEV Community: Rogério Ramos</title>
      <link>https://dev.to/habutre</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/habutre"/>
    <language>en</language>
    <item>
      <title>Using Duration with Ecto+Postgrex</title>
      <dc:creator>Rogério Ramos</dc:creator>
      <pubDate>Sun, 23 Mar 2025 15:40:56 +0000</pubDate>
      <link>https://dev.to/habutre/using-duration-with-ectopostgrex-13pc</link>
      <guid>https://dev.to/habutre/using-duration-with-ectopostgrex-13pc</guid>
      <description>&lt;h2&gt;
  
  
  Duration: a useful time interval representation
&lt;/h2&gt;

&lt;p&gt;Duration is covered by &lt;a href="https://en.wikipedia.org/wiki/ISO_8601" rel="noopener noreferrer"&gt;ISO 8601&lt;/a&gt; standard that deal with time data and defines the amount of time in a given interval&lt;/p&gt;

&lt;p&gt;One might think in the simpler and classic example to explain a duration: the difference between two dates or time&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the age of a person?&lt;/li&gt;
&lt;li&gt;How many days to the due date of that expensive loan?&lt;/li&gt;
&lt;li&gt;The countdown in days or hours to the most anticipated concert&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thus a data type to represent a duration of a given time interval becomes useful in many use cases&lt;/p&gt;

&lt;p&gt;The readable representation for human beings of a duration is, according to the ISO 8601 standard, a letter representing the unit of time followed by a number representing the amount of this unit. So here we go:&lt;/p&gt;

&lt;p&gt;P is a marker used to split the &lt;strong&gt;P&lt;/strong&gt;eríodo portion of a given duration, represented as such:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;represents the number of years&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;Y&lt;/strong&gt;ears)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;represents the number of months&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;M&lt;/strong&gt;onths)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;W&lt;/td&gt;
&lt;td&gt;represents the number of weeks&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;W&lt;/strong&gt;eeks)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;represents the number of days&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;D&lt;/strong&gt;ays)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;T is a marker used to split the &lt;strong&gt;T&lt;/strong&gt;ime portion of a given duration, represented as such:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
&lt;td&gt;H&lt;/td&gt;
&lt;td&gt;represents the number of hours&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;H&lt;/strong&gt;ours)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;represents the number of minutes&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;M&lt;/strong&gt;inutes)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;represents the number of seconds&lt;/td&gt;
&lt;td&gt;(&lt;strong&gt;S&lt;/strong&gt;econds)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;P&lt;/code&gt;&lt;/strong&gt;&lt;code&gt;3W2D&lt;/code&gt;&lt;strong&gt;&lt;code&gt;T&lt;/code&gt;&lt;/strong&gt;&lt;code&gt;10H45M&lt;/code&gt; represents a duration of 3 weeks, 2 days, 10 hours e 45 minutes&lt;/p&gt;

&lt;h3&gt;
  
  
  Ecto, Postgrex and Duration
&lt;/h3&gt;

&lt;p&gt;The Elixir structure &lt;code&gt;%Duration{}&lt;/code&gt; and its functions were introduced in the version 1.17 and in previous versions, according to the documentation, the used structure to decode time intervals on PostgreSQL was &lt;code&gt;Postgrex.Interval&lt;/code&gt; that so far is still the default structure&lt;/p&gt;

&lt;p&gt;In the following snippets on can see the &lt;code&gt;schema&lt;/code&gt; and &lt;code&gt;migration&lt;/code&gt; definitions for a fictitious set of data as well as the materialization on database&lt;/p&gt;

&lt;h4&gt;
  
  
  Schema
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="s2"&gt;"records"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt; 
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:utc_datetime&lt;/span&gt;
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:duration&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Migration
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:records&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;primary_key:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
     &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;primary_key:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
     &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
     &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
     &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;:start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:utc_datetime&lt;/span&gt;
     &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;:duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:duration&lt;/span&gt;

     &lt;span class="n"&gt;timestamps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:utc_datetime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Table Structure
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   Column    |              Type              | Collation | Nullable | Default
&lt;span class="nt"&gt;-------------&lt;/span&gt;+--------------------------------+-----------+----------+---------+
 &lt;span class="nb"&gt;id&lt;/span&gt;          | uuid                           |           | not null |         |
 name        | character varying&lt;span class="o"&gt;(&lt;/span&gt;255&lt;span class="o"&gt;)&lt;/span&gt;         |           |          |         |
 description | character varying&lt;span class="o"&gt;(&lt;/span&gt;255&lt;span class="o"&gt;)&lt;/span&gt;         |           |          |         |
 start       | timestamp&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt; without &lt;span class="nb"&gt;time &lt;/span&gt;zone |           |          |         |
 duration    | interval                       |           |          |         |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Persisted Data
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;                  &lt;span class="nb"&gt;id&lt;/span&gt;                  |    name    |     description      | start | duration |
&lt;span class="nt"&gt;--------------------------------------&lt;/span&gt;+------------+----------------------+-------+----------+
 664e5fd6-17ab-4a27-8799-9ebca4c603e5 | Record AA | The Record AA descr   |       | 11 days  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What went wrong and why I brought this topic?
&lt;/h4&gt;

&lt;p&gt;As the default structure mapped to PostgreSQL's intervals is &lt;code&gt;Postgrex.Interval&lt;/code&gt; when the &lt;code&gt;:duration&lt;/code&gt; type is defined in the &lt;em&gt;schema&lt;/em&gt; and also in the &lt;em&gt;migrations&lt;/em&gt; the value is correctly persisted in the other hand when it's retrieved the interval cannot be mapped to &lt;code&gt;%Duration{}&lt;/code&gt; and the following error is thrown:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(ArgumentError) cannot load &lt;code&gt;%Postgrex.Interval{months: 0, days: 11, secs: 0, microsecs: 0}&lt;/code&gt; as type :duration for field :duration&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When someone is working in a product is desired to keep the focus in the work being done and mainly in the business domain, sometimes mixed up infrastructure code or external libraries might cause technical debts, maintenance and perhaps the lack of code readability and clearness&lt;/p&gt;

&lt;p&gt;It's important to ensure a good level of homogenized code, leverage the usage of standard libraries. In the case of &lt;code&gt;Duration&lt;/code&gt; structure it was supported but due my lack of knowledge it was not working properly.&lt;/p&gt;

&lt;p&gt;I figure out that &lt;code&gt;Postgrex.Interval&lt;/code&gt; was the default structure to decode PostgreSQL's intervals came through several researches about how to solve the error above&lt;/p&gt;

&lt;p&gt;Learning is a constant in the software industry, however is not always possible to spend time as one would wish to acquire new knowledge, explore new libraries or frameworks, etc. Quite often developer seek for shortcuts that could solve the issue and allow them to move forward in a faster way&lt;/p&gt;

&lt;p&gt;I've search exhaustively but I couldn't find nothing like a &lt;em&gt;copy &amp;amp; paste&lt;/em&gt; to commit my code and end my day, so I start collecting pieces of information here and there stopping of being a lazy developer and reading more the&lt;a href="https://hexdocs.pm/postgrex/Postgrex.Types.html#define/3-options" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; perhaps it may save some time from someone on future&lt;/p&gt;

&lt;p&gt;I am wondering that I might not have found more info 'cause I didn't use the right &lt;em&gt;keywords&lt;/em&gt; or by insisting to use &lt;a href="https://duckduckgo.com/?t=ffab&amp;amp;q=postgrex+duration+ArgumentError&amp;amp;ia=web" rel="noopener noreferrer"&gt;DuckDuckGo&lt;/a&gt; as it sounds the results lately are poorer than before &lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;In a nutshell the configuration of &lt;code&gt;Duration&lt;/code&gt; as &lt;code&gt;interval&lt;/code&gt; decoding is done in two main files: &lt;code&gt;config.exs&lt;/code&gt; e &lt;code&gt;postgres_types.ex&lt;/code&gt; (the last one might have any name, &lt;em&gt;postgres_types.ex&lt;/em&gt; is just a natural suggestion)&lt;/p&gt;

&lt;p&gt;The file &lt;code&gt;postgres_types.ex&lt;/code&gt; contains the configuration to overwrite the default one &lt;code&gt;Postgrex.Interval&lt;/code&gt;, looking to file &lt;code&gt;config.exs&lt;/code&gt; it associates the custom type to &lt;a href="https://hexdocs.pm/ecto/Ecto.Repo.html" rel="noopener noreferrer"&gt;&lt;code&gt;Ecto.Repo&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's move forward and prepare the so expected snippet of code to copy, paste and close the day, thus the configuration that makes everything to work in a almost magical way (almost magical because in the end of day it's code design made by awesome guys behind the language, libraries and frameworks)is shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/config.exs&lt;/span&gt;
&lt;span class="c1"&gt;# configures postgrex types&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="no"&gt;Config&lt;/span&gt;

&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;ecto_repos:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="ss"&gt;generators:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;timestamp_type:&lt;/span&gt; &lt;span class="ss"&gt;:utc_datetime&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# configures postgrex types&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;types:&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PostgresTypes&lt;/span&gt;

&lt;span class="c1"&gt;# Configures the endpoint&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;continues&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;








&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lib/my_app/postgres_types.ex&lt;/span&gt;
&lt;span class="c1"&gt;# set the interval decode&lt;/span&gt;

&lt;span class="no"&gt;Postgrex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;ConstruaApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PostgresTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="no"&gt;Ecto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Adapters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Postgres&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="ss"&gt;interval_decode_type:&lt;/span&gt; &lt;span class="no"&gt;Duration&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# --- that's all folks ---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  It works
&lt;/h3&gt;

&lt;p&gt;The search for a simple example, straight to the point doesn't work for me and in my rush to figure out the solution I have forgotten to ask to the available AI mechanisms on how to solve the issue in an easy and fast way (Doh!)&lt;/p&gt;

&lt;p&gt;Now when someone seek for a handy code to solve this problem or a similar one here they have, but it's important to not forget (like me) the GPTs, Geminis and other AIs around to help&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a pt_BR version is available &lt;a href="https://blog.rogerioramos.net.br/2025/03/21/postgrex-ecto-duration.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>elixir</category>
      <category>ecto</category>
      <category>postgrex</category>
    </item>
    <item>
      <title>Ctrl+Alt+Arrow (Right, Left) not working on IntelliJ</title>
      <dc:creator>Rogério Ramos</dc:creator>
      <pubDate>Wed, 11 Dec 2024 13:36:11 +0000</pubDate>
      <link>https://dev.to/habutre/ctrlaltarrow-right-left-not-working-on-intellij-2e2e</link>
      <guid>https://dev.to/habutre/ctrlaltarrow-right-left-not-working-on-intellij-2e2e</guid>
      <description>&lt;p&gt;This post aims to be just a quick tip for those facing the same issue as I was facing.&lt;br&gt;
It seems just a stupid and not critical issue but it affects my productivity quite a lot and searching around I couldn't find a help directly to my problem but combining tips and and there I was able to figure out my issue&lt;/p&gt;

&lt;p&gt;Lately I decide to refresh all my laptops to GNU Arch Linux installations before I used to have Kali, Manjaro and Arch. Now I have streamlined my installations and yeah the family at home had to overcome any barrier of using a GNU Linux box, even my little that is going to turn seven. For my surprise one of the my shortcuts were not working as usually does before&lt;/p&gt;

&lt;p&gt;Going directly to the problem the configurations on my system was hiding some shortcut configs so it took me some time to realize that something was not correct&lt;br&gt;
There is a very common shortcut conflict between Gnome and IntelliJ (when using the Xwin keymap). Gnome workspace switch to left|right (&lt;code&gt;Settings -&amp;gt; Keyboard -&amp;gt; Keyboard Shortcuts&lt;/code&gt;)  shares the same key combination* as IntelliJ (Xwin) navigate back and forward (&lt;code&gt;File -&amp;gt; Navigate -&amp;gt; Back|Forward&lt;/code&gt;) which is the subject of this post&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9juquzus8obyeu6sub97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9juquzus8obyeu6sub97.png" alt="Image description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As one can see the configuration only shows one shortcut assigned to switching workspaces, when in fact 3 was set for moving to right and other 3 to left. The only way to discover it was to follow some tips like &lt;a href="https://stackoverflow.com/a/50373094" rel="noopener noreferrer"&gt;here&lt;/a&gt; and check the shortcuts under the table&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user&amp;gt; $ gsettings get org.gnome.desktop.wm.keybindings \
switch-to-workspace-left
['&amp;lt;Super&amp;gt;Page_Up', '&amp;lt;Super&amp;gt;&amp;lt;Alt&amp;gt;Left', '&amp;lt;Control&amp;gt;&amp;lt;Alt&amp;gt;Left']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user&amp;gt; $ gsettings get org.gnome.desktop.wm.keybindings \
switch-to-workspace-right 
['&amp;lt;Super&amp;gt;Page_Down', '&amp;lt;Super&amp;gt;&amp;lt;Alt&amp;gt;Right', '&amp;lt;Control&amp;gt;&amp;lt;Alt&amp;gt;Right']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So as one can realize the configuration is shown in the screen only the first shortcut &lt;code&gt;&amp;lt;Super&amp;gt;Page_Down&lt;/code&gt; and &lt;code&gt;&amp;lt;Super&amp;gt;Page_Up&lt;/code&gt; but in the end other shortcuts were there hidden and provoking the malfunctioning behavior&lt;/p&gt;

&lt;p&gt;Fixing is pretty easy when you know the reason, so just matter of remove/add the desired shortcuts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user&amp;gt; $ gsettings set org.gnome.desktop.wm.keybindings \
switch-to-workspace-right "['&amp;lt;Super&amp;gt;Page_Down', '&amp;lt;Super&amp;gt;&amp;lt;Alt&amp;gt;Right']"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user&amp;gt; $ gsettings set org.gnome.desktop.wm.keybindings \
switch-to-workspace-left "['&amp;lt;Super&amp;gt;Page_Up', '&amp;lt;Super&amp;gt;&amp;lt;Alt&amp;gt;Left']"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final result was that everything works as expected and may be the next step suggest or even add contributions to Gnome project to have all shortcuts displayed in the configuration to prevent issues like this&lt;/p&gt;

&lt;p&gt;* Ctrl+Alt+Left, Ctrl+Alt+Right&lt;/p&gt;

</description>
      <category>gnulinux</category>
      <category>gnome</category>
      <category>intellij</category>
      <category>tip</category>
    </item>
    <item>
      <title>Migrating Spring Cloud Stream v2 to v3</title>
      <dc:creator>Rogério Ramos</dc:creator>
      <pubDate>Fri, 21 Jan 2022 20:25:09 +0000</pubDate>
      <link>https://dev.to/habutre/migrating-spring-cloud-stream-v2-to-v3-5dip</link>
      <guid>https://dev.to/habutre/migrating-spring-cloud-stream-v2-to-v3-5dip</guid>
      <description>&lt;h2&gt;
  
  
  Cloud Stream V2 x V3
&lt;/h2&gt;

&lt;p&gt;If you have landed here there is a high chance you are looking for ways of migrating the &lt;a href="https://docs.spring.io/spring-cloud-stream/docs/current/reference/html/"&gt;Spring Cloud Stream (SCS)&lt;/a&gt; to version 3.x where almost everything has changed&lt;/p&gt;

&lt;p&gt;The version 3.x has its focus mainly in serverless applications where a service will execute a single function and the combination of all functions perform a workflow or process related to a given feature through &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html"&gt;&lt;code&gt;Consumer&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html"&gt;&lt;code&gt;Supplier&lt;/code&gt;&lt;/a&gt; and/or &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html"&gt;&lt;code&gt;Function&lt;/code&gt;&lt;/a&gt; bean functions, but not all applications are already using the new approach although is a trending now&lt;/p&gt;

&lt;p&gt;Looking at version 2.x &lt;a href="https://docs.spring.io/spring-cloud-stream/docs/Ditmars.SR5/reference/htmlsingle/#__code_source_code_code_sink_code_and_code_processor_code"&gt;&lt;code&gt;Sink&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://docs.spring.io/spring-cloud-stream/docs/Ditmars.SR5/reference/htmlsingle/#__code_source_code_code_sink_code_and_code_processor_code"&gt;&lt;code&gt;Source&lt;/code&gt;&lt;/a&gt; e &lt;a href="https://docs.spring.io/spring-cloud-stream/docs/Ditmars.SR5/reference/htmlsingle/#_producing_and_consuming_messages"&gt;&lt;code&gt;StreamListeners&lt;/code&gt;&lt;/a&gt; build the set of configurations that allows an application to consume messages from multiple upstream sources to execute a flow as well as to publish messages with the resulting output of that flow&lt;/p&gt;

&lt;p&gt;This post aims to demonstrate how the migration from version 2.x to 3.x can be done&lt;/p&gt;

&lt;p&gt;The idea behind Cloud Function (CF) along with SCS is to be used in a FaaS application as unique function with single responsibility&lt;/p&gt;

&lt;p&gt;A non-FaaS application can consumes information from several sources, that is an approach quite common on SCS v2.x, below it will be demonstrated how you can do such migration to SCS v3.x, if you have already checked &lt;a href="https://docs.spring.io/spring-cloud-stream/docs/current/reference/html/spring-cloud-stream.html#_whats_new_in_3_0"&gt;what's new&lt;/a&gt; on SCS version 3 you will note that definitions of &lt;code&gt;Sink&lt;/code&gt;, &lt;code&gt;Source&lt;/code&gt; and &lt;code&gt;Processor&lt;/code&gt; were replaced by &lt;code&gt;Consumer&lt;/code&gt;, &lt;code&gt;Supplier&lt;/code&gt; and &lt;code&gt;Function&lt;/code&gt; bean functions&lt;/p&gt;

&lt;p&gt;The function name mapping to a topic or queue might looks unclear at first sight, on SCS v2.x this used to be configure explicitly and it was easy to identify which topic or queue would be consumed by the application via &lt;code&gt;Sink&lt;/code&gt; configuration and now you have to map the function name directly to the input or output configured on application.yaml&lt;/p&gt;

&lt;p&gt;Particularly I didn´t like that much this configuration but I do not discard being only an initial impression or the natural resistance to novelties, depending on number of topics/queues it may produce a big and unreadable list of mapping functions (&lt;code&gt;spring.cloud.stream.function.definition&lt;/code&gt;) on configuration file. I have not checked the limit - if any - about the size of this property value&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;application.yaml&lt;/em&gt; file has a mixture of Spring Cloud Stream and Spring Cloud Function configurations, the function and function definition belongs to Spring Cloud Function configuration&lt;/p&gt;

&lt;p&gt;There isn't big differences in the configuration except the  &lt;code&gt;spring.cloud.stream.function.definition&lt;/code&gt; property that contains the functions to be mapped to bean functions &lt;code&gt;Consumer&lt;/code&gt;, &lt;code&gt;Supplier&lt;/code&gt; and &lt;code&gt;Function&lt;/code&gt; names, the standard suffix for input and output configuration are &lt;code&gt;&amp;lt;function-name&amp;gt;-in-0&lt;/code&gt; and &lt;code&gt;&amp;lt;function-name&amp;gt;-out-0&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Consuming messages
&lt;/h3&gt;

&lt;p&gt;On version 2 the &lt;code&gt;Sink&lt;/code&gt; is used to configure which topic/queue will be listened for input messages as well as the annotation &lt;code&gt;StreamListener&lt;/code&gt; that allows many configurations including to filter messages from upstream systems&lt;br&gt;
On version 3 a &lt;code&gt;Consumer&lt;/code&gt; function annotated with &lt;code&gt;@Bean&lt;/code&gt; is used and the filter that was defined before via annotation now is done programmatically&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Producing messages
&lt;/h3&gt;

&lt;p&gt;The recommended method to produce messages is quite similar to the consumer function using &lt;code&gt;Supplier&lt;/code&gt; instead &lt;code&gt;Consumer&lt;/code&gt;, but an easier option in my opinion is to use the &lt;code&gt;StreamBridge&lt;/code&gt; component that allows to send messages dynamically just passing the destination output&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  CloudEvents (optional)
&lt;/h3&gt;

&lt;p&gt;Cloud Events is heavily used message specification and its usage is growing very fast, basically it puts a message payload in an "envelope" enriching the message with attributes like source, publish time, type, content type, etc&lt;/p&gt;

&lt;p&gt;In the example below it's possible to check the event serialization and deserialization. Keep in mind that using CloudEvents is completely optional&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The CloudEvents SDK offers many amenities that can be found  &lt;a href="https://cloudevents.github.io/sdk-java/"&gt;here&lt;/a&gt;, e.g. the converter below allowing integration with Spring:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Conclusion and next steps
&lt;/h3&gt;

&lt;p&gt;The goal here is to help with examples and configurations what has changed among SCS versions 2.x e 3.x and how such upgrade can be done&lt;/p&gt;

&lt;p&gt;It's an abrupt change on how CSC is used and it can cause resistance to adopt keeping the already deprecated programming model still in use for while in the other hand can impose some challenging on running applications that will require a consistent set of testing mainly load and resiliency tests.&lt;/p&gt;

&lt;p&gt;Tests were not covered on that time but they also changed quite a lot and it will be covered on further posts but if you can not wait to make it happen &lt;a href="https://docs.spring.io/spring-cloud-stream/docs/3.0.10.RELEASE/reference/html/spring-cloud-stream.html#_testing"&gt;here&lt;/a&gt; you will find the steps to move forward&lt;/p&gt;

&lt;p&gt;I hope this info could be helpful and don't hold yourself to share it everywhere&lt;/p&gt;

&lt;p&gt;Esse post foi originalmente publicado &lt;a href="https://blog.rogerioramos.net.br/2021/01/16/spring-cloud-stream.html"&gt;aqui&lt;/a&gt; em português brasileiro&lt;/p&gt;

&lt;p&gt;cya&lt;/p&gt;

&lt;p&gt;-Rogério&lt;/p&gt;

</description>
      <category>spring</category>
      <category>eventdriven</category>
      <category>cloudevents</category>
    </item>
    <item>
      <title>The terrifying mongoDB sintaxe</title>
      <dc:creator>Rogério Ramos</dc:creator>
      <pubDate>Fri, 07 Jun 2019 08:00:38 +0000</pubDate>
      <link>https://dev.to/habutre/the-terrifying-mongodb-sintaxe-1gk7</link>
      <guid>https://dev.to/habutre/the-terrifying-mongodb-sintaxe-1gk7</guid>
      <description>&lt;p&gt;The main responsibility of experienced Sw Developers is help others and use the gained experience to overcome issues always teaching, learning and sharing.&lt;/p&gt;

&lt;p&gt;I want to share a simple thing that make me think about complexity and trade-offs. I co-worker came to me asking for help on a MongoDB aggregate query:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How would I aggregate the data that I need since I am using a NoSQL database?&lt;/p&gt;

&lt;p&gt;Can I use my previous SQL knowledge to make it happen?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, I think the things could be simpler but not. Look at the example bellow.&lt;/p&gt;

&lt;p&gt;I have a series of events happening in my application where a particular event seems to be happening more often than expected. I would like check how often that event happens.&lt;/p&gt;

&lt;p&gt;On mongo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongo-client-shell&amp;gt; db.orders.aggregate([ 
  { $match: {"event": "order.event.OrderPickedEvent"}} ,
  { $group : { _id: {"event": "$event", "orderNumber": '$orderNumber'}, count: { $sum: 1 } } }, 
  { $sort: {count: -1}}
], 
{allowDiskUse:true}
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On Postgresql:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql&amp;gt; select count(*) as total 
  from order 
  where event = "order.event.OrderPickedEvent" 
  group by orderNumber 
  order by total desc;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The question on my mind: Why Mongo make things so weird to not say complex? &lt;/p&gt;

&lt;p&gt;Its not natural to the reader.&lt;br&gt;
We are always talking about code clearness, readability and making things simpler. But seems that big player not thing in the same way.&lt;/p&gt;

&lt;p&gt;I hope this mini post can help others and maybe sensitize the tool's suppliers to make life easier*.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I find a SQL translator to NoSQL which could help in that case &lt;a href="https://studio3t.com/"&gt;https://studio3t.com/&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mongodb</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
