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 }