diff --git a/_example/go.mod b/_example/go.mod index e37590f..f4a691b 100644 --- a/_example/go.mod +++ b/_example/go.mod @@ -6,6 +6,7 @@ replace github.com/mackee/go-sqlla/v2 => ../ require ( github.com/go-sql-driver/mysql v1.6.0 + github.com/google/go-cmp v0.5.9 github.com/mackee/go-genddl v0.0.0-20220809061459-645eadea7290 github.com/mackee/go-sqlla/v2 v2.11.0 github.com/mattn/go-sqlite3 v1.14.9 @@ -41,6 +42,5 @@ require ( golang.org/x/net v0.7.0 // indirect golang.org/x/sys v0.5.0 // indirect golang.org/x/tools v0.1.12 // indirect - golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/_example/go.sum b/_example/go.sum index 9d34196..b605aa1 100644 --- a/_example/go.sum +++ b/_example/go.sum @@ -53,8 +53,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -186,12 +187,12 @@ golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -217,8 +218,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/_example/item.gen.go b/_example/item.gen.go new file mode 100644 index 0000000..d21c18c --- /dev/null +++ b/_example/item.gen.go @@ -0,0 +1,739 @@ +// Code generated by github.com/mackee/go-sqlla/v2/cmd/sqlla - DO NOT EDIT. +package example + +import ( + "context" + "fmt" + "strconv" + "strings" + + "database/sql" + + "github.com/mackee/go-sqlla/v2" +) + +type itemSQL struct { + where sqlla.Where +} + +func NewItemSQL() itemSQL { + q := itemSQL{} + return q +} + +var itemAllColumns = []string{ + "`id`", "`name`", +} + +type itemSelectSQL struct { + itemSQL + Columns []string + order string + limit *uint64 + offset *uint64 + tableAlias string + joinClauses []string + + additionalWhereClause string + additionalWhereClauseArgs []interface{} + + groupByColumns []string + + isForUpdate bool +} + +func (q itemSQL) Select() itemSelectSQL { + return itemSelectSQL{ + q, + itemAllColumns, + "", + nil, + nil, + "", + nil, + "", + nil, + nil, + false, + } +} + +func (q itemSelectSQL) Or(qs ...itemSelectSQL) itemSelectSQL { + ws := make([]sqlla.Where, 0, len(qs)) + for _, q := range qs { + ws = append(ws, q.where) + } + q.where = append(q.where, sqlla.ExprOr(ws)) + return q +} + +func (q itemSelectSQL) Limit(l uint64) itemSelectSQL { + q.limit = &l + return q +} + +func (q itemSelectSQL) Offset(o uint64) itemSelectSQL { + q.offset = &o + return q +} + +func (q itemSelectSQL) ForUpdate() itemSelectSQL { + q.isForUpdate = true + return q +} + +func (q itemSelectSQL) TableAlias(alias string) itemSelectSQL { + q.tableAlias = "`" + alias + "`" + return q +} + +func (q itemSelectSQL) SetColumns(columns ...string) itemSelectSQL { + q.Columns = make([]string, 0, len(columns)) + for _, column := range columns { + if strings.ContainsAny(column, "(.`") { + q.Columns = append(q.Columns, column) + } else { + q.Columns = append(q.Columns, "`"+column+"`") + } + } + return q +} + +func (q itemSelectSQL) JoinClause(clause string) itemSelectSQL { + q.joinClauses = append(q.joinClauses, clause) + return q +} + +func (q itemSelectSQL) AdditionalWhereClause(clause string, args ...interface{}) itemSelectSQL { + q.additionalWhereClause = clause + q.additionalWhereClauseArgs = args + return q +} + +func (q itemSelectSQL) appendColumnPrefix(column string) string { + if q.tableAlias == "" || strings.ContainsAny(column, "(.") { + return column + } + return q.tableAlias + "." + column +} + +func (q itemSelectSQL) GroupBy(columns ...string) itemSelectSQL { + q.groupByColumns = make([]string, 0, len(columns)) + for _, column := range columns { + if strings.ContainsAny(column, "(.`") { + q.groupByColumns = append(q.groupByColumns, column) + } else { + q.groupByColumns = append(q.groupByColumns, "`"+column+"`") + } + } + return q +} + +func (q itemSelectSQL) ID(v ItemID, exprs ...sqlla.Operator) itemSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: string(v), Op: op, Column: q.appendColumnPrefix("`id`")} + q.where = append(q.where, where) + return q +} + +func (q itemSelectSQL) IDIn(vs ...ItemID) itemSelectSQL { + _vs := make([]string, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, string(v)) + } + where := sqlla.ExprMultiString{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`id`")} + q.where = append(q.where, where) + return q +} + +func (q itemSelectSQL) OrderByID(order sqlla.Order) itemSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`id`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q itemSelectSQL) Name(v string, exprs ...sqlla.Operator) itemSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: q.appendColumnPrefix("`name`")} + q.where = append(q.where, where) + return q +} + +func (q itemSelectSQL) NameIn(vs ...string) itemSelectSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`name`")} + q.where = append(q.where, where) + return q +} + +func (q itemSelectSQL) OrderByName(order sqlla.Order) itemSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`name`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q itemSelectSQL) ToSql() (string, []interface{}, error) { + columns := strings.Join(q.Columns, ", ") + wheres, vs, err := q.where.ToSql() + if err != nil { + return "", nil, err + } + + tableName := "item" + if q.tableAlias != "" { + tableName = tableName + " AS " + q.tableAlias + pcs := make([]string, 0, len(q.Columns)) + for _, column := range q.Columns { + pcs = append(pcs, q.appendColumnPrefix(column)) + } + columns = strings.Join(pcs, ", ") + } + query := "SELECT " + columns + " FROM " + tableName + if len(q.joinClauses) > 0 { + jc := strings.Join(q.joinClauses, " ") + query += " " + jc + } + if wheres != "" { + query += " WHERE" + wheres + } + if q.additionalWhereClause != "" { + query += " " + q.additionalWhereClause + if len(q.additionalWhereClauseArgs) > 0 { + vs = append(vs, q.additionalWhereClauseArgs...) + } + } + if len(q.groupByColumns) > 0 { + query += " GROUP BY " + gbcs := make([]string, 0, len(q.groupByColumns)) + for _, column := range q.groupByColumns { + gbcs = append(gbcs, q.appendColumnPrefix(column)) + } + query += strings.Join(gbcs, ", ") + } + query += q.order + if q.limit != nil { + query += " LIMIT " + strconv.FormatUint(*q.limit, 10) + } + if q.offset != nil { + query += " OFFSET " + strconv.FormatUint(*q.offset, 10) + } + + if q.isForUpdate { + query += " FOR UPDATE" + } + + return query + ";", vs, nil +} + +func (q itemSelectSQL) Single(db sqlla.DB) (Item, error) { + q.Columns = itemAllColumns + query, args, err := q.ToSql() + if err != nil { + return Item{}, err + } + + row := db.QueryRow(query, args...) + return q.Scan(row) +} + +func (q itemSelectSQL) SingleContext(ctx context.Context, db sqlla.DB) (Item, error) { + q.Columns = itemAllColumns + query, args, err := q.ToSql() + if err != nil { + return Item{}, err + } + + row := db.QueryRowContext(ctx, query, args...) + return q.Scan(row) +} + +func (q itemSelectSQL) All(db sqlla.DB) ([]Item, error) { + rs := make([]Item, 0, 10) + q.Columns = itemAllColumns + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + + rows, err := db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + r, err := q.Scan(rows) + if err != nil { + return nil, err + } + rs = append(rs, r) + } + return rs, nil +} + +func (q itemSelectSQL) AllContext(ctx context.Context, db sqlla.DB) ([]Item, error) { + rs := make([]Item, 0, 10) + q.Columns = itemAllColumns + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + + rows, err := db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + r, err := q.Scan(rows) + if err != nil { + return nil, err + } + rs = append(rs, r) + } + return rs, nil +} + +func (q itemSelectSQL) Scan(s sqlla.Scanner) (Item, error) { + var row Item + err := s.Scan( + &row.ID, + &row.Name, + ) + return row, err +} + +type itemUpdateSQL struct { + itemSQL + setMap sqlla.SetMap + Columns []string +} + +func (q itemSQL) Update() itemUpdateSQL { + return itemUpdateSQL{ + itemSQL: q, + setMap: sqlla.SetMap{}, + } +} + +func (q itemUpdateSQL) SetID(v ItemID) itemUpdateSQL { + q.setMap["`id`"] = v + return q +} + +func (q itemUpdateSQL) WhereID(v ItemID, exprs ...sqlla.Operator) itemUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: string(v), Op: op, Column: "`id`"} + q.where = append(q.where, where) + return q +} + +func (q itemUpdateSQL) WhereIDIn(vs ...ItemID) itemUpdateSQL { + _vs := make([]string, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, string(v)) + } + where := sqlla.ExprMultiString{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`id`"} + q.where = append(q.where, where) + return q +} + +func (q itemUpdateSQL) SetName(v string) itemUpdateSQL { + q.setMap["`name`"] = v + return q +} + +func (q itemUpdateSQL) WhereName(v string, exprs ...sqlla.Operator) itemUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`name`"} + q.where = append(q.where, where) + return q +} + +func (q itemUpdateSQL) WhereNameIn(vs ...string) itemUpdateSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`name`"} + q.where = append(q.where, where) + return q +} + +func (q itemUpdateSQL) ToSql() (string, []interface{}, error) { + var err error + var s interface{} = Item{} + if t, ok := s.(itemDefaultUpdateHooker); ok { + q, err = t.DefaultUpdateHook(q) + if err != nil { + return "", []interface{}{}, err + } + } + setColumns, svs, err := q.setMap.ToUpdateSql() + if err != nil { + return "", []interface{}{}, err + } + wheres, wvs, err := q.where.ToSql() + if err != nil { + return "", []interface{}{}, err + } + + query := "UPDATE item SET" + setColumns + if wheres != "" { + query += " WHERE" + wheres + } + + return query + ";", append(svs, wvs...), nil +} +func (q itemUpdateSQL) Exec(db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.Exec(query, args...) +} + +func (q itemUpdateSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.ExecContext(ctx, query, args...) +} + +type itemDefaultUpdateHooker interface { + DefaultUpdateHook(itemUpdateSQL) (itemUpdateSQL, error) +} + +type itemInsertSQL struct { + itemSQL + setMap sqlla.SetMap + Columns []string +} + +func (q itemSQL) Insert() itemInsertSQL { + return itemInsertSQL{ + itemSQL: q, + setMap: sqlla.SetMap{}, + } +} + +func (q itemInsertSQL) ValueID(v ItemID) itemInsertSQL { + q.setMap["`id`"] = v + return q +} + +func (q itemInsertSQL) ValueName(v string) itemInsertSQL { + q.setMap["`name`"] = v + return q +} + +func (q itemInsertSQL) ToSql() (string, []interface{}, error) { + query, vs, err := q.itemInsertSQLToSql() + if err != nil { + return "", []interface{}{}, err + } + return query + ";", vs, nil +} + +func (q itemInsertSQL) itemInsertSQLToSql() (string, []interface{}, error) { + var err error + var s interface{} = Item{} + if t, ok := s.(itemDefaultInsertHooker); ok { + q, err = t.DefaultInsertHook(q) + if err != nil { + return "", []interface{}{}, err + } + } + qs, vs, err := q.setMap.ToInsertSql() + if err != nil { + return "", []interface{}{}, err + } + + query := "INSERT INTO item " + qs + + return query, vs, nil +} + +func (q itemInsertSQL) OnDuplicateKeyUpdate() itemInsertOnDuplicateKeyUpdateSQL { + return itemInsertOnDuplicateKeyUpdateSQL{ + insertSQL: q, + onDuplicateKeyUpdateMap: sqlla.SetMap{}, + } +} + +func (q itemInsertSQL) Exec(db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + + return nil, err + } + result, err := db.Exec(query, args...) + return result, err +} + +func (q itemInsertSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + + return nil, err + } + result, err := db.ExecContext(ctx, query, args...) + return result, err +} + +type itemDefaultInsertHooker interface { + DefaultInsertHook(itemInsertSQL) (itemInsertSQL, error) +} + +type itemInsertSQLToSqler interface { + itemInsertSQLToSql() (string, []interface{}, error) +} + +type itemInsertOnDuplicateKeyUpdateSQL struct { + insertSQL itemInsertSQLToSqler + onDuplicateKeyUpdateMap sqlla.SetMap +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateID(v ItemID) itemInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`id`"] = v + return q +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateID(v sqlla.SetMapRawValue) itemInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`id`"] = v + return q +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) SameOnUpdateID() itemInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`id`"] = sqlla.SetMapRawValue("VALUES(`id`)") + return q +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateName(v string) itemInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`name`"] = v + return q +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateName(v sqlla.SetMapRawValue) itemInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`name`"] = v + return q +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) SameOnUpdateName() itemInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`name`"] = sqlla.SetMapRawValue("VALUES(`name`)") + return q +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) ToSql() (string, []interface{}, error) { + var err error + var s interface{} = Item{} + if t, ok := s.(itemDefaultInsertOnDuplicateKeyUpdateHooker); ok { + q, err = t.DefaultInsertOnDuplicateKeyUpdateHook(q) + if err != nil { + return "", []interface{}{}, err + } + } + + query, vs, err := q.insertSQL.itemInsertSQLToSql() + if err != nil { + return "", []interface{}{}, err + } + + os, ovs, err := q.onDuplicateKeyUpdateMap.ToUpdateSql() + if err != nil { + return "", []interface{}{}, err + } + query += " ON DUPLICATE KEY UPDATE" + os + vs = append(vs, ovs...) + + return query + ";", vs, nil +} + +func (q itemInsertOnDuplicateKeyUpdateSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + + return nil, err + } + result, err := db.ExecContext(ctx, query, args...) + return result, err +} + +type itemDefaultInsertOnDuplicateKeyUpdateHooker interface { + DefaultInsertOnDuplicateKeyUpdateHook(itemInsertOnDuplicateKeyUpdateSQL) (itemInsertOnDuplicateKeyUpdateSQL, error) +} + +type itemBulkInsertSQL struct { + insertSQLs []itemInsertSQL +} + +func (q itemSQL) BulkInsert() *itemBulkInsertSQL { + return &itemBulkInsertSQL{ + insertSQLs: []itemInsertSQL{}, + } +} + +func (q *itemBulkInsertSQL) Append(iqs ...itemInsertSQL) { + q.insertSQLs = append(q.insertSQLs, iqs...) +} + +func (q *itemBulkInsertSQL) itemInsertSQLToSql() (string, []interface{}, error) { + if len(q.insertSQLs) == 0 { + return "", []interface{}{}, fmt.Errorf("sqlla: This itemBulkInsertSQL's InsertSQL was empty") + } + iqs := make([]itemInsertSQL, len(q.insertSQLs)) + copy(iqs, q.insertSQLs) + + var s interface{} = Item{} + if t, ok := s.(itemDefaultInsertHooker); ok { + for i, iq := range iqs { + var err error + iq, err = t.DefaultInsertHook(iq) + if err != nil { + return "", []interface{}{}, err + } + iqs[i] = iq + } + } + + sms := make(sqlla.SetMaps, 0, len(q.insertSQLs)) + for _, iq := range q.insertSQLs { + sms = append(sms, iq.setMap) + } + + query, vs, err := sms.ToInsertSql() + if err != nil { + return "", []interface{}{}, err + } + + return "INSERT INTO `item` " + query, vs, nil +} + +func (q *itemBulkInsertSQL) ToSql() (string, []interface{}, error) { + query, vs, err := q.itemInsertSQLToSql() + if err != nil { + return "", []interface{}{}, err + } + return query + ";", vs, nil +} + +func (q *itemBulkInsertSQL) OnDuplicateKeyUpdate() itemInsertOnDuplicateKeyUpdateSQL { + return itemInsertOnDuplicateKeyUpdateSQL{ + insertSQL: q, + onDuplicateKeyUpdateMap: sqlla.SetMap{}, + } +} + +func (q *itemBulkInsertSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + result, err := db.ExecContext(ctx, query, args...) + return result, err +} + +type itemDeleteSQL struct { + itemSQL +} + +func (q itemSQL) Delete() itemDeleteSQL { + return itemDeleteSQL{ + q, + } +} + +func (q itemDeleteSQL) ID(v ItemID, exprs ...sqlla.Operator) itemDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: string(v), Op: op, Column: "`id`"} + q.where = append(q.where, where) + return q +} + +func (q itemDeleteSQL) IDIn(vs ...ItemID) itemDeleteSQL { + _vs := make([]string, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, string(v)) + } + where := sqlla.ExprMultiString{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`id`"} + q.where = append(q.where, where) + return q +} + +func (q itemDeleteSQL) Name(v string, exprs ...sqlla.Operator) itemDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`name`"} + q.where = append(q.where, where) + return q +} + +func (q itemDeleteSQL) NameIn(vs ...string) itemDeleteSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`name`"} + q.where = append(q.where, where) + return q +} + +func (q itemDeleteSQL) ToSql() (string, []interface{}, error) { + wheres, vs, err := q.where.ToSql() + if err != nil { + return "", nil, err + } + + query := "DELETE FROM item" + if wheres != "" { + query += " WHERE" + wheres + } + + return query + ";", vs, nil +} + +func (q itemDeleteSQL) Exec(db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.Exec(query, args...) +} + +func (q itemDeleteSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.ExecContext(ctx, query, args...) +} diff --git a/_example/item.go b/_example/item.go new file mode 100644 index 0000000..42c62c5 --- /dev/null +++ b/_example/item.go @@ -0,0 +1,12 @@ +package example + +//go:generate go run ../cmd/sqlla/main.go + +type ItemID string + +//sqlla:table item +//genddl:table item +type Item struct { + ID ItemID `db:"id"` + Name string `db:"name"` +} diff --git a/_example/mysql.sql b/_example/mysql.sql index 9d4e594..4fcc1e0 100644 --- a/_example/mysql.sql +++ b/_example/mysql.sql @@ -1,5 +1,13 @@ -- generated by github.com/mackee/go-genddl. DO NOT EDIT!!! +DROP TABLE IF EXISTS `item`; + +CREATE TABLE `item` ( + `id` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( @@ -19,6 +27,7 @@ DROP TABLE IF EXISTS `user_external`; CREATE TABLE `user_external` ( `id` BIGINT unsigned NOT NULL PRIMARY KEY, `user_id` BIGINT unsigned NOT NULL, + `icon_image` BLOB NULL, `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; @@ -35,3 +44,23 @@ CREATE TABLE `user_item` ( `used_at` DATETIME NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +DROP TABLE IF EXISTS `user_sns`; + +CREATE TABLE `user_sns` ( + `id` BIGINT unsigned NOT NULL PRIMARY KEY, + `sns_type` VARCHAR(191) NOT NULL, + `created_at` DATETIME NOT NULL, + `updated_at` DATETIME NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE VIEW `user_item_detail` + (`ui_id`, `ui_user_id`, `ui_item_id`, `ui_is_used`, `ui_has_extension`, `ui_used_at`, `i_id`, `i_name`, `u_id`, `u_name`, `u_age`, `u_rate`, `u_icon_image`, `u_created_at`, `u_updated_at`) AS + SELECT + ui.id, ui.user_id, ui.item_id, ui.is_used, ui.has_extension, ui.used_at, + i.id, i.name, + u.id, u.name, u.age, u.rate, u.icon_image, u.created_at, u.updated_at + FROM user_item AS ui + INNER JOIN item AS i ON ui.item_id = i.id + INNER JOIN user AS u ON ui.user_id = u.id; + diff --git a/_example/sqlite3.sql b/_example/sqlite3.sql index eba5cb3..b77d21d 100644 --- a/_example/sqlite3.sql +++ b/_example/sqlite3.sql @@ -1,5 +1,13 @@ -- generated by github.com/mackee/go-genddl. DO NOT EDIT!!! +DROP TABLE IF EXISTS "item"; + +CREATE TABLE "item" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL +) ; + + DROP TABLE IF EXISTS "user"; CREATE TABLE "user" ( @@ -46,3 +54,13 @@ CREATE TABLE "user_sns" ( "updated_at" DATETIME NOT NULL ) ; +CREATE VIEW "user_item_detail" + ("ui_id", "ui_user_id", "ui_item_id", "ui_is_used", "ui_has_extension", "ui_used_at", "i_id", "i_name", "u_id", "u_name", "u_age", "u_rate", "u_icon_image", "u_created_at", "u_updated_at") AS + SELECT + ui.id, ui.user_id, ui.item_id, ui.is_used, ui.has_extension, ui.used_at, + i.id, i.name, + u.id, u.name, u.age, u.rate, u.icon_image, u.created_at, u.updated_at + FROM user_item AS ui + INNER JOIN item AS i ON ui.item_id = i.id + INNER JOIN user AS u ON ui.user_id = u.id; + diff --git a/_example/user.go b/_example/user.go index 3ee1b82..97f2b6c 100644 --- a/_example/user.go +++ b/_example/user.go @@ -9,7 +9,7 @@ import ( ) //go:generate go run ../cmd/sqlla/main.go -//go:generate genddl -outpath=./sqlite3.sql -driver=sqlite3 +//go:generate go run github.com/mackee/go-genddl/cmd/genddl@41aa2f4 -outpath=./sqlite3.sql -driver=sqlite3 type UserId uint64 diff --git a/_example/user_item_detail.gen.go b/_example/user_item_detail.gen.go new file mode 100644 index 0000000..8847ce5 --- /dev/null +++ b/_example/user_item_detail.gen.go @@ -0,0 +1,1936 @@ +// Code generated by github.com/mackee/go-sqlla/v2/cmd/sqlla - DO NOT EDIT. +package example + +import ( + "context" + "fmt" + "strconv" + "strings" + + "database/sql" + "github.com/go-sql-driver/mysql" + "time" + + "github.com/mackee/go-sqlla/v2" +) + +type userItemDetailSQL struct { + where sqlla.Where +} + +func NewUserItemDetailSQL() userItemDetailSQL { + q := userItemDetailSQL{} + return q +} + +var userItemDetailAllColumns = []string{ + "`ui_id`", "`ui_user_id`", "`ui_item_id`", "`ui_is_used`", "`ui_has_extension`", "`ui_used_at`", "`i_id`", "`i_name`", "`u_id`", "`u_name`", "`u_age`", "`u_rate`", "`u_icon_image`", "`u_created_at`", "`u_updated_at`", +} + +type userItemDetailSelectSQL struct { + userItemDetailSQL + Columns []string + order string + limit *uint64 + offset *uint64 + tableAlias string + joinClauses []string + + additionalWhereClause string + additionalWhereClauseArgs []interface{} + + groupByColumns []string + + isForUpdate bool +} + +func (q userItemDetailSQL) Select() userItemDetailSelectSQL { + return userItemDetailSelectSQL{ + q, + userItemDetailAllColumns, + "", + nil, + nil, + "", + nil, + "", + nil, + nil, + false, + } +} + +func (q userItemDetailSelectSQL) Or(qs ...userItemDetailSelectSQL) userItemDetailSelectSQL { + ws := make([]sqlla.Where, 0, len(qs)) + for _, q := range qs { + ws = append(ws, q.where) + } + q.where = append(q.where, sqlla.ExprOr(ws)) + return q +} + +func (q userItemDetailSelectSQL) Limit(l uint64) userItemDetailSelectSQL { + q.limit = &l + return q +} + +func (q userItemDetailSelectSQL) Offset(o uint64) userItemDetailSelectSQL { + q.offset = &o + return q +} + +func (q userItemDetailSelectSQL) ForUpdate() userItemDetailSelectSQL { + q.isForUpdate = true + return q +} + +func (q userItemDetailSelectSQL) TableAlias(alias string) userItemDetailSelectSQL { + q.tableAlias = "`" + alias + "`" + return q +} + +func (q userItemDetailSelectSQL) SetColumns(columns ...string) userItemDetailSelectSQL { + q.Columns = make([]string, 0, len(columns)) + for _, column := range columns { + if strings.ContainsAny(column, "(.`") { + q.Columns = append(q.Columns, column) + } else { + q.Columns = append(q.Columns, "`"+column+"`") + } + } + return q +} + +func (q userItemDetailSelectSQL) JoinClause(clause string) userItemDetailSelectSQL { + q.joinClauses = append(q.joinClauses, clause) + return q +} + +func (q userItemDetailSelectSQL) AdditionalWhereClause(clause string, args ...interface{}) userItemDetailSelectSQL { + q.additionalWhereClause = clause + q.additionalWhereClauseArgs = args + return q +} + +func (q userItemDetailSelectSQL) appendColumnPrefix(column string) string { + if q.tableAlias == "" || strings.ContainsAny(column, "(.") { + return column + } + return q.tableAlias + "." + column +} + +func (q userItemDetailSelectSQL) GroupBy(columns ...string) userItemDetailSelectSQL { + q.groupByColumns = make([]string, 0, len(columns)) + for _, column := range columns { + if strings.ContainsAny(column, "(.`") { + q.groupByColumns = append(q.groupByColumns, column) + } else { + q.groupByColumns = append(q.groupByColumns, "`"+column+"`") + } + } + return q +} + +func (q userItemDetailSelectSQL) UserItemId(v uint64, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: v, Op: op, Column: q.appendColumnPrefix("`ui_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserItemIdIn(vs ...uint64) userItemDetailSelectSQL { + where := sqlla.ExprMultiUint64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`ui_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserItemId(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`ui_id`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserItemUserId(v uint64, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: v, Op: op, Column: q.appendColumnPrefix("`ui_user_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserItemUserIdIn(vs ...uint64) userItemDetailSelectSQL { + where := sqlla.ExprMultiUint64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`ui_user_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserItemUserId(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`ui_user_id`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserItemItemId(v string, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: q.appendColumnPrefix("`ui_item_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserItemItemIdIn(vs ...string) userItemDetailSelectSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`ui_item_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserItemItemId(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`ui_item_id`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserItemIsUsed(v bool, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprBool{Value: v, Op: op, Column: q.appendColumnPrefix("`ui_is_used`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserItemIsUsedIn(vs ...bool) userItemDetailSelectSQL { + where := sqlla.ExprMultiBool{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`ui_is_used`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserItemIsUsed(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`ui_is_used`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserItemHasExtension(v sql.NullBool, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullBool{Value: v, Op: op, Column: q.appendColumnPrefix("`ui_has_extension`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserItemHasExtensionIn(vs ...sql.NullBool) userItemDetailSelectSQL { + where := sqlla.ExprMultiNullBool{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`ui_has_extension`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserItemHasExtension(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`ui_has_extension`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserItemUsedAt(v sql.NullTime, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullTime{Value: v, Op: op, Column: q.appendColumnPrefix("`ui_used_at`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserItemUsedAtIn(vs ...sql.NullTime) userItemDetailSelectSQL { + where := sqlla.ExprMultiNullTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`ui_used_at`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserItemUsedAt(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`ui_used_at`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) ItemID(v ItemID, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: string(v), Op: op, Column: q.appendColumnPrefix("`i_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) ItemIDIn(vs ...ItemID) userItemDetailSelectSQL { + _vs := make([]string, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, string(v)) + } + where := sqlla.ExprMultiString{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`i_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByItemID(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`i_id`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) ItemName(v string, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: q.appendColumnPrefix("`i_name`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) ItemNameIn(vs ...string) userItemDetailSelectSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`i_name`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByItemName(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`i_name`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserId(v UserId, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: uint64(v), Op: op, Column: q.appendColumnPrefix("`u_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserIdIn(vs ...UserId) userItemDetailSelectSQL { + _vs := make([]uint64, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, uint64(v)) + } + where := sqlla.ExprMultiUint64{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_id`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserId(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_id`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserName(v string, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: q.appendColumnPrefix("`u_name`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserNameIn(vs ...string) userItemDetailSelectSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_name`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserName(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_name`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserAge(v sql.NullInt64, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullInt64{Value: v, Op: op, Column: q.appendColumnPrefix("`u_age`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserAgeIn(vs ...sql.NullInt64) userItemDetailSelectSQL { + where := sqlla.ExprMultiNullInt64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_age`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserAge(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_age`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserRate(v float64, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprFloat64{Value: v, Op: op, Column: q.appendColumnPrefix("`u_rate`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserRateIn(vs ...float64) userItemDetailSelectSQL { + where := sqlla.ExprMultiFloat64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_rate`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserRate(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_rate`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserIconImage(v []byte, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprBytes{Value: v, Op: op, Column: q.appendColumnPrefix("`u_icon_image`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserIconImageIn(vs ...[]byte) userItemDetailSelectSQL { + where := sqlla.ExprMultiBytes{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_icon_image`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserIconImage(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_icon_image`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserCreatedAt(v time.Time, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprTime{Value: v, Op: op, Column: q.appendColumnPrefix("`u_created_at`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserCreatedAtIn(vs ...time.Time) userItemDetailSelectSQL { + where := sqlla.ExprMultiTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_created_at`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserCreatedAt(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_created_at`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) UserUpdatedAt(v mysql.NullTime, exprs ...sqlla.Operator) userItemDetailSelectSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprMysqlNullTime{Value: v, Op: op, Column: q.appendColumnPrefix("`u_updated_at`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) UserUpdatedAtIn(vs ...mysql.NullTime) userItemDetailSelectSQL { + where := sqlla.ExprMultiMysqlNullTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: q.appendColumnPrefix("`u_updated_at`")} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailSelectSQL) OrderByUserUpdatedAt(order sqlla.Order) userItemDetailSelectSQL { + q.order = " ORDER BY " + q.appendColumnPrefix("`u_updated_at`") + if order == sqlla.Asc { + q.order += " ASC" + } else { + q.order += " DESC" + } + + return q +} + +func (q userItemDetailSelectSQL) ToSql() (string, []interface{}, error) { + columns := strings.Join(q.Columns, ", ") + wheres, vs, err := q.where.ToSql() + if err != nil { + return "", nil, err + } + + tableName := "user_item_detail" + if q.tableAlias != "" { + tableName = tableName + " AS " + q.tableAlias + pcs := make([]string, 0, len(q.Columns)) + for _, column := range q.Columns { + pcs = append(pcs, q.appendColumnPrefix(column)) + } + columns = strings.Join(pcs, ", ") + } + query := "SELECT " + columns + " FROM " + tableName + if len(q.joinClauses) > 0 { + jc := strings.Join(q.joinClauses, " ") + query += " " + jc + } + if wheres != "" { + query += " WHERE" + wheres + } + if q.additionalWhereClause != "" { + query += " " + q.additionalWhereClause + if len(q.additionalWhereClauseArgs) > 0 { + vs = append(vs, q.additionalWhereClauseArgs...) + } + } + if len(q.groupByColumns) > 0 { + query += " GROUP BY " + gbcs := make([]string, 0, len(q.groupByColumns)) + for _, column := range q.groupByColumns { + gbcs = append(gbcs, q.appendColumnPrefix(column)) + } + query += strings.Join(gbcs, ", ") + } + query += q.order + if q.limit != nil { + query += " LIMIT " + strconv.FormatUint(*q.limit, 10) + } + if q.offset != nil { + query += " OFFSET " + strconv.FormatUint(*q.offset, 10) + } + + if q.isForUpdate { + query += " FOR UPDATE" + } + + return query + ";", vs, nil +} + +func (q userItemDetailSelectSQL) Single(db sqlla.DB) (UserItemDetail, error) { + q.Columns = userItemDetailAllColumns + query, args, err := q.ToSql() + if err != nil { + return UserItemDetail{}, err + } + + row := db.QueryRow(query, args...) + return q.Scan(row) +} + +func (q userItemDetailSelectSQL) SingleContext(ctx context.Context, db sqlla.DB) (UserItemDetail, error) { + q.Columns = userItemDetailAllColumns + query, args, err := q.ToSql() + if err != nil { + return UserItemDetail{}, err + } + + row := db.QueryRowContext(ctx, query, args...) + return q.Scan(row) +} + +func (q userItemDetailSelectSQL) All(db sqlla.DB) ([]UserItemDetail, error) { + rs := make([]UserItemDetail, 0, 10) + q.Columns = userItemDetailAllColumns + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + + rows, err := db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + r, err := q.Scan(rows) + if err != nil { + return nil, err + } + rs = append(rs, r) + } + return rs, nil +} + +func (q userItemDetailSelectSQL) AllContext(ctx context.Context, db sqlla.DB) ([]UserItemDetail, error) { + rs := make([]UserItemDetail, 0, 10) + q.Columns = userItemDetailAllColumns + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + + rows, err := db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + r, err := q.Scan(rows) + if err != nil { + return nil, err + } + rs = append(rs, r) + } + return rs, nil +} + +func (q userItemDetailSelectSQL) Scan(s sqlla.Scanner) (UserItemDetail, error) { + var row UserItemDetail + err := s.Scan( + &row.UserItem.Id, + &row.UserItem.UserId, + &row.UserItem.ItemId, + &row.UserItem.IsUsed, + &row.UserItem.HasExtension, + &row.UserItem.UsedAt, + &row.Item.ID, + &row.Item.Name, + &row.User.Id, + &row.User.Name, + &row.User.Age, + &row.User.Rate, + &row.User.IconImage, + &row.User.CreatedAt, + &row.User.UpdatedAt, + ) + return row, err +} + +type userItemDetailUpdateSQL struct { + userItemDetailSQL + setMap sqlla.SetMap + Columns []string +} + +func (q userItemDetailSQL) Update() userItemDetailUpdateSQL { + return userItemDetailUpdateSQL{ + userItemDetailSQL: q, + setMap: sqlla.SetMap{}, + } +} + +func (q userItemDetailUpdateSQL) SetUserItemId(v uint64) userItemDetailUpdateSQL { + q.setMap["`ui_id`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemId(v uint64, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: v, Op: op, Column: "`ui_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemIdIn(vs ...uint64) userItemDetailUpdateSQL { + where := sqlla.ExprMultiUint64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserItemUserId(v uint64) userItemDetailUpdateSQL { + q.setMap["`ui_user_id`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemUserId(v uint64, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: v, Op: op, Column: "`ui_user_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemUserIdIn(vs ...uint64) userItemDetailUpdateSQL { + where := sqlla.ExprMultiUint64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_user_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserItemItemId(v string) userItemDetailUpdateSQL { + q.setMap["`ui_item_id`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemItemId(v string, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`ui_item_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemItemIdIn(vs ...string) userItemDetailUpdateSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_item_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserItemIsUsed(v bool) userItemDetailUpdateSQL { + q.setMap["`ui_is_used`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemIsUsed(v bool, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprBool{Value: v, Op: op, Column: "`ui_is_used`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemIsUsedIn(vs ...bool) userItemDetailUpdateSQL { + where := sqlla.ExprMultiBool{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_is_used`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserItemHasExtension(v sql.NullBool) userItemDetailUpdateSQL { + q.setMap["`ui_has_extension`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemHasExtension(v sql.NullBool, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullBool{Value: v, Op: op, Column: "`ui_has_extension`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemHasExtensionIn(vs ...sql.NullBool) userItemDetailUpdateSQL { + where := sqlla.ExprMultiNullBool{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_has_extension`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserItemUsedAt(v sql.NullTime) userItemDetailUpdateSQL { + q.setMap["`ui_used_at`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemUsedAt(v sql.NullTime, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullTime{Value: v, Op: op, Column: "`ui_used_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserItemUsedAtIn(vs ...sql.NullTime) userItemDetailUpdateSQL { + where := sqlla.ExprMultiNullTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_used_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetItemID(v ItemID) userItemDetailUpdateSQL { + q.setMap["`i_id`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereItemID(v ItemID, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: string(v), Op: op, Column: "`i_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereItemIDIn(vs ...ItemID) userItemDetailUpdateSQL { + _vs := make([]string, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, string(v)) + } + where := sqlla.ExprMultiString{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`i_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetItemName(v string) userItemDetailUpdateSQL { + q.setMap["`i_name`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereItemName(v string, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`i_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereItemNameIn(vs ...string) userItemDetailUpdateSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`i_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserId(v UserId) userItemDetailUpdateSQL { + q.setMap["`u_id`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserId(v UserId, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: uint64(v), Op: op, Column: "`u_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserIdIn(vs ...UserId) userItemDetailUpdateSQL { + _vs := make([]uint64, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, uint64(v)) + } + where := sqlla.ExprMultiUint64{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserName(v string) userItemDetailUpdateSQL { + q.setMap["`u_name`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserName(v string, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`u_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserNameIn(vs ...string) userItemDetailUpdateSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserAge(v sql.NullInt64) userItemDetailUpdateSQL { + q.setMap["`u_age`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserAge(v sql.NullInt64, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullInt64{Value: v, Op: op, Column: "`u_age`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserAgeIn(vs ...sql.NullInt64) userItemDetailUpdateSQL { + where := sqlla.ExprMultiNullInt64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_age`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserRate(v float64) userItemDetailUpdateSQL { + q.setMap["`u_rate`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserRate(v float64, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprFloat64{Value: v, Op: op, Column: "`u_rate`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserRateIn(vs ...float64) userItemDetailUpdateSQL { + where := sqlla.ExprMultiFloat64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_rate`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserIconImage(v []byte) userItemDetailUpdateSQL { + q.setMap["`u_icon_image`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserIconImage(v []byte, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprBytes{Value: v, Op: op, Column: "`u_icon_image`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserIconImageIn(vs ...[]byte) userItemDetailUpdateSQL { + where := sqlla.ExprMultiBytes{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_icon_image`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserCreatedAt(v time.Time) userItemDetailUpdateSQL { + q.setMap["`u_created_at`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserCreatedAt(v time.Time, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprTime{Value: v, Op: op, Column: "`u_created_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserCreatedAtIn(vs ...time.Time) userItemDetailUpdateSQL { + where := sqlla.ExprMultiTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_created_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) SetUserUpdatedAt(v mysql.NullTime) userItemDetailUpdateSQL { + q.setMap["`u_updated_at`"] = v + return q +} + +func (q userItemDetailUpdateSQL) WhereUserUpdatedAt(v mysql.NullTime, exprs ...sqlla.Operator) userItemDetailUpdateSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprMysqlNullTime{Value: v, Op: op, Column: "`u_updated_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) WhereUserUpdatedAtIn(vs ...mysql.NullTime) userItemDetailUpdateSQL { + where := sqlla.ExprMultiMysqlNullTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_updated_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailUpdateSQL) ToSql() (string, []interface{}, error) { + var err error + var s interface{} = UserItemDetail{} + if t, ok := s.(userItemDetailDefaultUpdateHooker); ok { + q, err = t.DefaultUpdateHook(q) + if err != nil { + return "", []interface{}{}, err + } + } + setColumns, svs, err := q.setMap.ToUpdateSql() + if err != nil { + return "", []interface{}{}, err + } + wheres, wvs, err := q.where.ToSql() + if err != nil { + return "", []interface{}{}, err + } + + query := "UPDATE user_item_detail SET" + setColumns + if wheres != "" { + query += " WHERE" + wheres + } + + return query + ";", append(svs, wvs...), nil +} +func (q userItemDetailUpdateSQL) Exec(db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.Exec(query, args...) +} + +func (q userItemDetailUpdateSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.ExecContext(ctx, query, args...) +} + +type userItemDetailDefaultUpdateHooker interface { + DefaultUpdateHook(userItemDetailUpdateSQL) (userItemDetailUpdateSQL, error) +} + +type userItemDetailInsertSQL struct { + userItemDetailSQL + setMap sqlla.SetMap + Columns []string +} + +func (q userItemDetailSQL) Insert() userItemDetailInsertSQL { + return userItemDetailInsertSQL{ + userItemDetailSQL: q, + setMap: sqlla.SetMap{}, + } +} + +func (q userItemDetailInsertSQL) ValueUserItemId(v uint64) userItemDetailInsertSQL { + q.setMap["`ui_id`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserItemUserId(v uint64) userItemDetailInsertSQL { + q.setMap["`ui_user_id`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserItemItemId(v string) userItemDetailInsertSQL { + q.setMap["`ui_item_id`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserItemIsUsed(v bool) userItemDetailInsertSQL { + q.setMap["`ui_is_used`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserItemHasExtension(v sql.NullBool) userItemDetailInsertSQL { + q.setMap["`ui_has_extension`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserItemUsedAt(v sql.NullTime) userItemDetailInsertSQL { + q.setMap["`ui_used_at`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueItemID(v ItemID) userItemDetailInsertSQL { + q.setMap["`i_id`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueItemName(v string) userItemDetailInsertSQL { + q.setMap["`i_name`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserId(v UserId) userItemDetailInsertSQL { + q.setMap["`u_id`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserName(v string) userItemDetailInsertSQL { + q.setMap["`u_name`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserAge(v sql.NullInt64) userItemDetailInsertSQL { + q.setMap["`u_age`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserRate(v float64) userItemDetailInsertSQL { + q.setMap["`u_rate`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserIconImage(v []byte) userItemDetailInsertSQL { + q.setMap["`u_icon_image`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserCreatedAt(v time.Time) userItemDetailInsertSQL { + q.setMap["`u_created_at`"] = v + return q +} + +func (q userItemDetailInsertSQL) ValueUserUpdatedAt(v mysql.NullTime) userItemDetailInsertSQL { + q.setMap["`u_updated_at`"] = v + return q +} + +func (q userItemDetailInsertSQL) ToSql() (string, []interface{}, error) { + query, vs, err := q.userItemDetailInsertSQLToSql() + if err != nil { + return "", []interface{}{}, err + } + return query + ";", vs, nil +} + +func (q userItemDetailInsertSQL) userItemDetailInsertSQLToSql() (string, []interface{}, error) { + var err error + var s interface{} = UserItemDetail{} + if t, ok := s.(userItemDetailDefaultInsertHooker); ok { + q, err = t.DefaultInsertHook(q) + if err != nil { + return "", []interface{}{}, err + } + } + qs, vs, err := q.setMap.ToInsertSql() + if err != nil { + return "", []interface{}{}, err + } + + query := "INSERT INTO user_item_detail " + qs + + return query, vs, nil +} + +func (q userItemDetailInsertSQL) OnDuplicateKeyUpdate() userItemDetailInsertOnDuplicateKeyUpdateSQL { + return userItemDetailInsertOnDuplicateKeyUpdateSQL{ + insertSQL: q, + onDuplicateKeyUpdateMap: sqlla.SetMap{}, + } +} + +func (q userItemDetailInsertSQL) Exec(db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + + return nil, err + } + result, err := db.Exec(query, args...) + return result, err +} + +func (q userItemDetailInsertSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + + return nil, err + } + result, err := db.ExecContext(ctx, query, args...) + return result, err +} + +type userItemDetailDefaultInsertHooker interface { + DefaultInsertHook(userItemDetailInsertSQL) (userItemDetailInsertSQL, error) +} + +type userItemDetailInsertSQLToSqler interface { + userItemDetailInsertSQLToSql() (string, []interface{}, error) +} + +type userItemDetailInsertOnDuplicateKeyUpdateSQL struct { + insertSQL userItemDetailInsertSQLToSqler + onDuplicateKeyUpdateMap sqlla.SetMap +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserItemId(v uint64) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserItemId(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserItemId() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_id`"] = sqlla.SetMapRawValue("VALUES(`ui_id`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserItemUserId(v uint64) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_user_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserItemUserId(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_user_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserItemUserId() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_user_id`"] = sqlla.SetMapRawValue("VALUES(`ui_user_id`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserItemItemId(v string) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_item_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserItemItemId(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_item_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserItemItemId() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_item_id`"] = sqlla.SetMapRawValue("VALUES(`ui_item_id`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserItemIsUsed(v bool) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_is_used`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserItemIsUsed(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_is_used`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserItemIsUsed() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_is_used`"] = sqlla.SetMapRawValue("VALUES(`ui_is_used`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserItemHasExtension(v sql.NullBool) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_has_extension`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserItemHasExtension(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_has_extension`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserItemHasExtension() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_has_extension`"] = sqlla.SetMapRawValue("VALUES(`ui_has_extension`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserItemUsedAt(v sql.NullTime) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_used_at`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserItemUsedAt(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_used_at`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserItemUsedAt() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`ui_used_at`"] = sqlla.SetMapRawValue("VALUES(`ui_used_at`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateItemID(v ItemID) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`i_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateItemID(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`i_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateItemID() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`i_id`"] = sqlla.SetMapRawValue("VALUES(`i_id`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateItemName(v string) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`i_name`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateItemName(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`i_name`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateItemName() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`i_name`"] = sqlla.SetMapRawValue("VALUES(`i_name`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserId(v UserId) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserId(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_id`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserId() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_id`"] = sqlla.SetMapRawValue("VALUES(`u_id`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserName(v string) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_name`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserName(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_name`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserName() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_name`"] = sqlla.SetMapRawValue("VALUES(`u_name`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserAge(v sql.NullInt64) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_age`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserAge(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_age`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserAge() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_age`"] = sqlla.SetMapRawValue("VALUES(`u_age`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserRate(v float64) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_rate`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserRate(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_rate`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserRate() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_rate`"] = sqlla.SetMapRawValue("VALUES(`u_rate`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserIconImage(v []byte) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_icon_image`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserIconImage(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_icon_image`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserIconImage() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_icon_image`"] = sqlla.SetMapRawValue("VALUES(`u_icon_image`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserCreatedAt(v time.Time) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_created_at`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserCreatedAt(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_created_at`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserCreatedAt() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_created_at`"] = sqlla.SetMapRawValue("VALUES(`u_created_at`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ValueOnUpdateUserUpdatedAt(v mysql.NullTime) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_updated_at`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) RawValueOnUpdateUserUpdatedAt(v sqlla.SetMapRawValue) userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_updated_at`"] = v + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) SameOnUpdateUserUpdatedAt() userItemDetailInsertOnDuplicateKeyUpdateSQL { + q.onDuplicateKeyUpdateMap["`u_updated_at`"] = sqlla.SetMapRawValue("VALUES(`u_updated_at`)") + return q +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ToSql() (string, []interface{}, error) { + var err error + var s interface{} = UserItemDetail{} + if t, ok := s.(userItemDetailDefaultInsertOnDuplicateKeyUpdateHooker); ok { + q, err = t.DefaultInsertOnDuplicateKeyUpdateHook(q) + if err != nil { + return "", []interface{}{}, err + } + } + + query, vs, err := q.insertSQL.userItemDetailInsertSQLToSql() + if err != nil { + return "", []interface{}{}, err + } + + os, ovs, err := q.onDuplicateKeyUpdateMap.ToUpdateSql() + if err != nil { + return "", []interface{}{}, err + } + query += " ON DUPLICATE KEY UPDATE" + os + vs = append(vs, ovs...) + + return query + ";", vs, nil +} + +func (q userItemDetailInsertOnDuplicateKeyUpdateSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + + return nil, err + } + result, err := db.ExecContext(ctx, query, args...) + return result, err +} + +type userItemDetailDefaultInsertOnDuplicateKeyUpdateHooker interface { + DefaultInsertOnDuplicateKeyUpdateHook(userItemDetailInsertOnDuplicateKeyUpdateSQL) (userItemDetailInsertOnDuplicateKeyUpdateSQL, error) +} + +type userItemDetailBulkInsertSQL struct { + insertSQLs []userItemDetailInsertSQL +} + +func (q userItemDetailSQL) BulkInsert() *userItemDetailBulkInsertSQL { + return &userItemDetailBulkInsertSQL{ + insertSQLs: []userItemDetailInsertSQL{}, + } +} + +func (q *userItemDetailBulkInsertSQL) Append(iqs ...userItemDetailInsertSQL) { + q.insertSQLs = append(q.insertSQLs, iqs...) +} + +func (q *userItemDetailBulkInsertSQL) userItemDetailInsertSQLToSql() (string, []interface{}, error) { + if len(q.insertSQLs) == 0 { + return "", []interface{}{}, fmt.Errorf("sqlla: This userItemDetailBulkInsertSQL's InsertSQL was empty") + } + iqs := make([]userItemDetailInsertSQL, len(q.insertSQLs)) + copy(iqs, q.insertSQLs) + + var s interface{} = UserItemDetail{} + if t, ok := s.(userItemDetailDefaultInsertHooker); ok { + for i, iq := range iqs { + var err error + iq, err = t.DefaultInsertHook(iq) + if err != nil { + return "", []interface{}{}, err + } + iqs[i] = iq + } + } + + sms := make(sqlla.SetMaps, 0, len(q.insertSQLs)) + for _, iq := range q.insertSQLs { + sms = append(sms, iq.setMap) + } + + query, vs, err := sms.ToInsertSql() + if err != nil { + return "", []interface{}{}, err + } + + return "INSERT INTO `user_item_detail` " + query, vs, nil +} + +func (q *userItemDetailBulkInsertSQL) ToSql() (string, []interface{}, error) { + query, vs, err := q.userItemDetailInsertSQLToSql() + if err != nil { + return "", []interface{}{}, err + } + return query + ";", vs, nil +} + +func (q *userItemDetailBulkInsertSQL) OnDuplicateKeyUpdate() userItemDetailInsertOnDuplicateKeyUpdateSQL { + return userItemDetailInsertOnDuplicateKeyUpdateSQL{ + insertSQL: q, + onDuplicateKeyUpdateMap: sqlla.SetMap{}, + } +} + +func (q *userItemDetailBulkInsertSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + result, err := db.ExecContext(ctx, query, args...) + return result, err +} + +type userItemDetailDeleteSQL struct { + userItemDetailSQL +} + +func (q userItemDetailSQL) Delete() userItemDetailDeleteSQL { + return userItemDetailDeleteSQL{ + q, + } +} + +func (q userItemDetailDeleteSQL) UserItemId(v uint64, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: v, Op: op, Column: "`ui_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemIdIn(vs ...uint64) userItemDetailDeleteSQL { + where := sqlla.ExprMultiUint64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemUserId(v uint64, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: v, Op: op, Column: "`ui_user_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemUserIdIn(vs ...uint64) userItemDetailDeleteSQL { + where := sqlla.ExprMultiUint64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_user_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemItemId(v string, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`ui_item_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemItemIdIn(vs ...string) userItemDetailDeleteSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_item_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemIsUsed(v bool, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprBool{Value: v, Op: op, Column: "`ui_is_used`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemIsUsedIn(vs ...bool) userItemDetailDeleteSQL { + where := sqlla.ExprMultiBool{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_is_used`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemHasExtension(v sql.NullBool, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullBool{Value: v, Op: op, Column: "`ui_has_extension`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemHasExtensionIn(vs ...sql.NullBool) userItemDetailDeleteSQL { + where := sqlla.ExprMultiNullBool{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_has_extension`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemUsedAt(v sql.NullTime, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullTime{Value: v, Op: op, Column: "`ui_used_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserItemUsedAtIn(vs ...sql.NullTime) userItemDetailDeleteSQL { + where := sqlla.ExprMultiNullTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`ui_used_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) ItemID(v ItemID, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: string(v), Op: op, Column: "`i_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) ItemIDIn(vs ...ItemID) userItemDetailDeleteSQL { + _vs := make([]string, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, string(v)) + } + where := sqlla.ExprMultiString{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`i_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) ItemName(v string, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`i_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) ItemNameIn(vs ...string) userItemDetailDeleteSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`i_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserId(v UserId, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprUint64{Value: uint64(v), Op: op, Column: "`u_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserIdIn(vs ...UserId) userItemDetailDeleteSQL { + _vs := make([]uint64, 0, len(vs)) + for _, v := range vs { + _vs = append(_vs, uint64(v)) + } + where := sqlla.ExprMultiUint64{Values: _vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_id`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserName(v string, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprString{Value: v, Op: op, Column: "`u_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserNameIn(vs ...string) userItemDetailDeleteSQL { + where := sqlla.ExprMultiString{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_name`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserAge(v sql.NullInt64, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprNullInt64{Value: v, Op: op, Column: "`u_age`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserAgeIn(vs ...sql.NullInt64) userItemDetailDeleteSQL { + where := sqlla.ExprMultiNullInt64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_age`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserRate(v float64, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprFloat64{Value: v, Op: op, Column: "`u_rate`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserRateIn(vs ...float64) userItemDetailDeleteSQL { + where := sqlla.ExprMultiFloat64{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_rate`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserIconImage(v []byte, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprBytes{Value: v, Op: op, Column: "`u_icon_image`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserIconImageIn(vs ...[]byte) userItemDetailDeleteSQL { + where := sqlla.ExprMultiBytes{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_icon_image`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserCreatedAt(v time.Time, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprTime{Value: v, Op: op, Column: "`u_created_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserCreatedAtIn(vs ...time.Time) userItemDetailDeleteSQL { + where := sqlla.ExprMultiTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_created_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserUpdatedAt(v mysql.NullTime, exprs ...sqlla.Operator) userItemDetailDeleteSQL { + var op sqlla.Operator + if len(exprs) == 0 { + op = sqlla.OpEqual + } else { + op = exprs[0] + } + where := sqlla.ExprMysqlNullTime{Value: v, Op: op, Column: "`u_updated_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) UserUpdatedAtIn(vs ...mysql.NullTime) userItemDetailDeleteSQL { + where := sqlla.ExprMultiMysqlNullTime{Values: vs, Op: sqlla.MakeInOperator(len(vs)), Column: "`u_updated_at`"} + q.where = append(q.where, where) + return q +} + +func (q userItemDetailDeleteSQL) ToSql() (string, []interface{}, error) { + wheres, vs, err := q.where.ToSql() + if err != nil { + return "", nil, err + } + + query := "DELETE FROM user_item_detail" + if wheres != "" { + query += " WHERE" + wheres + } + + return query + ";", vs, nil +} + +func (q userItemDetailDeleteSQL) Exec(db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.Exec(query, args...) +} + +func (q userItemDetailDeleteSQL) ExecContext(ctx context.Context, db sqlla.DB) (sql.Result, error) { + query, args, err := q.ToSql() + if err != nil { + return nil, err + } + return db.ExecContext(ctx, query, args...) +} diff --git a/_example/user_item_detail.go b/_example/user_item_detail.go new file mode 100644 index 0000000..e8b0cf0 --- /dev/null +++ b/_example/user_item_detail.go @@ -0,0 +1,23 @@ +package example + +//go:generate go run ../cmd/sqlla/main.go + +//sqlla:table user_item_detail +//genddl:view user_item_detail +type UserItemDetail struct { + UserItem UserItem `db:"ui_,nested"` + Item Item `db:"i_,nested"` + User User `db:"u_,nested"` +} + +func (u UserItemDetail) _selectStatement() string { + return ` +SELECT + ui.id, ui.user_id, ui.item_id, ui.is_used, ui.has_extension, ui.used_at, + i.id, i.name, + u.id, u.name, u.age, u.rate, u.icon_image, u.created_at, u.updated_at +FROM user_item AS ui + INNER JOIN item AS i ON ui.item_id = i.id + INNER JOIN user AS u ON ui.user_id = u.id +` +} diff --git a/_example/user_withmysql_test.go b/_example/user_withmysql_test.go index 3b0243a..223bd8c 100644 --- a/_example/user_withmysql_test.go +++ b/_example/user_withmysql_test.go @@ -16,13 +16,14 @@ import ( "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql" + "github.com/google/go-cmp/cmp" "github.com/mackee/go-sqlla/v2" "github.com/ory/dockertest/v3" ) var db *sql.DB -//go:generate genddl -outpath=./mysql.sql -driver=mysql +//go:generate go run github.com/mackee/go-genddl/cmd/genddl@41aa2f4 -outpath=./mysql.sql -driver=mysql func TestMain(m *testing.M) { // uses a sensible default on windows (tcp/http) and linux/osx (socket) @@ -32,7 +33,7 @@ func TestMain(m *testing.M) { } // pulls an image, creates a container based on it and runs it - resource, err := pool.Run("mysql", "5.7", []string{ + resource, err := pool.Run("mysql", "8.0", []string{ "MYSQL_ROOT_PASSWORD=secret", "MYSQL_DATABASE=test", }) @@ -246,3 +247,53 @@ func TestBulkInsertOnDuplicateKeyUpdate__WithMySQL(t *testing.T) { } } + +func TestSelectViews(t *testing.T) { + ctx := context.Background() + now := time.Now() + + u, err := NewUserSQL().Insert(). + ValueID(42). + ValueName("foobar"). + ValueAge(sql.NullInt64{Valid: true, Int64: 17}). + ValueRate(3.14). + ValueIconImage([]byte{}). + ValueCreatedAt(now). + ValueUpdatedAt(mysql.NullTime{Valid: true, Time: now}). + ExecContext(ctx, db) + if err != nil { + t.Fatal("unexpected error:", err) + } + if _, err := NewItemSQL().Insert(). + ValueID("itemid"). + ValueName("super_expensive_item"). + ExecContext(ctx, db); err != nil { + t.Fatal("unexpected error:", err) + } + item, err := NewItemSQL().Select().ID("itemid").SingleContext(ctx, db) + if err != nil { + t.Fatal("unexpected error:", err) + } + ui, err := NewUserItemSQL().Insert(). + ValueID(222). + ValueUserID(uint64(u.Id)). + ValueItemID(string(item.ID)). + ValueIsUsed(true). + ExecContext(ctx, db) + if err != nil { + t.Fatal("unexpected error:", err) + } + + detail, err := NewUserItemDetailSQL().Select().UserItemId(ui.Id).SingleContext(ctx, db) + if err != nil { + t.Fatal("unexpected error:", err) + } + expect := UserItemDetail{ + UserItem: ui, + User: u, + Item: item, + } + if diff := cmp.Diff(expect, detail); diff != "" { + t.Errorf("result is mismatch (-want +got):\n%s", diff) + } +} diff --git a/main.go b/main.go index 2af21c2..c5dbde6 100644 --- a/main.go +++ b/main.go @@ -111,54 +111,172 @@ func toTable(tablePkg *types.Package, annotationComment string, gd *ast.GenDecl, } for _, field := range structType.Fields.List { - tagText := field.Tag.Value[1 : len(field.Tag.Value)-1] - tag := reflect.StructTag(tagText) - columnInfo := tag.Get("db") - columnMaps := strings.Split(columnInfo, ",") - columnName := columnMaps[0] - isPk := false - for _, cm := range columnMaps { - if cm == "primarykey" { - isPk = true - break - } + columns := toColumns(toColumnsInput{ + field: field, + ti: ti, + pkg: tablePkg, + }) + table.AddColumns(columns) + } + + return table, nil +} + +type dbTag struct { + columnName string + attrs []string +} + +func parseDBTag(tagText string) *dbTag { + tag := reflect.StructTag(tagText) + columnInfo := tag.Get("db") + if columnInfo == "" { + return nil + } + + attrs := strings.Split(columnInfo, ",") + columnName := attrs[0] + + return &dbTag{ + columnName: columnName, + attrs: attrs, + } +} + +func (d *dbTag) nested() bool { + for _, attr := range d.attrs[1:] { + if attr == "nested" { + return true } - t := ti.TypeOf(field.Type) - var typeName, pkgName string - baseTypeName := t.String() - nt, ok := t.(*types.Named) - if ok { - pkgName = nt.Obj().Pkg().Path() - if tablePkg.Path() != pkgName { - typeName = strings.Join([]string{nt.Obj().Pkg().Name(), nt.Obj().Name()}, ".") - } else { - typeName = nt.Obj().Name() - } - baseTypeName = typeName - if _, ok := supportedNonPrimitiveTypes[typeName]; !ok { - bt := nt.Underlying() - for _, ok := bt.Underlying().(*types.Named); ok; bt = bt.Underlying() { - } - baseTypeName = bt.String() - } + } + return false +} + +func (d *dbTag) isPrimaryKey() bool { + for _, attr := range d.attrs[1:] { + if attr == "primarykey" { + return true + } + } + return false +} + +type toColumnsInput struct { + field *ast.Field + ti *types.Info + pkg *types.Package +} + +func toColumns(input toColumnsInput) []Column { + tagText := input.field.Tag.Value[1 : len(input.field.Tag.Value)-1] + dt := parseDBTag(tagText) + if dt == nil { + return nil + } + if dt.nested() { + return toNestedColumns(toNestedColumnsInput{ + field: input.field, + ti: input.ti, + pkg: input.pkg, + prefix: dt.columnName, + }) + } + + fieldName := input.field.Names[0].Name + t := input.ti.TypeOf(input.field.Type) + return []Column{toColumn(toColumnInput{ + fieldName: fieldName, + t: t, + pkg: input.pkg, + dbTag: dt, + })} +} + +type toColumnInput struct { + fieldName string + t types.Type + pkg *types.Package + dbTag *dbTag +} + +func toColumn(input toColumnInput) Column { + isPk := input.dbTag.isPrimaryKey() + t := input.t + var typeName, pkgName string + baseTypeName := t.String() + nt, ok := t.(*types.Named) + if ok { + pkgName = nt.Obj().Pkg().Path() + if input.pkg.Path() != pkgName { + typeName = strings.Join([]string{nt.Obj().Pkg().Name(), nt.Obj().Name()}, ".") } else { - typeName = t.String() + typeName = nt.Obj().Name() } - column := Column{ - Field: field, - Name: columnName, - IsPk: isPk, - TypeName: typeName, - BaseTypeName: baseTypeName, - PkgName: pkgName, + baseTypeName = typeName + if _, ok := supportedNonPrimitiveTypes[typeName]; !ok { + bt := nt.Underlying() + for _, ok := bt.Underlying().(*types.Named); ok; bt = bt.Underlying() { + } + baseTypeName = bt.String() } - if alt, ok := altTypeNames[baseTypeName]; ok { - column.AltTypeName = alt + } else { + typeName = t.String() + } + column := Column{ + FieldName: input.fieldName, + Name: input.dbTag.columnName, + IsPk: isPk, + TypeName: typeName, + BaseTypeName: baseTypeName, + PkgName: pkgName, + } + if alt, ok := altTypeNames[baseTypeName]; ok { + column.AltTypeName = alt + } + return column +} + +type toNestedColumnsInput struct { + field *ast.Field + ti *types.Info + pkg *types.Package + prefix string +} + +func toNestedColumns(input toNestedColumnsInput) []Column { + t := input.ti.TypeOf(input.field.Type) + tn, ok := t.(*types.Named) + if !ok { + return nil + } + ut := tn.Underlying() + st, ok := ut.(*types.Struct) + if !ok { + return nil + } + columns := make([]Column, 0, st.NumFields()) + fieldName := input.field.Names[0].Name + for i := 0; i < st.NumFields(); i++ { + field := st.Field(i) + tagText := st.Tag(i) + dt := parseDBTag(tagText) + if dt == nil { + continue } - table.AddColumn(column) + + column := toColumn(toColumnInput{ + fieldName: field.Name(), + t: field.Type(), + pkg: input.pkg, + dbTag: dt, + }) + column.FieldName = strings.Join([]string{fieldName, column.FieldName}, ".") + column.Name = input.prefix + column.Name + column.IsPk = false + columns = append(columns, column) } - return table, nil + return columns } func trimAnnotation(comment string) string { diff --git a/table.go b/table.go index d009648..7531655 100644 --- a/table.go +++ b/table.go @@ -3,7 +3,6 @@ package sqlla import ( - "go/ast" "go/types" "io" "strings" @@ -26,15 +25,22 @@ func (t *Table) NamingIsStructName() bool { return t.Name == t.StructName } +func (t *Table) AddColumns(columns []Column) { + for _, c := range columns { + t.AddColumn(c) + } +} + func (t *Table) AddColumn(c Column) { if t.additionalPackagesMap == nil { t.additionalPackagesMap = make(map[string]struct{}) } c.TableName = t.Name if t.NamingIsStructName() { - c.MethodName = c.FieldName() + c.MethodName = strings.ReplaceAll(c.FieldName, ".", "") } else { - c.MethodName = strings.Title(snaker.SnakeToCamel(c.Name)) + n := strings.ReplaceAll(c.Name, ".", "_") + c.MethodName = strings.Title(snaker.SnakeToCamel(n)) } if c.IsPk { t.PkColumn = &c @@ -66,7 +72,7 @@ func (t Table) Render(w io.Writer) error { type Columns []Column type Column struct { - Field *ast.Field + FieldName string Name string MethodName string TypeName string @@ -80,10 +86,3 @@ type Column struct { func (c Column) String() string { return c.Name } - -func (c Column) FieldName() string { - if len(c.Field.Names) > 0 { - return c.Field.Names[0].Name - } - return "" -}