<?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: Timothy Karani</title>
    <description>The latest articles on DEV Community by Timothy Karani (@c3n7).</description>
    <link>https://dev.to/c3n7</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%2F847102%2F3145e57d-b788-4a2e-87b9-39dfc1910c5a.jpeg</url>
      <title>DEV Community: Timothy Karani</title>
      <link>https://dev.to/c3n7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/c3n7"/>
    <language>en</language>
    <item>
      <title>Laravel 10.x + Livewire 3.x Pre-Commit Linting and Formatting</title>
      <dc:creator>Timothy Karani</dc:creator>
      <pubDate>Mon, 15 Jan 2024 23:43:19 +0000</pubDate>
      <link>https://dev.to/c3n7/laravel-10x-livewire-3x-pre-commit-linting-and-formatting-af1</link>
      <guid>https://dev.to/c3n7/laravel-10x-livewire-3x-pre-commit-linting-and-formatting-af1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When creating Laravel+Livewire projects, especially for teams, pre-commit hooks come in handy by ensuring everyone on the team follows the same formatting standards and adheres to some level of code quality. In this blog-post we will use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/typicode/husky"&gt;&lt;em&gt;husky&lt;/em&gt;&lt;/a&gt;: Sets up pre-commit hooks&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/prettier/prettier"&gt;&lt;em&gt;prettier&lt;/em&gt;&lt;/a&gt;: To format &lt;code&gt;*.css&lt;/code&gt;, &lt;code&gt;*.js&lt;/code&gt; and &lt;code&gt;*.blade&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/shufo/prettier-plugin-blade"&gt;&lt;em&gt;@shufo/prettier-plugin-blade&lt;/em&gt;&lt;/a&gt;: A prettier plugin for formatting &lt;code&gt;*blade&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/laravel/pint"&gt;&lt;em&gt;laravel/pint&lt;/em&gt;&lt;/a&gt;: to format PHP files like classes, traits, etc.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/larastan/larastan"&gt;larastan&lt;/a&gt;: does PHP static analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Assuming you are creating a project from scratch, let us begin the set-up.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new project, I will name mine &lt;code&gt;livewire-precommits-demo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;composer create-project laravel/laravel livewire-precommits-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the project, initialize git and make the first commit:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;livewire-precommits-demo
&lt;span class="nv"&gt;$ &lt;/span&gt;git init
&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nt"&gt;-A&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"First of many"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;code&gt;husky&lt;/code&gt;, &lt;code&gt;prettier&lt;/code&gt;, and &lt;code&gt;@shufo/prettier-plugin-blade&lt;/code&gt; as dev dependencies:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; husky prettier @shufo/prettier-plugin-blade
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add Laravel Pint:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;composer require laravel/pint &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;To test it out in action:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./vendor/bin/pint
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Larastan:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;composer require larastan/larastan:^2.0 &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;phpstan.neon&lt;/code&gt; file in the root of the project with this:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;includes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;vendor/larastan/larastan/extension.neon&lt;/span&gt;

&lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app/&lt;/span&gt;

    &lt;span class="c1"&gt;# Level 9 is the highest level&lt;/span&gt;
    &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="c1"&gt;#    ignoreErrors:&lt;/span&gt;
&lt;span class="c1"&gt;#        - '#PHPDoc tag @var#'&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#    excludePaths:&lt;/span&gt;
&lt;span class="c1"&gt;#        - ./*/*/FileToBeExcluded.php&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#    checkMissingIterableValueType: false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;To test if it works:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;./vendor/bin/phpstan analyse
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We have installed everything we need, now we can create a commit to track these changes:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Added linting and formatting packages"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Set Up Pre-Commit Hook
&lt;/h2&gt;

&lt;p&gt;We have all the packages needed for static analysis and code formatting so now let us create a pre-commit hook that runs them before every commit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First we should install husky's Git hooks&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;npx husky &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a file under the &lt;code&gt;.husky&lt;/code&gt; directory called &lt;code&gt;pre-commit&lt;/code&gt;, in full (&lt;code&gt;.husky/pre-commit&lt;/code&gt;), and add the following content:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="c"&gt;#!/usr/bin/env sh&lt;/span&gt;
 &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/_/husky.sh"&lt;/span&gt;

 &lt;span class="c"&gt;# Format resources&lt;/span&gt;
 &lt;span class="c"&gt;# https://stackoverflow.com/a/6879568&lt;/span&gt;
 &lt;span class="c"&gt;# https://stackoverflow.com/a/1587952&lt;/span&gt;
 ./node_modules/.bin/prettier &lt;span class="nt"&gt;--ignore-unknown&lt;/span&gt; &lt;span class="nt"&gt;--write&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--name-only&lt;/span&gt; &lt;span class="nt"&gt;--diff-filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ACMR HEAD &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s1"&gt;'*.blade.php'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
 ./node_modules/.bin/prettier resources/&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.js  resources/&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.css &lt;span class="nt"&gt;--write&lt;/span&gt;

 &lt;span class="c"&gt;# Format php classes&lt;/span&gt;
 ./vendor/bin/pint &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git add &lt;span class="nt"&gt;-A&lt;/span&gt;

 &lt;span class="c"&gt;# Do static analysis&lt;/span&gt;
 ./vendor/bin/phpstan analyse &lt;span class="nt"&gt;--memory-limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2G
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Let us break down this command: &lt;code&gt;/node_modules/.bin/prettier --ignore-unknown --write $(git diff --name-only --diff-filter=ACMR HEAD -- '*.blade.php')&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--ignore-unknown&lt;/code&gt; prevents the command from returning a non-zero result if no match is found in our filter&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--write&lt;/code&gt; tells prettier to write the formatting changes to the respective files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--diff-filter=ACMR HEAD&lt;/code&gt; matches files that have either been &lt;a href="https://stackoverflow.com/a/6879568"&gt;&lt;strong&gt;A&lt;/strong&gt;dded, &lt;strong&gt;C&lt;/strong&gt;opied, &lt;strong&gt;M&lt;/strong&gt;odified, or &lt;strong&gt;R&lt;/strong&gt;enamed&lt;/a&gt;. &lt;code&gt;HEAD&lt;/code&gt; adds to this filter by matching files that have gone through either of the aforementioned changes, whether they have been staged for commit or not. If this is not the desired behaviour &lt;a href="https://stackoverflow.com/a/1587952"&gt;this resource should come in handy&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make the &lt;code&gt;.husky/pre-commit&lt;/code&gt; executable:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x .husky/pre-commit
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now when we do a commit, the pre-commit hook should run&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Commit our changes:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nt"&gt;-A&lt;/span&gt;
 &lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Added pre-commit hook"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Congratulations! Now linting and static analysis is done before every commit. There's one more thing we can do to help new team members install the pre-commit hook:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update &lt;code&gt;package.json&lt;/code&gt; and the following script. It runs right after one runs &lt;code&gt;npm install&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"prepare"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"husky install &amp;amp;&amp;amp; git add .husky/pre-commit"&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now an &lt;code&gt;npm install&lt;/code&gt; should trigger the installation of the pre-commit hooks, or one can just run &lt;code&gt;npm run prepare&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://stackoverflow.com/a/6879568"&gt;Filter git diff by type of change&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://stackoverflow.com/a/1587952"&gt;How do I show the changes which have been staged?&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>laravel</category>
      <category>livewire</category>
    </item>
    <item>
      <title>ORDER BY x LIMIT y Gotcha</title>
      <dc:creator>Timothy Karani</dc:creator>
      <pubDate>Fri, 29 Dec 2023 21:54:11 +0000</pubDate>
      <link>https://dev.to/c3n7/order-by-x-limit-y-gotcha-1ej4</link>
      <guid>https://dev.to/c3n7/order-by-x-limit-y-gotcha-1ej4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;On a production environment I was watching a query I had just made attempts at optimizing take longer and longer as days went. Usually I would look at &lt;code&gt;WHERE&lt;/code&gt; clauses to inform me on indexes that need creating or queries that need restructuring but often overlooked &lt;code&gt;ORDER BY&lt;/code&gt; clauses, turns out both need equal attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduction
&lt;/h2&gt;

&lt;p&gt;I will be using Laravel for this because of easy &lt;code&gt;EXPLAIN&lt;/code&gt; statements provided by &lt;a href="https://github.com/barryvdh/laravel-debugbar"&gt;&lt;code&gt;barryvdh/laravel-debugbar&lt;/code&gt;&lt;/a&gt; and &lt;a&gt;&lt;code&gt;FakerPHP&lt;/code&gt;&lt;/a&gt; that we'll use to seed the database with lots of records.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Laravel Project
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nv"&gt;$ &lt;/span&gt;composer create-project laravel/laravel order-by-gotcha
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update &lt;code&gt;.env&lt;/code&gt; and set &lt;code&gt;DB_DATABASE&lt;/code&gt;, &lt;code&gt;DB_USERNAME&lt;/code&gt; and &lt;code&gt;DB_PASSWORD&lt;/code&gt;. I will be using &lt;code&gt;mysql&lt;/code&gt;. You might need to create a database.&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;Client&lt;/code&gt; model together with a corresponding migration and controller.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nv"&gt;$ &lt;/span&gt;php artisan make:model Client &lt;span class="nt"&gt;-mc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update the migration. Only the email column is indexed, for future demonstration purposes.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'phone'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update the &lt;code&gt;Client&lt;/code&gt; model to make the columns fillable.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
       &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s1"&gt;'phone'&lt;/span&gt;
   &lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update the &lt;code&gt;DatabaseSeeder&lt;/code&gt; to seed 1,000,000 clients. This might take a bit, 6 min on my end (SSD, 8 Cores):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
        &lt;span class="nv"&gt;$start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;microtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$iter_start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;microtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// For logging, just to see stuff works&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;microtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nv"&gt;$cumulative&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$end_time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;$start_time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nv"&gt;$iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$end_time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;$iter_start_time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt; - Cumulative: &lt;/span&gt;&lt;span class="nv"&gt;$cumulative&lt;/span&gt;&lt;span class="s2"&gt;, Iter: &lt;/span&gt;&lt;span class="nv"&gt;$iter&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nv"&gt;$iter_start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;microtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nv"&gt;$records&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="s1"&gt;'phone'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="s1"&gt;'created_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dateTimeBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'-10 Years'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'now'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s1"&gt;'updated_at'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dateTimeBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'-10 Years'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'now'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;];&lt;/span&gt;

            &lt;span class="c1"&gt;// Bulk insert every 1000 records&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;1_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'clients'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$records&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nv"&gt;$records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
            &lt;span class="p"&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;ol&gt;
&lt;li&gt;Now on to the &lt;code&gt;ClientController&lt;/code&gt; class, with the following methods:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'welcome'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'client'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index_with_where_clause&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ca'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'like'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$filter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'welcome'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'client'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index_order_by_email&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'welcome'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'client'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index_order_by_id&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'welcome'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'client'&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;ol&gt;
&lt;li&gt;Clean up &lt;code&gt;welcome.blade.php&lt;/code&gt;, just show the client name:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;   &lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Laravel&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
       {{ $client-&amp;gt;name }}
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update &lt;code&gt;web.php&lt;/code&gt; to add the route:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;ClientController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'index'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/with_where'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;ClientController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'index_with_where_clause'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/order_by_email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;ClientController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'index_order_by_email'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/order_by_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;ClientController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'index_order_by_id'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add &lt;code&gt;laravel-debugbar&lt;/code&gt; and publish the config:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;composer require barryvdh/laravel-debugbar &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;php artisan vendor:publish &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Barryvdh&lt;/span&gt;&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="s2"&gt;ebugbar&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;erviceProvider"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable explain output by editing &lt;code&gt;config/debugbar.php&lt;/code&gt;. Scroll until you find the setting then update it as follows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'explain'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;                 &lt;span class="c1"&gt;// Show EXPLAIN output on queries&lt;/span&gt;
    &lt;span class="s1"&gt;'enabled'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'types'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'SELECT'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;     &lt;span class="c1"&gt;// Deprecated setting, is always only SELECT&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run migrations and seed the database:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;php artisan migrate &lt;span class="nt"&gt;--seed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start the server&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Exploring Performance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When we open &lt;a href="http://localhost:8000/"&gt;http://localhost:8000/&lt;/a&gt;, this is what the debug bar shows us as the &lt;code&gt;EXPLAIN&lt;/code&gt; output:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;explain&lt;/span&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="nv"&gt;`clients`&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;`created_at`&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  | table   | type | possible_keys | key | key_len | ref | rows   | Extra          |
  | ------- | ---- | ------------- | --- | ------- | --- | ------ | -------------- |
  | clients | ALL  |               |     |         |     | 999001 | Using filesort |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;999001 records are being loaded into memory! And the query takes &lt;code&gt;904ms&lt;/code&gt;. Not good. On production, a comparable query was taking &lt;code&gt;1.7 seconds&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You might think that a query with a where clause would help things, let's open &lt;a href="http://localhost:8000/with_where"&gt;http://localhost:8000/with_where&lt;/a&gt; to see if that's the case:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;explain&lt;/span&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="nv"&gt;`clients`&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`email`&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'%ca%'&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;`created_at`&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  | table   | type | possible_keys | key | key_len | ref | rows   | Extra                       |
  | ------- | ---- | ------------- | --- | ------- | --- | ------ | --------------------------- |
  | clients | ALL  |               |     |         |     | 999001 | Using where; Using filesort |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still way to many records being loaded with the operation taking &lt;code&gt;767ms&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We added an index on the &lt;code&gt;email&lt;/code&gt; column though? Maybe let's use it when ordering instead of &lt;code&gt;created_by&lt;/code&gt;. Let's open &lt;a href="http://localhost:8000/order_by_email"&gt;http://localhost:8000/order_by_email&lt;/a&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;explain&lt;/span&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="nv"&gt;`clients`&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;`email`&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  | table   | type  | possible_keys | key                 | key_len | ref | rows | Extra |
  | ------- | ----- | ------------- | ------------------- | ------- | --- | ---- | ----- |
  | clients | index |               | clients_email_index | 1022    |     | 1    |       |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only one row is loaded, and the index is used with the select operation taking &lt;code&gt;2.46ms&lt;/code&gt;. Just like that we get a significant bump in performance. On production the query went from &lt;code&gt;1.7 seconds&lt;/code&gt; to ~&lt;code&gt;70ms&lt;/code&gt;. Now you can either add an index to the &lt;code&gt;created_at&lt;/code&gt; column or leverage the primary key which is indexed by default. The &lt;code&gt;email&lt;/code&gt; index in this example was just to show indexes help in &lt;code&gt;ORDER BY&lt;/code&gt; statements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's use the &lt;code&gt;PRIMARY KEY&lt;/code&gt; for ordering &lt;a href="http://localhost:8000/order_by_id"&gt;http://localhost:8000/order_by_id&lt;/a&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;explain&lt;/span&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="nv"&gt;`clients`&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  | table   | type  | possible_keys | key     | key_len | ref | rows | Extra |
  | ------- | ----- | ------------- | ------- | ------- | --- | ---- | ----- |
  | clients | index |               | PRIMARY | 8       |     | 1    |       |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one takes &lt;code&gt;1.74ms&lt;/code&gt;, doesn't load close to a million records to memory, looks alright.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Use indexed columns when using &lt;code&gt;ORDER BY&lt;/code&gt; clauses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources for Further Exploration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/c3n7-learning/order-by-gotcha"&gt;Code (on GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html"&gt;8.2.1.16 ORDER BY Optimization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sql</category>
      <category>laravel</category>
      <category>mysql</category>
    </item>
    <item>
      <title>Mapping Huion Keys on Linux</title>
      <dc:creator>Timothy Karani</dc:creator>
      <pubDate>Thu, 14 Apr 2022 01:09:14 +0000</pubDate>
      <link>https://dev.to/c3n7/mapping-huion-keys-on-linux-49l1</link>
      <guid>https://dev.to/c3n7/mapping-huion-keys-on-linux-49l1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This post assumes you already have the tablet working and the &lt;code&gt;xsetwacom&lt;/code&gt; command already exists on your linux installation.&lt;br&gt;&lt;br&gt;
For this post I'll be mapping the buttons on my HS611 Tablet. A HS611 tablet has 8 buttons on the pad and 2 buttons on the stylus.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Things Up
&lt;/h2&gt;

&lt;p&gt;Let us get the name of the graphics tablet:&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="nv"&gt;$ &lt;/span&gt;xsetwacom &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above gives the output below if the connected tablet is a HS611&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HUION Huion Tablet_HS611 stylus         id: 15  type: STYLUS
HUION Huion Tablet_HS611 Pad pad        id: 16  type: PAD
HUION Huion Tablet_HS611 Touch Strip pad        id: 17  type: PAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of importance to us are &lt;code&gt;HUION Huion Tablet_HS611 stylus&lt;/code&gt; and &lt;code&gt;HUION Huion Tablet_HS611 Pad pad&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping
&lt;/h2&gt;

&lt;p&gt;Fire up your favorite text editor, and create bash script file with a name of your choice. For this post I'll choose &lt;code&gt;set_keys.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;in &lt;strong&gt;&lt;code&gt;set_keys.sh&lt;/code&gt;:&lt;/strong&gt;&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;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="c"&gt;# PAD MAPPINGS&lt;/span&gt;
&lt;span class="c"&gt;#top set&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 1 &lt;span class="s2"&gt;"key ctrl shift z"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 2 &lt;span class="s2"&gt;"key ctrl z"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 3 &lt;span class="s2"&gt;"key ctrl p"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 8 &lt;span class="s2"&gt;"key ctrl shift ="&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 9 &lt;span class="s2"&gt;"key ctrl -"&lt;/span&gt;

&lt;span class="c"&gt;#bottom set&lt;/span&gt;
&lt;span class="c"&gt;# https://askubuntu.com/a/1193029&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 10 &lt;span class="s2"&gt;"key +ISO_Level3_Shift +9"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 11 &lt;span class="s2"&gt;"key 4"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 12 &lt;span class="s2"&gt;"key del"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 13 &lt;span class="s2"&gt;"key 6"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 Pad pad'&lt;/span&gt; Button 14 &lt;span class="s2"&gt;"key +ISO_Level3_Shift +8"&lt;/span&gt;


&lt;span class="c"&gt;# STYLUS MAPPINGS&lt;/span&gt;
&lt;span class="c"&gt;# xsetwacom --set 'HUION Huion Tablet_HS611 stylus' Button 1 "key h" # on click&lt;/span&gt;
&lt;span class="c"&gt;# button 1 on the stylus is triggerd when you tap the stylus tip on the tab. Simulates a "click" by default.&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 stylus'&lt;/span&gt; Button 2 &lt;span class="s2"&gt;"key b"&lt;/span&gt;
xsetwacom &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="s1"&gt;'HUION Huion Tablet_HS611 stylus'&lt;/span&gt; Button 3 &lt;span class="s2"&gt;"key e"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mappings are configured with Krita in mind:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pad Mappings&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Button&lt;/th&gt;
&lt;th&gt;Mapping&lt;/th&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Button 1&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;Z&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Redo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Z&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Undo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 3&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;P&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Pan Mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 8&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;=&lt;/code&gt; (equivalent to &lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;+&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Zoom In&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 9&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;-&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Zoom Out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 10&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;+ISO_Level3_Shift&lt;/code&gt; + &lt;code&gt;+9&lt;/code&gt; (aka &lt;code&gt;altgr&lt;/code&gt; + &lt;code&gt;9&lt;/code&gt; or &lt;code&gt;]&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Increase brush size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 11&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rotate Left&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 12&lt;/td&gt;
&lt;td&gt;&lt;code&gt;del&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clear Canvas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 13&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rotate Right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 14&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;+ISO_Level3_Shift&lt;/code&gt; + &lt;code&gt;+8&lt;/code&gt; (aka &lt;code&gt;altgr&lt;/code&gt; + &lt;code&gt;8&lt;/code&gt; or &lt;code&gt;[&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Decrease brush size&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stylus Mappings&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Button&lt;/th&gt;
&lt;th&gt;Mapping&lt;/th&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Button 1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Brush Tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button 2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Eraser Tool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With that done, let us now give execution permissions to our script file:&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x set_keys.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run the file every time we connect the tablet so as to map the keys:&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="nv"&gt;$ &lt;/span&gt;./set_keys.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've mapped the keys, you can fire open Krita and draw to your heart's content :).&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips
&lt;/h2&gt;

&lt;p&gt;You can view all mappable keys/modifires with the command below. Sometimes they don't map as we expect (example &lt;code&gt;[&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt;), but with a bit of Googling you will find your solution:&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="nv"&gt;$ &lt;/span&gt;xsetwacom &lt;span class="nt"&gt;--list&lt;/span&gt; modifiers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test in a terminal which key is being input by the button after mapping, you could monitor either using the &lt;code&gt;xev&lt;/code&gt; command or &lt;code&gt;showkey -a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Happy drawing :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/title/Wacom_tablet"&gt;Archlinux docs on Wacom Tablets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://isaacs.pw/2020/06/mapping-huion-h610-drawing-tablet-buttons/"&gt;Mapping HUION H610 Drawing Tablet Buttons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>design</category>
    </item>
  </channel>
</rss>
