From 633a4af44506a7ba293384b4aabb7d7824290507 Mon Sep 17 00:00:00 2001 From: tkc Date: Sat, 10 Oct 2020 23:01:57 +0900 Subject: [PATCH] Add null value report --- src/domain/model/model.go | 7 ++ src/usecase/presenter/report.go | 3 + src/usecase/services/analyzer_service.go | 101 ++++++++++----------- src/usecase/services/validation_service.go | 23 +++-- 4 files changed, 75 insertions(+), 59 deletions(-) diff --git a/src/domain/model/model.go b/src/domain/model/model.go index d834044..ab89893 100644 --- a/src/domain/model/model.go +++ b/src/domain/model/model.go @@ -64,6 +64,9 @@ func (v ValidatorNode) HasError() bool { if v.HasInsertColumnsError() { return true } + if v.HasNullValueOperationError() { + return true + } return false } @@ -94,6 +97,10 @@ func (v ValidatorNode) HasInsertColumnsError() bool { return false } +func (v ValidatorNode) HasNullValueOperationError() bool { + return len(v.NullValueOperation) > 0 +} + type Report struct { Analyzer Analyzer ValidatorNode *ValidatorNode diff --git a/src/usecase/presenter/report.go b/src/usecase/presenter/report.go index ee7a910..84d1ea5 100644 --- a/src/usecase/presenter/report.go +++ b/src/usecase/presenter/report.go @@ -59,6 +59,9 @@ func (p reportPresenter) Show(reports []model.Report) { if len(report.ValidatorNode.NullValueOperation) > 0 { color.Magenta("NullValueOperation") + for _, notNullColumn := range report.ValidatorNode.NullValueOperation { + color.White(notNullColumn.Column) + } } } } diff --git a/src/usecase/services/analyzer_service.go b/src/usecase/services/analyzer_service.go index 3d85a37..afae8ff 100644 --- a/src/usecase/services/analyzer_service.go +++ b/src/usecase/services/analyzer_service.go @@ -35,42 +35,41 @@ type Visitor struct { Analyzer model.Analyzer } -//func checkNilValue(in ast.Node, analyzer *model.Analyzer) { -// if patternInExpr, ok := in.(*ast.PatternInExpr); ok { -// if valueExpr, ok := patternInExpr.List[0].(*test_driver.ValueExpr); ok { -// if valueExpr.Datum.GetValue() == nil { -// var nullValueOperation model.AnalyzerNullValueOperation -// nullValueOperation.TableName = analyzer.TableName -// nullValueOperation.Value = valueExpr.Datum.GetValue() -// nullValueOperation.Type = model.OpTypeIn -// if columnNameExpr, ok := patternInExpr.Expr.(*ast.ColumnNameExpr); ok { -// nullValueOperation.Column = columnNameExpr.Name.String() -// } -// analyzer.NullValueOperation = append(analyzer.NullValueOperation, nullValueOperation) -// } -// } -// } -// -// if binaryOperationExpr, ok := in.(*ast.BinaryOperationExpr); ok { -// if binaryOperationExpr.Op.String() == string(model.OpTypeEq) { -// if valueExpr, ok := binaryOperationExpr.R.(*test_driver.ValueExpr); ok { -// if valueExpr.Datum.GetValue() == nil { -// var nullValueOperation model.AnalyzerNullValueOperation -// nullValueOperation.TableName = analyzer.TableName -// nullValueOperation.Value = valueExpr.Datum.GetValue() -// nullValueOperation.Type = model.OpTypeEq -// if columnNameExpr, ok := binaryOperationExpr.R.(*ast.ColumnNameExpr); ok { -// nullValueOperation.Column = columnNameExpr.Name.String() -// } -// analyzer.NullValueOperation = append(analyzer.NullValueOperation, nullValueOperation) -// } -// } -// } -// } -//} +func (v *Visitor) checkNilValue(in ast.Node) { + //if patternInExpr, ok := in.(*ast.PatternInExpr); ok { + // if valueExpr, ok := patternInExpr.List[0].(*test_driver.ValueExpr); ok { + // if valueExpr.Datum.GetValue() == nil { + // var nullValueOperation model.AnalyzerNullValueOperation + // nullValueOperation.TableName = v.Analyzer.TableName + // nullValueOperation.Value = valueExpr.Datum.GetValue() + // nullValueOperation.Type = model.OpTypeIn + // if columnNameExpr, ok := patternInExpr.Expr.(*ast.ColumnNameExpr); ok { + // nullValueOperation.Column = columnNameExpr.Name.String() + // } + // v.Analyzer.NullValueOperation = append(v.Analyzer.NullValueOperation, nullValueOperation) + // } + // } + //} -func (v *Visitor) Enter(in ast.Node) (ast.Node, bool) { - // TableName + if binaryOperationExpr, ok := in.(*ast.BinaryOperationExpr); ok { + if binaryOperationExpr.Op.String() == string(model.OpTypeEq) { + if valueExpr, ok := binaryOperationExpr.R.(*test_driver.ValueExpr); ok { + if valueExpr.Datum.GetValue() == nil { + var nullValueOperation model.AnalyzerNullValueOperation + nullValueOperation.TableName = v.Analyzer.TableName + nullValueOperation.Value = valueExpr.Datum.GetValue() + nullValueOperation.Type = model.OpTypeEq + if columnNameExpr, ok := binaryOperationExpr.R.(*ast.ColumnNameExpr); ok { + nullValueOperation.Column = columnNameExpr.Name.String() + } + v.Analyzer.NullValueOperation = append(v.Analyzer.NullValueOperation, nullValueOperation) + } + } + } + } +} + +func (v *Visitor) tableName(in ast.Node) { if TableSource, ok := in.(*ast.TableSource); ok { if len(v.Analyzer.TableName) == 0 { if tableName, ok := TableSource.Source.(*ast.TableName); ok { @@ -83,9 +82,9 @@ func (v *Visitor) Enter(in ast.Node) (ast.Node, bool) { } } } +} - //checkNilValue(in, &v.Analyzer) - +func (v *Visitor) stmtType(in ast.Node) { if insertStmt, ok := in.(*ast.InsertStmt); ok { // TODO : sub query if len(v.Analyzer.StmtType) == 0 { @@ -95,29 +94,27 @@ func (v *Visitor) Enter(in ast.Node) (ast.Node, bool) { } } } - if _, ok := in.(*ast.SelectStmt); ok { // TODO : sub query if len(v.Analyzer.StmtType) == 0 { v.Analyzer.StmtType = model.StmtTypeSelect } } - if _, ok := in.(*ast.UpdateStmt); ok { // TODO : sub query if len(v.Analyzer.StmtType) == 0 { v.Analyzer.StmtType = model.StmtTypeUpdate } } - if _, ok := in.(*ast.DeleteStmt); ok { // TODO : sub query if len(v.Analyzer.StmtType) == 0 { v.Analyzer.StmtType = model.StmtTypeDelete } } +} - // IsNullExpr +func (v *Visitor) isNullExpr(in ast.Node) { if isNullExpr, ok := in.(*ast.IsNullExpr); ok { if columnNameExpr, ok := isNullExpr.Expr.(*ast.ColumnNameExpr); ok { v.Analyzer.NotNullColumns = append( @@ -125,49 +122,51 @@ func (v *Visitor) Enter(in ast.Node) (ast.Node, bool) { formatColumnName(columnNameExpr.Name.String(), v.Analyzer.TableName)) } } +} - // patternInExpr +func (v *Visitor) patternInExpr(in ast.Node) { if patternInExpr, ok := in.(*ast.PatternInExpr); ok { var operation model.AnalyzerOperation operation.Type = model.OpTypeIn - if columnNameExpr, ok := patternInExpr.Expr.(*ast.ColumnNameExpr); ok { operation.Column = formatColumnName(columnNameExpr.Name.String(), v.Analyzer.TableName) } - if valueExpr, ok := patternInExpr.List[0].(*test_driver.ValueExpr); ok { operation.Value = valueExpr.Datum.GetInt64() } - //if columnNameExpr, ok := patternInExpr.List[0].(*ast.ColumnNameExpr); ok { //operation.Value = columnNameExpr..GetInt64() //} - v.Analyzer.Operations = append(v.Analyzer.Operations, operation) } +} - // BinaryOperationExpr +func (v *Visitor) binaryOperationExpr(in ast.Node) { if binaryOperationExpr, ok := in.(*ast.BinaryOperationExpr); ok { if binaryOperationExpr.Op.String() == string(model.OpTypeEq) { var operation model.AnalyzerOperation operation.Type = model.OpType(binaryOperationExpr.Op.String()) - if columnNameExpr, ok := binaryOperationExpr.L.(*ast.ColumnNameExpr); ok { operation.Column = formatColumnName(columnNameExpr.Name.String(), v.Analyzer.TableName) } - if valueExpr, ok := binaryOperationExpr.R.(*test_driver.ValueExpr); ok { operation.Value = valueExpr.Datum.GetValue() } - if columnNameExpr, ok := binaryOperationExpr.R.(*ast.ColumnNameExpr); ok { operation.Value = columnNameExpr.Name.String() } - v.Analyzer.Operations = append(v.Analyzer.Operations, operation) } } +} +func (v *Visitor) Enter(in ast.Node) (ast.Node, bool) { + v.tableName(in) + v.stmtType(in) + v.isNullExpr(in) + v.patternInExpr(in) + v.binaryOperationExpr(in) + v.checkNilValue(in) return in, false } diff --git a/src/usecase/services/validation_service.go b/src/usecase/services/validation_service.go index 518e541..6f64e92 100644 --- a/src/usecase/services/validation_service.go +++ b/src/usecase/services/validation_service.go @@ -7,8 +7,7 @@ import ( const errorMessageNullColumn = "fail null column check : " const errorMessageInsertColumn = "fail insert column check :" const errorMessageOperation = "fail operations check : " - -//const errorMessageNilValueOperation = "fail nil value check : " +const errorMessageNilValueOperation = "fail nil value check : " type validateService struct{} @@ -30,25 +29,26 @@ func (v validateService) Validates(analyzers []model.Analyzer, validator model.V return reports } -func validate(analyzer model.Analyzer, node *model.ValidatorNode, ignores []string) *model.Report { +func isIgnoreTable(analyzer model.Analyzer, node *model.ValidatorNode, ignores []string) bool { for _, ignore := range ignores { if analyzer.SQL == ignore { - return nil + return true } } - if analyzer.TableName != node.TableName { - return nil + return true } - stmtTypeMatch := false for _, stmtTypes := range node.StmtTypePattern { if analyzer.StmtType == stmtTypes { stmtTypeMatch = true } } + return !stmtTypeMatch +} - if !stmtTypeMatch { +func validate(analyzer model.Analyzer, node *model.ValidatorNode, ignores []string) *model.Report { + if isIgnoreTable(analyzer, node, ignores) { return nil } @@ -94,6 +94,13 @@ func validate(analyzer model.Analyzer, node *model.ValidatorNode, ignores []stri } } + if len(analyzer.NullValueOperation) > 0 { + node.NullValueOperation = analyzer.NullValueOperation + for _, analyzerOperation := range analyzer.NullValueOperation { + node.Messages = append(node.Messages, errorMessageNilValueOperation+analyzerOperation.Column) + } + } + if node.HasError() { return &model.Report{ Analyzer: analyzer,