github.com/shuguocloud/go-zero@v1.3.0/core/stores/sqlx/utils.go (about)

     1  package sqlx
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/shuguocloud/go-zero/core/logx"
     9  	"github.com/shuguocloud/go-zero/core/mapping"
    10  )
    11  
    12  func desensitize(datasource string) string {
    13  	// remove account
    14  	pos := strings.LastIndex(datasource, "@")
    15  	if 0 <= pos && pos+1 < len(datasource) {
    16  		datasource = datasource[pos+1:]
    17  	}
    18  
    19  	return datasource
    20  }
    21  
    22  func escape(input string) string {
    23  	var b strings.Builder
    24  
    25  	for _, ch := range input {
    26  		switch ch {
    27  		case '\x00':
    28  			b.WriteString(`\x00`)
    29  		case '\r':
    30  			b.WriteString(`\r`)
    31  		case '\n':
    32  			b.WriteString(`\n`)
    33  		case '\\':
    34  			b.WriteString(`\\`)
    35  		case '\'':
    36  			b.WriteString(`\'`)
    37  		case '"':
    38  			b.WriteString(`\"`)
    39  		case '\x1a':
    40  			b.WriteString(`\x1a`)
    41  		default:
    42  			b.WriteRune(ch)
    43  		}
    44  	}
    45  
    46  	return b.String()
    47  }
    48  
    49  func format(query string, args ...interface{}) (string, error) {
    50  	numArgs := len(args)
    51  	if numArgs == 0 {
    52  		return query, nil
    53  	}
    54  
    55  	var b strings.Builder
    56  	var argIndex int
    57  	bytes := len(query)
    58  
    59  	for i := 0; i < bytes; i++ {
    60  		ch := query[i]
    61  		switch ch {
    62  		case '?':
    63  			if argIndex >= numArgs {
    64  				return "", fmt.Errorf("error: %d ? in sql, but less arguments provided", argIndex)
    65  			}
    66  
    67  			writeValue(&b, args[argIndex])
    68  			argIndex++
    69  		case '$':
    70  			var j int
    71  			for j = i + 1; j < bytes; j++ {
    72  				char := query[j]
    73  				if char < '0' || '9' < char {
    74  					break
    75  				}
    76  			}
    77  			if j > i+1 {
    78  				index, err := strconv.Atoi(query[i+1 : j])
    79  				if err != nil {
    80  					return "", err
    81  				}
    82  
    83  				// index starts from 1 for pg
    84  				if index > argIndex {
    85  					argIndex = index
    86  				}
    87  				index--
    88  				if index < 0 || numArgs <= index {
    89  					return "", fmt.Errorf("error: wrong index %d in sql", index)
    90  				}
    91  
    92  				writeValue(&b, args[index])
    93  				i = j - 1
    94  			}
    95  		default:
    96  			b.WriteByte(ch)
    97  		}
    98  	}
    99  
   100  	if argIndex < numArgs {
   101  		return "", fmt.Errorf("error: %d arguments provided, not matching sql", argIndex)
   102  	}
   103  
   104  	return b.String(), nil
   105  }
   106  
   107  func logInstanceError(datasource string, err error) {
   108  	datasource = desensitize(datasource)
   109  	logx.Errorf("Error on getting sql instance of %s: %v", datasource, err)
   110  }
   111  
   112  func logSqlError(stmt string, err error) {
   113  	if err != nil && err != ErrNotFound {
   114  		logx.Errorf("stmt: %s, error: %s", stmt, err.Error())
   115  	}
   116  }
   117  
   118  func writeValue(buf *strings.Builder, arg interface{}) {
   119  	switch v := arg.(type) {
   120  	case bool:
   121  		if v {
   122  			buf.WriteByte('1')
   123  		} else {
   124  			buf.WriteByte('0')
   125  		}
   126  	case string:
   127  		buf.WriteByte('\'')
   128  		buf.WriteString(escape(v))
   129  		buf.WriteByte('\'')
   130  	default:
   131  		buf.WriteString(mapping.Repr(v))
   132  	}
   133  }