UpdateStatement updates a statement of a specific type (permission, relation, or attribute) for a given entity within the schema. It either updates an existing statement or appends a new one if not found.
(entityName string, newStmt Statement)
| 113 | // UpdateStatement updates a statement of a specific type (permission, relation, or attribute) |
| 114 | // for a given entity within the schema. It either updates an existing statement or appends a new one if not found. |
| 115 | func (sch *Schema) UpdateStatement(entityName string, newStmt Statement) error { |
| 116 | // Iterate through all statements in the schema to find the one matching the entity name. |
| 117 | for _, statement := range sch.Statements { |
| 118 | if statement.GetName() == entityName { |
| 119 | // Convert the generic statement interface to a specific EntityStatement type. |
| 120 | entityStmt, ok := statement.(*EntityStatement) |
| 121 | if !ok { |
| 122 | return errors.New(base.ErrorCode_ERROR_CODE_CANNOT_CONVERT_TO_ENTITY_STATEMENT.String()) |
| 123 | } |
| 124 | |
| 125 | // Construct a unique reference key for the new statement. |
| 126 | referenceKey := fmt.Sprintf("%s#%s", entityName, newStmt.GetName()) |
| 127 | |
| 128 | // Check if a reference for the statement already exists within the schema. |
| 129 | if !sch.GetReferences().IsReferenceExist(referenceKey) { |
| 130 | return errors.New(base.ErrorCode_ERROR_CODE_REFERENCE_NOT_FOUND.String()) |
| 131 | } |
| 132 | |
| 133 | // Based on the statement type, update the corresponding list in the EntityStatement. |
| 134 | switch newStmt.StatementType() { |
| 135 | case PERMISSION_STATEMENT, RELATION_STATEMENT, ATTRIBUTE_STATEMENT: |
| 136 | var stmts *[]Statement // Pointer to the slice of statements to update. |
| 137 | |
| 138 | // Assign the correct slice based on the type of the new statement. |
| 139 | switch newStmt.StatementType() { |
| 140 | case PERMISSION_STATEMENT: |
| 141 | stmts = &entityStmt.PermissionStatements |
| 142 | case RELATION_STATEMENT: |
| 143 | stmts = &entityStmt.RelationStatements |
| 144 | case ATTRIBUTE_STATEMENT: |
| 145 | stmts = &entityStmt.AttributeStatements |
| 146 | } |
| 147 | |
| 148 | // Flag to check if the statement has been updated. |
| 149 | updated := false |
| 150 | |
| 151 | // Iterate over the statements to find and update the one with the matching name. |
| 152 | for i, stmt := range *stmts { |
| 153 | if stmt.GetName() == newStmt.GetName() { |
| 154 | (*stmts)[i] = newStmt |
| 155 | updated = true |
| 156 | break // Stop iterating once the statement is updated. |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // If the statement was not found and updated, append it to the slice. |
| 161 | if !updated { |
| 162 | *stmts = append(*stmts, newStmt) |
| 163 | } |
| 164 | |
| 165 | // Update the reference in the schema based on the statement type. |
| 166 | switch newStmt.StatementType() { |
| 167 | case PERMISSION_STATEMENT: |
| 168 | return sch.GetReferences().UpdatePermissionReference(referenceKey) |
| 169 | case RELATION_STATEMENT: |
| 170 | if rs, ok := newStmt.(*RelationStatement); ok { |
| 171 | return sch.GetReferences().UpdateRelationReferences(referenceKey, rs.RelationTypes) |
| 172 | } |
no test coverage detected