String の replaceAll で IllegalArgumentException

"\"バックスラッシュへの変換や、"$" 文字を含む replacement への変換を
String の replaceAll で実行すると、
IllegalArgumentException: Illegal group reference
になるので、注意!
しかもこの例外は、replaceAll(String regex, String replacement) の
regex → replacement において、 "\" や "$" 文字へ実際に変換が
実行される時のみに発生する例外なので、とても見つけにくい例外だ。

うっかり、こういう replaceAll の使い方をしてしまう。。

そういう場合は、java.util.regex.Matcher の quoteReplacement を使う。

string.replaceAll("_", Matcher.quoteReplacement("$_"));

MySQL 照合順序の指定エラー Error Code: 1253

collate utf8_unicode_ci

utfbm4 のキャラクタコードに対してこの collate を指定するとエラーになる、
Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'utf8mb4'
以下でデーターベースがどうなっているか確認する

SHOW VARIABLES LIKE 'character_set_database';

+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| character_set_database | utf8mb4 |
+------------------------+---------+
1 row in set (0.00 sec)

データベース、グローバレベルの collation を確認すると、

show global variables like 'collation_server';

+------------------------+--------------------+
| Variable_name          | Value              |
+------------------------+--------------------+
| character_set_database | utf8mb4_0900_ai_ci |
+------------------------+--------------------+

MySQL 5.7 のデフォルト・キャラクタコード を utf8mb4 にしていたら
デフォルトの collation は、utf8mb4_general_ci でした。
しかし、MySQL 8.0 以降は、デフォルト・キャラクタコード = utf8mb4 に対して
デフォルトの collation = utf8mb4_0900_ai_ci になります。

0900 は、Unicode のバージョン 9.00 を示してます。
_ai は、Accent Insensitive の略、アクセントの違いを区別しません。
_ci は、Case Insensitive の略、大文字小文字区別しない。

https://dev.mysql.com/doc/refman/8.0/ja/charset-collation-names.html
に、照合の命名規則が書いてあります。

サフィックス 意味
_ai アクセントを区別しない
_as アクセントを区別する
_ci 大文字小文字を区別しない
_cs Case-sensitive
_ks カナを区別する
_bin バイナリ

collation で大文字小文字を区別しない厳格なバイナリ照合なら utf8mb4_bin を使います。

utf8mb4_0900_ai_ci
'あ' → 'ア', 'ア' にマッチする
'は' → 'バ', 'パ' にマッチする
大文字小文字区別しない

utf8mb4_0900_as_ci
'あ' → 'ア', 'ア' にマッチする、
'は' → 'バ', 'パ' にマッチしない
大文字小文字区別しない

utf8mb4_0900_as_cs
'あ' → 'ア', 'ア' にマッチしない
'は' → 'バ', 'パ' にマッチしない
大文字小文字区別する

utf8mb4_0900_ai_cs という照合順序は、存在しません。
utf8mb4_0900_cs という照合順序は、存在しません。

utf8mb4_unicode_ci
'あ' → 'ア', 'ア' にマッチする
'は' → 'バ', 'パ' にマッチする
大文字小文字区別しない

utf8mb4_unicode_cs という照合順序は、存在しません。
utf8mb4_unicode_ai という照合順序は、存在しません。
utf8mb4_unicode_as という照合順序は、存在しません。
utf8mb4_unicode_ai_ci という照合順序は、存在しません。
utf8mb4_unicode_as_ci という照合順序は、存在しません。

utf8mb4_general_ci
'あ' → 'ア', 'ア' にマッチしない
'は' → 'バ', 'パ' にマッチしない
大文字小文字区別しない

utf8mb4_general_cs という照合順序は、存在しません。

また、MySQL のマニュアルに、キャラクタコードセット utf8 を例に以下の説明で記載されてます。
utf8_unicode_ci では、縮約および無視可能な文字もサポートされています。
utf8_general_ci は、拡張、縮小または無視可能な文字をサポートしないレガシー照合です。
文字間で 1 対 1 の比較しかできません。

日付時刻の最小値最大値とMySQL

Java8 以降、java.time.LocalDate と java.time.LocalDateTime の最小値/最大値は、

LocalDate.MIN → -999999999-01-01
LocalDate.MAX → +999999999-12-31

LocalDateTime.MIN → -999999999-01-01T00:00
LocalDateTime.MIN → +999999999-12-31T23:59:59.999999999

である。
MySQL データベースのTIMESTAMP型は、このような言語の数学的な最小値と最大値は
データを作れません。
JSTのdatabase の場合、UTCエポック時刻 +9:00 1970-01-01 09:00:00
の時刻でデータを作ろうとすると、
ERROR 1292: 1292: Incorrect datetime value:
+1秒の 1970-01-01 09:00:01 ならデータを作れる。
これはつまり、Java エポックの時刻(JST

LocalDateTime.ofEpochSecond(3600*9L, 0, ZoneOffset.UTC)

や、

OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(0, 0, 0), ZoneOffset.UTC)||<

は、ダメで

LocalDateTime.ofEpochSecond(3600*9L + 1, 0, ZoneOffset.UTC)
OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(0, 0, 1), ZoneOffset.UTC)||<

ならばOKなのである。
2038年問題の 2038-01-19 03:14:07 UTC でも同様のことが、TIMESTAMP では、
ERROR 1292: 1292: Incorrect datetime value:
のエラーを引き起こします。

解決策として、DATETIME型を用いることなのですが、
DATETIME型の場合、、

0000-01-01 00:00:00
9999-12-31 23:59:59

という値を入れることができて、
Javaでは、

OffsetDateTime.of(LocalDate.of(0, 1, 1), LocalTime.of(0, 0, 0), ZoneOffset.UTC)

OffsetDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(14, 59, 59), ZoneOffset.UTC)

でデータをセットできます。

サクラエディタ マークダウン表を作成するマクロ

マークダウン表を作る場合、オンラインの以下も便利なのですが、、
https://www.tablesgenerator.com/markdown_tables

下記、紹介の引用です。
たいへん有難い。
[小ネタ]backlogテキスト整形のルール~表の生成技~
ヌーラボの backLog の表を作成する場合です。
登録するマクロ
backLogTable.mac

//キーボードマクロのファイル
ReplaceAll('"', '', 28);	// すべて置換
ReplaceAll('\\r\\n', '\\r', 28);	// すべて置換
ReplaceAll('\\n', '&br;', 28);	// すべて置換
ReplaceAll('\\r', '|\\r\\n', 28);	// すべて置換
ReplaceAll('\\t', '|', 28);	// すべて置換
ReplaceAll('^', '|', 28);	// すべて置換
ReDraw(0);	// 再描画
GoFileTop(0);	// ファイルの先頭に移動
GoLineEnd(0);	// 行末に移動(折り返し単位)
Char(104);	// 文字入力

では、git-hub のマークダウンの表を作成するマクロを書いてみましょう。
githubTable.mac

//キーボードマクロのファイル
GoFileTop(0);	// ファイルの先頭に移動
GoLineEnd_Sel(0);	// (選択)行末に移動(折り返し単位)
Copy(0);	// コピー
Right(0);	// カーソル右移動
Char(13);	// 文字入力
Paste(0);	// 貼り付け
GoLineTop_Sel(0);	// (選択)行頭に移動(折り返し単位)
ReplaceAll('[^\\t\\r\\n]+', ':---', 188);	// すべて置換
ReplaceAll('"', '', 28);	// すべて置換
ReplaceAll('\\r\\n', '\\r', 28);	// すべて置換
ReplaceAll('\\n', '&br;', 28);	// すべて置換
ReplaceAll('\\r', '|\\r\\n', 28);	// すべて置換
ReplaceAll('\\t', '|', 28);	// すべて置換
ReplaceAll('^', '|', 28);	// すべて置換
ReDraw(0);	// 再描画

タブで区切ったテキストから
以下の様に変換します。
変換前

A	B	C
11	12	13
21	22	23
31	32	33

変換後

|A|B|C|
|:---|:---|:---|
|11|12|13|
|21|22|23|
|31|32|33|

サクラエディタ ユニコード変換マクロ

ユニコードのままの文字列を元の2byte文字に変換するマクロ

unicodeEscape.js

var cnt = GetLineCount(0);
var result = ''; 

for (var i = 1; i <= cnt; i++) {
    // i行目を取得
    var str = GetLineStr(i);
    // \u.... の文字列の配列で取得、大文字小文字は問わない
    uniArray = str.match(/\\u.{4}/ig);
    if (uniArray) { 
        for (var j = 0, len = uniArray.length; j < len; j++) {
            str = str.replace(uniArray[j], String.fromCharCode(uniArray[j].replace('\\u', '0x')))
        }
    }
    result += str;
}
SelectAll(0);
InsText(result);

(変換の例)

 \u3042\u3044\u3046\u3048\u304a_abc123_\uff76\uff77\uff78\uff79\uff7a

マクロ実行後

あいうえお_abc123_カキクケコ

サクラエディタのマクロの登録は、下記を参考に。。。
サクラエディタで snakecase ⇔ camelcase - Oboe吹きプログラマの黙示録

サクラエディタのマクロで JSON を整形する

JSON整形をブラウザでオンラインツールなどで行うなら、過去に紹介した
JSON Editor の紹介 - Oboe吹きプログラマの黙示録
を使えば良いが、
サクラエディタのマクロに登録しておくものがある。
しかし、ネットで紹介されてるマクロは、複数の項目 or 値がある時、
区切りのカンマ文字の前で改行している。カンマ区切りの後で改行してほしい。
そこで、ちょっと手を加えてあげればよい。
登録するマクロを次のようにする。

jsonpretty.js

var cnt = GetLineCount(0);
var textAll = "";
for(var i = 1; i <= cnt; i++){
   var str = GetLineStr(i).replace(/\n/,"").replace(/\r\n/,"");
   textAll += str;
}
var editJson = "";
var innerFlg = false;
var intentLv = 0;
var quoteType = [];
var blockType = [];
var preChr = "";
var indent = "\t";   // インデント
var rtnChr = "\r\n"; // 改行
for(var i=0; i < textAll.length; i++){
   var prefix = "";
   var suffix = "";
   var rtn = "";
   var c = textAll.substring(i, i + 1);
   if (!innerFlg){
      if (c == " "){
         continue;
      }
      if (c == "\"" || c == "'"){
         innerFlg = true;
         quoteType[quoteType.length] = c;
         // JSON または 配列の1つ目の要素の時はスペース1個を追加
         var chkText = editJson.replace(/( |\t|\r\n|\n)/g, "");
         if (chkText.length > 0){
            var preChar = chkText.substring(chkText.length - 1, chkText.length);
         }
      }else{
         if (c == "{" || c == "["){
            suffix = "";
            intentLv = intentLv + 1;
            blockType[blockType.length] = c;
            for(var j = 0; j < intentLv; j++){
               suffix = suffix + indent;
            }
            rtn = rtnChr;
         }
         if (c == "}" || c == "]"){
            prefix = rtnChr;
            intentLv = intentLv - 1;
            blockType.pop(1);
         }
         if (c == ","){
            rtn = rtnChr;
            for(var j = 0; j < intentLv; j++){
               suffix = suffix + indent;
            }
         }
         if (c == ":"){
            c = " : ";
         }
      }
   }else{
      if (quoteType.length > 0 && c == quoteType[quoteType.length - 1]){
         innerFlg = false;
      }
   }
   if (prefix != ""){
      for(var j=0; j < intentLv; j++){
         prefix = prefix + indent;
      }
   }
   var line = prefix + c + rtn + suffix;
   if (preChr == "" && line.substring(0, 1) == rtnChr){
      line = line.substring(1);
   }
   editJson = editJson + line;
   preChr = line.substring(line.length - 1, line.length);
}
SelectAll(0);
InsText(editJson + rtnChr);

これをマクロとして登録すれば良い。
サクラエディタのマクロの登録は、下記を参考に。。。
サクラエディタで snakecase ⇔ camelcase - Oboe吹きプログラマの黙示録

APIのテストには、Insomnia

APIのテストに、curl コマンドばかり使っていたが、
Insomnia という便利なツールがあるんです。

https://insomnia.rest/

Insomnia Docs

https://docs.insomnia.rest/insomnia/get-started

Insomnia のWindows版ダウンロード
https://insomnia.rest/download


いろんな開発者に出会ったけど、curl コマンドを使うことに変なプライドがあるように
見受けられる場面があって辟易していた。