IDEMPIERE-5451 Create a form SQL Query - similar to SQL process to execute queries (FHCA-3849) (#1533)

* IDEMPIERE-5451 Create a form SQL Query - similar to SQL process to execute queries (FHCA-3849)

* - fix wrong default in SysConfig
* - remove unnecessary annotation
* - process the query in a read-only transaction
* - commit not needed since this is readonly
This commit is contained in:
Carlos Ruiz 2022-10-20 15:37:28 +02:00 committed by GitHub
parent 9b46986596
commit 67c9cb7abc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 503 additions and 2 deletions

View File

@ -0,0 +1,82 @@
-- IDEMPIERE-5451 Create a form SQL Query - similar to SQL process to execute queries (FHCA-3849)
SELECT register_migration_script('202210131930_IDEMPIERE-5451.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Oct 13, 2022, 7:30:19 PM CEST
INSERT INTO AD_Form (AD_Form_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,Help,Classname,AccessLevel,EntityType,IsBetaFunctionality,AD_Form_UU) VALUES (200018,0,0,'Y',TO_TIMESTAMP('2022-10-13 19:30:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-13 19:30:19','YYYY-MM-DD HH24:MI:SS'),100,'SQL Process','Process SQL Queries','Process SQL Queries','org.adempiere.webui.apps.form.WSQLQuery','4','D','N','c14e305d-8d88-4ee5-9cf6-b2e5ce1213b6')
;
-- Oct 13, 2022, 7:30:35 PM CEST
UPDATE AD_Form SET Name='SQL Query',Updated=TO_TIMESTAMP('2022-10-13 19:30:35','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Form_ID=200018
;
-- Oct 13, 2022, 7:31:00 PM CEST
INSERT INTO AD_Menu (AD_Menu_ID,Name,Description,Action,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSummary,IsSOTrx,AD_Form_ID,IsReadOnly,EntityType,IsCentrallyMaintained,AD_Menu_UU) VALUES (200218,'SQL Query','Process SQL Queries','X',0,0,'Y',TO_TIMESTAMP('2022-10-13 19:31:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-13 19:31:00','YYYY-MM-DD HH24:MI:SS'),100,'N','N',200018,'N','D','Y','08ed5ba3-ade5-41af-8abc-a10066e072e3')
;
-- Oct 13, 2022, 7:31:00 PM CEST
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNodeMM_UU) SELECT t.AD_Client_ID, 0, 'Y', getDate(), 100, getDate(), 100,t.AD_Tree_ID, 200218, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200218)
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=12,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200218
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=13,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=289
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=14,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=302
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=15,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200168
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=16,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200169
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=17,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=303
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=18,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200047
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=19,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200048
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=20,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=321
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=21,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=461
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=22,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=53193
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=23,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200161
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=24,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=53322
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=25,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=383
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=26,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200177
;

View File

@ -0,0 +1,79 @@
-- IDEMPIERE-5451 Create a form SQL Query - similar to SQL process to execute queries (FHCA-3849)
SELECT register_migration_script('202210131930_IDEMPIERE-5451.sql') FROM dual;
-- Oct 13, 2022, 7:30:19 PM CEST
INSERT INTO AD_Form (AD_Form_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,Help,Classname,AccessLevel,EntityType,IsBetaFunctionality,AD_Form_UU) VALUES (200018,0,0,'Y',TO_TIMESTAMP('2022-10-13 19:30:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-13 19:30:19','YYYY-MM-DD HH24:MI:SS'),100,'SQL Process','Process SQL Queries','Process SQL Queries','org.adempiere.webui.apps.form.WSQLQuery','4','D','N','c14e305d-8d88-4ee5-9cf6-b2e5ce1213b6')
;
-- Oct 13, 2022, 7:30:35 PM CEST
UPDATE AD_Form SET Name='SQL Query',Updated=TO_TIMESTAMP('2022-10-13 19:30:35','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Form_ID=200018
;
-- Oct 13, 2022, 7:31:00 PM CEST
INSERT INTO AD_Menu (AD_Menu_ID,Name,Description,"action",AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSummary,IsSOTrx,AD_Form_ID,IsReadOnly,EntityType,IsCentrallyMaintained,AD_Menu_UU) VALUES (200218,'SQL Query','Process SQL Queries','X',0,0,'Y',TO_TIMESTAMP('2022-10-13 19:31:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-10-13 19:31:00','YYYY-MM-DD HH24:MI:SS'),100,'N','N',200018,'N','D','Y','08ed5ba3-ade5-41af-8abc-a10066e072e3')
;
-- Oct 13, 2022, 7:31:00 PM CEST
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNodeMM_UU) SELECT t.AD_Client_ID, 0, 'Y', statement_timestamp(), 100, statement_timestamp(), 100,t.AD_Tree_ID, 200218, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200218)
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=12,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200218
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=13,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=289
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=14,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=302
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=15,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200168
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=16,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200169
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=17,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=303
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=18,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200047
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=19,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200048
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=20,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=321
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=21,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=461
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=22,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=53193
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=23,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200161
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=24,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=53322
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=25,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=383
;
-- Oct 13, 2022, 7:31:15 PM CEST
UPDATE AD_TreeNodeMM SET Parent_ID=155, SeqNo=26,Updated=TO_TIMESTAMP('2022-10-13 19:31:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200177
;

View File

@ -44,7 +44,7 @@ public class MSysConfig extends X_AD_SysConfig
/**
*
*/
private static final long serialVersionUID = 9018760438155531804L;
private static final long serialVersionUID = -1225938049955333281L;
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
public static final String ALERT_SEND_ATTACHMENT_AS_XLS = "ALERT_SEND_ATTACHMENT_AS_XLS";
@ -103,6 +103,10 @@ public class MSysConfig extends X_AD_SysConfig
public static final String FEEDBACK_EMAIL_CC = "FEEDBACK_EMAIL_CC";
public static final String FEEDBACK_EMAIL_TO = "FEEDBACK_EMAIL_TO";
public static final String FORM_SQL_PROCESS_ALLOWED_KEYWORDS = "FORM_SQL_PROCESS_ALLOWED_KEYWORDS";
public static final String FORM_SQL_QUERY_ALLOWED_KEYWORDS = "FORM_SQL_QUERY_ALLOWED_KEYWORDS";
public static final String FORM_SQL_QUERY_LOG_ISSUE = "FORM_SQL_QUERY_LOG_ISSUE";
public static final String FORM_SQL_QUERY_MAX_RECORDS = "FORM_SQL_QUERY_MAX_RECORDS";
public static final String FORM_SQL_QUERY_TIMEOUT_IN_SECONDS = "FORM_SQL_QUERY_TIMEOUT_IN_SECONDS";
public static final String GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS = "GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS";
public static final String HTML_REPORT_MINIFY = "HTML_REPORT_MINIFY";
public static final String HTML_REPORT_THEME = "HTML_REPORT_THEME";

View File

@ -67,6 +67,7 @@ public class SystemIDs
public final static int FORM_ADD_AUTHORIZATION = 200016;
public final static int FORM_MFA_REGISTER = 200017;
public final static int FORM_SQL_PROCESS = 111;
public final static int FORM_SQL_QUERY = 200018;
public final static int MENU_NOTICE = 233;

View File

@ -0,0 +1,335 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Carlos Ruiz - globalqss - bxservice *
**********************************************************************/
package org.adempiere.webui.apps.form;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.adempiere.exceptions.DBException;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.ListModelTable;
import org.adempiere.webui.component.Textbox;
import org.adempiere.webui.component.WListItemRenderer;
import org.adempiere.webui.component.WListbox;
import org.adempiere.webui.panel.ADForm;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.MIssue;
import org.compiere.model.MSysConfig;
import org.compiere.model.SystemIDs;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Div;
import org.zkoss.zul.Frozen;
import org.zkoss.zul.North;
import org.zkoss.zul.South;
/**
* A Custom Form to process SQL queries.
*
* The statement to be executed can be restricted using SysConfig
*/
public class WSQLQuery extends ADForm implements EventListener<Event>
{
/**
*
*/
private static final long serialVersionUID = -6641250848300700313L;
/** Log. */
private static final CLogger log = CLogger.getCLogger(WSQLQuery.class);
/** Grid used to layout components. */
private Borderlayout layout = new Borderlayout();
/** SQL label. */
private Label m_lblSql = new Label("SQL");
/** SQL statement field. */
private Textbox m_txbSqlField = new Textbox();
/** Process button. */
private Button m_btnSql = createProcessButton();
/** Field to hold result of SQL statement execution. */
private Textbox m_txbResultField = new Textbox();
/** Grid to show the result data. */
private ListModelTable model = null;
private WListbox listbox = new WListbox();
/**
* REGEX_REMOVE_COMMENTS
*/
private static final String REGEX_REMOVE_COMMENTS = "/\\*(?:.|[\\n\\r])*?\\*/";
/**
* REGEX_REMOVE_QUOTED_STRINGS
*/
private static final String REGEX_REMOVE_QUOTED_STRINGS = "'(?:.|[\\n\\r])*?'";
/**
* REGEX_REMOVE_LEADING_SPACES
*/
private static final String REGEX_REMOVE_LEADING_SPACES = "^\\s+";
/**
* Default constructor.
*/
public WSQLQuery() {
super();
}
@Override
protected void initForm() {
North north = new North();
Center center = new Center();
South south = new South();
final int maxStatementLength = 10000;
final int noStatementRows = 3;
final int noResultRows = 2;
ZKUpdateUtil.setWidth(layout, "100%");
ZKUpdateUtil.setHeight(layout, "100%");
layout.setStyle("background-color: transparent; position: relative;");
Div div = new Div();
// create the top row of components
m_txbSqlField.setMultiline(true);
m_txbSqlField.setMaxlength(maxStatementLength);
m_txbSqlField.setRows(noStatementRows);
ZKUpdateUtil.setHflex(m_txbSqlField, "1");
m_txbSqlField.setReadonly(false);
m_btnSql.addEventListener(Events.ON_CLICK, this);
div.appendChild(m_lblSql);
div.appendChild(m_txbSqlField);
div.appendChild(m_btnSql);
north.appendChild(div);
layout.appendChild(north);
// create the bottom row of components
m_txbResultField.setRows(noResultRows);
ZKUpdateUtil.setHflex(m_txbResultField, "1");
m_txbResultField.setReadonly(true);
center.appendChild(listbox);
ZKUpdateUtil.setVflex(listbox, "1");
ZKUpdateUtil.setHflex(listbox, "1");
layout.appendChild(center);
south.appendChild(m_txbResultField);
layout.appendChild(south);
this.appendChild(layout);
return;
}
/**
* Create Process Button.
* @return button
*/
public static final Button createProcessButton() {
Button btnProcess = new Button();
if(ThemeManager.isUseFontIconForImage())
btnProcess.setIconSclass("z-icon-Process");
else
btnProcess.setImage(ThemeManager.getThemeResource("images/Process24.png"));
btnProcess.setName(Msg.getMsg(Env.getCtx(), "Process"));
return btnProcess;
} // createProcessButton
/**
* Process SQL Statements.
*
* @param sqlStatement a single SQL statement
* @param allowDML whether to allow DML statements
* @return a string summarizing the results
*/
public String processStatement (String sqlStatement) {
m_txbResultField.setText(null);
listbox.clear();
if (sqlStatement == null || sqlStatement.length() == 0)
return "";
StringBuilder sb = new StringBuilder();
char[] chars = sqlStatement.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (Character.isWhitespace(c))
sb.append(' ');
else
sb.append(c);
}
String sql = sb.toString().trim();
if (sql.length() == 0)
return "";
//
StringBuilder result = new StringBuilder();
String SQL = sql.toUpperCase();
String cleanSQL = SQL
.replaceAll(REGEX_REMOVE_COMMENTS, "")
.replaceAll(REGEX_REMOVE_QUOTED_STRINGS, "")
.replaceFirst(REGEX_REMOVE_LEADING_SPACES, "");
if (cleanSQL.contains(";")) {
result.append("ERROR: Multiple Commands Not Allowed");
return result.toString();
}
int timeout = MSysConfig.getIntValue(MSysConfig.FORM_SQL_QUERY_TIMEOUT_IN_SECONDS, 120);
int maxRecords = MSysConfig.getIntValue(MSysConfig.FORM_SQL_QUERY_MAX_RECORDS, 500);
String[] allowedKeywords = MSysConfig.getValue(MSysConfig.FORM_SQL_QUERY_ALLOWED_KEYWORDS, "SELECT ,WITH ,SHOW ").split(",");
boolean isError = true;
for (int i = 0; i < allowedKeywords.length; i++) {
if (cleanSQL.startsWith(allowedKeywords[i])) {
isError = false;
break;
}
}
if (isError) {
result.append("ERROR: Not Allowed Command");
return result.toString();
}
List<String> header = new ArrayList<String>();
header.add("#");
model = new ListModelTable();
Frozen frozen = new Frozen();
frozen.setColumns(1);
listbox.appendChild(frozen);
Trx trx = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
long start = System.currentTimeMillis();
String trxName = Trx.createTrxName("WSQLQuery");
trx = Trx.get(trxName, false);
trx.setDisplayName(getClass().getName()+"_processStatement");
trx.getConnection().setReadOnly(true);
pstmt = DB.prepareNormalReadReplicaStatement(sql, trxName);
pstmt.setQueryTimeout(timeout);
rs = pstmt.executeQuery();
ResultSetMetaData meta = rs.getMetaData();
int count = 0;
for (int col = 1; col <= meta.getColumnCount(); col++) {
String columnName = meta.getColumnLabel(col);
header.add(columnName);
}
while (rs.next ()) {
if (count >= maxRecords) {
result.append("Maximum of " + maxRecords + " records reached. ");
break;
}
List<Object> row = new ArrayList<Object>();
row.add(++count);
for (int col = 1; col <= meta.getColumnCount(); col++) {
String colName = header.get(col).toLowerCase();
if (rs.getObject(col) instanceof BigDecimal
&& (colName.endsWith("_id") || colName.equals("createdby") || colName.equals("updatedby")))
row.add(rs.getInt(col));
else
row.add(rs.getObject(col));
} // for all columns
model.add(row);
}
long end = System.currentTimeMillis();
BigDecimal durationSeconds = BigDecimal.valueOf(end).subtract(BigDecimal.valueOf(start)).divide(BigDecimal.valueOf(1000.0));
result.append("Count = ").append(count);
if (MSysConfig.getBooleanValue(MSysConfig.FORM_SQL_QUERY_LOG_ISSUE, true)) {
MIssue issue = new MIssue(Env.getCtx(), 0, null);
issue.setIssueSummary("SQL executed on SQL Query form");
issue.setStackTrace(sql);
issue.setResponseText(result.toString());
issue.setIssueSource(MIssue.ISSUESOURCE_Form);
issue.setUserName(Env.getContext(Env.getCtx(), Env.AD_USER_NAME));
issue.setAD_Form_ID(SystemIDs.FORM_SQL_QUERY);
issue.setProcessed(true);
issue.setComments("Duration : " + durationSeconds + " seconds");
issue.saveEx();
}
// Show the result in WListbox
WListItemRenderer renderer = new WListItemRenderer(header);
model.setNoColumns(header.size());
listbox.setModel(model);
listbox.setItemRenderer(renderer);
listbox.initialiseHeader();
listbox.setSizedByContent(true);
} catch (Exception e) {
if (trx != null) {
trx.rollback();
}
if (DBException.isTimeout(e)) {
result.append("Maximum of " + timeout + " seconds reached, query cancelled.");
} else {
e.printStackTrace();
String exception = e.toString();
log.log(Level.SEVERE, "process statement: " + sql + " - " + exception);
result.append("Exception => ").append(exception);
}
} finally {
DB.close(rs, pstmt);
rs = null; pstmt = null;
if (trx != null) {
trx.close();
trx = null;
}
}
return result.toString();
}
/**
* Process the events for this form
* @param event
*/
public void onEvent(Event event) throws Exception {
if (event.getTarget() == m_btnSql)
m_txbResultField.setText(processStatement(m_txbSqlField.getText()));
super.onEvent(event);
}
}