2024年8月31日 星期六

[ASP.NET Core] HTTP response JSON format

 ASP.NET Core    Newtonsoft.Json    System.Text.Json 


Configuration


The following codes in Startup.cs: ConfigureServices(IServiceCollection services) , show the difference of JSON serialization for HTTP response with Newtonsoft.Json and System.Text.Json.

System.Text.Json

The namespace had been included in runtime in .NET Core 3.1 and later versions.


Newtonsoft.Json

If we still want to use Newtonsoft.Json as the default serialization/deserialization package, install it and write as following. 



2023年9月9日 星期六

[Vim] Using GitHub Copilot

    GitHub Copilot    Vim    Bash 


Introduction


copilot.vim is the Vim plugin to let us use GitHub Copilot in Vim.


Prerequisites


Node.js
Vim 9.0.0185


Setup


First enable GitHub Copilot to your GitHub account here.

Install the plugin: copilot.vim and enable it by

:Copilot auth


It will ask you to enter a OTP in https://github.com/login/device.
After the authentication, type :Copilot setup and a message will show that you've logged in.

Now type :Copilot version to check the version and :Copilot enable to get started.


Features


Panel of Suggestion

Select a text which contains your prompt, and then use the following command to show a list of solutions.

:Copilot panel


Ghost Text auto-completion


GitHub Copilot will show the auto-complete text, code or scripts based on the context of current working file. The auto-complete text will be shown in grey color, type TAB to complete it. 


For more details and default hotkeys, see :h copilot or :Copilot help.
I recorded a video to show how to use it in Vim and bash Vi mode.





Options


Disable by file type

Sometimes you want to disable it by default for some file types, you can write an AutoCommand like this (to disable it on markdown file).  

autocmd! BufNewFile,BufRead *.md exe 'Copilot disable'


copilot.vim has the global variable: "g:copilot_filetypes" that we can tell it to enable/disable GitHub Copilot on certain file types. See :h g:copilot_filetypes for details. Here is an example in my vimrc.

let g:copilot_filetypes = { 'xml': v:false, 'markdown': v:false, 'log': v:false, }


Or you can disable it in all filetypes(*) and only enable it in some filetypes by...

let g:copilot_filetypes = { '*': v:false, 'python': v:true, }









2023年7月9日 星期日

[開箱] FILCOキーボード工房 Majestouch 3 NINJA Tenkeyless

   FILCO   Majestouch 3 NINJA 

 



原本想入手茶軸的 Majestouch 3 NINJA ,台灣也有代理商;但是被官網的 キーボード工房 版本燒到,所以最後還是從日本購入這把 キーボード工房 Majestouch 3 NINJA Tenkeyless

上色後的 FILCO NINJA 非常的美,也沒有正刻帶來的繁雜感,對於我來說是極具收藏價值的藝術品;當然品質還是維持一樣的高水準。

購入時也附了一些特典,就一併直接上圖做個記錄囉!

 










2023年3月14日 星期二

[Oracle] CONNECT BY and Recursive CTE for hierarchy data

  Oracle   CTE   Hierarchy   CONNECT BY

 

Problem


Assume that we have a table, EMPLOYEES, which include hierarchy data like this,

 



Each employee has a manager, and a manager also has his/her manager, except JB, who is the boss.

We are going to learn how to use the following 2 ways to traverse the hierarchy rows.

1.  START WITH...CONNECT BY...

2.  Recursive CTE

 

START WITH...CONNECT BY...


We can use Oracle's START WITH... CONNECT BY... clause to traverse hierarchal rows.

Pattern


SELECT columns
FROM table
START WITH {condition to find the root row}
CONNECT BY {condition to find next row};
\

 

l   START WITH specifies the root row of the hierarchy.

l   CONNECT BY specifies the relationship of parent and child rows.

l   PRIOR indicates the recursive condition to traverse all the rows.
e.q. PRIOR A = B means using current row's column A to match next row's column B. And A = PRIOR B means use current row's column B to match next row's column A.

 

SQL

The following SQL lists the top-down hierarchy by starting from JB that has no manager and traverse the records that have manager as JB, and so on.

Notice that the condition to find next row is PRIOR EMP_NO = MANAGER_NO, and that means we use EMP_NO to find(match) the next row by its MANAGER_NO.

 


SELECT EMP_NO, NAME, MANAGER_NO
FROM EMPLOYEES
START WITH MANAGER_NO IS NULL
CONNECT BY PRIOR EMP_NO = MANAGER_NO;

 

Result:



 

And the following SQL lists the bottom-up hierarchy by from James and shows his reporting line.

Notice that the condition to find next row is EMP_NO = PRIOR MANAGER_NO, and that means we use MANAGER_NO to find(match) the next row by its EMP_NO.


SELECT EMP_NO, NAME, MANAGER_NO
FROM EMPLOYEES
START WITH NAME = 'James'
CONNECT BY EMP_NO = PRIOR MANAGER_NO;

 

Result:

 


CTE Recursive


We can do the same thing by using CTE recursive.

SQL


WITH t1(EMP_NO,NAME,MANAGER_NO) AS
(
    SELECT EMP_NO,NAME,MANAGER_NO FROM EMPLOYEES
    WHERE NAME = 'James'
    UNION ALL
    SELECT t2.EMP_NO, t2.NAME, t2.MANAGER_NO FROM EMPLOYEES t2, t1
    WHERE t2.EMP_NO = t1.MANAGER_NO
)
SELECT * FROM t1;

 

 

Result:

 


(Optional) Create a Function


Let's create a Function FindReportLine that returns the report line of an exployee by his/her name.


Function by START WITH... CONNECT BY...


CREATE OR REPLACE FUNCTION FindReportLine (
    in_name IN VARCHAR2
) RETURN SYS_REFCURSOR IS
    emp_cursor SYS_REFCURSOR;
BEGIN
    OPEN emp_cursor FOR
    SELECT EMP_NO, NAME, MANAGER_NO
    FROM EMPLOYEES
    START WITH NAME = in_name
    CONNECT BY EMP_NO = PRIOR MANAGER_NO;
    RETURN emp_cursor;
END;


Function by Recursive CTE


CREATE OR REPLACE FUNCTION FindReportLine (
    in_name IN VARCHAR2
) RETURN SYS_REFCURSOR IS
    emp_cursor SYS_REFCURSOR;
BEGIN
    OPEN emp_cursor FOR
    WITH t1(emp_no, name, manager_no) as (
        SELECT EMP_NO, NAME, MANAGER_NO
        FROM EMPLOYEES
        WHERE name = in_name
        UNION ALL
        SELECT t2.EMP_NO, t2.name, t2.MANAGER_NO
        FROM EMPLOYEES t2 INNER JOIN t1
        ON t2.EMP_NO = t1.MANAGER_NO
    )
    SELECT * FROM t1;
    RETURN emp_cursor;
END;


Use the Function

Since the function returns the rows as SYS_REFCURSOR, we can parse the result by XML.

XMLTABLE maps the result of an XQuery evaluation into relational rows and columns.


SELECT * FROM xmltable(
'/ROWSET/ROW'
PASSING xmltype(FindReportLine('James'))
columns
EMP_NO PATH 'EMP_NO',
NAME PATH 'NAME',
MANAGER_NO PATH 'MANAGER_NO'
);


The XMLSEQUENCE could also do the same thing, though it's deprecated.


SELECT
extractvalue(column_value,'/ROW/EMP_NO') EMP_NO,
extractvalue(column_value,'/ROW/NAME') NAME,
extractvalue(column_value,'/ROW/MANAGER_NO') MANAGER_NO
FROM TABLE(xmlsequence(FindReportLine('James')));


(Optional) Aggregate the Result

We can use LISTAGG function in Oracle to combine multiple rows into a single row with each value separated by a specified character or symbol. For example, the following SQL aggregates and show the names of the report line of James.


SELECT LISTAGG(NAME, ' / ') WITHIN GROUP ( ORDER BY ROWNUM ) AS REPORT_LINE
FROM
(
SELECT EMP_NO, NAME, MANAGER_NO
FROM EMPLOYEES
START WITH NAME = 'James'
CONNECT BY EMP_NO = PRIOR MANAGER_NO
);

The result will be "James / Jack / JB".


Reference


[Sql Server] Recursive CTE for hierarchy data

[PostgreSQL] Recursive CTE for hierarchy data

 

 

2022年8月7日 星期日

[開箱] FILCO Majestouch MINILA-R Convertible

  FILCO   MINILA-R 




 

身為一個碼農,對於鍵盤是有一定的要求度;但是在辦公室很少拿機械式鍵盤,原因是很不習慣聽到別人機械式鍵盤敲打的機械式聲音 😡,所以自己自然而然也就不會想用機械式鍵盤去影響別人 😅

 

但是這一年來,陸續接觸了紅軸機械式鍵盤,感覺是個可平衡的選項,聲音不大也有敲打機械式鍵盤獨特的段落感,所以陸續使用了

 

·        ROCCAT Vulcan TKL RGB 紅軸

·        LOGITECH G913 TKL 無線 紅軸

 

ROCCAT雖然是紅軸,但是敲打的聲音還是有清脆的反彈聲,雖然很好聽(跟其他家比起來,個人主觀)也讓輸入的過程非常的爽快,但必須接線又考量到聲音,所以目前拿來當FUN KEYBOARD使用。

而羅技的G913使用上非常滿意,因為短軸的緣故,所以輸入非常輕快和輕鬆,也整合了很直覺的音量調節旋鈕和多功能按鍵,可以切換藍芽和無線連接,而且非常順暢,唯一美中不足的是鍵帽的刻印不明顯,雖然我盲打,但是重點是開啟RGB燈效時,完全沒有FU,只看到鍵盤發光,但完全沒有美感(不過我是早期買的黑色版本,不確定後續是否有改善了),這方面還是ROCCAT比較有娛樂性;因為我在家裡同時必須要連接筆電和桌機,所以目前在家裡就以G913為主囉。

 

回到這篇的主角,也就是因為這一年使用機械式鍵盤的心得,所以就開始物色辦公室用的紅軸鍵盤 XDD

目前放辦公室的LOGITECH CRAFT使用上也非常滿意,但是薄膜式鍵盤的回饋力道比較明顯(快速輸入時,會不自覺的很大力的按到底),在經過連續幾個小時的敲打過程後,會讓我的手指開始產生疲累感,也因為它是100%全幅鍵盤,比較佔空間好吧,以上可能都是藉口 XDDD,總之研究了一番之後,決定入手FILCO Majestouch MINILA-R Convertible 60% 鍵盤。

 

我是直接從硬派精靈線上訂再貨到付款,從下訂單到送達門市約三個工作天。

 

接下來就直接上開箱照片了,後面再來說明我自己的60% 鍵盤配置。

 

(包裝盒正面)

 

(內容物)

 

 

 

鍵盤很樸素,也沒有RGB燈效,回歸到本質就是鍵位、組合和敲擊。

 

 

打了一天,大概知道為何有FILCO信仰了 😎

雖然是紅軸,但是打擊感除了線性也有扎實感,反彈的力道很Q、很舒服。 對於我自己的重點是因為我手指比較粗,所以我的鍵盤上的按鍵兩兩都必須要有一定的距離,可以看到上圖,它的按鍵是兩層的,對於避免誤觸到兩個鍵非常有幫助,而空白鍵兩旁的組合鍵「FN」,設計上是微凸起的,方便區隔。

當然缺點也是有,就是網路上說的按鍵會有油感,就是看起來和摸起來會有一點的感覺,使用了一天的確看起來好像使用了一個月 XDDD,不過我特地回去看其他黑色鍵盤也是會有,只是沒有那麼明顯,所以也有可能是按鍵顏色的關係會看起來比較有油感,不過不影響輸入。

 

接下來說一下我自己的按鍵配置,這一款60%有配置DIP開關,我打開了126:

 

DIP

Description

1

將「左ctrl」及「CapsLock」大寫鎖定交換

2

將「左ctrl」及「ESC」交換

6

省電模式

 

在工作上大部分使用 VIM 的按鍵方式,所以在其他鍵盤上,我也是會把原本的「CapsLock」變成「左CTRL」,「左CTRL」改成「ESC」, 這樣我按最左上和最左下都是退出的命令。

這鍵盤由於預設「ESC」是沒有直接輸入的按鍵的,必須要使用「FN+~」,這是比較不方便的,不過因為原本的習慣就可以接受改按最左下角位置,只是一開始在按「~」會下意識去找左上第二顆 XDD

 

另外沒有直接的方向鍵,必須使用以下任一種方式:

1.  搭配「FN」去按「E」「S」「D」「F

2.  搭配「FN」去按 ?/」、「DEL」、「WIN」、「ALT

3.  打開DIP開關4: 將右下方的「?/」、「DEL」、「WIN」、「ALT」直接變成「上」「右」「下」「左」方向鍵,但原本的ESDF方向鍵功能將失效,也沒有「?/

 

我是選擇不打開DIP開關4 因為「?/」在VIM是常用到的按鍵,所以比較需要花時間習慣的是方向鍵的部分。 如果你是WINDOWS用戶,可以透過 Windows PowerToys去調整按鍵配置。 如下圖我額外把「右CTRL」改成「?/」,上面我啟用的DIP其實也可以直接透過這個軟體來設定即可。

 

 

最後拍一下目前服役中的三個不同廠牌的紅軸鍵盤。

 

 

(更新)使用了兩周後的心得。

優點:

  1. 極佳的鍵盤敲打體驗。聲音很舒服不刺耳。
  2. 60%鍵盤,不占空間。
缺點:
  1. 上面提到打了一陣子後,鍵帽會看起來有一些油油的。
  2. 切換到不同鍵盤的時候,需要重新熟悉一下感覺,尤其是方向鍵。
  3. 方向鍵如果不打開 DIP開關4(右下角模式),因為必須要按著FN」,所以在一些組合會有點卡,例如切換並選擇當前應用程式(ALT + TAB + 方向鍵)就必須同時用到四隻手指頭。 雖然是可能還不熟練的關係 (這可能熟練嗎 😅)。
其他:
  1. 鍵盤比較高一些些,所以建議買一個中型的鍵盤護墊來搭配使用。
  2. 別人很大機率無法使用你的鍵盤(由於我自己比較注重衛生,所以別人用過我的鍵盤或滑鼠,我會偷偷地用酒精擦拭一下XDDD,不過我通常會放另外一個也連著電腦的鍵盤備用或別人用)

以上是比較針對FILCO Majestouch MINILA-R Convertible的部分。 而以下幾點是使用大部分 60% 鍵盤會需要熟悉的地方

  •  F1 ~ F12鍵必須透過組合鍵觸發(很多開發工具會用到)。
  • HOME」和END」其實還滿常用到的,所以如果有沒有獨立按鍵,也是會有點卡。(我一直以為他們不重要 😅)


(再更新)使用了一個月後的心得。

沒想到放在辦公室使用了一個月多幾天,已經完全適應了 FILCO Majestouch MINILA-R Convertible 60% 鍵盤,反而對家裡的80%鍵盤有點不太適應(尤其是方向鍵會想要先去找FN鍵 😅)。 所以... 又入手了一把茶軸的放家裡使用了 😱😱😱

接下來說一下茶軸的差異:

  1. 敲打音量我覺得可以說是完全沒差異,一樣是很乾淨,是"咚咚"的聲音,不會是那種"鏘鏘"比較尖銳的聲音。
  2. 敲按鍵有一股回饋(反彈)的力道,這是茶軸的特性。雖然力道不大,但是我自己會不自覺多用一點點力氣去敲打,所以個人覺得如果是要長時間快速寫程式或打字,紅軸是比較適合我自己的,但如果你想要有稍微打字機的感覺(就是鍵盤會告訴你... 確實有按下這個鍵的感覺),茶軸就比紅軸適合。 不過話說回來,一切真的都是習慣就好。
  3. 茶軸我是選青藍色(照片可能看不太出來差異),想比之下,灰色鍵盤會比較穩重一點。
最後再補上幾張茶軸的 FILCO Majestouch MINILA-R Convertible。