github.com/RevenueMonster/sqlike@v1.0.6/sql/stmt/statement.go (about)

     1  package sqlstmt
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"strings"
     7  	"time"
     8  )
     9  
    10  // Stmt :
    11  type Stmt interface {
    12  	io.StringWriter
    13  	io.ByteWriter
    14  	fmt.Stringer
    15  	Args() []interface{}
    16  	AppendArgs(args ...interface{})
    17  }
    18  
    19  // Formatter :
    20  type Formatter interface {
    21  	Format(it interface{}) string
    22  	Var(i int) string
    23  }
    24  
    25  // Statement :
    26  type Statement struct {
    27  	strings.Builder
    28  	start   time.Time
    29  	elapsed time.Duration
    30  	fmt     Formatter
    31  	c       int
    32  	args    []interface{}
    33  }
    34  
    35  // NewStatement :
    36  func NewStatement(fmt Formatter) (sm *Statement) {
    37  	sm = new(Statement)
    38  	sm.fmt = fmt
    39  	return
    40  }
    41  
    42  // Args :
    43  func (sm *Statement) Args() []interface{} {
    44  	return sm.args
    45  }
    46  
    47  // AppendArgs :
    48  func (sm *Statement) AppendArgs(args ...interface{}) {
    49  	sm.args = append(sm.args, args...)
    50  	sm.c = len(sm.args)
    51  }
    52  
    53  // Format :
    54  func (sm *Statement) Format(state fmt.State, verb rune) {
    55  	if sm.fmt == nil {
    56  		state.Write([]byte(`missing formatter, unable to debug`))
    57  		return
    58  	}
    59  
    60  	str := sm.String()
    61  	if !state.Flag('+') {
    62  		state.Write([]byte(str))
    63  		return
    64  	}
    65  
    66  	var (
    67  		i    = 1
    68  		args = sm.Args()
    69  		idx  int
    70  	)
    71  	for {
    72  		idx = strings.Index(str, sm.fmt.Var(i))
    73  		if idx < 0 {
    74  			state.Write([]byte(str))
    75  			break
    76  		}
    77  		state.Write([]byte(str[:idx]))
    78  		state.Write([]byte(sm.fmt.Format(args[0])))
    79  		str = str[idx+1:]
    80  		args = args[1:]
    81  		i++
    82  	}
    83  }
    84  
    85  // StartTimer :
    86  func (sm *Statement) StartTimer() {
    87  	sm.start = time.Now()
    88  }
    89  
    90  // StopTimer :
    91  func (sm *Statement) StopTimer() {
    92  	sm.elapsed = time.Since(sm.start)
    93  }
    94  
    95  // TimeElapsed :
    96  func (sm *Statement) TimeElapsed() time.Duration {
    97  	if sm.elapsed < 0 {
    98  		sm.StopTimer()
    99  	}
   100  	return sm.elapsed
   101  }
   102  
   103  // Reset : implement resetter as strings.Builer
   104  func (sm *Statement) Reset() {
   105  	sm.args = nil
   106  	sm.Builder.Reset()
   107  }