1 #title = "@SQL"
  2 #tooltip = "SQL変換"
  3 #include "lib/sgc4jsee.jsee"
  4 
  5 /**
  6  * @fileOverview
  7  * ポップアップメニューの選択により、以下の機能を提供します。<br />
  8  * <strong>どの機能も厳密な処理を行わないため、補助的に使用してください。</strong>
  9  * <dl>
 10  * <dt><p>■TSVをinsert文に簡易変換</p></dt>
 11  * <dd><p>
 12  * カラム名とデータから成るTSVを元に、insert文を生成します。<br />
 13  * TSVは、1行目にカラム名の羅列、2行目以降がデータの羅列であることが前提です。
 14  * <p>
 15  * 以下の文字列を日付型として認識します。
 16  * <ul>
 17  * <li>YYYY/MM/DD HH24:MM:SS</li>
 18  * <li>YYYY-MM-DD HH24:MM:SS</li>
 19  * <li>YYYY/MM/DD</li>
 20  * <li>YYYY-MM-DD</li>
 21  * </ul>
 22  * </p>
 23  * <p>
 24  * 数値をシングルクォーテーションで囲わないようにして、<br />
 25  * 空項目も「''」ではなく「null」としたい場合は<code>judgeNumber</code>変数にtrueを指定してください。 
 26  * </p>
 27  * </p></dd>
 28  * 
 29  * <dt><p>■select文をupdate文に簡易変換</p></dt>
 30  * <dd><p>
 31  * 選択文字列があればそれを、なければドキュメント全体を対象に、<br />
 32  * select文からupdate文への変換を行います。
 33  * </p></dd>
 34  * 
 35  * <dt><p>■SQLコメント簡易削除</p></dt>
 36  * <dd><p>
 37  * SQLのコメントと空行を削除します。<br />
 38  * 甘い仕様のため、文字列内にコメントの記号があったり、コメントが入れ子になっていたりすると誤作動します。<br />
 39  * PL/SQLでのエラー行の判定に使用することを主目的としています。
 40  * </p></dd>
 41  * </dl>
 42  * 
 43  * @author gecca from 雪月花 (http://setsugecca.org/)
 44  * @version 1.00 for EmEditor v10.0
 45  */
 46 
 47 (function() {
 48 	// 数値をシングルクォーテーションで囲わないようにして、空項目を「''」ではなく「null」とする場合はtrue (Oracleであればfalse推奨)
 49 	var judgeNumber = false;
 50 	
 51 	JseeUtil.createPopupMenu([
 52 		["TSV -> insert (&I)", tsv2insert],
 53 		["select -> update (&U)", select2update],
 54 		["SQLコメント簡易削除 (&-)", deleteComment],
 55 	]);
 56 	
 57 	return;
 58 	
 59 	function tsv2insert() {
 60 		document.selection.SelectAll();
 61 		if(!document.selection.Text) {
 62 			return;
 63 		}
 64 		var tableName = prompt("insert先のテーブル名", clipboardData.getData("Text"));
 65 		if(!tableName) {
 66 			return;
 67 		}
 68 		
 69 		var lines = JseeUtil.str2lines(JseeUtil.getAllText());
 70 		var insertSqls = [];
 71 		
 72 		// 「insert into TABLE_NAME (COLUMN1, COLUMN2)」の部分を作成
 73 		var columnLine = lines[0];
 74 		var preStatement = "insert into " + tableName + " (" + columnLine.replace(/\t/g, ", ") + ")";
 75 		
 76 		// データ判定用マッチャー
 77 		var dateMatcher = /\d{4}([-\/])\d{2}([-\/])\d{2}( \d{2}:\d{2}:\d{2})?/;
 78 		var numberMatcher = /^\d+$/;
 79 		
 80 		// データの行を処理 (「 values (DATA1, DATA2);」の部分を作成)
 81 		for(var i=1;i<lines.length;i++) {
 82 			var dataLines = lines[i].split("\t");
 83 			var valuesStatement = " values (";
 84 			
 85 			// データの項目内容を1つずつ判定
 86 			for(var j=0;j<dataLines.length;j++) {
 87 				var dataItem = dataLines[j];
 88 				if(dateMatcher.test(dataItem) && RegExp.$1 == RegExp.$2) {
 89 					// Date型
 90 					var ymdDelimiter = RegExp.$1;
 91 					var existsHms = RegExp.$3 != "";
 92 					valuesStatement += "to_date('" + dataItem + "', 'YYYY" + ymdDelimiter + "MM" + ymdDelimiter + "DD" + (existsHms ? " HH24:MM:SS" : "") + "'), ";
 93 				} else if(judgeNumber && numberMatcher.test(dataItem)) {
 94 					// 数値
 95 					valuesStatement += dataItem + ", ";
 96 				} else if(judgeNumber && dataItem == "") {
 97 					// 空の数値
 98 					valuesStatement += "null, ";
 99 				} else {
100 					// それ以外
101 					valuesStatement += "'" + dataItem + "', ";
102 				}
103 			}
104 			
105 			valuesStatement = valuesStatement.replace(/, $/, "") + ");"
106 			
107 			// insert文の1行を作成し、確保
108 			insertSqls.push(preStatement + valuesStatement);
109 		}
110 		
111 		document.selection.Text = insertSqls.join(JseeUtil.getBr()) + JseeUtil.getBr();
112 		
113 		try {
114 			document.ConfigName = "SQL";
115 		} catch(e) {}
116 	}
117 	
118 	function select2update() {
119 		var target;
120 		if(document.selection.Text) {
121 			target = document.selection.Text;
122 		} else {
123 			document.selection.SelectAll();
124 			target = document.selection.Text;
125 		}
126 		if(!target) {
127 			return;
128 		}
129 		
130 		if(!/(^|\s)select\s/i.test(target)) {
131 			alert("select句がありません。\n処理を中断します。");
132 			return;
133 		}
134 		if(!/\sfrom\s/i.test(target)) {
135 			alert("from句がありません。\n処理を中断します。");
136 			return;
137 		}
138 		
139 		if(!/\swhere\s/i.test(target)) {
140 			alert("where句がありません。\n全件更新するupdate文が生成されますので、ご注意ください。");
141 			document.selection.Text = target.replace(/(^|\s)select\s+(.+)\s+from\s+(.+)/i, "update $3 set $2 = 'XXXXX'");
142 		} else {
143 			document.selection.Text = target.replace(/(^|\s)select\s+(.+)\s+from\s+(.+)(\s+where\s+.+)/i, "update $3 set $2 = 'XXXXX'$4");
144 		}
145 		
146 		try {
147 			document.ConfigName = "SQL";
148 		} catch(e) {}
149 	}
150 	
151 	function deleteComment() {
152 		document.selection.SelectAll();
153 		document.selection.Text = document.selection.Text
154 			.replace(/--[^\r\n]*/g, "")
155 			.replace(/\/\*[\s\S]*?\*\//g, "")
156 			.replace(/(^|\r\n)\s*\r\n/g, "$1").replace(/(^|\r)\s*(\r)/g, "$1").replace(/(^|\n)\s*(\n)/g, "$1")
157 		;
158 		
159 		try {
160 			document.ConfigName = "SQL";
161 		} catch(e) {}
162 	}
163 	
164 })();
165