Refactor checked column specific SQL

This commit is contained in:
Elizabeth Engelman 2019-06-13 11:53:48 -05:00
parent adf91df23a
commit f292888195
3 changed files with 72 additions and 44 deletions

View File

@ -121,37 +121,47 @@ func GetCheckedColumnNames(db *postgres.DB) ([]string, error) {
return columnNames, nil
}
// Builds a SQL string that checks if any column value is 0, given the column names.
// Builds a SQL string that checks if any column should be checked/rechecked.
// Defaults to FALSE when no columns are provided.
// Ex: ["columnA", "columnB"] => "NOT (columnA!=0 AND columnB!=0)"
// [] => "FALSE"
func CreateNotCheckedSQL(boolColumns []string, recheckHeaders constants.TransformerExecution) string {
var result bytes.Buffer
func CreateHeaderCheckedPredicateSQL(boolColumns []string, recheckHeaders constants.TransformerExecution) string {
if len(boolColumns) == 0 {
return "FALSE"
}
result.WriteString("NOT (")
if recheckHeaders {
return createHeaderCheckedPredicateSQLForRecheckedHeaders(boolColumns)
} else {
return createHeaderCheckedPredicateSQLForMissingHeaders(boolColumns)
}
}
func createHeaderCheckedPredicateSQLForMissingHeaders(boolColumns []string) string {
var result bytes.Buffer
result.WriteString(" (")
// Loop excluding last column name
for _, column := range boolColumns[:len(boolColumns)-1] {
if recheckHeaders {
result.WriteString(fmt.Sprintf("%v>=%s AND ", column, constants.RecheckHeaderCap))
} else {
result.WriteString(fmt.Sprintf("%v!=0 AND ", column))
}
result.WriteString(fmt.Sprintf("%v=0 OR ", column))
}
// No trailing "OR" for the last column name
if recheckHeaders {
result.WriteString(fmt.Sprintf("%v>=%s)", boolColumns[len(boolColumns)-1], constants.RecheckHeaderCap))
} else {
result.WriteString(fmt.Sprintf("%v!=0)", boolColumns[len(boolColumns)-1]))
}
result.WriteString(fmt.Sprintf("%v=0)", boolColumns[len(boolColumns)-1]))
return result.String()
}
func createHeaderCheckedPredicateSQLForRecheckedHeaders(boolColumns []string) string {
var result bytes.Buffer
result.WriteString(" (")
// Loop excluding last column name
for _, column := range boolColumns[:len(boolColumns)-1] {
result.WriteString(fmt.Sprintf("%v<%s OR ", column, constants.RecheckHeaderCap))
}
// No trailing "OR" for the last column name
result.WriteString(fmt.Sprintf("%v<%s)", boolColumns[len(boolColumns)-1], constants.RecheckHeaderCap))
return result.String()
}

View File

@ -135,7 +135,7 @@ var _ = Describe("Repository", func() {
columnNames, err := shared.GetCheckedColumnNames(db)
Expect(err).NotTo(HaveOccurred())
notCheckedSQL = shared.CreateNotCheckedSQL(columnNames, constants.HeaderMissing)
notCheckedSQL = shared.CreateHeaderCheckedPredicateSQL(columnNames, constants.HeaderMissing)
startingBlockNumber = rand.Int63()
eventSpecificBlockNumber = startingBlockNumber + 1
@ -285,33 +285,51 @@ var _ = Describe("Repository", func() {
})
})
Describe("CreateNotCheckedSQL", func() {
It("generates a correct SQL string for one column", func() {
columns := []string{"columnA"}
expected := "NOT (columnA!=0)"
actual := shared.CreateNotCheckedSQL(columns, constants.HeaderMissing)
Expect(actual).To(Equal(expected))
Describe("CreateCustomColumnNamesSQL", func() {
Describe("for MissingHeaders", func() {
It("generates a correct SQL string for one column", func() {
columns := []string{"columnA"}
expected := " (columnA=0)"
actual := shared.CreateHeaderCheckedPredicateSQL(columns, constants.HeaderMissing)
Expect(actual).To(Equal(expected))
})
It("generates a correct SQL string for several columns", func() {
columns := []string{"columnA", "columnB"}
expected := " (columnA=0 OR columnB=0)"
actual := shared.CreateHeaderCheckedPredicateSQL(columns, constants.HeaderMissing)
Expect(actual).To(Equal(expected))
})
It("defaults to FALSE when there are no columns", func() {
expected := "FALSE"
actual := shared.CreateHeaderCheckedPredicateSQL([]string{}, constants.HeaderMissing)
Expect(actual).To(Equal(expected))
})
})
It("generates a correct SQL string for several columns", func() {
columns := []string{"columnA", "columnB"}
expected := "NOT (columnA!=0 AND columnB!=0)"
actual := shared.CreateNotCheckedSQL(columns, constants.HeaderMissing)
Expect(actual).To(Equal(expected))
Describe("RecheckHeadersCustomColumnNames", func() {
It("defaults to FALSE when there are no columns", func() {
expected := "FALSE"
actual := shared.CreateHeaderCheckedPredicateSQL([]string{}, constants.HeaderRecheck)
Expect(actual).To(Equal(expected))
})
It("generates a correct SQL string for rechecking headers for one column", func() {
columns := []string{"columnA"}
expected := fmt.Sprintf(" (columnA<%s)", constants.RecheckHeaderCap)
actual := shared.CreateHeaderCheckedPredicateSQL(columns, constants.HeaderRecheck)
Expect(actual).To(Equal(expected))
})
It("generates a correct SQL string for rechecking headers for several columns", func() {
columns := []string{"columnA", "columnB"}
expected := fmt.Sprintf(" (columnA<%s OR columnB<%s)", constants.RecheckHeaderCap, constants.RecheckHeaderCap)
actual := shared.CreateHeaderCheckedPredicateSQL(columns, constants.HeaderRecheck)
Expect(actual).To(Equal(expected))
})
})
It("defaults to FALSE when there are no columns", func() {
expected := "FALSE"
actual := shared.CreateNotCheckedSQL([]string{}, constants.HeaderMissing)
Expect(actual).To(Equal(expected))
})
It("generates a correct SQL string for rechecking headers", func() {
columns := []string{"columnA", "columnB"}
expected := fmt.Sprintf("NOT (columnA>=%s AND columnB>=%s)", constants.RecheckHeaderCap, constants.RecheckHeaderCap)
actual := shared.CreateNotCheckedSQL(columns, constants.HeaderRecheck)
Expect(actual).To(Equal(expected))
})
})
})

View File

@ -96,7 +96,7 @@ func (watcher *EventWatcher) Execute(recheckHeaders constants.TransformerExecuti
if err != nil {
return err
}
notCheckedSQL := repository.CreateNotCheckedSQL(checkedColumnNames, recheckHeaders)
notCheckedSQL := repository.CreateHeaderCheckedPredicateSQL(checkedColumnNames, recheckHeaders)
missingHeaders, err := repository.MissingHeaders(*watcher.StartingBlock, -1, watcher.DB, notCheckedSQL)
if err != nil {