github.com/RevenueMonster/sqlike@v1.0.6/sqlike/delete.go (about) 1 package sqlike 2 3 import ( 4 "context" 5 "errors" 6 7 "github.com/RevenueMonster/sqlike/reflext" 8 sqldialect "github.com/RevenueMonster/sqlike/sql/dialect" 9 sqldriver "github.com/RevenueMonster/sqlike/sql/driver" 10 "github.com/RevenueMonster/sqlike/sql/expr" 11 sqlstmt "github.com/RevenueMonster/sqlike/sql/stmt" 12 "github.com/RevenueMonster/sqlike/sqlike/actions" 13 "github.com/RevenueMonster/sqlike/sqlike/logs" 14 "github.com/RevenueMonster/sqlike/sqlike/options" 15 ) 16 17 // DestroyOne : hard delete a record on the table using primary key. You should alway have primary key defined in your struct in order to use this api. 18 func (tb *Table) DestroyOne(ctx context.Context, delete interface{}, opts ...*options.DestroyOneOptions) error { 19 opt := new(options.DestroyOneOptions) 20 if len(opts) > 0 && opts[0] != nil { 21 opt = opts[0] 22 } 23 return destroyOne( 24 ctx, 25 tb.dbName, 26 tb.name, 27 tb.pk, 28 tb.client.cache, 29 tb.driver, 30 tb.dialect, 31 tb.logger, 32 delete, 33 opt, 34 ) 35 } 36 37 // DeleteOne : delete single record on the table using where clause. 38 func (tb *Table) DeleteOne(ctx context.Context, act actions.DeleteOneStatement, opts ...*options.DeleteOneOptions) (int64, error) { 39 x := new(actions.DeleteOneActions) 40 if act != nil { 41 *x = *(act.(*actions.DeleteOneActions)) 42 } 43 opt := new(options.DeleteOneOptions) 44 if len(opts) > 0 && opts[0] != nil { 45 opt = opts[0] 46 } 47 x.Limit(1) 48 return deleteMany( 49 ctx, 50 tb.dbName, 51 tb.name, 52 tb.driver, 53 tb.dialect, 54 tb.logger, 55 &x.DeleteActions, 56 &opt.DeleteOptions, 57 ) 58 } 59 60 // Delete : delete multiple record on the table using where clause. If you didn't provided any where clause, it will throw error. For multiple record deletion without where clause, you should use `Truncate` instead. 61 func (tb *Table) Delete(ctx context.Context, act actions.DeleteStatement, opts ...*options.DeleteOptions) (int64, error) { 62 x := new(actions.DeleteActions) 63 if act != nil { 64 *x = *(act.(*actions.DeleteActions)) 65 } 66 opt := new(options.DeleteOptions) 67 if len(opts) > 0 && opts[0] != nil { 68 opt = opts[0] 69 } 70 return deleteMany( 71 ctx, 72 tb.dbName, 73 tb.name, 74 tb.driver, 75 tb.dialect, 76 tb.logger, 77 x, 78 opt, 79 ) 80 } 81 82 func deleteMany(ctx context.Context, dbName, tbName string, driver sqldriver.Driver, dialect sqldialect.Dialect, logger logs.Logger, act *actions.DeleteActions, opt *options.DeleteOptions) (int64, error) { 83 if act.Database == "" { 84 act.Database = dbName 85 } 86 if act.Table == "" { 87 act.Table = tbName 88 } 89 if len(act.Conditions) < 1 { 90 return 0, errors.New("sqlike: empty condition is not allow for delete, please use truncate instead") 91 } 92 93 stmt := sqlstmt.AcquireStmt(dialect) 94 defer sqlstmt.ReleaseStmt(stmt) 95 if err := dialect.Delete(stmt, act); err != nil { 96 return 0, err 97 } 98 result, err := sqldriver.Execute( 99 ctx, 100 driver, 101 stmt, 102 getLogger(logger, opt.Debug), 103 ) 104 if err != nil { 105 return 0, err 106 } 107 return result.RowsAffected() 108 } 109 110 func destroyOne(ctx context.Context, dbName, tbName, pk string, cache reflext.StructMapper, driver sqldriver.Driver, dialect sqldialect.Dialect, logger logs.Logger, delete interface{}, opt *options.DestroyOneOptions) error { 111 v := reflext.ValueOf(delete) 112 if !v.IsValid() { 113 return ErrInvalidInput 114 } 115 116 t := v.Type() 117 cdc := cache.CodecByType(t) 118 x := new(actions.DeleteActions) 119 x.Database = dbName 120 x.Table = tbName 121 122 var pkv = [2]interface{}{} 123 for _, sf := range cdc.Properties() { 124 fv := cache.FieldByIndexesReadOnly(v, sf.Index()) 125 if _, ok := sf.Tag().LookUp("primary_key"); ok { 126 pkv[0] = sf.Name() 127 pkv[1] = fv.Interface() 128 continue 129 } 130 if sf.Name() == pk && pkv[0] == nil { 131 pkv[0] = sf.Name() 132 pkv[1] = fv.Interface() 133 continue 134 } 135 } 136 137 if pkv[0] == nil { 138 return errors.New("sqlike: missing primary key field") 139 } 140 141 x.Where(expr.Equal(pkv[0], pkv[1])) 142 x.Limit(1) 143 144 stmt := sqlstmt.AcquireStmt(dialect) 145 defer sqlstmt.ReleaseStmt(stmt) 146 if err := dialect.Delete(stmt, x); err != nil { 147 return err 148 } 149 result, err := sqldriver.Execute( 150 ctx, 151 driver, 152 stmt, 153 getLogger(logger, opt.Debug), 154 ) 155 if err != nil { 156 return err 157 } 158 if affected, _ := result.RowsAffected(); affected <= 0 { 159 return errors.New("sqlike: unable to delete entity") 160 } 161 return err 162 }