Database console portlet

Warning !! This is not encourage to use in any production environment ! I created this for fun and tutorial.

Example, you can download source code or example here ~

Project setup

=========

1) First thing first, create a portlet project with maven command

2) Cd /web-db-console

3) mvn eclipse:eclipse -Dwtpversion=1.5

Create a 2 model/pojo class for database object, This object is used for obtain database properties from user.

DbProperties.java

public class DbProperties implements Serializable{

	private static final long serialVersionUID = 1L;
	private String dbDriver;
	private String dbUrl;
	private String dbUserID;
	private String dbPassword;
	private String sql;
	private String scretkey;

	public DbProperties() {}

	public String getDbDriver() {
		return dbDriver;
	}

	public void setDbDriver(String dbDriver) {
		this.dbDriver = dbDriver;
	}

	public String getDbUrl() {
		return dbUrl;
	}

	public void setDbUrl(String dbUrl) {
		this.dbUrl = dbUrl;
	}

	public String getDbUserID() {
		return dbUserID;
	}

	public void setDbUserID(String dbUserID) {
		this.dbUserID = dbUserID;
	}

	public String getDbPassword() {
		return dbPassword;
	}

	public void setDbPassword(String dbPassword) {
		this.dbPassword = dbPassword;
	}

	public String getSql() {
		return sql;
	}

	public void setSql(String sql) {
		this.sql = sql;
	}

	public String getScretkey() {
		return scretkey;
	}

	public void setScretkey(String scretkey) {
		this.scretkey = scretkey;
	}
}



Next, we create another object for store and rendering result from SQL query

TableResult.java

public class TableResult {

	private int numberOfColumns;
	private List columnLabel;
	private List columnResult;
	private List
> columnData;
	private String errorsCode;

	public TableResult() {}

	public int getNumberOfColumns() {
		return numberOfColumns;
	}

	public void setNumberOfColumns(int numberOfColumns) {
		this.numberOfColumns = numberOfColumns;
	}

	public List getColumnLabel() {
		return columnLabel;
	}

	public void setColumnLabel(List columnLabel) {
		this.columnLabel = columnLabel;
	}

	public List getColumnResult() {
		return columnResult;
	}

	public void setColumnResult(List columnResult) {
		this.columnResult = columnResult;
	}

	public String getErrorsCode() {
		return errorsCode;
	}

	public void setErrorsCode(String errorsCode) {
		this.errorsCode = errorsCode;
	}

	public List
> getColumnData() {
		return columnData;
	}

	public void setColumnData(List
> columnData) {
		this.columnData = columnData;
	}

}

Create controller to handle render phase and action phase

Query Controller

@Controller
@RequestMapping("VIEW")
public class QueryController {

	@Autowired
	private ConsoleValidator validator;

	@Autowired
	private ConsoleService service;

	@RenderMapping
	public String doView(RenderRequest request, RenderResponse response, ModelMap model)
	{
		return "view";
	}

	@RenderMapping(params = "action=queryResult")
	public String doViewResult(RenderRequest request, RenderResponse response, ModelMap model)
	{
		return "result";
	}

	@ModelAttribute("db")
	public DbProperties getCommandObject(){
		return new DbProperties();
	}

	@ActionMapping(params = "action=querySQL")
	public void runQuery(@ModelAttribute("db") DbProperties db,	BindingResult bindingResult,
			ActionRequest request, ActionResponse response, ModelMap modelMap)
	{
		if(db.getDbUrl().isEmpty())
			db.setDbUrl("jdbc:mysql://localhost/");

		if(db.getDbDriver().isEmpty())
			db.setDbDriver("org.gjt.mm.mysql.Driver");

		validator.validate(db, bindingResult);
		TableResult result = new TableResult();

		if (!bindingResult.hasErrors()) {
			Connection conn = null;
		    PreparedStatement stmt = null;
		    String sql = "";

		    try {
			      sql = db.getSql();
			      conn = (Connection) DriverManager.getConnection(db.getDbUrl(), db.getDbUserID() , db.getDbPassword());
			      stmt = (PreparedStatement) conn.prepareStatement(sql);
			      String tmp_SQL = sql.toUpperCase().trim();

		          boolean canExec = true;

		          if (tmp_SQL.startsWith("UPDATE") || tmp_SQL.startsWith("DELETE") || tmp_SQL.startsWith("ALTER")
		          	  ||  tmp_SQL.startsWith("DUMP") || tmp_SQL.startsWith("DROP"))
		          {
			          if (db.getScretkey().isEmpty() || !db.getScretkey().equalsIgnoreCase("letmego"))
			          	canExec = false;
		          }		          

		          if (canExec)
		          {
			          if (tmp_SQL.startsWith("INSERT") || tmp_SQL.startsWith("UPDATE") || tmp_SQL.startsWith("DELETE") ||
			              tmp_SQL.startsWith("ALTER") || tmp_SQL.startsWith("CREATE") || tmp_SQL.startsWith("DUMP") ||
			              tmp_SQL.startsWith("DROP")) {

			             int updateCount = stmt.executeUpdate();
			             modelMap.put("count", updateCount);
			          } else {
			             service.executeQuery(result, stmt);
			          }
			  	  } //end if can Exec		  	  

		      } catch (Exception e) {
		    	  result.setErrorsCode(e.toString());		          

		      } finally {
		          try {
		              if (stmt != null) stmt.close();
		              if (conn != null) conn.close();
		          } catch (Exception e) {

		          }
		      }
		    modelMap.put("showResult", true);
		} else {
			modelMap.put("showResult", false);
		}
		modelMap.put("result", result);
		response.setRenderParameter("action", "");
	}

}



Next, service and implementation

ConsoleService.java & ConsoleServiceImpl


public interface ConsoleService {
	public void executeQuery(TableResult result, PreparedStatement stmt) throws Exception;
}

@Service
public class ConsoleServiceImpl implements ConsoleService {

	public void executeQuery(TableResult result, PreparedStatement stmt) throws Exception {

		   ResultSet rs = null;
		   ResultSetMetaData meta = null;

		   try {
				rs = stmt.executeQuery();
				meta = rs.getMetaData();
				int numberOfColumns = meta.getColumnCount();

				// get record count
				rs.last();
				int numberOfRows = rs.getRow();
				result.setNumberOfColumns(numberOfColumns);
				rs.beforeFirst();

				// print out column name
				List labels = new ArrayList();
				for (int i=1; i<=numberOfColumns; i++) {
					labels.add(meta.getColumnLabel(i));
				}
				result.setColumnLabel(labels);
				// print out query result
				String columnData = "";

				List
> cols = new ArrayList
>();
				while (rs.next()) {
					List list = new ArrayList();
					for (int i=1; i<=numberOfColumns; i++) {
						columnData = printData(result, rs, i);
						list.add(columnData);
					}
					cols.add(list);
				}
				result.setColumnData(cols);
		    } finally {
				if (rs != null) rs.close();
					rs = null; meta = null;
			}
	}

	private String printData(TableResult result, ResultSet rs, int idx) throws Exception {
		String value = "";
		switch (rs.getMetaData().getColumnType(idx)) {

			case Types.CHAR : case Types.VARCHAR : case Types.LONGVARCHAR : {
				if(rs.getString(idx)!=null)
					value = rs.getString(idx);
				break;
			}

			case Types.DECIMAL :case Types.DOUBLE : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getDouble(idx));
				break;
			}

			case Types.FLOAT : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getFloat(idx));
				break;
			}

			case Types.BIGINT: case Types.INTEGER: case Types.SMALLINT:
			case Types.TINYINT : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getInt(idx));
				break;
			}

			case Types.DATE : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getDate(idx));
				break;
			}

			case Types.TIME : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getTime(idx));
				break;
			}

			case Types.TIMESTAMP : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getTimestamp(idx));
				break;
			}

			case Types.JAVA_OBJECT : case Types.OTHER : case Types.BINARY :
			case Types.LONGVARBINARY : {
				value = "[Java Object]";
				break;
			}

			case Types.CLOB : case Types.BLOB : {
				if(rs.getString(idx)==null)
					value = "";
				else
					value = String.valueOf(rs.getBlob(idx));
				break;
			}

			default : value = rs.getMetaData().getColumnTypeName(idx);
		}
		return value;
	}

}



Dont forget the validator !

ConsoleValidator.java

@Component
public class ConsoleValidator implements Validator {

	public boolean supports(Class clazz) {
		return DbProperties.class.isAssignableFrom(clazz);
	}

	public void validate(Object target, Errors errors)
	{
		DbProperties db = (DbProperties) target;

		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "dbDriver", "Driver Error");

		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "dbUrl", "Url Error");

		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "dbUserID", "No username");

		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "dbPassword", "Password required");

		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "sql", "Query required");
	}
}


Done

You can leave a response, or trackback from your own site.

2 Responses to “Database console portlet”

  1. Proficient blog! I’ll probably be citing some of this info in my next assignment.

  2. buy used books says:

    Marvelous blog! I’ll probably be referencing some of this info in my next speech.

Leave a Reply

Security Code: