袋鼠雲程式碼檢查服務,揭秘高質量程式碼背後的秘密
質量是產品的生命線, 是軟體開發過程中至關重要的一環,它可以幫助我們發現並糾正潛在的錯誤,提高軟體質量,降低維護成本。
在 中也存在這個問題,由於離線資料開發人員 SQL 水平不一,導致程式碼書寫混亂、SQL 程式碼執行問題較多。本文將介紹在 中如何利用 規範化 SQL 程式碼,對程式碼書寫問題進行攔截,便於統一管理,用於預防引入需要治理的問題。
透過本文的介紹,我們希望您能夠認識到 的重要性,並瞭解如何透過最/佳實踐來提高程式碼質量和開發效率。
何時進行程式碼規則檢查?
SQL 任務在 介面開發完成之後,點選執行的按鈕,會先經過程式碼規則檢查,如果程式碼規則不滿足則會提示到使用者具體的原因。
模組內建了 5 種 ,使用者可以根據需要選擇性開啟。
開啟後在離線專案管理中可以選擇使用的 、生效範圍和 SQL 任務型別。
在離線 SQL 任務中去執行一條 SQL 前會根據選擇的規則先進行程式碼檢查,如果程式碼檢查不透過則會反饋給使用者,使用者可以根據實際需要判斷要不要執行該 SQL。
在資料資產的程式碼檢查時間中可以看到已經觸發的檢查歷史以及相應的統計資料。
如何實現程式碼檢查規則?
在 CodeCheck 包下定義了通用的程式碼規則檢查的介面。
public interface ICheck { Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo); CodeCheckType getCheckType(); }
以 必須帶分割槽規則為例,會先呼叫 SQLParser 元件進行 SQL 解析,SQLParseInfo 即為 SQL 解析結果,檢查時會先判斷 SQL 語句是不是查詢語句,如果是則判斷查詢的表是不是分割槽表,再判斷是否有查詢條件,最後判斷查詢條件中是否包含分割槽欄位來判斷是否檢查透過。
public class CodeCheckImplType01 extends AbstractCheck { private static final Logger LOGGER = LoggerFactory.getLogger(CodeCheckImplType01.class); @Autowired private DataTableColumnThirdService dataTableColumnThirdService; @Autowired private DataTableThirdService dataTableThirdService; @Override public Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo) { if (!isQuery(sqlParseInfo.getSqlType())) { return Result.buildSuccessResult(); } try { MetadataSearchParam searchParam = new MetadataSearchParam(); searchParam.setDbName(sqlParseInfo.getMainTable().getDb()); searchParam.setTableName(sqlParseInfo.getMainTable().getName()); searchParam.setDataSourceType(dataSourceType); searchParam.setTenantId(tenantId); List<TableDTO> tableDTOS = dataTableThirdService.tableList(searchParam); // 獲取表資訊 for (TableDTO tableDTO : tableDTOS) { List<DataTableColumn> tableColumns = dataTableColumnThirdService.listColumnByTableIds(Lists.newArrayList(tableDTO.getTableId())); if (CollectionUtils.isEmpty(tableColumns)) { continue; } List<String> partitionColumnNameList = tableColumns.stream() .filter(Objects::nonNull) .filter(t -> HavePartitionEnum.have_partition.getPartitionValue().equals(t.getIsPartition())) .map(DataTableColumn::getColumnName) .collect(Collectors.toList()); // 非分割槽表直接返回 if (CollectionUtils.isEmpty(partitionColumnNameList)) { continue; } if (CollectionUtils.isEmpty(sqlParseInfo.getColumnIdentifierList())) { // 沒有查詢條件則校驗失敗 return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName())); } List<String> columnList = sqlParseInfo.getColumnIdentifierList().stream() .filter(c -> StringUtils.equals(c.getDb(), searchParam.getSchemaName()) && StringUtils.equals(c.getTable(), searchParam.getTableName())) .map(ColumnIdentifier::getColumn).collect(Collectors.toList()); boolean disjoint = Collections.disjoint(partitionColumnNameList, columnList); if (disjoint) { return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName())); } } } catch (Exception e) { // 異常情況先透過 LOGGER.error("code check error, check content: {}, defaultDb: {}, checkType: {}", checkContent, defaultDb, getCheckType().name()); } return Result.buildSuccessResult(); } @Override public CodeCheckType getCheckType() { return CodeCheckType.TYPE_01; } }
如何自定義程式碼檢查規則?
如果內建的程式碼檢查規則不滿足客戶的使用場景,客戶可以透過上傳 jar 的方式 檢查規則。
自定義程式碼檢查規則使用 載入使用者上傳的自定義 jar,並在程式碼檢測時呼叫 CodeCheck 方法,在資源關閉時呼叫 close 方法,使用者需要將配置檔案說明中的 jar 依賴自己的專案中。具體如下:
● 建立一個類實現介面
建立一個類實現介面 com.dtstack.assets.spi.codecheck.ICodeCheckClient 並實現 CodeCheck 和 close 方法,書寫相關邏輯程式碼,如果校驗透過需要將 CheckResult 物件中 success 設定為 true,失敗時設定 success 欄位為 false 並設定校驗不透過的理由。
package com.dtstack.assets.spi.codecheck; import java.util.Map; public interface ICodeCheckClient { /** * 程式碼檢查 * * @param checkContent 檢查內容 * @param extMap 擴充套件配置 * @return 檢查結果 */ CheckResult codeCheck(String checkContent, Map<String, Object> extMap); /** * 釋放資源, 呼叫時需要關閉所使用的資源 */ void close(); }
· 入參欄位解釋
– checkContent 為單條 SQL 資訊
– extMap 會設定一些平臺的屬性,包含任務名稱、任務型別等
· 出參欄位解釋
– success 為是否校驗透過,必須設定
– checkResult 為校驗結果,校驗不透過時不能為空
package com.dtstack.demo; import com.dtstack.assets.spi.codecheck.CheckResult; import java.util.Map; public class CodeCheckImpl implements com.dtstack.assets.spi.codecheck.ICodeCheckClient{ @Override public CheckResult codeCheck(String checkContent, Map<String, Object> extMap) { // 程式碼檢查相關邏輯 CheckResult checkResult = new CheckResult(); checkResult.setSuccess(false); checkResult.setCheckResult("校驗不透過的理由"); return checkResult; } @Override public void close() { // 關閉相關資源 } }
● 在 resource 目錄下建立 META-INF/services 目錄
● 在 META-INF/services 目錄下建立檔案
檔名稱為 com.dtstack.assets.spi.codecheck.ICodeCheckClient ,檔案內容為實現 ICodeCheckClient 介面類的許可權定類名。
檔名稱和內容示例:
● 打包當前工程並在資料資產頁面註冊
不符合條件的 jar 會給出提示。
如何載入自定義程式碼規則對應的 jar ?
我們會為上傳的每個規則對應的 jar 初始化一個唯/一的自定義 classloader,該 classloader 繼承 URLClassLoader 並保證子類載入器優先載入。
在第一次呼叫時進行載入並快取對應的 client。
在使用者重新上傳或者編輯規則後清除舊的 classloader 和載入的 client 並釋放資源。
《資料治理行業實踐白皮書》下載地址:
《數棧V6.0產品白皮書》下載地址:
想了解更多有關袋鼠雲大資料產品、行業解決方案、客戶案例的朋友,瀏覽袋鼠雲官網:https://www.dtstack.com/?src=szitpub
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69995740/viewspace-2986405/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- android 程式碼質量檢查工具Android
- 利用 ESLint 檢查程式碼質量EsLint
- CSS 程式碼靜態質量檢查CSS
- JavaScript 程式碼靜態質量檢查JavaScript
- 華為雲釋出CodeArts Check程式碼檢查服務,守護軟體質量和安全
- 何為程式碼檢查服務的門禁級檢查
- 使用Gradle做Java程式碼質量檢查GradleJava
- git 服務搭建及提交程式碼檢查Git
- 高質量的程式碼 - 函式(1)函式
- pre-commit鉤子,程式碼質量檢查MIT
- 基於SonarQube程式碼質量檢查工具總結
- 【Sonar程式碼質量檢測工具】
- 如何書寫高質量的jQuery程式碼jQuery
- Code Complete — 建立高質量的程式碼
- 掌握這些程式碼安全檢視方法,提升你的程式碼質量
- 怎樣編寫高質量的java程式碼Java
- 編寫高質量的程式碼,從命名入手
- 10 個有關程式碼審查和程式碼質量的事實
- 如何編寫高質量的C#程式碼(一)C#
- 探索低程式碼高擴充性背後的奧祕
- iOS 編寫高質量Objective-C程式碼iOSObjectC程式
- [轉]高質量JAVA程式碼編寫規範Java
- 程式碼質量第 4 層 - 健壯的程式碼
- 程式碼質量第 2 層 - 可重用的程式碼
- 程式碼質量第 3 層 - 可讀的程式碼
- CICD05 Jenkins流水線, 程式碼質量檢查sonarqube ubuntu使用JenkinsUbuntu
- 程式碼質量管控 -- 複雜度檢測複雜度
- Sonar程式碼質量管理
- 程式碼質量管理-Sonar
- 書寫高質量jQuery程式碼的12條經驗jQuery
- 如何編寫高質量和可維護的程式碼
- 高質量的C程式碼.釋放記憶體 薦記憶體
- 你也許不知道的Vuejs – 使用ESLint檢查程式碼質量VueJSEsLint
- 你也許不知道的Vuejs - 使用ESLint檢查程式碼質量VueJSEsLint
- 🐒編寫高質量程式碼(手撕程式碼)
- 程式設計師必看:如何充分利用程式碼審查提升你的程式碼質量?程式設計師
- 如何提高Java程式碼質量-優雅的寫程式碼Java
- 程式碼質量管理——如何寫出優雅的程式碼