Skip to content

Commit

Permalink
fixed NPE when executing SQL / JPQL queries
Browse files Browse the repository at this point in the history
  • Loading branch information
Mario David committed Nov 26, 2017
1 parent 2e21171 commit 86eaebe
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import org.springframework.stereotype.Service
import javax.inject.Inject
import javax.sql.DataSource

@Service(SqlDiagnoseService.NAME)
class SqlDiagnoseServiceBean implements SqlDiagnoseService {
@Service(DatabaseDiagnoseService.NAME)
class DatabaseDiagnoseServiceBean implements DatabaseDiagnoseService {

@Inject
Persistence persistence
Expand All @@ -25,7 +25,7 @@ class SqlDiagnoseServiceBean implements SqlDiagnoseService {
SqlSelectResultFactory selectResultFactory

@Inject
SqlConsoleParser sqlConsoleParser
DatabaseQueryParser databaseQueryParser

@Inject
TimeSource timeSource
Expand All @@ -39,71 +39,61 @@ class SqlDiagnoseServiceBean implements SqlDiagnoseService {
@Inject
DiagnoseExecutionFactory diagnoseExecutionFactory

@Inject
JpqlConsoleParser jpqlConsoleParser

@Override
SqlSelectResult runSqlDiagnose(String queryString, DiagnoseType diagnoseType) {
Statements queryStatements = sqlConsoleParser.analyseSql(queryString)
// analyzeSql are gonna return null in some cases
DatabaseQueryResult runSqlDiagnose(String queryString, DiagnoseType diagnoseType) {
Statements queryStatements = databaseQueryParser.analyseQueryString(queryString, diagnoseType)

if (!statementsAvailable(queryStatements)) {
return selectResultFactory.createFromRows([])
}

if (DiagnoseType.JPQL == diagnoseType) {
jpqlConsoleParser.analyseJpql(queryString)
}

def queryStatement = queryStatements.statements[0].toString()
DiagnoseExecution diagnoseExecution = createAdHocDiagnose(queryStatement, diagnoseType)
executeAdHocDiagnose(diagnoseType, queryStatement, queryStatements, diagnoseExecution)
}

private void executeAdHocDiagnose(DiagnoseType diagnoseType, String queryStatement, Statements queryStatements, DiagnoseExecution diagnoseExecution) {
SqlSelectResult sqlSelectResult
DatabaseQueryResult databaseQueryResult
try {
sqlSelectResult = getQueryResult(diagnoseType, queryStatement, queryStatements)
diagnoseExecution.handleSuccessfulExecution(sqlSelectResult.entities[0].toString())
databaseQueryResult = getQueryResult(diagnoseType, queryStatement, queryStatements)
diagnoseExecution.handleSuccessfulExecution(databaseQueryResult.entities[0].toString())
diagnoseExecutionLogService.logDiagnoseExecution(diagnoseExecution)
} catch (Exception e) {
sqlSelectResult = selectResultFactory.createFromRows([])
databaseQueryResult = selectResultFactory.createFromRows([])
diagnoseExecution.handleErrorExecution(e)
diagnoseExecutionLogService.logDiagnoseExecution(diagnoseExecution)
}

sqlSelectResult
databaseQueryResult
}

protected SqlSelectResult getQueryResult(DiagnoseType diagnoseType, String queryStatement, Statements queryStatements) {
SqlSelectResult sqlSelectResult
protected DatabaseQueryResult getQueryResult(DiagnoseType diagnoseType, String queryStatement, Statements queryStatements) {
DatabaseQueryResult sqlSelectResult
switch (diagnoseType) {
case DiagnoseType.JPQL:
sqlSelectResult = executeJpqlStatement(queryStatement, queryStatements)
break
case DiagnoseType.SQL:
def sql = createSqlConnection(persistence.dataSource)
sqlSelectResult = executeStatement(sql, queryStatement)
sqlSelectResult = executeSqlStatement(sql, queryStatement)
break
default:
throw new IllegalArgumentException('DiagnoseType is not supported (' + diagnoseType + ')')
}
sqlSelectResult
}

protected SqlSelectResult executeJpqlStatement(String queryStatement, Statements queryStatements) {
protected DatabaseQueryResult executeJpqlStatement(String queryStatement, Statements queryStatements) {
persistence.callInTransaction {
Query q = persistence.entityManager.createQuery(queryStatement)

if (sqlConsoleParser.containsDataManipulation(queryStatements)) {
if (databaseQueryParser.containsDataManipulation(queryStatements)) {
q.executeUpdate()
new SqlSelectResult()
new DatabaseQueryResult()
} else {
selectResultFactory.createFromRows(q.resultList)
}
}
}

protected SqlSelectResult executeStatement(Sql sql, String queryString) {
protected DatabaseQueryResult executeSqlStatement(Sql sql, String queryString) {
def rows = sql.rows(queryString)
selectResultFactory.createFromRows(rows)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package de.diedavids.cuba.runtimediagnose.sql

import com.haulmont.cuba.core.global.AppBeans
import com.haulmont.cuba.core.global.Messages
import com.haulmont.cuba.core.global.QueryParserAstBased
import com.haulmont.cuba.core.sys.jpql.DomainModel
import com.haulmont.cuba.core.sys.jpql.DomainModelBuilder
import de.diedavids.cuba.runtimediagnose.RuntimeDiagnoseConfiguration
import de.diedavids.cuba.runtimediagnose.SqlConsoleSecurityException
import de.diedavids.cuba.runtimediagnose.diagnose.DiagnoseType
import net.sf.jsqlparser.parser.CCJSqlParserUtil
import net.sf.jsqlparser.statement.SetStatement
import net.sf.jsqlparser.statement.Statements
Expand All @@ -24,7 +29,7 @@ import org.springframework.stereotype.Component
import javax.inject.Inject

@Component
class SqlConsoleParser {
class DatabaseQueryParser {

@Inject
RuntimeDiagnoseConfiguration configuration
Expand All @@ -42,9 +47,9 @@ class SqlConsoleParser {
Drop, CreateTable, CreateView, Alter, AlterView, CreateIndex
]

Statements analyseSql(String sqlString) {
Statements analyseQueryString(String queryString, DiagnoseType diagnoseType) {

Statements statements = CCJSqlParserUtil.parseStatements(sqlString)
Statements statements = CCJSqlParserUtil.parseStatements(queryString)

if (!configuration.sqlAllowDataManipulation && containsDataManipulation(statements)) {
throw new SqlConsoleSecurityException(messages.getMessage(getClass(), 'dataManipulationNotAllowed'))
Expand All @@ -58,9 +63,27 @@ class SqlConsoleParser {
throw new SqlConsoleSecurityException(messages.getMessage(getClass(), 'executeOperationNotAllowed'))
}


if (DiagnoseType.JPQL == diagnoseType) {
analyseJpql(queryString)
}

statements
}

void analyseJpql(String queryString) {
QueryParserAstBased parser = new QueryParserAstBased(ScriptManagerUtilsHolder.domainModelInstance, queryString)
parser.queryPaths
}

private static class ScriptManagerUtilsHolder {
private static class ScriptManagerUtilLazyHolder {
public static final DomainModel DOMAIN_MODEL_INSTANCE = AppBeans.get(DomainModelBuilder).produce()
}
static DomainModel getDomainModelInstance() {
ScriptManagerUtilLazyHolder.DOMAIN_MODEL_INSTANCE
}
}
boolean containsDataManipulation(Statements statements) {
containsIllegalOperation(statements, DATA_MANIPULATION_OPERATIONS)
}
Expand Down

This file was deleted.

Loading

0 comments on commit 86eaebe

Please sign in to comment.