github.com/RevenueMonster/sqlike@v1.0.6/sqlike/insert.go (about) 1 package sqlike 2 3 import ( 4 "context" 5 "database/sql" 6 "reflect" 7 8 "errors" 9 10 "github.com/RevenueMonster/sqlike/reflext" 11 "github.com/RevenueMonster/sqlike/sql/codec" 12 sqldialect "github.com/RevenueMonster/sqlike/sql/dialect" 13 sqldriver "github.com/RevenueMonster/sqlike/sql/driver" 14 sqlstmt "github.com/RevenueMonster/sqlike/sql/stmt" 15 "github.com/RevenueMonster/sqlike/sqlike/logs" 16 "github.com/RevenueMonster/sqlike/sqlike/options" 17 ) 18 19 // InsertOne : insert single record. You should always pass in the address of input. 20 func (tb *Table) InsertOne(ctx context.Context, src interface{}, opts ...*options.InsertOneOptions) (sql.Result, error) { 21 opt := new(options.InsertOneOptions) 22 if len(opts) > 0 && opts[0] != nil { 23 opt = opts[0] 24 } 25 v := reflect.ValueOf(src) 26 if !v.IsValid() { 27 return nil, ErrInvalidInput 28 } 29 t := v.Type() 30 if !reflext.IsKind(t, reflect.Ptr) { 31 return nil, ErrUnaddressableEntity 32 } 33 34 if v.IsNil() { 35 return nil, ErrNilEntity 36 } 37 38 arr := reflect.MakeSlice(reflect.SliceOf(t), 0, 1) 39 arr = reflect.Append(arr, v) 40 return insertMany( 41 ctx, 42 tb.dbName, 43 tb.name, 44 tb.pk, 45 tb.client.cache, 46 tb.codec, 47 tb.driver, 48 tb.dialect, 49 tb.logger, 50 arr.Interface(), 51 &opt.InsertOptions, 52 ) 53 } 54 55 // Insert : insert multiple records. You should always pass in the address of the slice. 56 func (tb *Table) Insert(ctx context.Context, src interface{}, opts ...*options.InsertOptions) (sql.Result, error) { 57 opt := new(options.InsertOptions) 58 if len(opts) > 0 && opts[0] != nil { 59 opt = opts[0] 60 } 61 return insertMany( 62 ctx, 63 tb.dbName, 64 tb.name, 65 tb.pk, 66 tb.client.cache, 67 tb.codec, 68 tb.driver, 69 tb.dialect, 70 tb.logger, 71 src, 72 opt, 73 ) 74 } 75 76 func insertMany(ctx context.Context, dbName, tbName, pk string, cache reflext.StructMapper, cdc codec.Codecer, driver sqldriver.Driver, dialect sqldialect.Dialect, logger logs.Logger, src interface{}, opt *options.InsertOptions) (sql.Result, error) { 77 v := reflext.ValueOf(src) 78 if !v.IsValid() { 79 return nil, ErrInvalidInput 80 } 81 82 v = reflext.Indirect(v) 83 t := v.Type() 84 if !reflext.IsKind(t, reflect.Array) && !reflext.IsKind(t, reflect.Slice) { 85 return nil, errors.New("sqlike: insert only support array or slice of entity") 86 } 87 88 if v.Len() < 1 { 89 return nil, ErrInvalidInput 90 } 91 92 t = reflext.Deref(t.Elem()) 93 if !reflext.IsKind(t, reflect.Struct) { 94 return nil, ErrUnaddressableEntity 95 } 96 97 def := cache.CodecByType(t) 98 stmt := sqlstmt.AcquireStmt(dialect) 99 defer sqlstmt.ReleaseStmt(stmt) 100 101 if err := dialect.InsertInto( 102 stmt, 103 dbName, 104 tbName, 105 pk, 106 cache, 107 cdc, 108 def.Properties(), 109 v, 110 opt, 111 ); err != nil { 112 return nil, err 113 } 114 return sqldriver.Execute( 115 ctx, 116 driver, 117 stmt, 118 getLogger(logger, opt.Debug), 119 ) 120 }