in module/apmgocql/signature.go [34:141]
func querySignature(query string) string {
s := sqlutil.NewScanner(query)
for s.Scan() {
if s.Token() != sqlutil.COMMENT {
break
}
}
scanUntil := func(until sqlutil.Token) bool {
for s.Scan() {
if s.Token() == until {
return true
}
}
return false
}
scanToken := func(tok sqlutil.Token) bool {
for s.Scan() {
switch s.Token() {
case tok:
return true
case sqlutil.COMMENT:
default:
return false
}
}
return false
}
switch s.Token() {
case sqlutil.DELETE:
if !scanUntil(sqlutil.FROM) {
break
}
if !scanToken(sqlutil.IDENT) {
break
}
tableName := s.Text()
for scanToken(sqlutil.PERIOD) && scanToken(sqlutil.IDENT) {
tableName += "." + s.Text()
}
return "DELETE FROM " + tableName
case sqlutil.INSERT:
if !scanUntil(sqlutil.INTO) {
break
}
if !scanToken(sqlutil.IDENT) {
break
}
tableName := s.Text()
for scanToken(sqlutil.PERIOD) && scanToken(sqlutil.IDENT) {
tableName += "." + s.Text()
}
return "INSERT INTO " + tableName
case sqlutil.SELECT:
var level int
scanLoop:
for s.Scan() {
switch tok := s.Token(); tok {
case sqlutil.LPAREN:
level++
case sqlutil.RPAREN:
level--
case sqlutil.FROM:
if level != 0 {
continue scanLoop
}
if !scanToken(sqlutil.IDENT) {
break scanLoop
}
tableName := s.Text()
for scanToken(sqlutil.PERIOD) && scanToken(sqlutil.IDENT) {
tableName += "." + s.Text()
}
return "SELECT FROM " + tableName
}
}
case sqlutil.TRUNCATE:
if !scanUntil(sqlutil.IDENT) {
break
}
tableName := s.Text()
for scanToken(sqlutil.PERIOD) && scanToken(sqlutil.IDENT) {
tableName += "." + s.Text()
}
return "TRUNCATE " + tableName
case sqlutil.UPDATE:
if !scanToken(sqlutil.IDENT) {
break
}
tableName := s.Text()
for scanToken(sqlutil.PERIOD) && scanToken(sqlutil.IDENT) {
tableName += "." + s.Text()
}
return "UPDATE " + tableName
}
// If all else fails, just return the first token of the query.
fields := strings.Fields(query)
if len(fields) == 0 {
return ""
}
return strings.ToUpper(fields[0])
}