casbin / gorm-adapter

GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex
https://github.com/casbin/casbin
Apache License 2.0
678 stars 206 forks source link

why not use Transaction to SavePolicy #207

Closed weloe closed 1 year ago

weloe commented 1 year ago

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
}
casbin-bot commented 1 year ago

@tangyang9464 @JalinWang @imp2002

weloe commented 1 year ago

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
}
hsluoyz commented 1 year ago

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

weloe commented 1 year ago

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

yes, I'll try

weloe commented 1 year ago

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

pr https://github.com/casbin/gorm-adapter/pull/208

shaolei commented 1 year ago

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