<?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: Dviejo</title>
    <description>The latest articles on DEV Community by Dviejo (@dviejopomata).</description>
    <link>https://dev.to/dviejopomata</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%2F79564%2F62985474-e677-4541-9ec2-b4234721af12.jpeg</url>
      <title>DEV Community: Dviejo</title>
      <link>https://dev.to/dviejopomata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dviejopomata"/>
    <language>en</language>
    <item>
      <title>Character set walkthrough</title>
      <dc:creator>Dviejo</dc:creator>
      <pubDate>Sat, 23 Nov 2019 15:11:03 +0000</pubDate>
      <link>https://dev.to/dviejopomata/character-set-lesson-9c4</link>
      <guid>https://dev.to/dviejopomata/character-set-lesson-9c4</guid>
      <description>&lt;p&gt;How do we write to a file a character like Ñ and the word привет? (hello in Russian: privet). We have the idea that to represent a character we need a byte, but this has not been so for many years.&lt;/p&gt;

&lt;p&gt;At the programming level, this currently represents one of the biggest problems when we have to make an application that contemplates several languages, with different character sets.&lt;/p&gt;

&lt;p&gt;This forces us to when we create a file we have to express the character set with which it is made. Whoever receives the file should know which character set it's been written to be able to read it properly.&lt;/p&gt;

&lt;p&gt;And in the databases, in which character set are the data recorded? When the database is created, database managers should usually express what character set they want to work with. If our database must store information in Russian and Spanish, we must use a character set that allows both.&lt;br&gt;
If we open the notepad ++, we write a Ñ and record as test.txt and do type test.txt we see&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnjuw7486t6s05ggckxuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnjuw7486t6s05ggckxuj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;but if we do it with the Powershell&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpyd2gy21aidxetox45lt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpyd2gy21aidxetox45lt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have written a Ñ and we have two different representations. This already poses a problem. One thing is what is in the file, which is a Ñ and another thing is how the programs interpret it, in this case, the cmd and PowerShell do it differently.&lt;/p&gt;

&lt;p&gt;If we read it with a program, for example in python,&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgvp4oq5sr060mx5cawac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgvp4oq5sr060mx5cawac.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;what is happening, in python, is that when you open the file we are not telling you that the character set is utf-8&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwbut9c7kbf8cegmyp7pc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwbut9c7kbf8cegmyp7pc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But why have we had to say utf-8 and not something else? In what character set has the notepad ++ recorded the file? The notepad, if we say nothing else, records the file in utf-8. When we tell the python that the file is in utf-8 we see the Ñ.&lt;/p&gt;

&lt;p&gt;What programmers do when we see "weird characters", we say, "that is a problem of the character set," but we don't really know very well what has happened. "&lt;/p&gt;

&lt;p&gt;One lesson to learn is that when we open a file or record a file we should specify the character set with which it is recorded.&lt;/p&gt;

&lt;p&gt;But why does it come out &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnjuw7486t6s05ggckxuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnjuw7486t6s05ggckxuj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
 as a representation of the Ñ in the cmd? Well, when we open a cmd it starts with a character set that is not the utf-8. If we run chcp ithit does notmy machine:&lt;/p&gt;

&lt;p&gt;Active code page: 850. If we see what code 850 is like in the following url &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fp3428txhvah1tux67cb6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fp3428txhvah1tux67cb6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will see that the first character is from row C column 3 and the second is from row 9 col 1. Therefore, refer to the C391 characters.&lt;/p&gt;

&lt;p&gt;If we change the character set to utf8 with the command &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;chcp 65001&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and type type.txt then it appears to us&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ñ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The CMD program has correctly interpreted the character set of the file.&lt;/p&gt;

&lt;p&gt;We have to keep in mind that sometimes the problem will not be in the file, but in the program that interprets the file.&lt;/p&gt;

&lt;p&gt;If we open the file with the notepad.exe, it interprets it properly and the Ñ appears&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvizu2hv34cctd54c6vul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvizu2hv34cctd54c6vul.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What bytes have actually been recorded in the file? If we look at the content in hexadecimal with the powershell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Format-Hex test.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we have:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fb1gk6g2b9heyraftuevi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fb1gk6g2b9heyraftuevi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Ñ is saved using two bytes C3 91&lt;/p&gt;

&lt;p&gt;If we see the utf-8 specification, we see that the Ñ is represented with two bytes (&lt;a href="https://www.utf8-chartable.de/" rel="noopener noreferrer"&gt;https://www.utf8-chartable.de/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0va548g57z35fvhcr7p3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0va548g57z35fvhcr7p3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UTF-8 IS a multibyte character encoding, which allows the exchange between different systems in a secure way. &lt;/p&gt;

&lt;p&gt;The first 128 characters are serialized in the same way, from 128 they are serialized with 2 bytes. There are characters that are serialized with 3 4 5 and 6 bytes.&lt;/p&gt;

&lt;p&gt;This article is the first in a series dedicated to character sets.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Loading data into Postgresql using Nodejs and Minio</title>
      <dc:creator>Dviejo</dc:creator>
      <pubDate>Tue, 12 Mar 2019 22:31:51 +0000</pubDate>
      <link>https://dev.to/dviejopomata/loading-data-into-postgresql-using-nodejs-and-minio-1l4c</link>
      <guid>https://dev.to/dviejopomata/loading-data-into-postgresql-using-nodejs-and-minio-1l4c</guid>
      <description>&lt;p&gt;I was recently loading a lot of files into PostgreSQL, and i had the need of doing it without many resources and to be fast.&lt;/p&gt;

&lt;p&gt;The requirements I had were the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Low footprint, not reading all lines of a file at once&lt;/li&gt;
&lt;li&gt;Easy to load data&lt;/li&gt;
&lt;li&gt;Write data efficiently into Postgres using "COPY TO" sentence&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these requirements, I came up with the idea of doing with streams in NodeJS because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's efficient&lt;/li&gt;
&lt;li&gt;It's simple&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's say I have the following file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;first_name, last_name, country
Karie,Zorn,Ukraine
Thebault,Flicker,France
Danya,Atcock,Canada
Lorne,Westmorland,Russia
Page,Greeve,Canada
Rene,Riccardini,Serbia
Adair,Mullin,Philippines
Della,Gumb,China
Charlie,Swadlinge,Cambodia
Celka,Karlowicz,Canada
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And the following table in PostgreSQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="nv"&gt;"uuid-ossp"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;PERSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;uuid_generate_v4&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we're going to use curl in the PostgreSQL sentence in order to get the file, we're going to extend the Postgresql Docker image with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM postgres:10.4
RUN apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; curl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I named this file postgresql.Dockerfile, when you have that file, we're going to get all running with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-f&lt;/span&gt; postgresql.Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; postgres-with-curl &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="nt"&gt;--name&lt;/span&gt; postgres &lt;span class="nt"&gt;--network&lt;/span&gt; host &lt;span class="nt"&gt;-d&lt;/span&gt; postgres-with-curl
docker run &lt;span class="nt"&gt;--network&lt;/span&gt; host &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;MINIO_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;user &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;MINIO_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password &lt;span class="nt"&gt;--restart&lt;/span&gt;  always &lt;span class="nt"&gt;--name&lt;/span&gt; minio &lt;span class="nt"&gt;-d&lt;/span&gt; minio/minio:RELEASE.2018-06-22T23-48-46Z server /data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So let's do it, first we need to create the connections for PostgreSQL and Minio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;minio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minioClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;minio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;accessKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;endPoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pgPool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;pg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we're going to do basically 3 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the file&lt;/li&gt;
&lt;li&gt;Upload to minio&lt;/li&gt;
&lt;li&gt;Execute SQL in PostgreSQL instance
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TABLE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public.people&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;people.csv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucketName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tmp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new.csv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;minioClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;putObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csvUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;minioClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;presignedGetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;bucketName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// duration in seconds of the url&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;copyDataSql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  COPY &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (FIRST_NAME, LAST_NAME, COUNTRY)
    FROM PROGRAM 'curl "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;csvUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"'
    WITH (FORMAT CSV , HEADER, QUOTE '"', DELIMITER ',' );`&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pgPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;copyDataSql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pgPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we execute the following code in nodejs we should see the rows in the database with the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;PUBLIC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PEOPLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The script can fail because of the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minio is not up&lt;/li&gt;
&lt;li&gt;Postgresql is not up&lt;/li&gt;
&lt;li&gt;Postgresql table has not been created&lt;/li&gt;
&lt;li&gt;Minio bucket "tmp" has not been created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This technique can be useful when we have no control over the disk in postgres and we have to perform a batch operation.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>node</category>
      <category>postgres</category>
      <category>backend</category>
      <category>s3</category>
    </item>
    <item>
      <title>Building SDKs for your SAAS</title>
      <dc:creator>Dviejo</dc:creator>
      <pubDate>Tue, 13 Nov 2018 02:25:42 +0000</pubDate>
      <link>https://dev.to/dviejopomata/building-sdks-for-your-saas-23hb</link>
      <guid>https://dev.to/dviejopomata/building-sdks-for-your-saas-23hb</guid>
      <description>&lt;h1&gt;
  
  
  Building SDKs for your SAAS
&lt;/h1&gt;

&lt;p&gt;I recently build a service, &lt;a href="https://docxmerge.com" rel="noopener noreferrer"&gt;docxmerge&lt;/a&gt;, which does a merge from a Microsoft Word and JSON document and converts it to PDF.&lt;/p&gt;

&lt;p&gt;The API is very simple, but in order to make easy for developers to integrate it in their applications, I chose to create a library for at least four languages, NodeJS, Dotnet, Java, and Python.&lt;/p&gt;

&lt;p&gt;Yeah, it looks like we got a bit of work. This task can be either too easy or too embarrassing. But I had a benefit, which was to use Swagger for the API definition, so basically, I could generate all the boilerplate code and just do a class in every language and publish it to the corresponding registry.&lt;/p&gt;

&lt;p&gt;With Swagger, all is based on the JSON generated in the backend in this case the next one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://api.docxmerge.com/api/swagger/v1/swagger.json" rel="noopener noreferrer"&gt;https://api.docxmerge.com/api/swagger/v1/swagger.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having that JSON, the swagger codegen is able to generate the code to interact with your api in a typed way and with no effort at all. I generate that code with docker which is much cleaner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/src/swagger:/local swaggerapi/swagger-codegen-cli:v2.3.1 generate &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SWAGGER_URL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; typescript-node &lt;span class="nt"&gt;-o&lt;/span&gt; /local &lt;span class="nt"&gt;--additional-properties&lt;/span&gt; &lt;span class="nv"&gt;supportsES6&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a said, Swagger was the biggest advantage, as it was effort free and I didn't have to worry about paths, query strings, multipart requests, etc. And lucky me, I was able to generate it from C# annotations using this &lt;a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore" rel="noopener noreferrer"&gt;Swashbucle library&lt;/a&gt; , so didn't have to write that mega JSON ;)&lt;/p&gt;

&lt;p&gt;I will do one post per language explaining how I built each library from the swagger-codegen to the publish.&lt;/p&gt;

&lt;p&gt;This is the repository where I'm working: &lt;br&gt;
&lt;a href="https://github.com/Docxmerge/docxmerge-sdk" rel="noopener noreferrer"&gt;https://github.com/Docxmerge/docxmerge-sdk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's still in progress, and I'm still missing the Java one to be deployed because of the verification, but it works.&lt;/p&gt;

</description>
      <category>dev</category>
      <category>programming</category>
      <category>saas</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Haproxy multiple certificates over single IP using SNI.</title>
      <dc:creator>Dviejo</dc:creator>
      <pubDate>Wed, 04 Jul 2018 19:06:24 +0000</pubDate>
      <link>https://dev.to/dviejopomata/haproxy-multiple-certificates-over-single-ip-using-sni-29ka</link>
      <guid>https://dev.to/dviejopomata/haproxy-multiple-certificates-over-single-ip-using-sni-29ka</guid>
      <description>&lt;h1&gt;
  
  
  Haproxy multiple certificates over single IP using SNI
&lt;/h1&gt;

&lt;p&gt;Hello!, I'm a fullstack/devops developer who is going to start sharing solutions to problems around. Over the last two years i have specialized on Kubernetes/Docker, NodeJS, Java and Angular/React. I will be writing about software solutions in the next posts.&lt;/p&gt;

&lt;p&gt;I had a problem with routing in haproxy and i didn't know why, i had the haproxy doing routing with &lt;a href="https://en.wikipedia.org/wiki/Server_Name_Indication" rel="noopener noreferrer"&gt;SNI&lt;/a&gt;(Server name indication), which is an extension of the TLS protocol which is useful in order to get the hostname at the start of the handshake, so i could do load balancing over multiple backends without doing handshake. But i found that if you do routing with SNI and present the same certificate in multiple hostname you won't always get the same result.&lt;/p&gt;

&lt;p&gt;To see the things clearly let's present an example.&lt;/p&gt;

&lt;p&gt;A configuration of haproxy with SNI routing could be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global
  log /dev/log    local0
  log /dev/log    local1 notice
  stats socket /haproxy-admin.sock mode 660 level admin
  stats timeout 30s
  daemon
defaults
  maxconn 1000
  mode http        
  log global
  option dontlognull # bind *:443 ssl crt .
  timeout http-request 5s
  timeout connect 5000
  timeout client 2000000 # ddos protection
  timeout server 2000000 # stick-table type ip size 100k expire 30s store conn_cur

frontend env_ssl_frontend
  bind *:443
  mode tcp
  option tcplog
  tcp-request inspect-delay 10s
  tcp-request content accept if { req_ssl_hello_type 1 }
  use_backend bk_app1 if { req.ssl_sni -m end app1.domain.com }
  use_backend bk_app2 if { req.ssl_sni -m end app2.domain.com }
  use_backend bk_app3 if { req.ssl_sni -m end app3.domain.com }

backend bk_app1
  balance source
  mode tcp
  option ssl-hello-chk
  server main 127.0.0.1:3000
backend bk_app2
  balance source
  mode tcp
  option ssl-hello-chk
  server main 127.0.0.1:3001
backend bk_app3
  balance source
  mode tcp
  option ssl-hello-chk
  server main 127.0.0.1:3002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend looks pretty clear, we have it listening on 443 on TCP mode (&lt;a href="https://en.wikipedia.org/wiki/OSI_model#Layer_4:_Transport_Layer" rel="noopener noreferrer"&gt;L4&lt;/a&gt;) and routing to bk_app1, app2 or app3, depending on the server_name coming from the Client Hello, and then, sends the traffic to the corresponding App. &lt;/p&gt;

&lt;p&gt;In the backend server you will have to terminate the handshake, if not, it will not work.&lt;/p&gt;

&lt;p&gt;You can test this easily without having to install haproxy by having Docker installed having a file named haproxy.cfg with the previous config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 443:443 &lt;span class="nt"&gt;--name&lt;/span&gt; haproxy &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/usr/local/etc/haproxy:ro haproxy:1.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to see which server_name is being sended, you can use &lt;a href="https://www.wireshark.org/" rel="noopener noreferrer"&gt;Wireshark&lt;/a&gt;&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%2Ft54lvrgmo6z8db1p5vee.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%2Ft54lvrgmo6z8db1p5vee.png" alt="Wireshark image" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this configuration, if you present the same certificate in bk_app1 and bk_app2, you will be redirected based on the current handshake. So, you access app1.domain.com, then access app2.domain.com, then app2.domain.com will routed to bk_app1.&lt;/p&gt;

&lt;p&gt;So always that you do routing over SNI, you have to do redirecto to the same backend per certificate!&lt;/p&gt;

&lt;p&gt;I hope it helped!&lt;/p&gt;

&lt;p&gt;I'm planning on writing about microservices, CI/CD and Kubernetes. So if you want me to talk about any themes feel free to ask!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
