SqModelとは?
SqModelとは、SQLを「書く」のではなく
命令句プロパティ(=意味)を組み合わせて、
文法ロジックに「組み立て」を委ねることで
認知摩擦(Cognitive Friction)を最小化するinternal DSLである。
SqModelでは以下の「4層アーキテクチャ」による責務分離によりSQLを「書く」のではなく「組み立てる」事を実現している。
●命令句プロパティ:SQLの意味(中間表現)
●方言プロパティ:DB毎の書式差分(形式の違い)
●文法ロジック:意味→形式への変換処理
●出力プロパティ:SQL文字列(実際に実行可能なSQL)
SqModelではこの構造により、
“同じ命令句” を入力しても、方言プロパティを切り替えるだけで
“異なるDB方言のSQL” を出力できる。
前回は「頭の中では答えが見えているのに、実装が上手くいかない…」という「認知摩擦」を解消するためのアイデアとしてSqModelという概念を提唱した
※前回記事:https://qiita.com/RyuQ/items/9b14daa01bee79a77bd1
今回はシンプルな選択クエリを「Access方言」ではなく、「MySQL方言」で生成する例を提示し、「意味」と「実装」の分離によるメリットを説明する。
以下はVBAのメインプロシージャ側のコードである。
前回の記事で掲載したコードと大差はないが、今回は使用する「方言」を定義するDialectプロパティに"mysql"を指定する。
つまり「MySQL方言の文法に基づいたSQLを生成せよ」という事である。
With md
.Dialect = "mysql"
.SELECT_ = "社員名, [販売担当者ID]"
.FROM_ = "社員マスタ"
.WHERE_ = "販売数量 >= 10"
.Modeling
Debug.Print .All
End With
そして、Modelingメソッドでは定義された方言に応じた文法ロジックを呼び出し、SQLを「生成」する。
' ※Modeling は「SQLを 書く」のではなく、「SQLを 生成する」メソッドです
Public Function Modeling()
Dim s As String
' 既存の結果を初期化
Me.All = ""
Select Case Me.Dialect
Case "accessdb"
s = BuildByAccess()
Case "sqlserver"
s = BuildBySqlServer()
Case "mysql"
s = BuildByMySQL()
Case Else
Err.Raise vbObjectError + 513, , "Unsupported Dialect: " & Me.Dialect
End Select
' 出力はここでのみセミコロン付与(重複防止)
If Right(Trim(s), 1) <> ";" Then s = s & ";"
' 結果プロパティ更新
Me.All = s
End Function
なお、この記事はあくまでもSqModelの「構造の提示」であるため、文法ロジックの詳細については割愛する。
だが、以下のように方言ごとの並び順を配列として定義する事で、方言差による「認知摩擦」は内部構造で吸収される。
' 方言ごとの命令句の並び(例)
Dialect_Access = Array("SELECT","FROM","WHERE","GROUP BY","HAVING","ORDER BY")
Dialect_SQLServer = Array("SELECT","FROM","WHERE","GROUP BY","HAVING","ORDER BY") 'TOP対応はBuild内
Dialect_MySQL = Array("SELECT","FROM","WHERE","GROUP BY","HAVING","ORDER BY","LIMIT")
出力結果
Access方言で同じ選択クエリを生成する場合と比較しても、変化した箇所は Dialect プロパティのみである。.Dialect = "mysql"
つまり、人間は「意味」だけを渡し、「実装(文法翻訳)」は Modeling メソッドに委ねる。その結果、同じ入力から、方言に応じた異なる出力が生成される。
SELECT `社員名`, `販売担当者ID`
FROM `社員マスタ`
WHERE `販売数量` >= 10
LIMIT 18446744073709551615;
SELECT [社員名], [販売担当者ID]
FROM [社員マスタ]
WHERE [販売数量] >= 10;
最後に
結局、SQLを「書く」という行為そのものが、人間の“意味”を“文法”へ翻訳する工程であり、ここに認知摩擦が発生する。
故に人間は「意味」だけを考えて「組み立て」を行い、「翻訳」という実装行為はプログラムに委ねるべきなのだ。