mirror of
https://github.com/jbranchaud/til
synced 2026-01-20 23:48:02 +00:00
Compare commits
1 Commits
15d4ee1590
...
c2dda60ca8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2dda60ca8 |
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1429 TILs and counting..._
|
_1423 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -261,7 +261,6 @@ _1429 TILs and counting..._
|
|||||||
|
|
||||||
- [Accessing a Lost Commit](git/accessing-a-lost-commit.md)
|
- [Accessing a Lost Commit](git/accessing-a-lost-commit.md)
|
||||||
- [Add A Range Of Filename To gitignore](git/add-a-range-of-filenames-to-gitignore.md)
|
- [Add A Range Of Filename To gitignore](git/add-a-range-of-filenames-to-gitignore.md)
|
||||||
- [Add Only Tracked Files From A Directory](git/add-only-tracked-files-from-a-directory.md)
|
|
||||||
- [Amend Author Of Previous Commit](git/amend-author-of-previous-commit.md)
|
- [Amend Author Of Previous Commit](git/amend-author-of-previous-commit.md)
|
||||||
- [Auto-Squash Those Fixup Commits](git/auto-squash-those-fixup-commits.md)
|
- [Auto-Squash Those Fixup Commits](git/auto-squash-those-fixup-commits.md)
|
||||||
- [Caching Credentials](git/caching-credentials.md)
|
- [Caching Credentials](git/caching-credentials.md)
|
||||||
@@ -321,7 +320,6 @@ _1429 TILs and counting..._
|
|||||||
- [Quicker Commit Fixes With The Fixup Flag](git/quicker-commit-fixes-with-the-fixup-flag.md)
|
- [Quicker Commit Fixes With The Fixup Flag](git/quicker-commit-fixes-with-the-fixup-flag.md)
|
||||||
- [Rebase Commits With An Arbitrary Command](git/rebase-commits-with-an-arbitrary-command.md)
|
- [Rebase Commits With An Arbitrary Command](git/rebase-commits-with-an-arbitrary-command.md)
|
||||||
- [Reference A Commit Via Commit Message Pattern Matching](git/reference-a-commit-via-commit-message-pattern-matching.md)
|
- [Reference A Commit Via Commit Message Pattern Matching](git/reference-a-commit-via-commit-message-pattern-matching.md)
|
||||||
- [Remove Untracked Files From A Directory](git/remove-untracked-files-from-a-directory.md)
|
|
||||||
- [Rename A Remote](git/rename-a-remote.md)
|
- [Rename A Remote](git/rename-a-remote.md)
|
||||||
- [Renaming A Branch](git/renaming-a-branch.md)
|
- [Renaming A Branch](git/renaming-a-branch.md)
|
||||||
- [Resetting A Reset](git/resetting-a-reset.md)
|
- [Resetting A Reset](git/resetting-a-reset.md)
|
||||||
@@ -462,7 +460,6 @@ _1429 TILs and counting..._
|
|||||||
- [Find Where Yarn Is Installing Binaries](javascript/find-where-yarn-is-installing-binaries.md)
|
- [Find Where Yarn Is Installing Binaries](javascript/find-where-yarn-is-installing-binaries.md)
|
||||||
- [for...in Iterates Over Object Properties](javascript/for-in-iterates-over-object-properties.md)
|
- [for...in Iterates Over Object Properties](javascript/for-in-iterates-over-object-properties.md)
|
||||||
- [Format A Decimal To A Fixed Number Of Digits](javascript/format-a-decimal-to-a-fixed-number-of-digits.md)
|
- [Format A Decimal To A Fixed Number Of Digits](javascript/format-a-decimal-to-a-fixed-number-of-digits.md)
|
||||||
- [Format Time Zone Identifier](javascript/format-time-zone-identifier.md)
|
|
||||||
- [Formatting Values With Units For Display](javascript/formatting-values-with-units-for-display.md)
|
- [Formatting Values With Units For Display](javascript/formatting-values-with-units-for-display.md)
|
||||||
- [Freeze An Object, Sorta](javascript/freeze-an-object-sorta.md)
|
- [Freeze An Object, Sorta](javascript/freeze-an-object-sorta.md)
|
||||||
- [Generate A V4 UUID In The Browser](javascript/generate-a-v4-uuid-in-the-browser.md)
|
- [Generate A V4 UUID In The Browser](javascript/generate-a-v4-uuid-in-the-browser.md)
|
||||||
@@ -611,7 +608,6 @@ _1429 TILs and counting..._
|
|||||||
- [List Databases And Tables](mysql/list-databases-and-tables.md)
|
- [List Databases And Tables](mysql/list-databases-and-tables.md)
|
||||||
- [Run Statements In A Transaction](mysql/run-statements-in-a-transaction.md)
|
- [Run Statements In A Transaction](mysql/run-statements-in-a-transaction.md)
|
||||||
- [Select Rows After An Offset](mysql/select-rows-after-an-offset.md)
|
- [Select Rows After An Offset](mysql/select-rows-after-an-offset.md)
|
||||||
- [Set Value On Null JSON Column](mysql/set-value-on-null-json-column.md)
|
|
||||||
- [Show Create Statement For A Table](mysql/show-create-statement-for-a-table.md)
|
- [Show Create Statement For A Table](mysql/show-create-statement-for-a-table.md)
|
||||||
- [Show Tables That Match A Pattern](mysql/show-tables-that-match-a-pattern.md)
|
- [Show Tables That Match A Pattern](mysql/show-tables-that-match-a-pattern.md)
|
||||||
- [Show Indexes For A Table](mysql/show-indexes-for-a-table.md)
|
- [Show Indexes For A Table](mysql/show-indexes-for-a-table.md)
|
||||||
@@ -1378,9 +1374,7 @@ _1429 TILs and counting..._
|
|||||||
- [Fix Unlinked Node Binaries With asdf](unix/fix-unlinked-node-binaries-with-asdf.md)
|
- [Fix Unlinked Node Binaries With asdf](unix/fix-unlinked-node-binaries-with-asdf.md)
|
||||||
- [Forward Multiple Ports Over SSH](unix/forward-multiple-ports-over-ssh.md)
|
- [Forward Multiple Ports Over SSH](unix/forward-multiple-ports-over-ssh.md)
|
||||||
- [Generate A SAML Key And Certificate Pair](unix/generate-a-saml-key-and-certificate-pair.md)
|
- [Generate A SAML Key And Certificate Pair](unix/generate-a-saml-key-and-certificate-pair.md)
|
||||||
- [Generate Base64 Encoding Without Newlines](unix/generate-base64-encoding-without-newlines.md)
|
|
||||||
- [Generate Random 20-Character Hex String](unix/generate-random-20-character-hex-string.md)
|
- [Generate Random 20-Character Hex String](unix/generate-random-20-character-hex-string.md)
|
||||||
- [Get A List Of Locales On Your System](unix/get-a-list-of-locales-on-your-system.md)
|
|
||||||
- [Get Matching Filenames As Output From Grep](unix/get-matching-filenames-as-output-from-grep.md)
|
- [Get Matching Filenames As Output From Grep](unix/get-matching-filenames-as-output-from-grep.md)
|
||||||
- [Get The Unix Timestamp](unix/get-the-unix-timestamp.md)
|
- [Get The Unix Timestamp](unix/get-the-unix-timestamp.md)
|
||||||
- [Global Substitution On The Previous Command](unix/global-substitution-on-the-previous-command.md)
|
- [Global Substitution On The Previous Command](unix/global-substitution-on-the-previous-command.md)
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
# Add Only Tracked Files From A Directory
|
|
||||||
|
|
||||||
The two extremes of staging files in a git repo are to either selectively pick
|
|
||||||
each individual chunk of changes with `git add --patch` (my preference!) or to
|
|
||||||
run `git add -A` to add everything.
|
|
||||||
|
|
||||||
Now let's say I have large directory full of files that get generated during
|
|
||||||
test runs. Most of these files are tracked (already checked in to the
|
|
||||||
repository). There are also many new files generated as part of the most recent
|
|
||||||
test run.
|
|
||||||
|
|
||||||
I want to staging the changes to files that are already tracked, but hold off
|
|
||||||
on doing anything with the new files.
|
|
||||||
|
|
||||||
Running `git add spec/cassettes` won't do the track because that will pull in
|
|
||||||
everything. Running `git add --patch spec/cassettes` will take long and be
|
|
||||||
tedious. Instead what I want is the `-u` flag. It's short for _update_ which
|
|
||||||
means it will only stage already tracked files.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git add -u spec/cassettes
|
|
||||||
```
|
|
||||||
|
|
||||||
That will stage every change to any already known files in `spec/cassettes`.
|
|
||||||
|
|
||||||
See `man git-add` for more details.
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# Remove Untracked Files From A Directory
|
|
||||||
|
|
||||||
Let's say I have a directory (`spec/cassettes`) full of a ton of generated YAML
|
|
||||||
files. Most of these files are tracked by git. However, I just generated a
|
|
||||||
bunch of new ones that are untracked. For whatever reason, I don't want these
|
|
||||||
files. I need to delete them.
|
|
||||||
|
|
||||||
Running `rm` on each of them is going to be too tedious. And it is tricky to
|
|
||||||
target them for a bulk delete since there are a ton of other files in that
|
|
||||||
directory that I want to keep.
|
|
||||||
|
|
||||||
One way to approach this is have `git ls-files` help out with listing all files in the
|
|
||||||
directory that are untracked. The `--others` flag filters to untracked files.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git ls-files --others --exclude-standard spec/cassettes
|
|
||||||
```
|
|
||||||
|
|
||||||
From there, I can pipe it to `rm` (with `xargs` collapsing all the files into a
|
|
||||||
single line):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git ls-files --others --exclude-standard spec/cassettes | xargs rm
|
|
||||||
```
|
|
||||||
|
|
||||||
See `man git-ls-files` for more details.
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Format Time Zone Identifier
|
|
||||||
|
|
||||||
Though there are surely libraries that can help with this task, we now have
|
|
||||||
full support in the [`Intl.DateTimeFormat`
|
|
||||||
API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat)
|
|
||||||
for formatting a date's time zone identifier in various ways.
|
|
||||||
|
|
||||||
To do this, we have to create a formatter specifying the locale, the `timeZone`
|
|
||||||
option, and any formatting options. For the formatting, I'll try the
|
|
||||||
`timeZoneName` with both `short` and `longGeneric`.
|
|
||||||
|
|
||||||
Then we `formatToParts` on any date object and extract the `timeZoneName`
|
|
||||||
value:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const options = { timeZone: 'America/Chicago', timeZoneName: "short" }
|
|
||||||
const formatter = new Intl.DateTimeFormat("en-US", options)
|
|
||||||
|
|
||||||
formatter.formatToParts(new Date()).find((part) => part.type === "timeZoneName").value
|
|
||||||
//=> 'CDT'
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, let's try this for `longGeneric`:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const options = { timeZone: 'America/Chicago', timeZoneName: "longGeneric" }
|
|
||||||
const formatter = new Intl.DateTimeFormat("en-US", options)
|
|
||||||
|
|
||||||
formatter.formatToParts(new Date()).find((part) => part.type === "timeZoneName").value
|
|
||||||
//=> 'Central Time'
|
|
||||||
```
|
|
||||||
|
|
||||||
There are several more options for the `timeZoneName` as well as a bunch more
|
|
||||||
you can do with the `Intl.DateTimeFormat` API.
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# Set Value On Null JSON Column
|
|
||||||
|
|
||||||
To set a key-value pair on a JSON field, you can reach for
|
|
||||||
[MySQL's `json_set`](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-set)
|
|
||||||
or one of [the other JSON setter
|
|
||||||
functions](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html).
|
|
||||||
|
|
||||||
However, if the JSON field you are updating is `null`, you might get an
|
|
||||||
unexpected result.
|
|
||||||
|
|
||||||
```sql
|
|
||||||
> update User
|
|
||||||
set metadata = json_set(metadata, '$.discord_id', 'discord_123')
|
|
||||||
where id = 123;
|
|
||||||
|
|
||||||
Query OK, 0 rows affected (0.00 sec)
|
|
||||||
Rows matched: 1 Changed: 0 Warnings: 0
|
|
||||||
```
|
|
||||||
|
|
||||||
We can see that the `where` clause matched on a single row as expected, but
|
|
||||||
right above that it says _0 rows affected_.
|
|
||||||
|
|
||||||
What happened?
|
|
||||||
|
|
||||||
The `json_set` function is not able to set a key-value pair on `null`. It needs
|
|
||||||
a JSON object to work on.
|
|
||||||
|
|
||||||
There are a number of ways to get around this. I find that
|
|
||||||
[`coalesce`](https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#function_coalesce)
|
|
||||||
is a natural way to handle this. If `metadata` happens to be `null`, then we
|
|
||||||
_coalesce_ it to `'{}'` (an empty object).
|
|
||||||
|
|
||||||
```sql
|
|
||||||
> update User
|
|
||||||
set metadata = json_set(coalesce(metadata, '{}'), '$.discord_id', 'discord_123')
|
|
||||||
where id = 123;
|
|
||||||
|
|
||||||
Query OK, 1 row affected (0.02 sec)
|
|
||||||
Rows matched: 1 Changed: 1 Warnings: 0
|
|
||||||
```
|
|
||||||
|
|
||||||
It updates as expected. That same statement will work on a row where `metadata`
|
|
||||||
already contains a JSON object since the `coalesce` will resolve to that
|
|
||||||
instead of the empty object.
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# Generate Base64 Encoding Without Newlines
|
|
||||||
|
|
||||||
There are a variety of tools that can generate a Base64 encoding of given text.
|
|
||||||
Most of them that I've encountered have a number of characters at which they
|
|
||||||
introduce a newline character. Here is `openssl` as an example:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
❯ echo "here is a long bit of text to base64 encode with openssl" | openssl base64
|
|
||||||
aGVyZSBpcyBhIGxvbmcgYml0IG9mIHRleHQgdG8gYmFzZTY0IGVuY29kZSB3aXRo
|
|
||||||
IG9wZW5zc2wK
|
|
||||||
```
|
|
||||||
|
|
||||||
[The theory I've seen](https://superuser.com/a/1225139) is that this is to
|
|
||||||
accommodate 80-character terminal screens when chunks of encoding were included
|
|
||||||
in emails.
|
|
||||||
|
|
||||||
With the `openssl base64` command, there is not an option to exclude the
|
|
||||||
newlines, but we can pipe it through `tr` to remove them.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
❯ echo "here is a long bit of text to base64 encode with openssl" | \
|
|
||||||
openssl base64 | \
|
|
||||||
tr -d '\n'
|
|
||||||
aGVyZSBpcyBhIGxvbmcgYml0IG9mIHRleHQgdG8gYmFzZTY0IGVuY29kZSB3aXRoIG9wZW5zc2wK
|
|
||||||
```
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# Get A List Of Locales On Your System
|
|
||||||
|
|
||||||
The `locale -a` command will list all the available locales on your system.
|
|
||||||
|
|
||||||
You'll see a giant list that probably includes these and many more values.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ locale -a
|
|
||||||
|
|
||||||
en_NZ
|
|
||||||
nl_NL.UTF-8
|
|
||||||
pt_BR.UTF-8
|
|
||||||
fr_CH.ISO8859-15
|
|
||||||
eu_ES.ISO8859-15
|
|
||||||
en_US.US-ASCII
|
|
||||||
af_ZA
|
|
||||||
bg_BG
|
|
||||||
cs_CZ.UTF-8
|
|
||||||
fi_FI
|
|
||||||
zh_CN.UTF-8
|
|
||||||
eu_ES
|
|
||||||
sk_SK.ISO8859-2
|
|
||||||
nl_BE
|
|
||||||
fr_BE
|
|
||||||
sk_SK
|
|
||||||
en_US.UTF-8
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Each of these locales identifies itself by the language and the manner in which
|
|
||||||
the language is used in a particular place. For example, `en_NZ` is _English as
|
|
||||||
it is spoken in New Zealand_. `fr_BE` is _French as it is spoken in Belgium_.
|
|
||||||
`en_US.UTF-8` is _English as it is spoken in the US, with a UTF-8 character set
|
|
||||||
encoding_.
|
|
||||||
|
|
||||||
[source](https://www.postgresql.org/docs/current/locale.html#LOCALE-OVERVIEW)
|
|
||||||
Reference in New Issue
Block a user