SQL Generator 實作前確認
1. 文件目的
本文件用於整理進入程式 repo 實作 MySqlSchemaSqlGenerator 前的確認項目。
目前已完成:
- Schema Attribute 第一版。
- Schema Model 第一版。
- SchemaDefinitionParser 第一版。
- Schema Attribute 使用與 SQL 產生器設計文件。
本文件只確認「SQL 字串產生器」的第一批實作範圍,不代表已經同意實際連線 MySQL、執行 DDL、建立資料表、修改專案啟動方式或導入 WebApi / ServiceHost。
2. 建議結論
建議下一步先做:
MySqlSchemaSqlGenerator第一版,只產生CREATE TABLE IF NOT EXISTSSQL 字串。
第一版先不做:
- 不連線 MySQL。
- 不執行 SQL。
- 不做
ALTER TABLE。 - 不做
SchemaInitializer。 - 不讀取
information_schema。 - 不安裝 MySQL 套件。
- 不改變 ConsoleHost / API 啟動方式。
理由:
- 目前 Attribute / Parser 已完成,下一個最小可驗證節點是從
TableDefinition產出穩定 SQL。 - 先不接 DB 可以降低風險,測試只需驗證 SQL 字串與錯誤處理。
- MySQL 5.6.2 語法需要保守處理,先把 DDL 產生規則固定,再進入實際連線更穩。
3. 第一批允許範圍
| 類別 | 允許內容 |
|---|---|
| SQL Generator | MySqlSchemaSqlGenerator |
| Options | MySqlSchemaSqlGeneratorOptions |
| 輸入 | TableDefinition 或 SchemaDefinition |
| 輸出 | CREATE TABLE IF NOT EXISTS SQL 字串 |
| 驗證 | table / column / index 命名、type 白名單、comment escaping |
| 測試 | xUnit 單元測試 |
| 文件 | 更新實作紀錄與下一步 |
4. 第一批禁止範圍
| 類別 | 不做內容 | 原因 |
|---|---|---|
| DB 連線 | 不連線 MySQL | 尚未進入連線驗證節點 |
| DDL 執行 | 不執行 CREATE TABLE | 避免誤改資料庫 |
| Schema Initializer | 不做啟動時自動建表 | 需等 SQL Generator 驗收後 |
| ALTER TABLE | 不補欄位、不補索引 | 需先有 schema diff 設計 |
| 套件 | 不新增 MySQL 套件 | 純字串產生器不需要 DB driver |
| 啟動方式 | 不改 ConsoleHost / API 啟動流程 | 避免擴大範圍 |
| 資料模型 | 不新增 TaskStore record 欄位 | 先沿用既有 schema class 草案 |
5. 建議放置位置
目前 Schema Attribute 與 Parser 位於:
src/HS.DeviceControl.Core/Schema
第一版 SQL Generator 建議先放在同一個 Schema 命名空間下,理由:
- 目前尚未建立
Infrastructure或 DB 子模組。 - SQL Generator 第一版不連線 DB,只是 schema 字串產生器。
- 放在同一處可降低專案切分成本。
後續若進入 MySQL 連線、TaskStore、SchemaInitializer,才再評估搬到:
src/HS.DeviceControl.Infrastructure
或新增 DB 專案。
6. 建議類別清單
| 類別 | 責任 |
|---|---|
MySqlSchemaSqlGenerator | 將 TableDefinition 產成 MySQL CREATE TABLE SQL |
MySqlSchemaSqlGeneratorOptions | 控制 Engine、Charset、是否使用反引號 |
MySqlSchemaTypeValidator | 驗證 MySQL 5.6.2 型別白名單 |
MySqlIdentifierValidator | 驗證 table / column / index 命名 |
MySqlSqlEscaper | 處理 identifier 包裝與 comment escaping |
若第一批想再縮小,可先只建立:
MySqlSchemaSqlGeneratorMySqlSchemaSqlGeneratorOptions
其他 helper 可先做成 private method,但測試要覆蓋行為。
7. Options 建議
public sealed class MySqlSchemaSqlGeneratorOptions
{
public string Engine { get; set; } = "InnoDB";
public string Charset { get; set; } = "utf8";
public bool QuoteIdentifiers { get; set; } = true;
}
第一版不建議開放:
- Collation。
- Row format。
- Default value SQL。
- Table partition。
- Foreign key。
8. SQL 產出規則
8.1 Table
輸出格式:
CREATE TABLE IF NOT EXISTS `task_executions` (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='任務執行紀錄';
規則:
- 一律使用
CREATE TABLE IF NOT EXISTS。 - Engine 預設
InnoDB。 - Charset 預設
utf8。 - Table description 轉成
COMMENT='...'。
8.2 Column
輸出格式:
`task_id` varchar(64) NOT NULL COMMENT '任務識別碼'
規則:
IsRequired = true時產出NOT NULL。IsPrimaryKey = true時即使IsRequired = false,也要產出NOT NULL。- 非必填欄位產出
NULL。 - Description 轉成
COMMENT '...'。 - Type 字串只允許白名單,不接受任意 SQL 片段。
8.3 Primary Key
輸出格式:
PRIMARY KEY (`task_id`)
規則:
- 第一版至少要有一個 primary key。
- 多欄位 primary key 可支援,但 TaskStore 第一版建議先以單一 id 為主。
8.4 Index
輸出格式:
INDEX `idx_task_executions_status` (`status`)
唯一索引:
UNIQUE INDEX `uk_task_executions_task_id` (`task_id`)
規則:
- Index 指向的 column 必須存在。
- Index name 必須符合 identifier 規則。
- Index columns 需保留宣告順序。
9. Identifier 規則
建議第一版規則:
^[A-Za-z][A-Za-z0-9_]*$
適用:
- Table name。
- Column name。
- Index name。
禁止:
- 空白。
- 破折號。
- 點號。
- 反引號。
- 分號。
- 中文 identifier。
說明:
欄位描述可以中文,但 DB identifier 第一版先固定英文與底線,方便跨工具、跨系統維護。
10. Type 白名單
第一版建議允許:
| 類型 | 允許格式 |
|---|---|
| 字串 | varchar(n),n 建議 1 到 255 |
| 長文字 | text、longtext |
| 整數 | int、bigint |
| 小數 | decimal(p,s) |
| 時間 | datetime |
| 布林 | tinyint(1) |
第一版禁止:
jsonenumsetblobtimestampdefaultauto_incrementforeign keygenerated column- 任意含分號的 type 字串
11. 錯誤處理
建議沿用既有錯誤碼:
SchemaDefinitionInvalid
需能辨識:
| 錯誤情境 | 預期 |
|---|---|
| table name 空白 | 回傳錯誤,不產 SQL |
| table name 格式不合法 | 回傳錯誤,不產 SQL |
| column name 空白 | 回傳錯誤,不產 SQL |
| column type 空白 | 回傳錯誤,不產 SQL |
| column type 不在白名單 | 回傳錯誤,不產 SQL |
| primary key 缺失 | 回傳錯誤,不產 SQL |
| index 指向不存在欄位 | 回傳錯誤,不產 SQL |
若既有 Parser 已擋下部分錯誤,SQL Generator 仍需做防呆,避免未來被其他來源直接呼叫。
12. 測試清單
| 測試項目 | 預期結果 |
|---|---|
| 產出單一 table | SQL 包含 CREATE TABLE IF NOT EXISTS |
| 產出 primary key | SQL 包含 PRIMARY KEY |
| required column | SQL 包含 NOT NULL |
| nullable column | SQL 包含 NULL |
| 一般 index | SQL 包含 INDEX |
| unique index | SQL 包含 UNIQUE INDEX |
| comment 含單引號 | SQL 正確 escape |
| table name 不合法 | 回傳錯誤 |
| type 不合法 | 回傳錯誤 |
| index 指向不存在欄位 | 回傳錯誤 |
| MySQL 5.6.2 不支援型別 | 回傳錯誤 |
13. 驗收標準
完成 SQL Generator 第一版後,需達成:
- 不需要 MySQL 服務即可跑完測試。
- 不需要 MySQL 套件即可跑完測試。
- 能從 TaskStore schema class 產出穩定的
CREATE TABLESQL。 - 錯誤情境可回傳標準錯誤,不吞 exception。
- 不改變現有 ConsoleHost 啟動方式。
14. 仍需使用者確認
進入程式 repo 前,建議確認:
| 確認項目 | 建議值 | 是否可先採用 |
|---|---|---|
第一版是否只做 CREATE TABLE | 是 | 可先採用 |
| 是否先不連線 MySQL | 是 | 可先採用 |
是否先不做 ALTER TABLE | 是 | 可先採用 |
| Engine | InnoDB | 可先採用 |
| Charset | utf8 | 可先採用 |
| Identifier 是否只允許英文 / 數字 / 底線 | 是 | 可先採用 |
| Type 白名單是否採用本文件 | 是 | 可先採用 |
15. 建議下一步
建議下一步:
進行 MySqlSchemaSqlGenerator 第一版實作前 commit/push 前確認
確認後再切換到程式 repo 實作:
MySqlSchemaSqlGeneratorOptionsMySqlSchemaSqlGenerator- SQL escaping / validation helper
- xUnit 測試
完成後再回文件 repo 更新進度與驗證紀錄。