<?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: Halim Samy</title>
    <description>The latest articles on DEV Community by Halim Samy (@halimsamy).</description>
    <link>https://dev.to/halimsamy</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%2F261442%2Ff14d5384-40ce-489d-9062-518b944a6eac.jpg</url>
      <title>DEV Community: Halim Samy</title>
      <link>https://dev.to/halimsamy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/halimsamy"/>
    <language>en</language>
    <item>
      <title>SQL: Soft Deleting and Unique Constraint</title>
      <dc:creator>Halim Samy</dc:creator>
      <pubDate>Mon, 27 Feb 2023 18:32:27 +0000</pubDate>
      <link>https://dev.to/halimsamy/sql-soft-deleting-and-unique-constraint-48k4</link>
      <guid>https://dev.to/halimsamy/sql-soft-deleting-and-unique-constraint-48k4</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;There are two ways to delete data in a database: soft delete and hard delete. Soft delete is a process where the data is not permanently deleted but rather marked as deleted by adding a column like a &lt;code&gt;deleted_at&lt;/code&gt; timestamp. This allows the data to be retrieved later if needed. Hard delete, on the other hand, is a process where the data is permanently deleted from the database and cannot be retrieved. Soft delete is often preferred over hard delete as it provides a safety net in case data is accidentally deleted. It also allows for auditing and tracking of deleted data.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;One issue with soft delete is that it is not compatible with unique constraints. This is because a unique constraint is enforced across all rows, including those that have been marked as deleted with a &lt;code&gt;deleted_at&lt;/code&gt; timestamp. As a result, if a row is soft deleted, the unique constraint will prevent the insertion of a new row with the same values, even though the original row is no longer active. This can lead to data integrity issues and should be considered when implementing soft delete in a database.&lt;/p&gt;

&lt;p&gt;Consider the following table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;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;255&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;email&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;255&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;deleted_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- We are using a soft-delete mechanism, we won't be deleting any row.&lt;/span&gt;
&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'halimsamy'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, The &lt;code&gt;deleted_at&lt;/code&gt; column is used to determine whether it's deleted or not, and when exactly it has been deleted. We are revoking/removing the delete permission on this table because we will not hard-deleting anything for sure.&lt;/p&gt;

&lt;p&gt;Now let's play a bit with our table and see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Add a new user.&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Halim Samy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'me@halimsamy.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Delete the added user&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Ok, The user was deleted, Let's add him again.&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Halim Samy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'me@halimsamy.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- ERROR:&lt;/span&gt;
&lt;span class="c1"&gt;-- [23000][1062] Duplicate entry 'me@halimsamy.com' for key 'users.email'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Umm... It seems like I can't add the user again because it's already there theoretically but it's not actually there it's deleted. Well, That's a problem!&lt;/p&gt;

&lt;h1&gt;
  
  
  The Solution
&lt;/h1&gt;

&lt;p&gt;Dropping the unique constraints it's even an option, so don't even think about it. It has to be there to maintain the consistency of the data. Let's get to the real world:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Partial Indexes (PostgreSQL, MSSQL, ...)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;PostgreSQL and MSSQL approached this problem by implementing what is called "Partial Indexes", Which can be applied to a subset of entries according to a specific condition in the &lt;code&gt;WHERE&lt;/code&gt; clause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;users_email_unique&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="k"&gt;IS&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;h2&gt;
  
  
  Virtual Columns (MySQL)
&lt;/h2&gt;

&lt;p&gt;Although the approach of using Partial Indexes is pretty convenient and easy, things aren't that easy when it comes to MySQL for a single reason:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the Unique Constraint contains any &lt;code&gt;NULL&lt;/code&gt; values, MySQL will ignore the constraint completely. (e.g. &lt;code&gt;UNIQUE KEY (email, deleted_at)&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will be using this behavior alongside Virtual Columns as a hack to get soft-delete working with Unique Constraint. Consider the table after modification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;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;255&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;email&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;255&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;deleted_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&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;unarchived&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt; &lt;span class="k"&gt;GENERATED&lt;/span&gt; &lt;span class="n"&gt;ALWAYS&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&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;VIRTUAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unarchived&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;What is the &lt;code&gt;GENERATED VIRTUAL&lt;/code&gt; column? It's an auto-generated column based on some expression that gets computed upon selecting a row from that table (not saved to the data storage). We are using that to automatically set &lt;code&gt;unarchived&lt;/code&gt; column to &lt;code&gt;1&lt;/code&gt; if the row is not soft-deleted, otherwise we leave &lt;code&gt;NULL&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;Setting the &lt;code&gt;unarchived&lt;/code&gt; column to &lt;code&gt;1&lt;/code&gt; when not soft-deleted, gives it a value. The value doesn't matter, it can be anything but it should be constant, so it's not actually a uniqueness factor, the only factor is the &lt;code&gt;email&lt;/code&gt; column. On the other hand, when the &lt;code&gt;unarchived&lt;/code&gt; column is &lt;code&gt;NULL&lt;/code&gt; (row is soft-deleted), MySQL will ignore the Unique Constraint completely (as said above), and that's fine, we don't need to check the consistency of archived data because It was already checked before it became archived.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I think in the case of MySQL we have to hack the technology if the technology is missing something, I think that's called Anti-Pattern. Yet, I am totally OK with that because it's almost at zero cost with no notable downsides except for the new &lt;code&gt;unarchived&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That was a brief P/S Article (Problem and Solution Article) as I would like to call it. I hope that it was quick, enjoyable, and of course useful. See you later and Don't forget to hit me with a Like!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>mysql</category>
    </item>
    <item>
      <title>WSL for Developers!: Connect USB devices</title>
      <dc:creator>Halim Samy</dc:creator>
      <pubDate>Mon, 06 Jun 2022 01:22:20 +0000</pubDate>
      <link>https://dev.to/halimsamy/wsl-for-developers-connect-usb-devices-63m</link>
      <guid>https://dev.to/halimsamy/wsl-for-developers-connect-usb-devices-63m</guid>
      <description>&lt;p&gt;Have you ever wanted to connect a USB to WSL for development or debugging? Good news! this is possible thanks to the &lt;a href="https://github.com/dorssel/usbipd-win"&gt;usbipd-win&lt;/a&gt; project!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the usbipd-win project?
&lt;/h2&gt;

&lt;p&gt;Umm! it's simple. Quoted from their &lt;a href="https://github.com/dorssel/usbipd-win"&gt;GitHub repo&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Windows software for sharing locally connected USB devices to other machines, including Hyper-V guests and WSL 2.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thus, it requires WSL 2, not WSL 1 (you shouldn't be using WSL 1 anyway!). With this being said let's dive more into this!&lt;/p&gt;

&lt;h2&gt;
  
  
  Check if your WSL version is supported
&lt;/h2&gt;

&lt;p&gt;What we will be doing here is not supported by every WSL kernel. Open up your WSL terminal and run the following command to check your kernel version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output should be something like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Linux HALIMSAMY 5.10.102.1-microsoft-standard-WSL2 &lt;span class="c"&gt;#1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you see that kernel version above? It should be 5.10.60.1 or later (with WSL2), if that's not the case, feel free to close the article or update your WSL!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Windows side
&lt;/h2&gt;

&lt;p&gt;There are two ways to install &lt;a href="https://github.com/dorssel/usbipd-win"&gt;usbipd-win&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running the (.msi) installer. Get it from their &lt;a href="https://github.com/dorssel/usbipd-win/releases"&gt;releases page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use the Windows Package Manager (winget): &lt;code&gt;winget install usbipd&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn't matter how you install it as long as it gets installed at the end, this is up to your personal preference. However, &lt;em&gt;take this note into consideration&lt;/em&gt; from their repo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are using a third-party firewall, you may have to reconfigure it to allow incoming connections on TCP port 3240.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting up the WSL side
&lt;/h2&gt;

&lt;p&gt;With the Windows side ready, let's move to WSL. (I'm using &lt;em&gt;Ubuntu 20.04 LTS&lt;/em&gt;) Again open up your WSL terminal and run the following command to install some packages that are needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="c"&gt;# recommend, but not required&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;linux-tools-virtual hwdata
&lt;span class="nb"&gt;sudo &lt;/span&gt;update-alternatives &lt;span class="nt"&gt;--install&lt;/span&gt; /usr/local/bin/usbip usbip /usr/lib/linux-tools/&lt;span class="k"&gt;*&lt;/span&gt;/usbip 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Attaching device
&lt;/h2&gt;

&lt;p&gt;Plug in the device using USB to the host machine (Windows) and open PowerShell or Command Prompt on your Windows machine &lt;strong&gt;as Administrator&lt;/strong&gt; to continue.&lt;/p&gt;

&lt;p&gt;You can list all of the available device by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;usbipd wsl list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can expect the output to be like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BUSID VID:PID DEVICE STATE
1-2 22b8:2e81 &amp;lt; YOUR DEVICE &amp;gt; Not attached
1-3 0b05:1866 USB Input Device Not attached
2-1 0461:4dfb USB Input Device Not attached
2-4 13d3:3563 MediaTek Bluetooth Adapter Not attached
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you find the device you want and it's bus ID, you can attach it using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;usbipd wsl attach &lt;span class="nt"&gt;--busid&lt;/span&gt; &amp;lt;BUD ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might face a problem where the device is already being used by your Windows host or some application make sure to close that and try again. Also when attaching a device it is recommended to have a WSL terminal already opened so that we ensure that the WSL lightweight VM is up and running!&lt;/p&gt;

&lt;p&gt;Now switching to the WSL side, Verify that the device was attached by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lsusb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see an output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 22b8:2e81 &amp;lt; YOUR DEVICE &amp;gt;
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! Now you can access your devices from inside WSL! When you're done with your device from inside WSL you can de-attach and give it back to the Windows machine by running the following command (from the same &lt;em&gt;Administrator shell&lt;/em&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;usbipd wsl detach &lt;span class="nt"&gt;--busid&lt;/span&gt; &amp;lt;BUS ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ADB not detecting your phone/device?
&lt;/h2&gt;

&lt;p&gt;When you realize that you can access your USB devices from inside WSL, you would want to use that for your Android development! Well, it's possible actually and in the previous part of the series, we managed to install the Android SDK so we can do that. You can simply just run &lt;code&gt;adb devices&lt;/code&gt; and it might detect your device out of the box (it worked for me once!) or we might need to do some extra steps!&lt;/p&gt;

&lt;p&gt;Remember that output you got from running &lt;code&gt;lsusb&lt;/code&gt;? Do you see those magic numbers after the text "ID" (The &lt;code&gt;22b8:2e81&lt;/code&gt; part), In fact, those are not just magic numbers, those are the VendorID and ProductID (in order) &lt;strong&gt;Now keep that in mind.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, I would like you to edit the following file: &lt;code&gt;/etc/udev/rules.d/51-android.rules&lt;/code&gt;, use &lt;code&gt;vim&lt;/code&gt; or &lt;code&gt;nano&lt;/code&gt; it doesn't matter, maybe you would need to install one of them if not already installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nano
&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/udev/rules.d/51-android.rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is expected that the file would be empty, now add the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SUBSYSTEM=="usb", ATTR{idVendor}=="22b8", ATTR{idProduct}=="2e81", MODE="0666", GROUP="plugdev", SYMLINK+="android%n"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remember to change the VendorID and ProductID&lt;/strong&gt; to what you have got from &lt;code&gt;lsusb&lt;/code&gt;. Now everything should be working fine. &lt;code&gt;adb devices&lt;/code&gt; should show your device.&lt;/p&gt;

&lt;p&gt;Additionally, you might need to add the VendorID to your &lt;code&gt;~/.android/adb_usb.ini&lt;/code&gt; (one ID per line, in hex notation like: &lt;code&gt;0x22b8&lt;/code&gt;), but this is usually not needed!&lt;/p&gt;

&lt;p&gt;One more issue you can face while attaching your Android device is that Chrome DevTools is using your device from your Windows machine, Disable it for now!&lt;/p&gt;

&lt;p&gt;You can also find that starting the adb server as root fixes the problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adb kill-server
&lt;span class="nb"&gt;sudo &lt;/span&gt;adb start-server
adb devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;I'm a man who respects copyrights and if I would quote someone or use this work, I would have to mention him. I didn't come up with all of this out of the blue! In fact, &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/connect-usb"&gt;Microsoft has documentation about this topic&lt;/a&gt; and &lt;a href="https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl"&gt;a blog post on the Windows Command Line Blog&lt;/a&gt; beside the &lt;a href="https://github.com/dorssel/usbipd-win/wiki/WSL-support"&gt;usbipd-win repo wiki&lt;/a&gt; and the fix of the ADB issue came from a &lt;a href="https://android.stackexchange.com/questions/144966/how-do-i-get-my-device-detected-by-adb-on-linux"&gt;Stack Exchange answer&lt;/a&gt;. I'm just documenting all of those in a single place to save time for people searching for all of this!&lt;/p&gt;

</description>
      <category>usb</category>
      <category>wsl2</category>
      <category>android</category>
      <category>mobile</category>
    </item>
    <item>
      <title>WSL for Developers!: Installing the Android SDK</title>
      <dc:creator>Halim Samy</dc:creator>
      <pubDate>Wed, 01 Jun 2022 19:09:34 +0000</pubDate>
      <link>https://dev.to/halimsamy/wsl-for-developers-installing-the-android-sdk-53n9</link>
      <guid>https://dev.to/halimsamy/wsl-for-developers-installing-the-android-sdk-53n9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As any developer, you have probably started your career with a Windows machine, after some time you will begin to notice how Windows is horrible with development stuff (at least this is my opinion). For me, I wanted to switch to Linux so badly, Guess what? I did actually. Out of the blue Windows were a part of the past. and used Linux for almost 2 years! everything was perfect except for one thing that you probably know. Yes, thats gaming. for me, Xbox wasnt enough. I wanted a PC gaming experience. (note: dual boot is a pain in the ass)&lt;/p&gt;

&lt;p&gt;In the meanwhile, Windows you know, was kind of getting better over time, with the best achievement of Microsoft arrived (that is WSL) I have switched back to Windows. Now I have both Windows gaming and Linux superpower!&lt;/p&gt;

&lt;h2&gt;
  
  
  About this series
&lt;/h2&gt;

&lt;p&gt;In this series (WSL for Developers!) I will document how I do I use WSL for my different development, for the sake of this series I will assume you have already installed WSL with the Ubuntu distro. You can search online for how to install WSL. Microsoft has an &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install"&gt;official documentation for installing WSL&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing OpenJDK and Gradle
&lt;/h2&gt;

&lt;p&gt;You probably know that Android development requires the JDK and Gradle to be installed. Lets get this done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;openjdk-8-jdk-headless gradle
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib/jvm/java-8-openjdk-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can install OpenJDK 11 if you want, for me I didn't face any issues with both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Android Command Line Tools
&lt;/h2&gt;

&lt;p&gt;First, we need to get the latest Android command-line tools. You can get it from &lt;a href="https://developer.android.com/studio#downloads"&gt;this link&lt;/a&gt;. (Make sure you get the one for Linux, not Windows)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~ &lt;span class="c"&gt;# Make sure you are at home!&lt;/span&gt;
curl https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/cmd-tools.zip
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; android/cmdline-tools
unzip &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; android/cmdline-tools /tmp/cmd-tools.zip
&lt;span class="nb"&gt;mv &lt;/span&gt;android/cmdline-tools/cmdline-tools android/cmdline-tools/latest
&lt;span class="nb"&gt;rm&lt;/span&gt; /tmp/cmd-tools.zip &lt;span class="c"&gt;# delete the zip file (optional)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up environment variables
&lt;/h2&gt;

&lt;p&gt;The Android SDK requires some environment variables to be set. Feel free to edit your &lt;code&gt;.bash_profile&lt;/code&gt; or export them the way you like!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/android
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANDROID_SDK_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/cmdline-tools/latest/bin:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/platform-tools:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/tools:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/tools/bin:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Accepting SDK licenses
&lt;/h2&gt;

&lt;p&gt;You got it right? we need to agree to some licenses. You probably should read them (if you havent already).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;yes&lt;/span&gt; | sdkmanager &lt;span class="nt"&gt;--licenses&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing SDK components
&lt;/h2&gt;

&lt;p&gt;Now the final part, let's install what we need, feel free to adjust the versions or components depending on your needs!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdkmanager &lt;span class="nt"&gt;--update&lt;/span&gt;
sdkmanager &lt;span class="s2"&gt;"platforms;android-30"&lt;/span&gt; &lt;span class="s2"&gt;"build-tools;30.0.3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get a list of all the components available and their versions by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdkmanager &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Up to this point, you can build your android apps from inside WSL, but isnt this all about development? where is the emulator? or even attaching a device with USB? What about my IDE and coding experience? Well to be honest those are topics for the up coming article of the series (WSL for Developers!). I like lightweight articles thats my style of writing. Dont worry there is more coming next!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks!
&lt;/h2&gt;

&lt;p&gt;Thanks for reading and coming to the end. I wish that you have enjoyed it and of course found it useful. I would like to thank you that you have given my first article/post a chance and I hope that I will get better over time.&lt;/p&gt;

</description>
      <category>wsl</category>
      <category>wsl2</category>
      <category>android</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
