/******************************************************************************* * Copyright (c) 2013 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.dbinfos.composites; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import com.hangum.tadpole.commons.exception.dialog.ExceptionDetailsErrorDialog; import com.hangum.tadpole.commons.google.analytics.AnalyticCaller; import com.hangum.tadpole.commons.libs.core.message.CommonMessages; import com.hangum.tadpole.commons.util.CSVFileUtils; import com.hangum.tadpole.commons.util.NumberFormatUtils; import com.hangum.tadpole.commons.util.Utils; import com.hangum.tadpole.commons.util.download.DownloadServiceHandler; import com.hangum.tadpole.commons.util.download.DownloadUtils; import com.hangum.tadpole.engine.define.DBGroupDefine; import com.hangum.tadpole.engine.manager.TadpoleSQLManager; import com.hangum.tadpole.engine.query.dao.system.UserDBDAO; import com.hangum.tadpole.rdb.core.Activator; import com.hangum.tadpole.rdb.core.Messages; import com.hangum.tadpole.rdb.core.editors.dbinfos.RDBDBInfosEditor; import com.ibatis.sqlmap.client.SqlMapClient; /** * Tables composite * * @author hangum * */ public class TablesComposite extends DBInfosComposite { /** * Logger for this class */ private static final Logger logger = Logger.getLogger(TablesComposite.class); private UserDBDAO userDB; private TableViewer tvTableInform; private TableInfoFilter tableFilter; private Text textFilter; /** download service handler. */ private Composite compositeTail; private DownloadServiceHandler downloadServiceHandler; private List listTableInform = new ArrayList<>(); /** * Create the composite. * @param parent * @param style */ public TablesComposite(Composite parent, int style, UserDBDAO userDB) { super(parent, style); setLayout(new GridLayout(1, false)); this.userDB = userDB; Composite compositeHead = new Composite(this, SWT.NONE); compositeHead.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); compositeHead.setLayout(new GridLayout(3, false)); Label lblNewLabel = new Label(compositeHead, SWT.NONE); lblNewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblNewLabel.setText(CommonMessages.get().Filter); textFilter = new Text(compositeHead, SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL); textFilter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); textFilter.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { tableFilter.setSearchString(textFilter.getText()); tvTableInform.refresh(); } }); Button btnRefresh = new Button(compositeHead, SWT.NONE); btnRefresh.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { initUI(true); } }); btnRefresh.setText(CommonMessages.get().Refresh); tvTableInform = new TableViewer(this, /* SWT.VIRTUAL | */ SWT.BORDER | SWT.FULL_SELECTION); Table table = tvTableInform.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); createColumn(); tvTableInform.setContentProvider(new ArrayContentProvider()); tvTableInform.setLabelProvider(new TableInformLabelProvider(userDB)); tableFilter = new TableInfoFilter(); tvTableInform.addFilter(tableFilter); compositeTail = new Composite(this, SWT.NONE); compositeTail.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); compositeTail.setLayout(new GridLayout(1, false)); Button btnCsvExport = new Button(compositeTail, SWT.NONE); btnCsvExport.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { download(); } }); btnCsvExport.setBounds(0, 0, 94, 28); btnCsvExport.setText(Messages.get().TablesComposite_btnCsvExport_text); btnCsvExport.setEnabled("YES".equals(userDB.getIs_resource_download())); // initUI(); registerServiceHandler(); } /** * table column head를 생성합니다. */ private void createColumn() { if(DBGroupDefine.MYSQL_GROUP == userDB.getDBGroup()) { String[] name = {"Name", "Engine", "Rows", "Auto Increment", "collation", "Size(MB)", "Created", "Comment"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ int[] size = {120, 70, 70, 100, 80, 80, 120, 220}; int[] align = {SWT.LEFT, SWT.LEFT, SWT.RIGHT, SWT.RIGHT, SWT.LEFT, SWT.RIGHT, SWT.RIGHT, SWT.LEFT}; createColumn(name, size, align); } else if(DBGroupDefine.ORACLE_GROUP == userDB.getDBGroup()) { String[] name = {"Table Name","Tablespace Name","Pct Free","Ini Trans","Logging","Num Rows","Blocks","Avg Row Len","Degree","Sample Size","Last Analyzed","Partitioned","Buffer Pool","Row Movement","Duration","Compression","Dropped","Read Only","Temporary","Max Extents","Iot Type","Initial Extent","Next Extent","Min Extents"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ int[] size = {120, 120, 90, 90, 52 , 90, 90, 90, 80 , 90, 120, 52 , 68 , 72 , 100, 72 , 52 , 52 , 40 , 90, 88 , 90, 90, 90}; int[] align = {SWT.LEFT ,SWT.LEFT ,SWT.RIGHT ,SWT.RIGHT ,SWT.LEFT ,SWT.RIGHT ,SWT.RIGHT ,SWT.RIGHT ,SWT.RIGHT ,SWT.RIGHT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.LEFT ,SWT.RIGHT ,SWT.LEFT ,SWT.RIGHT ,SWT.RIGHT ,SWT.RIGHT}; createColumn(name, size, align); } else if(DBGroupDefine.ALTIBASE_GROUP == userDB.getDBGroup()) { String[] name = {"Table Name", "Owner", "Rows", "Tablespace Name", "Character Set", "Size (MB)", "Created", "Comment"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ int[] size = {200, 70, 70, 200, 100, 80, 120, 250}; int[] align = {SWT.LEFT, SWT.LEFT, SWT.RIGHT, SWT.LEFT, SWT.LEFT, SWT.RIGHT, SWT.RIGHT, SWT.LEFT}; createColumn(name, size, align); } else { String[] name = {"Name", "comment", "Index", "Shared", "Primary Key", "Triggers", "Sub Class", "Rules", "Option"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ int[] size = {120, 150, 60, 60, 100, 80, 80, 60, 60}; int[] align = {SWT.LEFT, SWT.LEFT, SWT.CENTER, SWT.CENTER, SWT.CENTER, SWT.CENTER, SWT.CENTER, SWT.CENTER, SWT.CENTER}; createColumn(name, size, align); } } /** * 실제 컬럼의 헤더를 생성합니다. * * @param name * @param size */ private void createColumn(String[] name, int[] size, int[] align) { for (int i=0; i<name.length; i++) { TableViewerColumn tableColumn = new TableViewerColumn(tvTableInform, align[i]); tableColumn.getColumn().setText(name[i]); tableColumn.getColumn().setWidth(size[i]); } } /** * initialize ui data */ public void initUI(boolean isRefresh) { if(isRefresh) { listTableInform.clear(); } else { if(listTableInform.size() != 0) return; } try { SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB); if (DBGroupDefine.ORACLE_GROUP == userDB.getDBGroup()){ HashMap<String, String>paramMap = new HashMap<String, String>(); paramMap.put("schema_name", userDB.getSchema()); //$NON-NLS-1$ listTableInform = sqlClient.queryForList("tableInformation", paramMap); //$NON-NLS-1$ //$NON-NLS-2$ } else if (DBGroupDefine.MYSQL_GROUP == userDB.getDBGroup()){ HashMap<String, String>paramMap = new HashMap<String, String>(); paramMap.put("schema_name", userDB.getSchema()); //$NON-NLS-1$ listTableInform = sqlClient.queryForList("tableInformation", paramMap); //$NON-NLS-1$ //$NON-NLS-2$ } else { listTableInform = sqlClient.queryForList("tableInformation", userDB.getDb()); //$NON-NLS-1$ //$NON-NLS-2$ } tvTableInform.setInput(listTableInform); tvTableInform.refresh(); } catch (Exception e) { logger.error("Initialize session list", e); //$NON-NLS-1$ Status errStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); //$NON-NLS-1$ ExceptionDetailsErrorDialog.openError(null,CommonMessages.get().Error, Messages.get().MainEditor_19, errStatus); //$NON-NLS-1$ } // google analytic AnalyticCaller.track(RDBDBInfosEditor.ID, "TablesComposite"); //$NON-NLS-1$ } /** download service handler call */ private void unregisterServiceHandler() { RWT.getServiceManager().unregisterServiceHandler(downloadServiceHandler.getId()); downloadServiceHandler = null; } /** * download */ private void download() { if(tvTableInform.getTable().getItemCount() == 0) return; if(!MessageDialog.openConfirm(null, CommonMessages.get().Confirm, Messages.get().TablesComposite_3)) return; List<String[]> listCsvData = new ArrayList<String[]>(); // add header Table tbl = tvTableInform.getTable(); TableColumn[] tcs = tbl.getColumns(); String[] strArryHeader = new String[tcs.length]; for (int i=0; i<strArryHeader.length; i++) { strArryHeader[i] = tcs[i].getText(); } listCsvData.add(strArryHeader); String[] strArryData = new String[tcs.length]; for (int i=0; i<tbl.getItemCount(); i++ ) { strArryData = new String[tbl.getColumnCount()]; TableItem gi = tbl.getItem(i); for(int intCnt = 0; intCnt<tcs.length; intCnt++) { strArryData[intCnt] = Utils.convHtmlToLine(gi.getText(intCnt)); } listCsvData.add(strArryData); } try { String strCVSContent = CSVFileUtils.makeData(listCsvData); downloadExtFile(userDB.getDisplay_name() + "_TableInformation.csv", strCVSContent); //$NON-NLS-1$ MessageDialog.openInformation(null, CommonMessages.get().Information, Messages.get().TablesComposite_5); } catch (Exception e) { logger.error("Save CSV Data", e); //$NON-NLS-1$ } } /** * download external file * * @param fileName * @param newContents */ public void downloadExtFile(String fileName, String newContents) { downloadServiceHandler.setName(fileName); downloadServiceHandler.setByteContent(newContents.getBytes()); DownloadUtils.provideDownload(compositeTail, downloadServiceHandler.getId()); } /** Register a service handler */ private void registerServiceHandler() { downloadServiceHandler = new DownloadServiceHandler(); RWT.getServiceManager().registerServiceHandler(downloadServiceHandler.getId(), downloadServiceHandler); } public void dispose() { unregisterServiceHandler(); super.dispose(); }; } /** * mysql, mariadb label provider * @author hangum * */ class TableInformLabelProvider extends LabelProvider implements ITableLabelProvider { private UserDBDAO userDB; public TableInformLabelProvider(UserDBDAO userDB) { this.userDB = userDB; } @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object element, int columnIndex) { Map resultMap = (HashMap)element; if(DBGroupDefine.MYSQL_GROUP == userDB.getDBGroup()) { switch(columnIndex) { case 0: return ""+resultMap.get("TABLE_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ case 1: return ""+resultMap.get("ENGINE"); //$NON-NLS-1$ //$NON-NLS-2$ case 2: return NumberFormatUtils.commaFormat(""+resultMap.get("TABLE_ROWS")); //$NON-NLS-1$ //$NON-NLS-2$ case 3: return NumberFormatUtils.commaFormat(StringUtils.replace(""+resultMap.get("AUTO_INCREMENT"), "null", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ case 4: return ""+resultMap.get("TABLE_COLLATION"); //$NON-NLS-1$ //$NON-NLS-2$ case 5: return ""+resultMap.get("SIZEOFMB"); //$NON-NLS-1$ //$NON-NLS-2$ case 6: return ""+resultMap.get("CREATE_TIME"); //$NON-NLS-1$ //$NON-NLS-2$ case 7: return ""+resultMap.get("TABLE_COMMENT"); //$NON-NLS-1$ //$NON-NLS-2$ } } else if(DBGroupDefine.ORACLE_GROUP == userDB.getDBGroup()) { switch(columnIndex) { case 0 : return "" + resultMap.get("TABLE_NAME" ); //$NON-NLS-1$ //$NON-NLS-2$ case 1 : return "" + resultMap.get("TABLESPACE_NAME" ); //$NON-NLS-1$ //$NON-NLS-2$ case 2 : return NumberFormatUtils.commaFormat("" + resultMap.get("PCT_FREE" )); //$NON-NLS-1$ //$NON-NLS-2$ case 3 : return NumberFormatUtils.commaFormat("" + resultMap.get("INI_TRANS" )); //$NON-NLS-1$ //$NON-NLS-2$ case 4 : return "" + resultMap.get("LOGGING" ); //$NON-NLS-1$ //$NON-NLS-2$ case 5 : return NumberFormatUtils.commaFormat("" + resultMap.get("NUM_ROWS" )); //$NON-NLS-1$ //$NON-NLS-2$ case 6 : return NumberFormatUtils.commaFormat("" + resultMap.get("BLOCKS" )); //$NON-NLS-1$ //$NON-NLS-2$ case 7 : return NumberFormatUtils.commaFormat("" + resultMap.get("AVG_ROW_LEN" )); //$NON-NLS-1$ //$NON-NLS-2$ case 8 : return NumberFormatUtils.commaFormat("" + resultMap.get("DEGREE" )); //$NON-NLS-1$ //$NON-NLS-2$ case 9 : return NumberFormatUtils.commaFormat("" + resultMap.get("SAMPLE_SIZE" )); //$NON-NLS-1$ //$NON-NLS-2$ case 10: return "" + resultMap.get("LAST_ANALYZED" ); //$NON-NLS-1$ //$NON-NLS-2$ case 11: return "" + resultMap.get("PARTITIONED" ); //$NON-NLS-1$ //$NON-NLS-2$ case 12: return "" + resultMap.get("BUFFER_POOL" ); //$NON-NLS-1$ //$NON-NLS-2$ case 13: return "" + resultMap.get("ROW_MOVEMENT" ); //$NON-NLS-1$ //$NON-NLS-2$ case 14: return "" + resultMap.get("DURATION" ); //$NON-NLS-1$ //$NON-NLS-2$ case 15: return "" + resultMap.get("COMPRESSION" ); //$NON-NLS-1$ //$NON-NLS-2$ case 16: return "" + resultMap.get("DROPPED" ); //$NON-NLS-1$ //$NON-NLS-2$ case 17: return "" + resultMap.get("READ_ONLY" ); //$NON-NLS-1$ //$NON-NLS-2$ case 18: return "" + resultMap.get("TEMPORARY" ); //$NON-NLS-1$ //$NON-NLS-2$ case 19: return NumberFormatUtils.commaFormat("" + resultMap.get("MAX_EXTENTS" )); //$NON-NLS-1$ //$NON-NLS-2$ case 20: return "" + resultMap.get("IOT_TYPE" ); //$NON-NLS-1$ //$NON-NLS-2$ case 21: return NumberFormatUtils.commaFormat("" + resultMap.get("INITIAL_EXTENT" )); //$NON-NLS-1$ //$NON-NLS-2$ case 22: return NumberFormatUtils.commaFormat("" + resultMap.get("NEXT_EXTENT" )); //$NON-NLS-1$ //$NON-NLS-2$ case 23: return NumberFormatUtils.commaFormat("" + resultMap.get("MIN_EXTENTS" )); //$NON-NLS-1$ //$NON-NLS-2$ } } else if(DBGroupDefine.ALTIBASE_GROUP == userDB.getDBGroup()) { switch(columnIndex) { case 0: return ""+resultMap.get("TABLE_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ case 1: return ""+resultMap.get("OWNER"); //$NON-NLS-1$ //$NON-NLS-2$ case 2: return NumberFormatUtils.commaFormat(""+resultMap.get("TABLE_ROWS")); //$NON-NLS-1$ //$NON-NLS-2$ case 3: return NumberFormatUtils.commaFormat(StringUtils.replace(""+resultMap.get("TABLESPACE_NAME"), "null", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ case 4: return ""+resultMap.get("CHARACTER_SET"); //$NON-NLS-1$ //$NON-NLS-2$ case 5: return ""+resultMap.get("SIZEOFMB"); //$NON-NLS-1$ //$NON-NLS-2$ case 6: return ""+resultMap.get("CREATED"); //$NON-NLS-1$ //$NON-NLS-2$ case 7: return ""+resultMap.get("TABLE_COMMENT"); //$NON-NLS-1$ //$NON-NLS-2$ } } else { switch(columnIndex) { case 0: return ""+resultMap.get("name"); //$NON-NLS-1$ //$NON-NLS-2$ case 1: return StringUtils.replace(""+resultMap.get("comment"), "null", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ case 2: return "true".equals(""+resultMap.get("has_index")) ? "has" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ case 3: return "true".equals(""+resultMap.get("is_shared")) ? "has" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ case 4: return "true".equals(""+resultMap.get("has_pk")) ? "has" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ case 5: return "true".equals(""+resultMap.get("has_triggers")) ? "has" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ case 6: return "true".equals(""+resultMap.get("has_subclass")) ? "has" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ case 7: return "true".equals(""+resultMap.get("has_rules")) ? "has" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ case 8: return StringUtils.replace(""+resultMap.get("options"), "null", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } return "*** Invalid column index ***"; //$NON-NLS-1$ } } /** * name filter * * @author hangum * */ class TableInfoFilter extends ViewerFilter { String searchString; public void setSearchString(String s) { this.searchString = ".*" + s + ".*"; //$NON-NLS-1$ //$NON-NLS-2$ } @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if(searchString == null || searchString.length() == 0) { return true; } Map resultMap = (HashMap)element; String tbName = ""; //$NON-NLS-1$ if(resultMap.get("TABLE_NAME") != null) tbName = ""+resultMap.get("TABLE_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ else tbName = ""+resultMap.get("name"); //$NON-NLS-1$ //$NON-NLS-2$ if(tbName.matches(searchString)) return true; return false; } }