aws.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package cloudutil
  2. import (
  3. "fmt"
  4. "strings"
  5. "unicode"
  6. "github.com/kubecost/cost-model/pkg/log"
  7. )
  8. // ConvertToGlueColumnFormat takes a string and runs through various regex
  9. // and string replacement statements to convert it to a format compatible
  10. // with AWS Glue and Athena column names.
  11. // Following guidance from AWS provided here ('Column Names' section):
  12. // https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/run-athena-sql.html
  13. // It returns a string containing the column name in proper column name format and length.
  14. func ConvertToGlueColumnFormat(columnName string) string {
  15. fmt.Printf("Calling convert on %s: ", columnName)
  16. var sb strings.Builder
  17. var prev rune
  18. for i, r := range columnName {
  19. if unicode.IsUpper(r) && prev != '_' && i != 0 {
  20. sb.WriteRune('_')
  21. }
  22. if !unicode.IsLetter(r) && !unicode.IsNumber(r) {
  23. if prev != '_' && i != 0 && i != (len(columnName)-1) {
  24. sb.WriteRune('_')
  25. }
  26. prev = '_'
  27. continue
  28. }
  29. if r == '_' {
  30. if prev == '_' || i == 0 || i == len(columnName)-1 {
  31. prev = '_'
  32. continue
  33. }
  34. }
  35. sb.WriteRune(unicode.ToLower(r))
  36. prev = r
  37. }
  38. final := sb.String()
  39. if prev == '_' { // string any trailing '_'
  40. final = final[:len(final)-1]
  41. }
  42. // Longer column name than expected - remove _ left to right
  43. allowedColLen := 128
  44. underscoreToRemove := len(final) - allowedColLen
  45. if underscoreToRemove > 0 {
  46. final = strings.Replace(final, "_", "", underscoreToRemove)
  47. }
  48. // If removing all of the underscores still didn't
  49. // make the column name < 128 characters, trim it!
  50. if len(final) > allowedColLen {
  51. final = final[:allowedColLen]
  52. }
  53. fmt.Println(final)
  54. log.Debugf("Column name being returned: \"%s\". Length: \"%d\".", final, len(final))
  55. return final
  56. }