/******************************************************************************* * Copyright (c) 2015 hangum. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * hangum - initial API and implementation ******************************************************************************/ package com.hangum.tadpole.rdb.core.editors.main.utils; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.hangum.tadpole.db.metadata.MakeContentAssistUtil; import com.hangum.tadpole.db.metadata.TadpoleMetaData; import com.hangum.tadpole.db.metadata.constants.SQLConstants; import com.hangum.tadpole.engine.define.DBDefine; import com.hangum.tadpole.engine.define.DBGroupDefine; import com.hangum.tadpole.engine.manager.TadpoleSQLManager; import com.hangum.tadpole.engine.query.dao.mysql.TableColumnDAO; import com.hangum.tadpole.engine.query.dao.mysql.TableDAO; import com.hangum.tadpole.engine.query.dao.system.UserDBDAO; import com.hangum.tadpole.engine.sql.util.SQLUtil; import com.hangum.tadpole.rdb.core.viewers.object.sub.utils.TadpoleObjectQuery; import com.hangum.tadpole.tajo.core.connections.TajoConnectionManager; import com.ibatis.sqlmap.client.SqlMapClient; /** * make content assist util * * @author hangum * */ public class ExtMakeContentAssistUtil extends MakeContentAssistUtil { private static final Logger logger = Logger.getLogger(ExtMakeContentAssistUtil.class); /** * make content assist util * * @param userDB * @param strQuery * @param intPosition * @return */ public String makeContentAssist(final UserDBDAO userDB, String strQuery, final int intPosition) throws Exception { strQuery = StringUtils.replace(strQuery, "\n", " "); String listContentAssist = ""; // 현재 위치한 커서 텍스트 String[] strPrevArryCursor = SQLTextUtil.findPreCursorObjectArry(strQuery, intPosition); String strCursor = strPrevArryCursor[0] + strPrevArryCursor[1]; if(logger.isDebugEnabled()) logger.debug("\t position text is [" + strCursor + "]"); // 이전 키워드를 얻는다. String strPrevKeyword = SQLTextUtil.findPrevKeywork(strQuery, intPosition); if(logger.isDebugEnabled()) logger.debug("\t prevous keyword is : [" + strPrevKeyword + "]"); CONTENT_ASSIST_KEYWORD_TYPE prevKeywordType = null; // 쿼리에 공백을 없앤다. strQuery = StringUtils.removeEnd(StringUtils.trimToEmpty(strQuery), ";") + " "; // 이전 키워드가 있다면 마지막이 테이블 키워드 인지, 컬럼 키워드 인지 찾는다. if(!"".equals(strPrevKeyword)) { if(SQLConstants.listTableKeywords.contains(strPrevKeyword)) { prevKeywordType = CONTENT_ASSIST_KEYWORD_TYPE.TABLE; } else if(SQLConstants.listColumnKeywords.contains(strPrevKeyword)) { prevKeywordType = CONTENT_ASSIST_KEYWORD_TYPE.COLUMN; } } if(prevKeywordType != null) { if(strCursor.length() == 0) { // 오브젝트의 컬럼 목록을 가져온다. if(prevKeywordType == CONTENT_ASSIST_KEYWORD_TYPE.COLUMN) { if(logger.isDebugEnabled()) logger.debug("==========[0][CURSOR][COLUMN] content assist : "); listContentAssist = getTableColumnAlias(userDB, strQuery, strCursor); // 오브젝트 목록을 가져온다. } else { if(logger.isDebugEnabled()) logger.debug("==========[0][CURSOR][TABLE] content assist : "); // insert 문이고 테이블 명을 발견했으면 컬럼 리스트를 리턴한다. listContentAssist = ifInsertGetColumn(userDB, strQuery, strCursor); // 컬럼이 없으면 테이블 목록을 넘겨준다. if("".equals(listContentAssist)) { listContentAssist = getSchemaOrTableContentAssist(userDB, strPrevArryCursor); } } if(logger.isDebugEnabled()) logger.debug("\t result : " + listContentAssist); } else { // 오브젝트의 컬럼 목록을 가져온다. if(prevKeywordType == CONTENT_ASSIST_KEYWORD_TYPE.COLUMN) { if(logger.isDebugEnabled()) logger.debug("+++++++++++[1][DEFAULT][COLUMN] content assist : " + listContentAssist); listContentAssist = getTableColumnAlias(userDB, strQuery, strCursor); } else { // 디비스키마 목록, 테이블 목록, 키워드 일수도 있다. if(logger.isDebugEnabled()) logger.debug("+++++++++++[1][DEFAULT][TABLE] content assist : " + listContentAssist); // insert 문이고 테이블 명을 발견했으면 컬럼 리스트를 리턴한다. listContentAssist = ifInsertGetColumn(userDB, strQuery, strCursor); // 컬럼이 없으면 테이블 목록을 넘겨준다. if("".equals(listContentAssist)) { listContentAssist = getSchemaOrTableContentAssist(userDB, strPrevArryCursor); } } if(logger.isDebugEnabled()) logger.debug("\t result : " + listContentAssist); } } else { if(logger.isDebugEnabled()) logger.debug("[NONE] content assist : " + listContentAssist); } return listContentAssist; } /** * insert 로 시작하고 테이블 명을 발견 했을 경우, 컬럼 리스트를 리턴해 주어야 한다. * * @param userDB * @param strQuery * @param strCursor * @return */ private String ifInsertGetColumn(UserDBDAO userDB, String strQuery, String strCursor) { String listContentAssist = ""; if(StringUtils.startsWithIgnoreCase(StringUtils.trimToEmpty(strQuery), "insert")) { listContentAssist = getTableColumnAlias(userDB, strQuery, strCursor); } return listContentAssist; } /** * * @param userDB * @param strQuery * @param strCursor */ private String getTableColumnAlias(final UserDBDAO userDB, final String strQuery, final String strCursor) { List<String> listName = new ArrayList<>(); TadpoleMetaData dbMetaData = TadpoleSQLManager.getDbMetadata(userDB); String strQuote = dbMetaData.getIdentifierQuoteString(); String strSeparator = "."; String strAlias = ""; if(StringUtils.indexOf(strCursor, strSeparator) != -1) { strAlias = StringUtils.substring(strCursor, 0, StringUtils.indexOf(strCursor, strSeparator)); } if(logger.isDebugEnabled()) { logger.debug("query is [" + strQuery + "]"); logger.debug("[quote]" + strQuote + " [alias]" + strAlias); } String tableNamePattern = "((?:" + strQuote + "(?:[.[^" + strQuote + "]]+)" + strQuote + ")|(?:[\\w" + Pattern.quote(strSeparator) + "]+))"; String structNamePattern; if (StringUtils.isEmpty(strAlias)) { structNamePattern = "(?:from|update|join|into)\\s*" + tableNamePattern; } else { structNamePattern = tableNamePattern + "(?:\\s*\\.\\s*" + tableNamePattern + ")?" + "\\s+(?:(?:AS)\\s)?" + strAlias + "[\\s,]+"; } try { Pattern aliasPattern = Pattern.compile(structNamePattern, Pattern.CASE_INSENSITIVE); Matcher matcher = aliasPattern.matcher(strQuery); if(!matcher.find()) { if(logger.isDebugEnabled()) logger.debug("=====> Not found match"); return ""; } if(matcher.groupCount() > 0) { for(int i = 1; i <= matcher.groupCount(); i++) { listName.add(matcher.group(i)); } } else { if(logger.isDebugEnabled()) logger.debug("=====> Not found object name"); return ""; } } catch (PatternSyntaxException e) { if(logger.isDebugEnabled()) logger.error("=====> find pattern exception"); return ""; } // find object column StringBuffer strColumnList = new StringBuffer(); for(String tblName : listName) { strColumnList.append(getAssistColumnList(userDB, tblName)).append(_PRE_GROUP); } return strColumnList.toString(); } /** * 보여 주어야할 테이블 목록을 정의합니다. * * @param userDB * @return * @throws Exception */ public List<TableDAO> getTableListOnlyTableName(final UserDBDAO userDB) throws Exception { List<TableDAO> showTables = null; if(DBGroupDefine.TAJO_GROUP == userDB.getDBGroup()) { TajoConnectionManager manager = new TajoConnectionManager(); showTables = manager.tableList(userDB); } else { SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB); showTables = sqlClient.queryForList("tableListOnlyName", userDB.getDb()); //$NON-NLS-1$ } /** filter 정보가 있으면 처리합니다. */ return getTableAfterwork(showTables, userDB); } /** * List of assist table column name * * @param userDB * @param tableName * @return */ public String getAssistColumnList(final UserDBDAO userDB, final String tableName) { String strColumnlist = ""; //$NON-NLS-1$ String strSchemaName = ""; String strTableName = tableName; if(DBGroupDefine.ALTIBASE_GROUP != userDB.getDBGroup()) { if(StringUtils.contains(tableName, '.')) { String[] arrTblInfo = StringUtils.split(tableName, "."); strSchemaName = arrTblInfo[0]; strTableName = arrTblInfo[1]; } } // 테이블 컬럼 리스트를 가져오기 위해 테이블 이름을 디비에서 저장되어 있는 대소문자 기준으로 가져옵니다. TadpoleMetaData tadpoleMetaData = TadpoleSQLManager.getDbMetadata(userDB); if(tadpoleMetaData.getSTORE_TYPE() == TadpoleMetaData.STORES_FIELD_TYPE.LOWCASE_BLANK) { strSchemaName = StringUtils.upperCase(strSchemaName); strTableName = StringUtils.upperCase(strTableName); } else if(tadpoleMetaData.getSTORE_TYPE() == TadpoleMetaData.STORES_FIELD_TYPE.UPPERCASE_BLANK) { strSchemaName = StringUtils.lowerCase(strSchemaName); strTableName = StringUtils.lowerCase(strTableName); } try { //SQLMap에 파라미터로 전달할때는 ", `, [ 등을 제거하고 사용한다. strTableName = SQLUtil.removeIdentifierQuoteString(userDB, strTableName); TableDAO table = new TableDAO(strTableName, ""); table.setSysName(strTableName); table.setSchema_name(strSchemaName); table.setName(strTableName); List<TableColumnDAO> showTableColumns = TadpoleObjectQuery.getTableColumns(userDB, table); for (TableColumnDAO tableDao : showTableColumns) { strColumnlist += tableDao.getSysName() + _PRE_DEFAULT + tableDao.getType() + _PRE_GROUP; //$NON-NLS-1$ } strColumnlist = StringUtils.removeEnd(strColumnlist, _PRE_GROUP); //$NON-NLS-1$ } catch(Exception e) { logger.error("MainEditor get the table column list", e); //$NON-NLS-1$ } return strColumnlist; } }