Setup Transaction
This commit is contained in:
		
							parent
							
								
									e2a360b9fa
								
							
						
					
					
						commit
						5ccd76f76c
					
				| @ -3,3 +3,7 @@ package gorm | |||||||
| // Association Mode contains some helper methods to handle relationship things easily.
 | // Association Mode contains some helper methods to handle relationship things easily.
 | ||||||
| type Association struct { | type Association struct { | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (db *DB) Association(column string) *Association { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | |||||||
| @ -11,12 +11,13 @@ func Query(db *gorm.DB) { | |||||||
| 	if db.Statement.SQL.String() == "" { | 	if db.Statement.SQL.String() == "" { | ||||||
| 		db.Statement.AddClauseIfNotExists(clause.Select{}) | 		db.Statement.AddClauseIfNotExists(clause.Select{}) | ||||||
| 		db.Statement.AddClauseIfNotExists(clause.From{}) | 		db.Statement.AddClauseIfNotExists(clause.From{}) | ||||||
| 
 |  | ||||||
| 		db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR") | 		db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_, err := db.DB.QueryContext(db.Context, db.Statement.SQL.String(), db.Statement.Vars...) | 	rows, err := db.DB.QueryContext(db.Context, db.Statement.SQL.String(), db.Statement.Vars...) | ||||||
| 	db.AddError(err) | 	db.AddError(err) | ||||||
|  | 	_ = rows | ||||||
|  | 	// scan rows
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Preload(db *gorm.DB) { | func Preload(db *gorm.DB) { | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ func (db *DB) Save(value interface{}) (tx *DB) { | |||||||
| 
 | 
 | ||||||
| // First find first record that match given conditions, order by primary key
 | // First find first record that match given conditions, order by primary key
 | ||||||
| func (db *DB) First(out interface{}, where ...interface{}) (tx *DB) { | func (db *DB) First(out interface{}, where ...interface{}) (tx *DB) { | ||||||
|  | 	// TODO handle where
 | ||||||
| 	tx = db.getInstance().Limit(1).Order(clause.OrderByColumn{ | 	tx = db.getInstance().Limit(1).Order(clause.OrderByColumn{ | ||||||
| 		Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, | 		Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, | ||||||
| 		Desc:   true, | 		Desc:   true, | ||||||
| @ -35,12 +36,18 @@ func (db *DB) First(out interface{}, where ...interface{}) (tx *DB) { | |||||||
| // Take return a record that match given conditions, the order will depend on the database implementation
 | // Take return a record that match given conditions, the order will depend on the database implementation
 | ||||||
| func (db *DB) Take(out interface{}, where ...interface{}) (tx *DB) { | func (db *DB) Take(out interface{}, where ...interface{}) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance() | ||||||
|  | 	tx.Statement.Dest = out | ||||||
|  | 	tx.callbacks.Query().Execute(tx) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Last find last record that match given conditions, order by primary key
 | // Last find last record that match given conditions, order by primary key
 | ||||||
| func (db *DB) Last(out interface{}, where ...interface{}) (tx *DB) { | func (db *DB) Last(out interface{}, where ...interface{}) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance().Limit(1).Order(clause.OrderByColumn{ | ||||||
|  | 		Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, | ||||||
|  | 	}) | ||||||
|  | 	tx.Statement.Dest = out | ||||||
|  | 	tx.callbacks.Query().Execute(tx) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -88,21 +95,12 @@ func (db *DB) Delete(value interface{}, where ...interface{}) (tx *DB) { | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (db *DB) Related(value interface{}, foreignKeys ...string) (tx *DB) { |  | ||||||
| 	tx = db.getInstance() |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //Preloads only preloads relations, don`t touch out
 | //Preloads only preloads relations, don`t touch out
 | ||||||
| func (db *DB) Preloads(out interface{}) (tx *DB) { | func (db *DB) Preloads(out interface{}) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance() | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (db *DB) Association(column string) *Association { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (db *DB) Count(value interface{}) (tx *DB) { | func (db *DB) Count(value interface{}) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance() | ||||||
| 	return | 	return | ||||||
| @ -130,6 +128,7 @@ func (db *DB) ScanRows(rows *sql.Rows, result interface{}) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Transaction start a transaction as a block, return error will rollback, otherwise to commit.
 | ||||||
| func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err error) { | func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err error) { | ||||||
| 	panicked := true | 	panicked := true | ||||||
| 	tx := db.Begin(opts...) | 	tx := db.Begin(opts...) | ||||||
| @ -150,21 +149,46 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Begin begins a transaction
 | ||||||
| func (db *DB) Begin(opts ...*sql.TxOptions) (tx *DB) { | func (db *DB) Begin(opts ...*sql.TxOptions) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance() | ||||||
|  | 	if beginner, ok := tx.DB.(TxBeginner); ok { | ||||||
|  | 		var opt *sql.TxOptions | ||||||
|  | 		var err error | ||||||
|  | 		if len(opts) > 0 { | ||||||
|  | 			opt = opts[0] | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if tx.DB, err = beginner.BeginTx(db.Context, opt); err != nil { | ||||||
|  | 			tx.AddError(err) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		tx.AddError(ErrInvalidTransaction) | ||||||
|  | 	} | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (db *DB) Commit() (tx *DB) { | // Commit commit a transaction
 | ||||||
| 	tx = db.getInstance() | func (db *DB) Commit() *DB { | ||||||
| 	return | 	if comminter, ok := db.DB.(TxCommiter); ok && comminter != nil { | ||||||
|  | 		db.AddError(comminter.Commit()) | ||||||
|  | 	} else { | ||||||
|  | 		db.AddError(ErrInvalidTransaction) | ||||||
|  | 	} | ||||||
|  | 	return db | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (db *DB) Rollback() (tx *DB) { | // Rollback rollback a transaction
 | ||||||
| 	tx = db.getInstance() | func (db *DB) Rollback() *DB { | ||||||
| 	return | 	if comminter, ok := db.DB.(TxCommiter); ok && comminter != nil { | ||||||
|  | 		db.AddError(comminter.Rollback()) | ||||||
|  | 	} else { | ||||||
|  | 		db.AddError(ErrInvalidTransaction) | ||||||
|  | 	} | ||||||
|  | 	return db | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Exec execute raw sql
 | ||||||
| func (db *DB) Exec(sql string, values ...interface{}) (tx *DB) { | func (db *DB) Exec(sql string, values ...interface{}) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance() | ||||||
| 	tx.Statement.SQL = strings.Builder{} | 	tx.Statement.SQL = strings.Builder{} | ||||||
|  | |||||||
| @ -25,6 +25,15 @@ type CommonDB interface { | |||||||
| 	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row | 	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type TxBeginner interface { | ||||||
|  | 	BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type TxCommiter interface { | ||||||
|  | 	Commit() error | ||||||
|  | 	Rollback() error | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type BeforeCreateInterface interface { | type BeforeCreateInterface interface { | ||||||
| 	BeforeCreate(*DB) | 	BeforeCreate(*DB) | ||||||
| } | } | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ type Interface interface { | |||||||
| 
 | 
 | ||||||
| var Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), Config{ | var Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), Config{ | ||||||
| 	SlowThreshold: 100 * time.Millisecond, | 	SlowThreshold: 100 * time.Millisecond, | ||||||
|  | 	LogLevel:      Warn, | ||||||
| 	Colorful:      true, | 	Colorful:      true, | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu