【プログラム】クエリフォーマット(javascript)+サクラエディタ
毎回勉強がてらという理由でプログラミングしていますが、だいたいのきっかけが「あ、これやってみよう!」という興味だけです。
今回は サクラエディタで利用する クエリ成形用マクロ(javascript) を作ってみました。 が、あまりいい出来ではないというか、美しさが足りないというか・・・
またテストも十分じゃないので、今後問題が見つかり次第直します。
■機能
インラインに対応したインデント整形を行います。条件文のクエリ(サブクエリ)はインデント一個足りなくなるぅぅぅぅ・・・
■使い方
●設定
①下部の プログラムソース の内容をコピーしてファイルを作成する。ファイル名は "formatSQL_v1.0.js" とする。
②サクラエディタ を開き [設定] → [共通設定] → [マクロ] をひらく。
③[参照]ボタンから ①のファイルを格納したフォルダを参照し、画像通りの以下の設定を行い[設定]を押下する。
④種別:外部マクロ を選択し、対象の機能(queryFormat)を選択する。以下の画像通りに設定し(Shift + Ctrl + ALt は好きに選択を) 割付 を押下する。
⑤[OK]を押下する
●使い方
サクラエディタを開き、対象のクエリを張り付ける。張り付けたクエリをすべて選択し、設定④ で設定した"キー"を押下する
●プログラムソース
/** * Version:1.0 */ /** * メンテナンス */ var DEBUG = 0; var debugTextArray = []; /** * イニシャライズメソッド. * データインプット情報を一元化する. */ function initialize(text){ //文字統一 var keywordArray = [" FROM\\(" , " JOIN\\(" , " GROUP BY\\(" , "HAVING\\(" , " WHERE\\(" , " AND\\(", "ORDER BY\\(" ]; text = text.toUpperCase(); text = replaceAll(text,"\r\n"," "); text = replaceAll(text,"\r"," "); text = replaceAll(text,"\n"," "); text = replaceAll(text,"\t"," "); text = replaceAll(text,"★",""); text = replaceAll(text,"☆",""); for(i=1; i<keywordArray.length-1; i++) { var beforeText = keywordArray[i]; var afterText = beforeText.replace("("," ("); var text = replaceAll(text,beforeText,afterText); } text = text.replace(/\s+/g, " ")// 2つ以上の空白を排除 return text; } /** * メイン処理を行うメソッド * インデント調整等を行う. */ function formatSql(allText){ //1.初期化 allText = initialize(allText); var returnValue = ""; var searchText901 = " INNER JOIN \\("; var searchText902 = " FROM \\("; var searchText903 = " LEFT JOIN \\("; var searchText904 = " LEFT OUTER JOIN \\("; var searchText905 = " IN \\("; allText = replaceAll(allText, searchText901," INNER JOIN ★("); allText = replaceAll(allText, searchText902," FROM ★("); allText = replaceAll(allText, searchText903," LEFT JOIN ★("); allText = replaceAll(allText, searchText904," LEFT OUTER JOIN ★("); allText = replaceAll(allText, searchText905," IN ★("); if (DEBUG == 1){ debugTextArray.push("[DEBUG]#1:" + allText + "\r\n")} //2.一文字ずつチェックし、内部クエリのSTARTとENDの"かっこ"を紐づける charList = allText.split(""); var q = 0; var s = 0; var allKakkoCountArray = []; var inQueryKakkoCountArray = []; //インクエリ判別用の配列 var flag = "0"; // すべての"(" ")"にIDを割り当てを行い、紐づける // "(" : "★", ")" : "☆" が後の処理の指標となる for(k=0; k<charList.length; k++){ var charValue = charList[k]; if(charValue == "★"){ flag = "1"; } if(charValue == "("){ s = s + 1 ; allKakkoCountArray.push(s); if (flag == "1") { inQueryKakkoCountArray.push(s); flag = "0"; } } if(charValue == ")"){ tmpValue = allKakkoCountArray.pop(); for(n=0; n<inQueryKakkoCountArray.length; n++){ if(tmpValue == inQueryKakkoCountArray[n]) { charList[k] = "☆)"; } } } } allText = charList.join("");// すべての文字を結合する if (DEBUG == 1){ debugTextArray.push("[DEBUG]#2:" + allText + "\r\n")} //3.基本的なキーワードで改行する var array =[]; var selectBlockArray = allText.split("SELECT ") var tmpBasicQuery = ""; for(i=1; i<selectBlockArray.length; i++){ text = "\r\n" + "SELECT\r\n\t"+ selectBlockArray[i]; text = replaceKeyword(text); tmpBasicQuery = tmpBasicQuery + text; } if (DEBUG == 1){ debugTextArray.push("[DEBUG]#3:" + tmpBasicQuery + "\r\n")} //4.インクエリの整形を行う baseTabCount = 0; baseTabText = ""; var flag = 0; //インクエリ整形実行用のフラグ var rnBlockTextArray = tmpBasicQuery.split("\r\n"); for(i=1; i<rnBlockTextArray.length; i++) { //flagが0以外の時→インクエリによるインデント調整 if (flag != 0) { baseTabText = ""; for(n=0; n<baseTabCount; n++) { baseTabText = baseTabText + "\t"; } flag = 0; } tmpText = rnBlockTextArray[i]; if (tmpText.indexOf("★") != -1) { returnValue = returnValue + baseTabText + tmpText.replace("★","") + "\r\n"; baseTabCount = baseTabCount + 1; flag = 1 continue; } if (tmpText.indexOf("☆") != -1) { tmpText = replaceAll(tmpText,"☆\\)","\r\n" + baseTabText + "☆)" ); returnValue = returnValue + baseTabText + tmpText.replace("\t☆","") + "\r\n"; baseTabCount = baseTabCount - 1; flag = 2 continue; } if (tmpText.indexOf("★") == -1 && tmpText.indexOf("☆") == -1) { returnValue = returnValue + baseTabText + tmpText + "\r\n"; } } if (DEBUG == 1){ debugTextArray.push("[DEBUG]#3:" + returnValue + "\r\n")} if (DEBUG == 1){ return debugTextArray.join("");} return returnValue; } /** * 置換メソッド. * 全件置換を行う際に利用する. */ function replaceAll(str, beforeStr, afterStr){ var reg = new RegExp(beforeStr, "g"); return str.replace(reg, afterStr); } /** * 基本的な改行判定してよいクエリ文字を規定し、置換するメソッド */ function replaceKeyword(text){ searchText001 = " FROM ★\\("; searchText002 = " FROM "; searchText003 = " INNER JOIN ★\\("; searchText004 = " INNER JOIN "; searchText005 = " LEFT JOIN ★\\("; searchText006 = " LEFT JOIN "; searchText007 = " LEFT OUTER JOIN ★\\("; searchText008 = " LEFT OUTER JOIN "; searchText099 = "," searchText101 = " WHERE "; searchText102 = " GROUP BY "; searchText103 = " HAVING " searchText104 = " AND " searchText105 = " ORDER BY " searchText106 = "☆" //FROM・JOIN text = replaceAll(text, searchText001, "\r\n" + "FROM\r\n" + "★("); text = replaceAll(text, searchText002, "\r\n" + "FROM\r\n" + "\t"); text = replaceAll(text, searchText003, "\r\n" + "INNER JOIN\r\n" +"★("); text = replaceAll(text, searchText004, "\r\n" + "INNER JOIN\r\n"); text = replaceAll(text, searchText005, "\r\n" + "LEFT JOIN\r\n" +"★("); text = replaceAll(text, searchText006, "\r\n" + "LEFT JOIN\r\n"); text = replaceAll(text, searchText007, "\r\n" + "LEFT OUTER JOIN\r\n" +"★("); text = replaceAll(text, searchText008, "\r\n" + "LEFT OUTER JOIN\r\n"); //OTHER text = replaceAll(text, searchText101, "\r\n" + "WHERE\r\n" + "\t" ); text = replaceAll(text, searchText102, "\r\n" + "GROUP BY\r\n" + "\t" ); text = replaceAll(text, searchText103, "\r\n" + "HAVING\r\n" + "\t" ); text = replaceAll(text, searchText104, "\r\n" + "\t" + "AND "); text = replaceAll(text, searchText099,"\r\n" + "\t" + ","); text = replaceAll(text, searchText105, "\r\n" + "ORDER BY\r\n" + "\t" ); text = replaceAll(text, searchText106, "\r\n☆"); return text; } /** * 実行 */ var text = Editor.GetSelectedString(0); if ( text !== "" ) Editor.InsText(formatSql(text));