github.com/yongjacky/phoenix-go-orm-builder@v0.3.5/builder_insert.go (about)

     1  // Copyright 2016 The Xorm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package builder
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"sort"
    11  )
    12  
    13  // Insert creates an insert Builder
    14  func Insert(eq ...interface{}) *Builder {
    15  	builder := &Builder{cond: NewCond()}
    16  	return builder.Insert(eq...)
    17  }
    18  
    19  func (b *Builder) insertSelectWriteTo(w Writer) error {
    20  	if _, err := fmt.Fprintf(w, "INSERT INTO %s ", b.into); err != nil {
    21  		return err
    22  	}
    23  
    24  	if len(b.insertCols) > 0 {
    25  		fmt.Fprintf(w, "(")
    26  		for _, col := range b.insertCols {
    27  			fmt.Fprintf(w, col)
    28  		}
    29  		fmt.Fprintf(w, ") ")
    30  	}
    31  
    32  	return b.selectWriteTo(w)
    33  }
    34  
    35  func (b *Builder) insertWriteTo(w Writer) error {
    36  	if len(b.into) <= 0 {
    37  		return ErrNoTableName
    38  	}
    39  	if len(b.insertCols) <= 0 && b.from == "" {
    40  		return ErrNoColumnToInsert
    41  	}
    42  
    43  	if b.into != "" && b.from != "" {
    44  		return b.insertSelectWriteTo(w)
    45  	}
    46  
    47  	if _, err := fmt.Fprintf(w, "INSERT INTO %s (", b.into); err != nil {
    48  		return err
    49  	}
    50  
    51  	var args = make([]interface{}, 0)
    52  	var bs []byte
    53  	var valBuffer = bytes.NewBuffer(bs)
    54  
    55  	for i, col := range b.insertCols {
    56  		value := b.insertVals[i]
    57  		fmt.Fprint(w, col)
    58  		if e, ok := value.(expr); ok {
    59  			fmt.Fprintf(valBuffer, "(%s)", e.sql)
    60  			args = append(args, e.args...)
    61  		} else if value == nil {
    62  			fmt.Fprintf(valBuffer, `null`)
    63  		} else {
    64  			fmt.Fprint(valBuffer, "?")
    65  			args = append(args, value)
    66  		}
    67  
    68  		if i != len(b.insertCols)-1 {
    69  			if _, err := fmt.Fprint(w, ","); err != nil {
    70  				return err
    71  			}
    72  			if _, err := fmt.Fprint(valBuffer, ","); err != nil {
    73  				return err
    74  			}
    75  		}
    76  	}
    77  
    78  	if _, err := fmt.Fprint(w, ") Values ("); err != nil {
    79  		return err
    80  	}
    81  
    82  	if _, err := w.Write(valBuffer.Bytes()); err != nil {
    83  		return err
    84  	}
    85  	if _, err := fmt.Fprint(w, ")"); err != nil {
    86  		return err
    87  	}
    88  
    89  	w.Append(args...)
    90  
    91  	return nil
    92  }
    93  
    94  type insertColsSorter struct {
    95  	cols []string
    96  	vals []interface{}
    97  }
    98  
    99  func (s insertColsSorter) Len() int {
   100  	return len(s.cols)
   101  }
   102  
   103  func (s insertColsSorter) Swap(i, j int) {
   104  	s.cols[i], s.cols[j] = s.cols[j], s.cols[i]
   105  	s.vals[i], s.vals[j] = s.vals[j], s.vals[i]
   106  }
   107  
   108  func (s insertColsSorter) Less(i, j int) bool {
   109  	return s.cols[i] < s.cols[j]
   110  }
   111  
   112  // Insert sets insert SQL
   113  func (b *Builder) Insert(eq ...interface{}) *Builder {
   114  	if len(eq) > 0 {
   115  		var paramType = -1
   116  		for _, e := range eq {
   117  			switch t := e.(type) {
   118  			case Eq:
   119  				if paramType == -1 {
   120  					paramType = 0
   121  				}
   122  				if paramType != 0 {
   123  					break
   124  				}
   125  				for k, v := range t {
   126  					b.insertCols = append(b.insertCols, k)
   127  					b.insertVals = append(b.insertVals, v)
   128  				}
   129  			case string:
   130  				if paramType == -1 {
   131  					paramType = 1
   132  				}
   133  				if paramType != 1 {
   134  					break
   135  				}
   136  				b.insertCols = append(b.insertCols, t)
   137  			}
   138  		}
   139  	}
   140  
   141  	if len(b.insertCols) == len(b.insertVals) {
   142  		sort.Sort(insertColsSorter{
   143  			cols: b.insertCols,
   144  			vals: b.insertVals,
   145  		})
   146  	}
   147  	b.optype = insertType
   148  	return b
   149  }