Xperia 5 (SIMフリー版) を衝動的に買いました。

 いわゆる「IYH」ってやつ。

image

◆Xperia 5 SIMフリーモデル

 ご存知の方も多いと思いますが、Sonyが出しているAndroidスマートフォン「Xperia 5」は2019年冬くらいに各キャリアから発売されました。が、つい先日、それのSIMフリー版を国内でも8/28に発売すると急に発表がありました。最初は買うつもりは無かったんですけど、日に日に欲しさが高まってきてしまい、ある晩に 酒を飲んでた勢いもあって 衝動的に注文してしまいました。

 最初はSony公式ストアで注文したんですけど、おとどけ予定日が10月と出てきて面喰い、ヨドバシカメラでの予約注文に切り替えました。そのため、Sony公式の保証サービスである「Xperiaケアプラン」には未加入です。

 SIMフリー版のXperia 5の主なスペックは以下の通り。(詳細が知りたい人は公式ページをどうぞ)

OS Android 10 (何故か公式サイトに記載なし)
CPU Snapdragon 855
メモリ 6GB
ストレージ 128GB + microSDカード対応
モニター 6.1インチ(ノッチなしパンチホールなし) 有機EL
Full HD(1080 * 2520)、21:9の縦長モニタ
端末サイズ 高さ:158mm
横幅:68mm
厚さ:8.2mm
重量:164g
カラー ブラック、グレー、ブルー、レッド
カメラ リアカメラ トリプルレンズ
 ・52mm 望遠 約1220万画素 / F値2.4
 ・26mm 標準 約1220万画素 / F値1.6
 ・16mm  超広角 約1220万画素 / F値2.4
フロントカメラ
 ・約800万画素 / F値2.0
バッテリー 3140mAh
その他 防水(IPX5/IPX8)防塵(IP6X)対応、USB Type-C、おサイフケータイ対応、指紋認証あり、nanoSIM、イヤフォンジャック無し

 キャリアモデルよりも内蔵ストレージ容量が増えていたり、SIMフリー版にはワンセグがついてないなど仕様の差がある模様。容量多いほうが助かりますしワンセグは使わないしで、私にとってはメリットしかないですね。問題は有機EL液晶なことでしょうか……。どうしても「焼き付き」が気になってしまうのですが出来れば避けたいんですけれども、さて。

続きを読む

Visual Studio Code で Java を使うにはJDK11が必要になりました。

 以前も書いたように、仕事ではJavaを使って仕事している私ですが、IDEはEclipseではなくVisual Studio Code(以下、VScode)を使っています。軽快ですし、コード補完等も機能するので満足しています。

 そんなJava開発を実現している拡張機能「Langage Support for Java」ですが、先日そのバージョンが「0.65」に更新されました。拡張機能を更新後にVScodeを再起動すると、下記のようなエラーが表示されました。

image

Java 11 or more recent is required to run. Please download and install a recent JDK

 急になんだ?!と思ったら、どうやらver0.65からは拡張機能の実行にJDK11が必須になった模様。(引き続きJava8での開発は可能)

◆JDK11をインストール

 驚きましたが、そういうことなら仕方ないです。私はJDK8を使っていたのでJDK11はインストールしてなかったため、まずはそこからです。「Amazon Corretto 11」をダウンロードしてきてインストールします。

image

 msiファイルのほうを使えばインストール完了後、環境変数JAVA_HOMEが自動的にJDK11のものに変わってるはずです。

image

 そしたらVScodeを再起動しましょう。これで冒頭のエラーは出なくなりました。

◆VScodeの設定

 JDK11をインストールしましたが、プロジェクトで使用するのは11ではなく8です。なので、次はVScode側で設定を行います。

 settings.jsonを開いて、以下のような設定を追記します。「path」の部分は、インストール済みのJDK8のインストールパスで読み替えてください。

    "java.configuration.runtimes": [
        {
            "default": true,
            "name": "JavaSE-1.8",
            "path": "C:\\Program Files\\Amazon Corretto\\jdk1.8.0_262"
        }
    ],

image

 これで、もう一度VScodeを再起動します。これでJDK11を入れていてもJDK8でプロジェクトの作成やデバッグが可能なはず、です。

◆JAVA_HOMEは変えたくない

 JDK11の使用はVScodeの拡張機能のためだけなので、JAVA_HOMEは変えたくない場合。この場合は、環境変数のJAVA_HOMEは今までの値に手動で戻しつつ、VScode側だけ設定を書き換えてやればOKです。

 JAVA_HOMEをもとに戻してVScodeを起動すると再度、冒頭のエラーが出てきますが無視して、先ほどと同じように「settings.json」を開いて以下のように追記します。例によって、インストールパスはご自身の環境の内容に読み替えてください。
(先ほどとの差異は1行目の強調部分)

    "java.home": "C:\\Program Files\\Amazon Corretto\\jdk11.0.3_7",
    "java.configuration.runtimes": [
        {
            "default": true,
            "name": "JavaSE-1.8",
            "path": "C:\\Program Files\\Amazon Corretto\\jdk1.8.0_262"
        }
    ],

 書き換え後、もう一度VScodeを再起動してください。これで解決してる、はず、です。

Open Live Writer の公式サイトのアドレスが変わってたことに気付けなかったって話

 もうタイトルが全てです。

◆経緯

 つい最近、自PCを買い換えました。実に5年ぶりの買い替えになりました。5年?!(過去記事にて若干言及してたので、いつ買い替えたか振り返れました。こういうとき助かりますね)

 Surface Pro 3(i5モデル)から、Surface Pro 6(i7、16GBモデル)へ買い替えたので、単純なスペック差もそうですがCPUの世代差もかなり大きく、一気に諸々が快適になりましたね。いやーMTGアリーナってこんなヌルサクで動くアプリだったんだなーって感動してるレベル。

 で、PC買い替えたときに付き物な作業として、各種データファイルやアプリやら色々と移行作業が必要になります。大体は特に問題なかったんですけど、1つだけ困ったのが、「Windows Live Writer」さん。私はこのブログを長いこと、このアプリで更新してましたが、Windows Live Writerはすでにサポート終了しております。
 移行先としてはこれのOSS版「Open Live Writer」がありますので、いい加減、切り替えるかーと、今回のPC移行にあわせて切り替えることにしました。

◆公式サイトに繋がらない

 とりあえず適当にぐぐったところOpen Live Writerは、普通にインストーラーからインストールするタイプとMSストアで配布されてるストアアプリ版の2種類あること、日本語化するにはストア版ではダメなことなどを把握。それらの記事から貼られているリンクをクリックしたところ・・・

http://openlivewriter.org/

image

 落ちてるやんけー!

 たまたま見てたサイトによれば、なんか少なくとも年明けくらいからずっとこのまんまらしくて、おいおいまともに運営されてないってことか・・・?と心配に。いやしかし待ってほしい、URLが間違ってるだけかもしれない。そうだよこういうときはちゃんと公式を確認しないとな!
 というわけで、GitHubで管理されてるって聞いたので、さっそくGitHubのページを開いてみました。

image

 えーと・・・あったあった、これやな。ぽちっとな。

image

 ・・・嘘でしょ?

image

 マジかよ・・・。

 

 

◆マジじゃない

 こうなってしまっては、日本語化を諦めてストアアプリ版をインストールするか、あるいは自分でGitHubのソースをビルドして~とやっていくか。あるいは普通にブラウザで記事書くか。どうするかなー・・・と思ってTwitterで愚痴ったところ、そこに救いの手が伸びてきました。

https://platform.twitter.com/widgets.js

 それです。

 あれ、なぜ・・・?と一人で混乱してましたが。

https://platform.twitter.com/widgets.js

 アッアッアッ・・・。

 いわれてみてから確認したら、確かに・・・。

image

image

image

 普通につながるじゃねーの・・・。

 というわけで。

 Open Live Writerの公式ページの正しいURLは「https://openlivewriter.com/」です!!!!!

◆言い訳タイム

 結構、古いほうのURLになったままの記事が多くて、ぜんぜん気付いてませんでした。上のほうで「こういうときはちゃんと公式を~」なんて書いてましたが全然ちゃんと見てなかったです。ごめんなさい。たまたま見てたサイトの人も自分と同様に古いほうのURLを見ていたようなので、「これは他の人も同じ勘違いする人でてきそうだな?」と思って、恥さらしではありますが記事に残しておきます。

 ちゃんと公式を(ちゃんとトップから)見ようね!

 ちなみに。
 Open Live Writerの日本語化手順自体は、インストールさえしちゃえばスムーズでして、これはいろんなとこで言及されてるから詳細は書きませんが、「私の故郷 田代町(これから錦江町)」さんで公開されてる記事から日本語化ファイル落としてくればすぐですよ!

 半年くらい放置してしまってたブログでしたが、久々に更新した記事がこんなって・・・。

 余談ですが、これ書いてるつい数時間前まで、私ずっと旧PCは「Surface Pro 4」を使ってるつもりでした。実際にはPro 3なのにね。これは恥ずかしい。

VScodeのPostgreSQL拡張が便利

 

 私がお仕事で作っているシステムが扱っているデータベースは、現状すべてがPostgreSQLだったりします。システム開発しているとプログラムだけじゃなくてSQLも色々書いたりしますし、日によっては一日中SQLとにらめっこしているなんてことも。
 プログラムの編集はVScodeで快適にやってますが、ちょっとしたSQLを実行したり、PL/pgSQLの関数書いたりするときに、編集だけならVScodeで可能ですが実行時にはいちいちツール切り替えるのが面倒だなぁ、って思っていました。(そんなに頻繁には切り替えませんが)

 で、そこはやはりVScode。探せばええ感じの拡張機能あるやろと思って調べたら、個人的に気に入ったものがありました。今回はそれを紹介します。

 

◆拡張機能「PostgreSQL」

 https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres

image

 名前がまんまですが、これ非公式です。(その名前でええんか……と思いつつも)
 開発者はChris Kolkman氏。

 こいつをさくっとインストールすると、サイドメニューのとこにPostgreSQLの象のアイコンが出てきます。そいつを選んで上にある「+」のアイコンをクリックすると、DB接続を設定できます。

image

 

 設定は、コマンドパレットの入力のように画面上部に入力欄が出てきます(下みたいな感じ)ので、そこに入力していく形式です。

image[1]

 この記事を書いている時点では、それぞれ順番に

 ・接続先ホスト名
 ・接続ユーザー名
 ・パスワード
 ・ポート番号
 ・SSL接続するかどうか(選択)
 ・表示するDB(全てか、選択したものだけか)
 ・この接続の名前

 となっているので、入力していきましょう。

 

 全部入力が終わると、左側のパネル内に作った定義が表示されます。これを展開していけば、そのDBのテーブル、ビュー、ファンクションなどの各オブジェクトが表示されます。テーブルをさらに展開すればカラムの一覧も出てきます。定義の確認などに使えますね。

image

image

 

 ここからテーブルの中身も見たい場合は、テーブルを右クリックして「Select Top 1000」を選べば先頭1000行が表示されます。ただしこれは参照だけであり、中身を書き換えたりすることは出来ません。
 また、Create/Delete Tableとかのデータ定義は、GUI上からは出来ません。あくまでもこのGUI部分はクエリ作成の補助機能である、と拡張機能の説明ページにも記載がありますのでご注意を。まあクエリを自分で書けば実行できますけど。

image

 

 

 

◆クエリを実行してみる

 定義が済んだら、VScodeのステータスバー上に出ている「Select Postgres Server」をクリックしましょう。そして先ほど定義しておいた接続を選択し、続けてDBを選択します。選択したものがステータスバー上に表示されたら準備完了!

image

image

image

 以上でVScode上から簡単にクエリが実行できるようになりました。これで、例えばVScodeでつれづれなるままにファイル編集などしている最中に、ふと急にクエリを実行したくてしかない症候群になったときでも大丈夫。

 

 

 

image

image

 このように、プログラムだろうがただのテキストファイルだろうが関係なく、エディタ上にいきなりSQL文をガガガっと書き込みます。書き込んだらその部分を選択して右クリックし、メニューから「Run Query」を選択すれば・・・。

 

 

 

image

 

 この通り

 実行できるクエリはSELECTに限らず、INSERT/UPDATE/DELETEはおろか、TRUNCATE/DROPなども。ようはクエリで書けるなら何でも。保存してあるPL/pgSQLのファイルを開いた場合も、全選択してRun Queryしてやれば実行できます。これでDB関数更新するためにいちいちpsql叩いたりpgAdmin起動したりしなくて済むぞ!やった!!

 

 

 なんでもかんでもこれを使えばいいというわけではありませんが、この使い方で十分という人も結構いるのではないでしょうか。もし興味のある方がいらっしゃれば是非、お試しあれ。

ついにスクスタがリリースされたので、どっぷりハマってます

 

 HTC U12+ を使い始めて、1年以上が経過しました。今でも私のメイン端末であり、大事に使っています。大事に使っていますが、酔っぱらって帰った日に勢いで?ガラスフィルムを剥がすという凶行をしたりしましたが、はい、大事に使っています。剥がした理由は私にもわかりません。

 

 さて、そもそもこの端末は私がとある3Dゲームを行うための端末として選んだものです。そのゲームの発表があったのが2017年、リリース予定とされたのが2018年、実際にリリースされたのが2019年9月末・・・と、長く長く待たされたわけですが、やっとリリースされたので、どっぷり遊んでいます。正直このままなかったことにされるのも覚悟してた。

 

 そのゲームこそが、そう。

 

Screenshot_20190925-212311

 ラブライブ スクールアイドルフェスティバル オールスターズ

 今日は下手糞ながらもこれのレビューでも・・・。というわけで今回はただのオタ記事です。興味ない人はここで回れ右。

続きを読む

Visual Studio Codeでもっと雑に背景画像を設定したい

 気が付けば8月どころか9月も終わりそうで大慌てしている僕です。御機嫌よう。相も変わらず社畜業に

 

 以前、「Visual Studio Code のデバッグコンソールとかに背景画像を設定したい」という記事でVScodeの背景画像を設定する方法を書きました。あの方法ならエディタ部分の背景、コンソール部分の背景など個別に設定するのには向いています。

 が。
 「そんなに細かく設定はいらなくて、1枚だけビターンと全体的に反映させてはい終了!みたいな、もっと雑でいいから楽に設定したい」という要望が出てきました。自分の中から。なのでもっと簡単な方法を紹介しときます。これもまた、CSS詳しい人なら最初から思いついてそうな内容ではありますが。

 

◆やり方

 基本的なやり方は同じで、CSSファイルをいじるだけです。前回の記事では書き忘れましたが、CSSファイルの場所は

C:\Users\{ユーザー名}\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench

 です。ユーザー名部分は適宜置き換えてください。CSSファイルはVer1.38.1時点で「workbench.desktop.main.css」です。少し前までは「workbench.main.css」というファイル名でしたが、最近変わりました。今後も変わっていくかもしれないですね。
 ファイルの末尾に、以下の感じで追記します。

body {
    background: url("///C:/vscode_custom/backgroundimg.jpg") no-repeat;
    background-position: left top;
    background-size: cover;
    opacity: 0.7;
}

 以前は「.monaco-workbench .part.panel」という名の要素だかクラスだかを指定してましたが、全体に貼り付けるだけならそんな深い階層探さなくても、「body」で全体的にはっつけちゃえばいいわけですね。

 

image

  適用した感じはこんな感じ。エディタやコンソール、そしてエクスプローラーやウィンドウバーなど全体に背景画像が設定されていますね。これでええやん!

 もちろん使用する場合は自己責任で、となりますが、これで皆さんも開発中のモチベをUPさせて、快適な 社畜ライフ プログラミングタイムを送れるようにしていきましょう。

U12+でUQモバイルに乗り換えたら、快適になったけど、うっとうしいSMSが届く

 

 お久しぶりです、OD-10Zです。炎上案件がたて続いててめっきり更新頻度が落ちていますが、私は元気です。

 

 さて、私は長いことIIJを使っていました。MVNOですから、通信速度が遅いことはふつうに我慢できたんですけど、ここ最近は速度よりも、通信が中断される頻度がめちゃくちゃ高いことが気になっており、かなりのストレスになっていました。なのでここは思い切って乗り換えることにしようかな、と……。メイン端末は今もSIMフリーのHTC U12+なので、こういう時に乗換のハードルが低いのはありがたいですね。
 乗換先として検討したのはUQモバイルです。2週間ほど無料でお試しが出来るトライSIMがあるので、まずはトライSIMに申し込んでみました。

 

Screenshot_20190707-123330 Screenshot_20190707-123336

 

 届いたSIMをぶっ刺すと、↑のようにUQモバイルのAPN設定がデフォルトで用意されているので、それを選ぶだけで設定切り替え完了です。楽ちんね!

 

Screenshot_20190624-121941

 

 UQモバイルはIIJと同じMVNO……といってもKDDIのサブブランドですから、速度はかなり速いです。昼時でも30Mbps以上出てるのでかなり快適です。そしてIIJのときの不満点だった、頻繁に発生していた通信途絶も、UQモバイルでは全然発生しません。この時点でかなり満足です。

 

Screenshot_20190624-210450

 平日の夜、会社を出たところで試してみたら、びっくりするような数値も出てきました。これ自宅回線よりはえぇわ……。

 

 

 

 と、いいこと尽くしで乗換を即決しようとしていたのですが、ここで問題が発生。それが、

image Screenshot_20190625-141435

 この、頻繁にSMSで届く鬱陶しいニュース

 Webで調べてみると、どうやらKDDIが緊急地震速報の仕組みを使って配信しているメールとのことで。仕組み上、これの配信を止めることは出来ません。届く内容は色々ですが、時期的に芸能系のニュースがやたら多くて、かけらも興味がない自分としてはこれのストレスが半端なかったです。

 

 対策は、これの送信先をブロックするだけなのですが……。U12+の問題なのかなんなのか、普通に届いたSMSをロングタップ → 連絡先をブロック としても止まりませんでした。なんでだろなーと思って色々試したところ、「連絡先に登録したうえでブロックすれば止まる」ということがわかりました。(保証は出来ませんが、私はこれでピタリと止まりました)

 

Screenshot_20190709-085415

 迷惑SMSを送ってくる番号は現時点では

 ・9701060
 ・9711060
 ・43009
 ・43013

 の4つだったので、それを全て登録します。(自宅とか勤務先とかの種別は別にどれでも構いません)
 名前はてきとーに「迷惑SMS」とでもしときます。

 

image Screenshot_20190709-085250

 登録したら、メニューにある「連絡先をブロック」をタップし、確認メッセージでOKを押します。

 

 

image

 これで無事に、迷惑SMSが届かなくなりました。やれやれ。

 

 

 連絡先として登録しないと(何故か)ブロック設定をすり抜けてくる、ということに気付くまでに時間がかかり、乗換を躊躇ってましたが、これで個人的には問題なくなったので、MNPしました。今ではUQモバイルで快適ライフを過ごしています。今のところは特に支障はありません。

PostgreSQL:テーブル・カラム情報をクエリで取得する

 テーブル一覧を取得したりカラム一覧を取得して、あれこれしたい、というときは結構あると思います。PostgreSQLでも当然そういう要望はあってぐぐれば出てくるんですが、いちいちクエリ書くの面倒くさいのでViewとして定義して使っています。折角なので自分が使ってるやつをここにペタペタしときますので、ご参考までにどうぞ。

--DROP VIEW public.view_columnlist;
CREATE OR REPLACE VIEW public.view_columnlist AS
    SELECT      cls.oid          AS object_id
               ,nms.nspname      AS schema_name
               ,cls.relname      AS table_name
               ,des1.description AS table_logical_name
               ,att.attnum       AS column_no
               ,att.attname      AS column_name
               ,des2.description AS column_logical_name
               ,typ.typname      AS column_type
               ,COALESCE(idx.indisprimary, FALSE) AS column_is_primary_key
               ,att.attnotnull   AS column_is_not_null
               ,cls.relkind      AS object_type
    FROM        pg_catalog.pg_class       cls
    LEFT  JOIN  pg_catalog.pg_namespace   nms
            ON  cls.relnamespace = nms.oid
    LEFT  JOIN  pg_catalog.pg_attribute   att
            ON  cls.oid = att.attrelid
           AND  att.attnum > 0
    LEFT  JOIN  pg_catalog.pg_type typ
            ON  att.atttypid = typ.oid
    LEFT  JOIN  pg_catalog.pg_description des1
            ON  cls.oid = des1.objoid
           AND  des1.objsubid = 0
    LEFT  JOIN  pg_catalog.pg_description des2
            ON  cls.oid = des2.objoid
           AND  att.attnum = des2.objsubid
    LEFT  JOIN  (SELECT indrelid,UNNEST(indkey) AS pk_column_no,indisprimary FROM pg_catalog.pg_index WHERE indisprimary) idx
            ON  cls.oid = idx.indrelid
           AND  att.attnum = idx.pk_column_no
    WHERE       cls.relkind IN ('r','v','m')
      AND       nms.nspname = 'public'
    ORDER BY    schema_name
               ,table_name
               ,column_no
    ;

ALTER TABLE public.view_columnlist
    OWNER TO ユーザー名;


COMMENT ON VIEW view_columnlist IS 'VIEW_テーブルカラム一覧取得';
COMMENT ON COLUMN view_columnlist.object_id IS 'OID';
COMMENT ON COLUMN view_columnlist.schema_name IS 'スキーマ名';
COMMENT ON COLUMN view_columnlist.table_name IS 'テーブル名';
COMMENT ON COLUMN view_columnlist.table_logical_name IS 'テーブル論理名';
COMMENT ON COLUMN view_columnlist.column_no IS 'カラム番号';
COMMENT ON COLUMN view_columnlist.column_name IS 'カラム名';
COMMENT ON COLUMN view_columnlist.column_logical_name IS 'カラム論理名';
COMMENT ON COLUMN view_columnlist.column_type IS 'カラム型';
COMMENT ON COLUMN view_columnlist.object_type IS 'オブジェクト型';
COMMENT ON COLUMN view_columnlist.column_is_primary_key IS '主キー制約';
COMMENT ON COLUMN view_columnlist.column_is_not_null IS '非NULL制約';

 ながい!
 けどそんなに複雑なことはしてないので、簡単に解説しておきます。

◆ざっくり解説

 全てPostgreSQLのシステムカタログテーブルです。まあ当然ですよね。詳細は公式ドキュメントを参照していただくとして、何のテーブルで何のために結合しているかだけ羅列しておきます。尚、各システムカタログテーブルは内部的にoid列をもっており、これが各テーブル間を結合するためのキーとなっています。(ただしoid同士を直接結び付けるわけではない)

テーブル名 説明
pg_class テーブルやビューなどの一覧が定義されている。クエリのメインのテーブル。
pg_namespace 各オブジェクトの名前空間を管理する。
取得対象を絞り込むために使用。(システム系のものを排除)
pg_class.relnamespace と同じ値がこのテーブルのoidになっている。
pg_attribute テーブルやビューの列情報を管理する。
列番号や名前を取得するために使用。
このテーブルのattrelidがpg_class.oidと同じ値になっている。
列番号が1以上の行が列情報。
pg_type 型情報が定義されている。
各カラムの型情報を取得するために使用。
pg_attribute.atttypidと同じ値がこのテーブルのoidになっている。
pg_description 各オブジェクトのコメントを管理する。
テーブルやカラムのコメント情報を取得するために使用。
pg_class.oidと同じ値がこのテーブルのobjoidに格納される。
テーブル情報(objsubid = 0)とカラム情報の両方を取得。
pg_index インデックス情報の一部を管理する。
主キー情報を取得するために使用。(サブクエリでindisprimary(bool)を絞り込んで使用)

indrelidが対象となるテーブルのOID(pg_class.oid)、indkeyが列番号(pg_attribute.attnum)と同じ値になる。
※ただしindkeyは配列型なので扱いに注意

 各テーブルの結合部分がTry&Errorで作ってったので面倒くさかったです。とはいえ、ドキュメントと実テーブルの内容さえわかってしまえば、あとは時間の問題だけでした。

 残りについては各カラムにつけた別名を見て頂ければ意味はわかってもらえると思います。また、WHERE句にある「cls.relkind IN (‘r’,’v’,’m’)」についてですが、これはオブジェクトの種類を絞り込んでおり、具体的には「r:テーブル」「v:ビュー」「m:マテリアライズドビュー」となります。詳細は公式ドキュm(略)

◆実際に使ってみる

 まずはテキトーに、テーブルを用意します。こんな具合に。

image

image

image

 そして、先ほど作成したビューを開いてみます。

image

 ちゃんと取得できてますね。なんか表示されてないテーブルがある気がするかもしれませんが、目の錯覚です。

 つたないクエリですが、よければご参考までに。(結構前に作ったやつなので、環境によってはうまく動かないかもしれませんが)

◆補足

 テーブルやカラムのコメント欄を論理名としているのは、普段はフリーツールの「A5:SQL Mk-2」を使用している関係からです。このツールではコメントを論理名として扱ってくれます。
 尚、論理名を指定しつつコメントも設定したい場合は、コメント部分をタブ区切りにすると認識してくれます。(その場合は上のクエリもタブで区切るように手直ししてください。具体的には↓みたいに)

--               ,des2.description AS column_logical_name
,COALESCE(CASE POSITION(CHR(9) IN des2.description) 
		 WHEN 0 THEN des2.description
		 ELSE        SUBSTRING(des2.description FROM 0 FOR POSITION(CHR(9) IN des2.description))
		 END
		,att.attname) 
				 AS column_logical_name
,CASE POSITION(CHR(9) IN des2.description) 
	WHEN 0 THEN NULL
	ELSE        SUBSTRING(des2.description FROM POSITION(CHR(9) IN des2.description))
END              AS column_comment

 んでもってこんなクエリを発行しておきます。

COMMENT ON COLUMN my_favorite_koto_hono.ss_evaluation IS 'SS評価    やっぱりことほのなんだよちゅんなぁ(・8・)';

※わかりづらいですが、間のはスペースではなくタブです

 そうするとこうなります。

image

image

 ばっちりね!

ブログに載せてたコード(の一部)をSyntaxHighlightに対応させました

 

 令和がはじまりましたね。ようこそ新時代。

 3月と4月は、炎上案件にぶち込まれて社畜ってた合間に、推し事でライブやら劇場版やらを見に行きまくってたせいで、すっかり更新をサボってしまいました。特に書けるネタが無かったというのもありますが。(ちなみにサンシャインの劇場版は40回見てきました

 

 で、タイトルの通りですが。
 ブログに載せていたSQLのコードとかが、変な表示になってしまっていた件、遅くなりましたが修正しておきました。一部、というのは「コノ世界ニ非ズ」に改名して以降の分だけ、です。(コード載せてるのなんて最近のくらいしかないはずですが……)

 現在ならばこんな感じで綺麗にシンタックスハイライトされて表示されています。

image

 

 うちのブログはWordpressの無料版の「Wordpress.com」を使っており、こいつではシンタックスハイライトって出来ないのかな?(追加プラグインとかで)と思って、調べてみたら、普通にやり方が書いてあるサイトがあって判明しました。思い込みしないで、ちゃんと調べないとダメですね。

 で、やり方は、なんてことはないです、コード部分を [code]で囲ってやるだけでいいみたいです。
 また、SQLとかCSSとか、言語に応じてハイライトを対応させることも出来るみたいで、例えばSQLならば[code language="sql"]って書いて囲ってやればいいみたいです。楽ちんね!

 と、いうわけで今後コードを載せるときは、ちゃんとこの機能を使って載せていきたいと思います。それでは令和もよろしくお願いします。

PostgreSQL: すべてのfunctionを一括で削除したい

 

 前に書いた「PostgreSQL:複数定義があるFunctionの一覧をクエリで取得する」って記事の続き的なもの。すっかり書くの忘れてましたが

 さて、上にあげた記事のように、うちのPJではめちゃくちゃFunctionが多くて色々と問題が起きておりまして。そのうえ、環境ごとにDBが乱立してしまい、あるDBのFunctionが最新版では無かったりして環境ごとに挙動が異なり、混乱を招いたりするのは日常茶飯事でした。
 もう完全に管理できてへんやんけ!という本音は横に置いておき、ひとまず事態を収めねばなりません。幸い、FunctionそのものはテキストファイルにしてSVN上で保存してあったので、最新版を当て直すだけならば、さほど難しくありません。

 しかし、どうせ当て直しするなら消し忘れの古い定義のFunctionとか、不要になったFunctionとか、一括して整理したいなぁと思いまして。なんか一括で消せないのかなーと思って調べたのですが、特にそういう機能は無いらしく、1個ずつ手動で消すのはあまりにも面倒だったので、↓みたいな方法で消すことにしました。

 

◆FunctionでFunctionを消す

 やり方は単純で、システムテーブルからFunction名とか引数定義とかを引っ張ってきて、動的SQL文を作って削除するってのを繰り返すだけです。らくちんね。
 自分自身を消さないようにしたり、対象を絞るようにするのを忘れないでください。例えば弊社の場合は、関数名の先頭に「fn_」ってつけることが規則になっていたので、絞り込むのは簡単でした。

・システムテーブルからFunction名と引数定義を取得する

SELECT
    nmsp.nspname || '.' || pgp.proname || '(' || pg_catalog.oidvectortypes(pgp.proargtypes) || ')' AS functionName
FROM
    pg_catalog.pg_proc pgp 
    LEFT JOIN pg_catalog.pg_namespace nmsp
    ON nmsp.oid = pgp.pronamespace
WHERE
        pgp.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype
    AND NOT pgp.proisagg
    AND nmsp.nspname = 'public'
    AND pgp.proname like 'fn_%'
;

 これを実行すると、publicに定義されてる、名前がfn_ではじまるfunction一覧が引数の型定義とセットで手に入ります。「名前(引数1の型, 引数2の型)」みたいな形で。あとはこれを、「DROP FUNCTION 名前(引数1の型, 引数2の型);」という文字列に加工してやって、ループで動的SQLとして実行し続ければOKです。

・動的SQLとしてDROP文を実行する

DECLARE
    rec_funcname_list  record;
    txt_sql            text;
BEGIN
    FOR rec_funcname_list IN
    SELECT
            nmsp.nspname || '.' || pgp.proname || '(' || pg_catalog.oidvectortypes(pgp.proargtypes) || ')' AS functionName
    FROM
            pg_catalog.pg_proc pgp
            LEFT JOIN pg_catalog.pg_namespace nmsp 
                   ON nmsp.oid = pgp.pronamespace
    WHERE   pgp.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype
      AND   NOT pgp.proisagg
      AND   nmsp.nspname = 'public' 
      AND   pgp.proname like 'fn_%'
    LOOP
        txt_sql = 'DROP FUNCTION ' || rec_funcname_list.functionName;
        execute txt_sql;
    END LOOP;
END;

 エラー処理とかは省略してます。実際に使ってるやつからは若干改変してます。(ほんとちょとだけ)
 先に書いたSQLの結果件数だけループさせて、「execute txt_sql;」で実行し続けるだけの簡単なfunctionです。

 使う場合には自己責任でどうぞ。(事前に、SELECT部分だけ実行してちゃんと目的のものだけになってるか、は目を通しておいたほうがいいと思います)