casbin / gorm-adapter

GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex

Home Page:https://github.com/casbin/casbin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

why not use Transaction to SavePolicy

weloe opened this issue · comments

commented

As a beginner i am a little confused, SavePolicy delete all data from table and add data after, If there is a erro in them, data can be lost

// SavePolicy saves policy to database.
func (a *Adapter) SavePolicy(model model.Model) error {
	err := a.truncateTable()
	if err != nil {
		return err
	}

	var lines []CasbinRule
	flushEvery := 1000
	for ptype, ast := range model["p"] {
		for _, rule := range ast.Policy {
			lines = append(lines, a.savePolicyLine(ptype, rule))
			if len(lines) > flushEvery {
				if err := a.db.Create(&lines).Error; err != nil {
					return err
				}
				lines = nil
			}
		}
	}

	for ptype, ast := range model["g"] {
		for _, rule := range ast.Policy {
			lines = append(lines, a.savePolicyLine(ptype, rule))
			if len(lines) > flushEvery {
				if err := a.db.Create(&lines).Error; err != nil {
					return err
				}
				lines = nil
			}
		}
	}
	if len(lines) > 0 {
		if err := a.db.Create(&lines).Error; err != nil {
			return err
		}
	}

	return nil
}
commented

like this

// SavePolicy saves policy to database.
func (a *Adapter) SavePolicy(model model.Model) error {
	var err error
	tx := a.db.Begin()

	if a.db.Config.Name() == sqlite.DriverName {
		err = tx.Exec(fmt.Sprintf("delete from %s", a.getFullTableName())).Error
	} else {
		err = tx.Exec(fmt.Sprintf("truncate table %s", a.getFullTableName())).Error
	}

	if err != nil {
		tx.Rollback()
		return err
	}

	var lines []CasbinRule
	flushEvery := 1000
	for ptype, ast := range model["p"] {
		for _, rule := range ast.Policy {
			lines = append(lines, a.savePolicyLine(ptype, rule))
			if len(lines) > flushEvery {
				if err := tx.Create(&lines).Error; err != nil {
					tx.Rollback()
					return err
				}
				lines = nil
			}
		}
	}

	for ptype, ast := range model["g"] {
		for _, rule := range ast.Policy {
			lines = append(lines, a.savePolicyLine(ptype, rule))
			if len(lines) > flushEvery {
				if err := tx.Create(&lines).Error; err != nil {
					tx.Rollback()
					return err
				}
				lines = nil
			}
		}
	}
	if len(lines) > 0 {
		if err := tx.Create(&lines).Error; err != nil {
			tx.Rollback()
			return err
		}
	}

	tx.Commit()

	return nil
}

@weloe good idea. Can you make a PR to add the transaction?

commented

@weloe good idea. Can you make a PR to add the transaction?

yes, I'll try

commented

@weloe good idea. Can you make a PR to add the transaction?

pr #208

也许这个能解决之前一些权限莫名其妙失效的问题