<?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: Insolita</title>
    <description>The latest articles on DEV Community by Insolita (@insolita).</description>
    <link>https://dev.to/insolita</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%2F30757%2Fdf6f0c3a-1a18-416d-bc26-7cf6bfb476c4.jpeg</url>
      <title>DEV Community: Insolita</title>
      <link>https://dev.to/insolita</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/insolita"/>
    <language>en</language>
    <item>
      <title>Postgres And Birthday Dates</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Sat, 09 Oct 2021 13:35:15 +0000</pubDate>
      <link>https://dev.to/insolita/postgres-and-birthday-dates-3ji4</link>
      <guid>https://dev.to/insolita/postgres-and-birthday-dates-3ji4</guid>
      <description>&lt;p&gt;Processing user`s dates of birthday is a often task, but sometimes newbies has difficult with it. So, I decide to write a few snippets.&lt;/p&gt;

&lt;p&gt;For ex. we have a table&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
CREATE TABLE users (&lt;br&gt;
   id serial primary key,&lt;br&gt;
   name varchar(100) not null,&lt;br&gt;
   birthday date&lt;br&gt;
);&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Find users who have birthdays at this month
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
SELECT * FROM users WHERE date_part('month', birthday) = date_part('month', CURRENT_DATE)&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Find users who have birthdays today
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
SELECT * FROM users &lt;br&gt;
WHERE date_part('day', birthday) = date_part('day', CURRENT_DATE) &lt;br&gt;
AND date_part('month', birthday) = date_part('month', CURRENT_DATE)&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2.1 Find users who have birthdays tomorrow
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
SELECT * FROM users &lt;br&gt;
WHERE &lt;br&gt;
   date_part('day', birthday) = date_part('day', CURRENT_DATE + INTERVAL '1day') &lt;br&gt;
    AND &lt;br&gt;
   date_part('month', birthday) = date_part('month', CURRENT_DATE + INTERVAL '1day')&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Find users who have birthdays during some period, for. ex. in recent month
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
 WITH lastDayOfMonth as (&lt;br&gt;
SELECT (date_trunc('month', CURRENT_DATE) + interval '1 month' - interval '1 day')::date as ldm&lt;br&gt;
)&lt;br&gt;
SELECT *&lt;br&gt;
FROM users, lastDayOfMonth&lt;br&gt;
WHERE (&lt;br&gt;
   date_part('month', birthday) = date_part('month', CURRENT_DATE) AND&lt;br&gt;
   date_part('day', birthday) BETWEEN date_part('day', CURRENT_DATE) AND date_part('day', ldm)&lt;br&gt;
) &lt;br&gt;
OR&lt;br&gt;
(&lt;br&gt;
   date_part('month', birthday) = date_part('month', CURRENT_DATE + interval '1 month')&lt;br&gt;
   AND date_part('day', birthday) BETWEEN 1 AND date_part('day', CURRENT_DATE)&lt;br&gt;
);&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But this method will be works only for month interval.&lt;br&gt;
If we need birthdays in recent 10 days, or 45 days... for more flexible calculation will better to use a days number of year. But we need take care about valid handling between years - for ex. 20 days since 25 december - is an interval 25.12.2021 - 14.01.2022&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
WITH lastDayOfYear AS (&lt;br&gt;
    SELECT (date_trunc('year', CURRENT_DATE) + interval '1 year' - interval '1 day')::date AS ldy&lt;br&gt;
)&lt;br&gt;
SELECT *&lt;br&gt;
FROM users, lastDayOfYear&lt;br&gt;
WHERE &lt;br&gt;
(&lt;br&gt;
-- if year is same &lt;br&gt;
   date_part('year', CURRENT_DATE) = date_part('year', CURRENT_DATE + interval '20days')&lt;br&gt;
   AND date_part('doy', birthday)&lt;br&gt;
       BETWEEN date_part('doy', CURRENT_DATE) AND date_part('doy', CURRENT_DATE + interval '20days')&lt;br&gt;
)&lt;br&gt;
OR (&lt;br&gt;
   date_part('year', CURRENT_DATE) &amp;lt; date_part('year', CURRENT_DATE + interval '20days')&lt;br&gt;
   AND (&lt;br&gt;
     date_part('doy', birthday) BETWEEN date_part('doy', CURRENT_DATE) AND date_part('doy', ldy) &lt;br&gt;
     OR date_part('doy', birthday) &amp;lt; (20 - date_part('day', age(ldy, CURRENT_DATE)))&lt;br&gt;
   )&lt;br&gt;
);&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Find users with age in some interval, for example, users with age between 30 and 40 years old.
&lt;/h3&gt;

&lt;p&gt;It is easy to solve on backend side, when you can prepare sql&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;php&lt;br&gt;
&amp;lt;?php&lt;br&gt;
$from = date('Y-m-d', strtotime('-30years'));&lt;br&gt;
$to =  date('Y-m-d', strtotime('-40years'));&lt;br&gt;
$sql = "SELECT * FROM users WHERE birthday BETWEEN '$from' AND '$to'";&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But sometimes direct query may be more useful - you can do it with postgres function &lt;code&gt;age&lt;/code&gt; that calculates an interval between dates&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;SQL&lt;br&gt;
SELECT * FROM users WHERE age(birthday) BETWEEN interval '30 years' AND interval '40 years';&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can play with these queries in &lt;a href="https://www.db-fiddle.com/f/6YNye44Kc9b73uNAsgfkbu/6"&gt;Db-Fiddle&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
    </item>
    <item>
      <title>Unused Scanner 2.3 released</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Thu, 15 Apr 2021 16:42:12 +0000</pubDate>
      <link>https://dev.to/insolita/unused-scanner-2-3-released-555f</link>
      <guid>https://dev.to/insolita/unused-scanner-2-3-released-555f</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now distributes as phar archive also! You can &lt;a href="https://github.com/Insolita/unused-scanner/releases/download/2.3.0/unused_scanner.phar"&gt;download phar&lt;/a&gt; from the &lt;a href="https://github.com/Insolita/unused-scanner/releases/tag/2.3.0"&gt;releases page&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;improved argument parsing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;added option for show app version only&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fixed silent output - it really silent now, only status code returned&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;removed nesbot/carbon dependency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it now at &lt;a href="https://github.com/Insolita/unused-scanner"&gt;https://github.com/Insolita/unused-scanner&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>composer</category>
      <category>console</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Linux tools for check disk usage and folders size</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Fri, 13 Nov 2020 00:53:00 +0000</pubDate>
      <link>https://dev.to/insolita/linux-tools-for-check-disk-usage-and-folders-size-1ko2</link>
      <guid>https://dev.to/insolita/linux-tools-for-check-disk-usage-and-folders-size-1ko2</guid>
      <description>&lt;h3&gt;
  
  
  1. Native ones
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;du&lt;/code&gt; - Summarize disk usage of the set of FILEs, recursively for directories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most popular commands:&lt;/strong&gt; &lt;br&gt;
&lt;code&gt;du -sh /path&lt;/code&gt; - show total summary for a defined path&lt;/p&gt;

&lt;p&gt;&lt;code&gt;du -h -d 1 /path&lt;/code&gt; - show directory sizes with custom depth (-d option)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;du -h -d 1 /path | sort -hr&lt;/code&gt; - same as previous, but with sort from largest to lowest&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa578jhqwiggttyyww0tw.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa578jhqwiggttyyww0tw.png" alt="du output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;df&lt;/code&gt; - report file system disk space usage&lt;/p&gt;

&lt;p&gt;Output result looks like:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhjsensv5vjv5ujzwuqew.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhjsensv5vjv5ujzwuqew.png" alt="df output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Dust - Rust-written du improve.
&lt;/h3&gt;

&lt;p&gt;Show result as a pretty tree with sort (Ascending by default)&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/bootandy/dust" rel="noopener noreferrer"&gt;https://github.com/bootandy/dust&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwietast14yrvsjsl0p1g.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwietast14yrvsjsl0p1g.png" alt="dust"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output can be limited by depth and reversed from largest to lowest&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dust -r -d 1&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs0w4sszkacpcf00htfzl.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs0w4sszkacpcf00htfzl.png" alt="dust -r -d1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, it has an interesting feature - showing by file count instead of files size&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjxysbjpxlzv9zvu39nr4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjxysbjpxlzv9zvu39nr4.png" alt="dust -fr"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ncdu - N-curses du version
&lt;/h3&gt;

&lt;p&gt;Site: &lt;a href="https://dev.yorhel.nl/ncdu" rel="noopener noreferrer"&gt;https://dev.yorhel.nl/ncdu&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Install on Ubuntu: &lt;code&gt;apt install ncdu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install on ArchLinux: &lt;code&gt;sudo pacman -S ncdu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It scans the defined directory, show disk usage, and bring the ability to navigate by child directories &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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1mlz71nbp51yic3vfm9n.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1mlz71nbp51yic3vfm9n.png" alt="ncdu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Dutree - yet another du alternative, written with rust
&lt;/h3&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/nachoparker/dutree" rel="noopener noreferrer"&gt;https://github.com/nachoparker/dutree&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installation: &lt;code&gt;cargo install dutree&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhacmod18fwjtyqb5zp1.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhacmod18fwjtyqb5zp1.png" alt="dutree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Pydf - df clone written with python
&lt;/h3&gt;

&lt;p&gt;Behavior is similar to native df, but with more pretty colorized output&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/garabik/pydf" rel="noopener noreferrer"&gt;https://github.com/garabik/pydf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install on Ubuntu/Debian: &lt;code&gt;apt install pydf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install on ArchLinux: &lt;code&gt;sudo pacman -S pydf&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8k0dbkrqdhzpuhfaov70.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8k0dbkrqdhzpuhfaov70.png" alt="pydf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Duf - Go-written better df alternative
&lt;/h3&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/muesli/duf" rel="noopener noreferrer"&gt;https://github.com/muesli/duf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install on Ubuntu/Debian: &lt;code&gt;apt install duf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install on ArchLinux: &lt;code&gt;yay -S duf&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;It is really fast, has a pretty look, and has a killer feature - the ability to output as JSON, that can be useful for monitoring&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F75uhnr0ictr9p5lii25n.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F75uhnr0ictr9p5lii25n.png" alt="duf"&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftvj0cxes9ctb6kiagnwg.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftvj0cxes9ctb6kiagnwg.png" alt="duf for path"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>console</category>
      <category>filesystem</category>
      <category>terminal</category>
    </item>
    <item>
      <title>How to flip array keys and values in the code editor?</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Mon, 02 Nov 2020 04:04:43 +0000</pubDate>
      <link>https://dev.to/insolita/how-to-flip-array-keys-and-values-in-the-code-6f9</link>
      <guid>https://dev.to/insolita/how-to-flip-array-keys-and-values-in-the-code-6f9</guid>
      <description>&lt;p&gt;Easy, with regex search!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press Ctrl+R for show replace bar&lt;/li&gt;
&lt;li&gt;Enable regex mode (button looks like .* near search field)&lt;/li&gt;
&lt;li&gt;Use regex in search field: &lt;code&gt;'(.+)'\s=&amp;gt;\s'(.+)',&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use expression for replace: &lt;code&gt;'$2' =&amp;gt; '$1',&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see a tooltip with a value that will be after replace&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7zbpp95oup0v6tni9e50.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7zbpp95oup0v6tni9e50.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is possible even you have different quotes and spaces between arrow&lt;/p&gt;

&lt;p&gt;Use regex&lt;br&gt;
&lt;code&gt;(?:'|")(.+)(?:'|")\s{0,}=&amp;gt;\s{0,}(?:'|")(.+)(?:'|"),&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And the same replace expression &lt;code&gt;'$2' =&amp;gt; '$1',&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftasb4nnmh3eabzlpipa1.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftasb4nnmh3eabzlpipa1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Named capture groups also available:&lt;/p&gt;

&lt;p&gt;Use regex&lt;br&gt;
&lt;code&gt;(?:'|")(?&amp;lt;src&amp;gt;.+)(?:'|")\s{0,}=&amp;gt;\s{0,}(?:'|")(?&amp;lt;tgt&amp;gt;.+)(?:'|"),&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And the same replace expression &lt;code&gt;'${tgt}' =&amp;gt; '${src}',&lt;/code&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>phpstorm</category>
      <category>tips</category>
      <category>regex</category>
    </item>
    <item>
      <title>Coloro - a console tool for show texts with highlighted colors</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Thu, 13 Aug 2020 21:17:38 +0000</pubDate>
      <link>https://dev.to/insolita/coloro-a-console-tool-for-show-texts-with-highlighted-colors-28cc</link>
      <guid>https://dev.to/insolita/coloro-a-console-tool-for-show-texts-with-highlighted-colors-28cc</guid>
      <description>&lt;p&gt;Let me introduce "coloro" - a simple console tool for output text with highlighted hex colors. I wrote it when playing with my polybar and bspwm design. &lt;/p&gt;

&lt;p&gt;Source available at &lt;a href="https://github.com/Insolita/coloro"&gt;https://github.com/Insolita/coloro&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can highlight text from arg&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--McUF2bg5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gw2ljg6pj07enz656wbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--McUF2bg5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gw2ljg6pj07enz656wbe.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Highlight text from file&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SwipYPlh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8mxvhxpcekjymxougckw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SwipYPlh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8mxvhxpcekjymxougckw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Highlight text from pipe&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DytqnONG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eaffrjmxgv20lyc4p6xf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DytqnONG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eaffrjmxgv20lyc4p6xf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9S7ZCh2h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a9p11z7p5yvkxrbsgkwd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9S7ZCh2h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a9p11z7p5yvkxrbsgkwd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And even highlight text from clipboard&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mqK4K5-G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ykxteer2u2x4c3knw08y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mqK4K5-G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ykxteer2u2x4c3knw08y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;( -n option allow to parse colors without hashtag prefix )&lt;/p&gt;

</description>
      <category>linux</category>
      <category>cli</category>
      <category>terminal</category>
      <category>python</category>
    </item>
    <item>
      <title>Notes for migrating an app from Mysql to Postgres</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Sun, 26 Jul 2020 21:39:17 +0000</pubDate>
      <link>https://dev.to/insolita/notes-for-migrating-an-app-from-mysql-to-postgres-3693</link>
      <guid>https://dev.to/insolita/notes-for-migrating-an-app-from-mysql-to-postgres-3693</guid>
      <description>&lt;p&gt;Actually, in most cases, we work with databases through abstraction layers of ORM/ActiveRecord libraries, which give us the ability to work with different databases in the same manner. That can make an illusion that we can easily be switching to another database system. Just run a new database system, change database driver in framework settings, and upload data dump to the new database. So, it can be the truth for some simple cases. But for larger projects, we forced to use raw database queries from time to time. It happens for different reasons - when we want to add better optimization or want to use database-specific features, or when we need a complex query. My article is about several differences between MySQL and PostgreSQL that we should keep in mind if we want to migrate from one to another. And if any kind of raw SQL queries are in our application, we should pay special attention to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quotes
&lt;/h2&gt;

&lt;p&gt;For MySQL, we can use single quotes '' as well as double quotes "" for strings and backticks  for system data - table names, column names.&lt;/p&gt;

&lt;p&gt;For PostgreSQL, we must use only single quotes for strings and double quotes for table, column names, etc...&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments
&lt;/h2&gt;

&lt;p&gt;MySQL supports ANSI standard comment prefix '--' double-hyphen and also hashtags. PostgreSQL understands only double-hyphen prefix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case Sensitiveness
&lt;/h2&gt;

&lt;p&gt;MySQL under Linux os is case sensitive for column, index, stored routine, and event names. And it is not sensitive for database and table names. &lt;br&gt;
Imagine, that we have table "my_table" with columns "name" and "myText"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select name, myText from my_table; -- ok
select Name, mytext from my_table; -- ok
select name, myText from My_Table; -- wrong
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Postgres is case-sensitive for quoted system names and insensitive for unquoted (But all unquoted names casts to lowercase)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select name, myText from my_table; -- wrong
select name, myText from "My_Table"; -- wrong

select name, "myText" from my_table; -- ok
select NAME, "myText" from my_table; -- ok
select name, "myText" from My_Table; -- ok
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Operators
&lt;/h2&gt;

&lt;p&gt;MySQL use &lt;code&gt;AND&lt;/code&gt;,&lt;code&gt;OR&lt;/code&gt; as well as alises &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt; - for logical operations.&lt;br&gt;
Postgres use only &lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;. The operator &lt;code&gt;||&lt;/code&gt; used for string concatenations.&lt;/p&gt;

&lt;p&gt;MySQL use &lt;code&gt;^&lt;/code&gt; for byte XOR operation.&lt;br&gt;
Postgres use &lt;code&gt;^&lt;/code&gt; for exponentiation and &lt;code&gt;#&lt;/code&gt; for byte XOR.&lt;/p&gt;

&lt;p&gt;Postgres haven't &lt;code&gt;SOUNDS LIKE&lt;/code&gt; operator. (But you can use &lt;a href="https://www.postgresql.org/docs/current/fuzzystrmatch.html"&gt;fuzzystrmatch&lt;/a&gt; extension, that can soundex and even more)&lt;/p&gt;

&lt;p&gt;MySQL &lt;code&gt;LIKE&lt;/code&gt; operator is case-insensitive. Postgres &lt;code&gt;LIKE&lt;/code&gt; operator case-sensitive. Use &lt;code&gt;ILIKE&lt;/code&gt; operator for an ignore-case search. &lt;/p&gt;
&lt;h2&gt;
  
  
  Strictness
&lt;/h2&gt;

&lt;p&gt;MySQL got real strictness mode settings only since 5.7 version. So if your MySQL version less than 5.7, or you use it without strict-mode - you must pay attention for sure that your application well-validate data size/length accordingly column limits. Because Postgres is strict for this. &lt;br&gt;
Also, one of the often mistakes that come from MySQL non-strictness is Grouping queries without explicit columns aggregating. &lt;/p&gt;

&lt;p&gt;I assume that we have a table users&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create table users(
 id bigserial primary key,
 name varchar(255) not null,
 age smallint default 0 null,
 department varchar(20) not null
);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;MySql in non-strict mode allows to make queries like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select *, count(id) from users group by department;
select name, age, count(id), department from users group by department;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Postgres requires explicit aggregation for columns that are not a part of &lt;code&gt;GROUP BY&lt;/code&gt;. So valid query should be looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select avg(age), array_agg(name),count(id), department from users group by department;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Data Types
&lt;/h2&gt;

&lt;p&gt;I make review only for several ones. You can find more details in the official documentation. &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/data-types.html"&gt;MySQl&lt;/a&gt; &lt;a href="https://www.postgresql.org/docs/12/datatype.html"&gt;PostgreSQL&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The BOOL type. In the MySQL it just an alias for TINYINT(1) and can take only 0, false, 1, true values;&lt;br&gt;
In the Postgres - bool is a separated type. It can be filled with values: true, false, 'true', 'false','yes', 'no', 't', 'f', 'y', 'n', '0', '1'. But it can't accept unquoted 0 and 1 values, which may become a problem for a data migration from MySQL. You should wrap 0 and 1 values in quotes, or add explicit type casting &lt;code&gt;0::bool&lt;/code&gt;, &lt;code&gt;1::bool&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are no TINYINT type in Postgres. The minimal integer type is 2-byte SMALLINT with values in range from -32768 to +32767&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Postgres haven't the UNSIGNED option. If you need to restrict data, you can add CHECK constraint.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE users (
  id serial primary key, 
  name  varchar(255),
  age smallint CHECK(age &amp;gt; 0) 
);
-- OR
ALTER TABLE users ADD CHECK(age &amp;gt;0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Postgres &lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html"&gt;functions for date and time&lt;/a&gt; manipulations are really different. If you use some of them in &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html"&gt;MySQL&lt;/a&gt;, don't forget to replace it with analogs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Postgres haven't the feature &lt;code&gt;ON UPDATE CURRENT_TIMESTAMP&lt;/code&gt; that allows automatically update timestamp value on every row update. You should write the trigger function for the same behavior, or make it on the application level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON. There are no problems for move data from the MySQL json field to Postgres. But syntax for operations with json in queries absolutely different. Also, you should know that Postgres offers a more efficient JSONB type. &lt;a href="https://www.compose.com/articles/faster-operations-with-the-jsonb-data-type-in-postgresql/"&gt;(What a difference?)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Postgres haven't a SET column type. The nearest alternative is Array with additions constraints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BYTEA - is a Postgres alternative for MySQL BINARY type. But it has known problems with data conversion. But &lt;a href="https://stackoverflow.com/questions/26990559/convert-mysql-binary-to-postgresql-bytea"&gt;solutions&lt;/a&gt; are known also.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ENUM. Postgres support it, but the way for it creation is different. You should define own TYPE as ENUM, and then declare it for a column.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TYPE job_state AS ENUM ('pending', 'active', 'fail', 'success');
CREATE TABLE jobs (
    id bigserial,
    name varchar(255),
    payload jsonb,
    state  job_state
);
INSERT INTO jobs (name, payload, state) 
VALUES ('do it', {"foo": "bar"}, 'pending')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating/Updating Table Schema
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unlike MySQL, Postgres can wrap in transactions not only data modifications but the table structure operations too. And it is useful for migrations.
&lt;/li&gt;
&lt;li&gt;Postgres can't change column positions. &lt;code&gt;... ADD COLUMN * AFTER&lt;/code&gt;, &lt;code&gt;... ADD COLUMN * BEFORE&lt;/code&gt;  are not supported&lt;/li&gt;
&lt;li&gt;There are differences for column change operations
In MySql, it can be used with one query:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE jobs MODIFY name varchar(100) NULL DEFAULT 'cron_job' COMMENT 'job name';
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Same for PostgreSQL will be like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE jobs ALTER COLUMN name TYPE varchar(100);
ALTER TABLE jobs ALTER COLUMN name DROP NOT NULL; 
ALTER TABLE jobs ALTER COLUMN name SET DEFAULT 'cron_jobs';
COMMENT ON COLUMN "jobs"."name" IS 'job name';
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;MySQL doesn't support default values for columns with types BLOB, TEXT, JSON, GEOMETRY. Postgres can set it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generated Columns
&lt;/h3&gt;

&lt;p&gt;MySQL supports generated columns, that calculate self-value based on values of other columns automatically. It looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE my_box ADD COLUMN volume integer as (width * height * len);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;PostgreSQL with version &amp;lt; 12 doesn't support it. But since 12 it can same with syntax like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE my_box ADD COLUMN volume integer GENERATED ALWAYS AS (width * height * len) STORED;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Autoincrement Index
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unlike MySQL, Postgres allows us to has more than one autoincremented column (and even with different increment settings). It called sequences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to get last inserted id? &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;You can create the insert query with an option for return id.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO users (name, age) VALUES ('Joe', 20) RETURNING id;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;You can use functions &lt;code&gt;currval()&lt;/code&gt; for last inserted id and &lt;code&gt;nextval()&lt;/code&gt; for next id.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT currval(pg_get_serial_sequence('users', 'id'));
SELECT nextval(pg_get_serial_sequence('users', 'id'));
-- pg_get_serial_sequence is a function for return sequence name by table name and index column name. In most cases it called like tablename_columnname_id_seq. 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;How to change the next increment value? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(It could become a necessary operation if you fill table ids manually)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT setval(
pg_get_serial_sequence('users', 'id'),
 (SELECT MAX(id) FROM users)
);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The TRUNCATE operation doesn't flush sequence by default. It could create unwanted effects. Use the truncate command with an explicit option
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TRUNCATE TABLE table_name RESTART IDENTITY;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Full-text Search
&lt;/h2&gt;

&lt;p&gt;If you use full-text search functional with MySQL, you should be ready for serious work to migrate, because Postgres analog is really different. &lt;br&gt;
I just publish a &lt;a href="https://www.postgresql.org/docs/current/textsearch.html"&gt;link to the official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to move the data?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PgChameleon &lt;a href="https://pgchameleon.org/documents/"&gt;https://pgchameleon.org/documents/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PgLoader &lt;a href="https://pgloader.io/"&gt;https://pgloader.io/&lt;/a&gt; and &lt;a href="https://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#Scripts.2C_programs"&gt;other converters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;via framework and ORM with both db connections. Read from one, modify and insert into another.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, seems that is all, that I remember from my experience. If you also have an experience in migration applications from one DB system to another - welcome to comments. &lt;/p&gt;

</description>
      <category>mysql</category>
      <category>postgres</category>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to use Invoker with docker containers?</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Sun, 26 Jul 2020 15:07:13 +0000</pubDate>
      <link>https://dev.to/insolita/how-to-use-invoker-with-docker-containers-59a3</link>
      <guid>https://dev.to/insolita/how-to-use-invoker-with-docker-containers-59a3</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is Invoker?&lt;/strong&gt;&lt;br&gt;
Invoker - is the universal data management tool for laravel/eloquent based applications You can see it features at &lt;a href="https://invoker.dev/" rel="noopener noreferrer"&gt;https://invoker.dev/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can work with local applications and with remote by ssh connection. But, unfortunately, it hasn't abilities for integration with apps that developed in dockers out of the box, because it distributed as executable gui application. &lt;br&gt;
So we need to add an ssh service for our docker-compose.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you use separated containers for cli and fpm, you should use cli version as a base for a new ssh container. Otherwise, use your common php container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you use prepared php image:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create new directory, named ssh in you folder with docker config&lt;/li&gt;
&lt;li&gt;Inside this directory create new Dockerfile
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM {your php image}

USER root
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y openssh-server \
    &amp;amp;&amp;amp; mkdir /var/run/sshd \
    &amp;amp;&amp;amp; echo 'root:secret' | chpasswd \
    &amp;amp;&amp;amp; sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
    &amp;amp;&amp;amp; sed -i 's/#PasswordAuthentication/PasswordAuthentication/' /etc/ssh/sshd_config \
    &amp;amp;&amp;amp; sed -i 's/#PermitRootLogin/PermitRootLogin/' /etc/ssh/sshd_config \
    &amp;amp;&amp;amp; sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd \
    &amp;amp;&amp;amp; apt-get clean \
    &amp;amp;&amp;amp;  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" &amp;gt;&amp;gt; /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you already use Dockerfile for php-cli service, copy it inside created ssh directory, remove CMD, ENTRYPOINT and EXPOSE instructions if it exists, and append ssh instructions above&lt;/p&gt;

&lt;p&gt;add record in docker-compose.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  sshd:
    build:
       context: your_docker_dir/ssh
    restart: on-failure
    ports:
    - '2266:22'
    links:
      - db # dabase service
      - php-cli  #php service
    volumes:
#for docker-compose &amp;lt; 3.x you can use volumes_from
      - data:/app  
    networks:
      - your_network  #if exists
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;docker-compose up -d&lt;/code&gt;, &lt;br&gt;
Open Invoker, press "Set up SSH connection", and fill&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1jwu6wpo29jp8y43yaof.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1jwu6wpo29jp8y43yaof.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you can explore your project models.&lt;/p&gt;

&lt;p&gt;If you use docker-compose with version &amp;gt;= 3.4 - you can combine Dokerfile instructions like below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM php:7.4-cli as php_base #use preferred php image
# Place here your php installation and configuration instructions
FROM php_base AS php_ssh

USER root
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y openssh-server \
    &amp;amp;&amp;amp; mkdir /var/run/sshd \
    &amp;amp;&amp;amp; echo 'root:secret' | chpasswd \
    &amp;amp;&amp;amp; sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
    &amp;amp;&amp;amp; sed -i 's/#PasswordAuthentication/PasswordAuthentication/' /etc/ssh/sshd_config \
    &amp;amp;&amp;amp; sed -i 's/#PermitRootLogin/PermitRootLogin/' /etc/ssh/sshd_config \
    &amp;amp;&amp;amp; sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd \
    &amp;amp;&amp;amp; apt-get clean \
    &amp;amp;&amp;amp;  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" &amp;gt;&amp;gt; /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And use it in docker-compose like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  php-cli:
    build:
      context: docker/php
      target: php_base
    restart: on-failure
    links:
      - db
      - redis
    volumes:
      - data:/app
    environment:
      - TZ=${DB_TIMEZONE}
      - PHP_XDEBUG_ENABLED=1
      - XDEBUG_CONFIG=remote_host=host.docker.internal
      - PHP_IDE_CONFIG="serverName=Docker"
    networks:
      - appnet
  sshd:
    build:
       context: docker/php
       target: php_ssh
    restart: on-failure
    ports:
    - '2266:22'
    links:
      - db
      - php-cli
    volumes:
      - data:/app
    networks:
      - appnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to take care about keep ssh service only for the local environment!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>docker</category>
      <category>php</category>
      <category>invoker</category>
    </item>
    <item>
      <title>Which Http Client is Faster for Web Scraping</title>
      <dc:creator>Insolita</dc:creator>
      <pubDate>Sat, 02 May 2020 18:06:40 +0000</pubDate>
      <link>https://dev.to/insolita/which-http-client-is-faster-for-web-scraping-c95</link>
      <guid>https://dev.to/insolita/which-http-client-is-faster-for-web-scraping-c95</guid>
      <description>&lt;p&gt;Inspired by an article &lt;a href="https://sergeyzhuk.me/2018/08/31/fast-webscraping-images/"&gt;Fast Web Scraping With ReactPHP&lt;/a&gt; I've decided to make a benchmark for checking, how much it faster than some other popular libraries, like &lt;a href="https://github.com/guzzle/guzzle"&gt;Guzzle&lt;/a&gt;, which also can create async requests via multicurl and &lt;a href="https://github.com/amphp"&gt;Amphp&lt;/a&gt; that is another non-blocking php framework, that contains http-client &lt;/p&gt;

&lt;p&gt;I don't want to make a synthetic benchmark and prefer for my test more practical task - is loading different real urls from the defined list (part of them may be broken), scrape it titles, and save into a file.&lt;/p&gt;

&lt;p&gt;During development, I've faced certain difficulties, which did not allow me to create my test clients completely similar. Each client has its own specific features, especially amphp, and also I have not so big experience with async libraries such as reactphp and amphp.&lt;/p&gt;

&lt;p&gt;So, you can see the repository with test stuff and benchmark results here&lt;br&gt;
&lt;a href="https://github.com/Insolita/php-async-benchmarks"&gt;https://github.com/Insolita/php-async-benchmarks&lt;/a&gt; All tests were written with php7.4. Each check was run 10 times, and I publish min, max, and average execution time.  I should add a notice that the concrete numbers not so important because it depends on internet speed, server config, etc.., and you can have another result. Only their relative differences has a value&lt;/p&gt;

&lt;p&gt;Firsts results really surprised me. &lt;a href="https://github.com/reactphp/reactphp"&gt;ReactPhp&lt;/a&gt; works 2 times slower than the Guzzle. I rechecked it again and again, but the numbers stayed the same. But with the increasing number of queries, its performance becomes better and better. On the other hand, amphp performance becomes slower and slower and I even exclude it from the last measurement. (It depends on its specific, at the documentation, I find out only one way for concurrent requests &lt;a href="https://amphp.org/http-client/concurrent"&gt;https://amphp.org/http-client/concurrent&lt;/a&gt;, probably exists better way or additional libraries that also allows to queue promises smarter (like a clue/reactphp-mq), but I have not found it)&lt;/p&gt;

&lt;p&gt;In summary, ReactPhp can be a good decision, when you need to fetch many thousands of urls, especially when you keep it as a separate worker, that will receive tasks by socket/Redis or http api. Amphp can be good when you need to fetch a little batch of urls, 5-10-50 asap. Also it can become better with additional wrappers. The Guzzle is awesome. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPD:&lt;/strong&gt; Just see the power of the Open Source community in action! One of maintainers of the Amphp, &lt;a href="https://github.com/kelunik"&gt;Niklas Keller&lt;/a&gt;, thanks to my benchmark find out and fix the bug. And now, thanks to the help of &lt;a href="https://github.com/dbalabka"&gt;Dmitry Balabka&lt;/a&gt; and Niklas Keller - the performance metric of Amphp http-client was significantly improved! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPD2:&lt;/strong&gt; An outsider becomes a winner! Thanks to improvements, Amphp metrics look good at small batches as well as big! I'm intrigued, will reactphp team to offer improvements for increase their http-client speed?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPD3:&lt;/strong&gt; Yes! ReactPHP team accept the challenge, and also start to work on the fix!&lt;/p&gt;



&lt;blockquote class="twitter-tweet"&gt;
&lt;br&gt;
&lt;p&gt;Interesting! It looks like your list of servers contains a bunch of entries that don't strictly conform to HTTP specs. I'm currently working on fix for &lt;a href="https://twitter.com/reactphp?ref_src=twsrc%5Etfw"&gt;@ReactPHP&lt;/a&gt; here: &lt;a href="https://t.co/1gwIR2s4fp"&gt;&lt;/a&gt;&lt;a href="https://t.co/1gwIR2s4fp"&gt;&lt;/a&gt;&lt;a href="https://t.co/1gwIR2s4fp"&gt;https://t.co/1gwIR2s4fp&lt;/a&gt;&lt;/p&gt;— Christian Lück (@another_clue) &lt;a href="https://twitter.com/another_clue/status/1257323820085415941?ref_src=twsrc%5Etfw"&gt;May 4, 2020&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt; 

</description>
      <category>php</category>
      <category>scraping</category>
      <category>async</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
