an ORM-free SQL experience
1package norm 2 3import ( 4 "context" 5 "database/sql" 6 "fmt" 7 "strings" 8) 9 10type insert struct { 11 into string 12 or InsertOr 13 values []struct { 14 col string 15 val any 16 } 17} 18 19type InsertOr int 20 21const ( 22 None InsertOr = iota 23 Abort 24 Fail 25 Ignore 26 Replace 27 Rollback 28) 29 30func (i InsertOr) String() string { 31 switch i { 32 case Abort: 33 return "ABORT" 34 case Fail: 35 return "FAIL" 36 case Ignore: 37 return "IGNORE" 38 case Replace: 39 return "REPLACE" 40 case Rollback: 41 return "ROLLBACK" 42 default: 43 return "" 44 } 45} 46 47func Insert() insert { 48 return insert{} 49} 50 51type InsertOpt func(s *insert) 52 53func (s insert) Into(table string) insert { 54 s.into = table 55 return s 56} 57 58func (s insert) Or(option InsertOr) insert { 59 s.or = option 60 return s 61} 62 63func (s insert) Value(column string, arg any) insert { 64 s.values = append(s.values, struct { 65 col string 66 val any 67 }{ 68 column, arg, 69 }) 70 return s 71} 72 73func (s insert) Values(values map[string]any) insert { 74 for column, arg := range values { 75 s = s.Value(column, arg) 76 } 77 return s 78} 79 80func (s insert) Compile() (string, []any, error) { 81 var sql strings.Builder 82 var args []any 83 84 sql.WriteString("INSERT ") 85 86 orKw := s.or.String() 87 if orKw != "" { 88 sql.WriteString("OR ") 89 sql.WriteString(s.or.String()) 90 sql.WriteString(" ") 91 } 92 93 if s.into == "" { 94 return "", nil, fmt.Errorf("INTO clause is required") 95 } 96 sql.WriteString("INTO ") 97 sql.WriteString(s.into) 98 99 if len(s.values) == 0 { 100 return "", nil, fmt.Errorf("no values supplied") 101 } 102 103 sql.WriteString(" (") 104 105 for i, v := range s.values { 106 if i != 0 { 107 sql.WriteString(", ") 108 } 109 110 sql.WriteString(v.col) 111 args = append(args, v.val) 112 } 113 114 sql.WriteString(") VALUES (") 115 sql.WriteString(strings.TrimSuffix(strings.Repeat("?, ", len(s.values)), ", ")) 116 sql.WriteString(")") 117 118 return sql.String(), args, nil 119} 120 121func (s insert) MustCompile() (string, []any) { 122 sql, args, err := s.Compile() 123 if err != nil { 124 panic(err) 125 } 126 127 return sql, args 128} 129 130func (s insert) Build(p Database) (*sql.Stmt, []any, error) { return Build(s, p) } 131func (s insert) MustBuild(p Database) (*sql.Stmt, []any) { return MustBuild(s, p) } 132 133func (s insert) Exec(p Database) (sql.Result, error) { return Exec(s, p) } 134func (s insert) ExecContext(ctx context.Context, p Database) (sql.Result, error) { 135 return ExecContext(ctx, s, p) 136} 137func (s insert) MustExec(p Database) sql.Result { return MustExec(s, p) } 138func (s insert) MustExecContext(ctx context.Context, p Database) sql.Result { 139 return MustExecContext(ctx, s, p) 140}