Add creatable, updatable, readable permission

This commit is contained in:
Jinzhu 2020-04-08 08:15:00 +08:00
parent d39bdc3513
commit 29cd35219f
5 changed files with 45 additions and 13 deletions

View File

@ -194,13 +194,13 @@ func AfterCreate(db *gorm.DB) {
func ConvertToCreateValues(stmt *gorm.Statement) clause.Values { func ConvertToCreateValues(stmt *gorm.Statement) clause.Values {
switch value := stmt.Dest.(type) { switch value := stmt.Dest.(type) {
case map[string]interface{}: case map[string]interface{}:
return ConvertMapToValues(stmt, value) return ConvertMapToValuesForCreate(stmt, value)
case []map[string]interface{}: case []map[string]interface{}:
return ConvertSliceOfMapToValues(stmt, value) return ConvertSliceOfMapToValuesForCreate(stmt, value)
default: default:
var ( var (
values = clause.Values{} values = clause.Values{}
selectColumns, restricted = SelectAndOmitColumns(stmt) selectColumns, restricted = SelectAndOmitColumns(stmt, true, false)
curTime = stmt.DB.NowFunc() curTime = stmt.DB.NowFunc()
isZero = false isZero = false
) )

View File

@ -8,7 +8,7 @@ import (
) )
// SelectAndOmitColumns get select and omit columns, select -> true, omit -> false // SelectAndOmitColumns get select and omit columns, select -> true, omit -> false
func SelectAndOmitColumns(stmt *gorm.Statement) (map[string]bool, bool) { func SelectAndOmitColumns(stmt *gorm.Statement, requireCreate, requireUpdate bool) (map[string]bool, bool) {
results := map[string]bool{} results := map[string]bool{}
// select columns // select columns
@ -36,13 +36,23 @@ func SelectAndOmitColumns(stmt *gorm.Statement) (map[string]bool, bool) {
} }
} }
if stmt.Schema != nil {
for _, field := range stmt.Schema.FieldsByDBName {
if requireCreate && !field.Creatable {
results[field.DBName] = false
} else if requireUpdate && !field.Updatable {
results[field.DBName] = false
}
}
}
return results, len(stmt.Selects) > 0 return results, len(stmt.Selects) > 0
} }
// ConvertMapToValues convert map to values // ConvertMapToValuesForCreate convert map to values
func ConvertMapToValues(stmt *gorm.Statement, mapValue map[string]interface{}) (values clause.Values) { func ConvertMapToValuesForCreate(stmt *gorm.Statement, mapValue map[string]interface{}) (values clause.Values) {
columns := make([]string, 0, len(mapValue)) columns := make([]string, 0, len(mapValue))
selectColumns, restricted := SelectAndOmitColumns(stmt) selectColumns, restricted := SelectAndOmitColumns(stmt, true, false)
var keys []string var keys []string
for k, _ := range mapValue { for k, _ := range mapValue {
@ -64,12 +74,12 @@ func ConvertMapToValues(stmt *gorm.Statement, mapValue map[string]interface{}) (
return return
} }
// ConvertSliceOfMapToValues convert slice of map to values // ConvertSliceOfMapToValuesForCreate convert slice of map to values
func ConvertSliceOfMapToValues(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) { func ConvertSliceOfMapToValuesForCreate(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) {
var ( var (
columns = []string{} columns = []string{}
result = map[string][]interface{}{} result = map[string][]interface{}{}
selectColumns, restricted = SelectAndOmitColumns(stmt) selectColumns, restricted = SelectAndOmitColumns(stmt, true, false)
) )
for idx, mapValue := range mapValues { for idx, mapValue := range mapValues {

View File

@ -56,7 +56,11 @@ func Scan(rows *sql.Rows, db *gorm.DB) {
fields := make([]*schema.Field, len(columns)) fields := make([]*schema.Field, len(columns))
for idx, column := range columns { for idx, column := range columns {
fields[idx] = db.Statement.Schema.LookUpField(column) if field := db.Statement.Schema.LookUpField(column); field != nil && field.Readable {
fields[idx] = field
} else {
values[idx] = sql.RawBytes{}
}
} }
for rows.Next() { for rows.Next() {
@ -80,7 +84,7 @@ func Scan(rows *sql.Rows, db *gorm.DB) {
} }
case reflect.Struct: case reflect.Struct:
for idx, column := range columns { for idx, column := range columns {
if field := db.Statement.Schema.LookUpField(column); field != nil { if field := db.Statement.Schema.LookUpField(column); field != nil && field.Readable {
values[idx] = field.ReflectValueOf(db.Statement.ReflectValue).Addr().Interface() values[idx] = field.ReflectValueOf(db.Statement.ReflectValue).Addr().Interface()
} else { } else {
values[idx] = sql.RawBytes{} values[idx] = sql.RawBytes{}

View File

@ -91,7 +91,7 @@ func AfterUpdate(db *gorm.DB) {
// ConvertToAssignments convert to update assignments // ConvertToAssignments convert to update assignments
func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
selectColumns, restricted := SelectAndOmitColumns(stmt) selectColumns, restricted := SelectAndOmitColumns(stmt, false, true)
reflectModelValue := reflect.ValueOf(stmt.Model) reflectModelValue := reflect.ValueOf(stmt.Model)
switch value := stmt.Dest.(type) { switch value := stmt.Dest.(type) {

View File

@ -42,6 +42,7 @@ type Field struct {
AutoIncrement bool AutoIncrement bool
Creatable bool Creatable bool
Updatable bool Updatable bool
Readable bool
HasDefaultValue bool HasDefaultValue bool
AutoCreateTime TimeType AutoCreateTime TimeType
AutoUpdateTime TimeType AutoUpdateTime TimeType
@ -73,6 +74,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
StructField: fieldStruct, StructField: fieldStruct,
Creatable: true, Creatable: true,
Updatable: true, Updatable: true,
Readable: true,
Tag: fieldStruct.Tag, Tag: fieldStruct.Tag,
TagSettings: ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";"), TagSettings: ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";"),
Schema: schema, Schema: schema,
@ -117,6 +119,21 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
if _, ok := field.TagSettings["-"]; ok { if _, ok := field.TagSettings["-"]; ok {
field.Creatable = false field.Creatable = false
field.Updatable = false field.Updatable = false
field.Readable = false
}
if v, ok := field.TagSettings["<-"]; ok {
if !strings.Contains(v, "create") {
field.Creatable = false
}
if !strings.Contains(v, "update") {
field.Updatable = false
}
}
if _, ok := field.TagSettings["->"]; ok {
field.Readable = false
} }
if dbName, ok := field.TagSettings["COLUMN"]; ok { if dbName, ok := field.TagSettings["COLUMN"]; ok {
@ -235,6 +252,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
var err error var err error
field.Creatable = false field.Creatable = false
field.Updatable = false field.Updatable = false
field.Readable = false
if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), &sync.Map{}, schema.namer); err != nil { if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), &sync.Map{}, schema.namer); err != nil {
schema.err = err schema.err = err
} }