Posts
Jenkins - SonarQube Plugin
如果要將 SonarQube 整合 Jenkins,讓 Jenkins 幫我們運行並將分析送到 SonarQube,可以使用 Jenkins 的 SonarQube Plugin。
先將 Jenkins 安裝 SonarQube Plugin。
安裝完後開啟 Jenkins 的組態設定,設定 SonarQube Server 的資訊。
接著開啟 Jenkins 的 Global Tool Configuration,讓 Jenkins 進行 SonarQube Scanner 的安裝。
安裝與設定都好了後,就可以在 job 的建置這邊使用 Execute SonarQube Scanner 做 SonarQube 分析的設定,語法可參閱 SonarQube Scanner 的設定方式(主要的設定就是 projectKey、projectName、與 sources)。
read morePosts
SonarQube - Manual setup plugins
SonarQube 有些套件未放置在 Update Center,無法透過 Update Center 進行安裝,必須自行手動安裝。
這邊以 PL/SQL Cop 的 SonarQube 套件為例做個示範,先將套件下載下來。
將下載的套件放置於 extensions\plugins 下(不用解壓縮)。
接著將 SonarQube 的服務重啟。
重啟後安裝的套件即會生效。因為多半的套件會有設定頁面,像是這邊示範的 PL/SQL Cop 套件就有,所以可以先從設定頁面這邊做個初步的確認。
read morePosts
SonarQube - Setup/update/remove plugins with Update Center
SonarQube 提供 Update Center 可以讓我們很容易的控管 SonarQube 外掛套件。要使用 Update Center,可點選 [Administrator | System | Update Center]。
Update Center 中的 Installed 頁面會列出所有已安裝的套件,Updates Only 頁面會列出所有可更新的套件,Available 頁面會列出所有可安裝的套件。
套件列表後方的按鈕可供我們安裝、更新、或是移除套件。
按下後會將對應的動作 Queue 起來等待運行,當確定要運行時可按下上方的 Restart 按鈕。
再次按下 Restart 按鈕確認。
就會開始運行對應的動作並將服務重啟。
重啟後對應的設定即會生效。
read morePosts
'C# 7.0 - Throw expressions'
C# 7.0 開始支援 Throw expressions。
三元運算中可以視需要直接丟出 exception。
... this.FirstName = firstName == null ? throw new ArgumentNullException(nameof(firstName)) : firstName; ... ?? 運算式中也可以直接丟出 exception。
... this.LastName = lastName ?? throw new ArgumentNullException(nameof(lastName)); ... Expression bodied member 也可以丟出 exception。
... public override string ToString() => throw new NotImplementedException(); ... 最後附上完整的測試範例:
class Program { static void Main(string[] args) { var person = new Person("Larry", "Nung"); Console.WriteLine(person.ToString()); } } struct Person { public string FirstName { get; set; } public string LastName { get; set; } public Person(string firstName, string lastName) { this.
read morePosts
'C# 7.0 - More expression bodied members'
C# 7.0 擴展了 Expression bodied。
開始支援建構子。
... class Program { ... public Program() => Console.WriteLine("Program()"); ... } ... 支援解構子。
... class Program { ... ~Program() => Console.WriteLine("~Program()"); ... } ... 支援 property accessors。
... private string _myProperty; public string MyProperty { get => _myProperty; set => _myProperty = value; } ... 支援 event accessors。
... public event EventHandler MyEvent { add => _myEvent += value; remove => _myEvent -= value; } .
read morePosts
>-
條款四十二,總是使用 NUMERIC FOR loop 去處理 dense array。
像是下面這樣的程式:
... BEGIN <<process_employees>> LOOP EXIT process_employees WHEN i > t_employees.COUNT(); … i := i + 1; END LOOP process_employees; END; 可以像下面這樣改寫,程式碼的維護性會比較好。
... BEGIN <<process_employees>> FOR i IN 1..t_employees.COUNT() LOOP … END LOOP process_employees; END;
read morePosts
'C# 7.0 - Deconstruction'
C# 7.0 新增 Deconstruction,可將 Tuple、結構、類別的成員拆解使用。
以 Tuple 為例,若想要將 Tuple 值拆解使用,可以用小括弧宣告出多個區域變數,並將 Value Tuple 指派過去,Value Tuple 的屬性值就會依序塞入這些區域變數。
(var v1, var v2) = GetTuple(); var (v1, v2) = GetTuple(); 若是結構或是類別,則要建一個 public 的 Deconstruct 方法,方法的參數用 out 將拆解出來的值依序傳出,編譯時編譯器就會自行幫我們調用 Deconstruct 方法將值拆解。
(var v1, var v2) = new MyClass(); ... class MyClass() { ... public void Deconstruct(out string v1, out string v2) { v1 = this.V1; v2 = this.V2; } } 若有需要 Deconstruct 也支援多載。
(var v1, var v2) = new MyClass(); .
read morePosts
'C# 7.0 - Tuple'
C# 7.0 新增了 Value Type 的 Tuple,因為是 Value Type,所以對 GC 的負擔會比較少。另外增加了一些語法糖,改進了本來 Tuple 類別可讀性不佳的問題。
使用上需先加入 System.ValueTuple 套件。
若不加入該套件編譯時會看到 System.ValueTuple is not defined or imported 的錯誤。
套件加入引用後我們可以看一下該套件的內容,可以看到有一堆泛型的 ValueTuple struct,裡面的成員屬性跟以往的 Tuple 一樣都是 Item1 ~ ItemN。
使用上可以直接建立 ValueTuple,然後在建立的同時指定其型態與值,在要取值的地方用 Item1 ~ ItemN 屬性來取值。
也可以用小括弧包住屬性值直接宣告。
但這樣的宣告方式跟舊的 Tuple 類別一樣有著可讀性不佳的問題,因此在用小括弧包住屬性值宣告的同時,我們將屬性名稱也一併指定,取值時就可以用指定的屬性名稱來取值。
編譯器在編譯時會自動幫你將程式轉換成 Item1 ~ ItemN。
若想要將 Tuple 值拆解使用,可以用小括弧宣告出多個區域變數,並將 Value Tuple 指派過去,Value Tuple 的屬性值就會依序塞入這些區域變數。
這些功能即使套用在方法的回傳值上也一樣適用。
Link Tackling Tuples: Understanding the New C# 7 Value Type - Our ComponentOne C# 7.0 – Tuples – CsharpStar Tuple deconstruction in C# 7 | Thomas Levesque’s .
read morePosts
PL/SQL SQL CODING GUIDELINE 39 - Never use GOTO statements in your code
條款三十九,從不使用 GOTO 語句。
像是下面這樣的程式。
... BEGIN ... <<check_digit>> FOR i IN co_lower_bound .. l_len_array LOOP <<check_pw_char>> FOR j IN co_lower_bound .. l_len_pw LOOP IF SUBSTR(in_password, j, 1) = SUBSTR(co_digitarray, i, 1) THEN l_isdigit := TRUE; GOTO check_other_things; END IF; END LOOP check_pw_char; END LOOP check_digit; <<check_other_things>> NULL; IF NOT l_isdigit THEN raise_application_error(co_errno, co_errmsg); END IF; END password_check; ... 可考慮使用 exit 搭配 label 從迴圈內跳離。
... BEGIN ... <<check_digit>> FOR i IN co_lower_bound .
read morePosts
>-
條款四十一,總是使用 CURSOR for loop,除非使用 Bulk operations。
像是下面這樣的程式:
... BEGIN <<read_employees>> LOOP FETCH c_employees INTO r_employee; EXIT read_employees WHEN c_employees%NOTFOUND; … END LOOP read_employees; CLOSE c_employees; END; 可以像下面這樣改寫,程式碼的維護性會比較好。
... BEGIN <<read_employees>> FOR r_employee IN c_employee LOOP … END LOOP read_employees; END;
read more