func SoftDeleteByIdAndVersion(DB db.IDb, table *db.Table, id int64, version int64) error { deletion := table.GetDeletionColumn() if deletion == nil { return dbx.NewPersistenceFail("DAOUtils.SoftDeleteByIdAndVersion", "Table "+table.GetName()+" does not have a deletion type column to do a soft delete.") } keyColumn := table.GetKeyColumns().Enumerator().Next().(*db.Column) versionColumn := table.GetVersionColumn() result, err := DB.Update(table). Set(deletion, tk.Milliseconds()). Set(versionColumn, version+1). Where( keyColumn.Matches(id), versionColumn.Matches(version), ). Execute() if err != nil { return err } if result == 0 { return dbx.NewOptimisticLockFail("DAOUtils.removeByIdVersion: Unable to soft delete by id and version for the table " + table.GetName()) } return nil }
func DeleteByIdAndVersion(DB db.IDb, table *db.Table, id int64, version int64) error { logger.CallerAt(1).Debugf("DAOUtils.removeByIdVersion: id: %v, version: %v", id, version) keyColumn := table.GetKeyColumns().Enumerator().Next().(*db.Column) versionColumn := table.GetVersionColumn() result, err := DB.Delete(table). Where( keyColumn.Matches(id), versionColumn.Matches(version), ). Execute() if err != nil { return err } if result == 0 { return dbx.NewOptimisticLockFail("DAOUtils.removeByIdVersion: Unable to delete by id and version for the table " + table.GetName()) } return nil }
func (this *Delete) Submit(value interface{}) (int64, error) { var mappings map[string]*EntityProperty var criterias []*Criteria typ := reflect.TypeOf(value) if typ.Kind() == reflect.Ptr { typ = typ.Elem() } if typ == this.lastType { mappings = this.lastMappings } else { mappings = PopulateMapping("", typ) criterias = make([]*Criteria, 0) this.criteria = nil this.lastMappings = mappings this.lastType = typ } var mustSucceed bool var hasId bool var ver int64 for e := this.table.GetColumns().Enumerator(); e.HasNext(); { column := e.Next().(*Column) alias := column.GetAlias() bp := mappings[alias] if bp != nil { val := bp.Get(reflect.ValueOf(value)) if val.Kind() == reflect.Ptr { val = val.Elem() } if column.IsKey() { if !val.IsValid() || (val.Kind() == reflect.Ptr && val.IsNil()) { return 0, errors.New(fmt.Sprintf("goSQL: Value for key property '%s' cannot be nil.", alias)) } if val.Kind() == reflect.Ptr { val = val.Elem() } id := val.Interface() if criterias != nil { criterias = append(criterias, column.Matches(Param(alias))) } this.SetParameter(alias, id) hasId = true } else if column.IsVersion() { if !val.IsValid() || (val.Kind() == reflect.Ptr && val.IsNil()) { panic(fmt.Sprintf("goSQL: Value for version property '%s' cannot be nil.", alias)) } if val.Kind() == reflect.Ptr { val = val.Elem() } ver = val.Int() if ver != 0 { if criterias != nil { criterias = append(criterias, column.Matches(Param(alias))) } this.SetParameter(alias, ver) mustSucceed = true } } } } if !hasId { return 0, errors.New(fmt.Sprintf("goSQL: No key field was identified in %s.", typ.String())) } if criterias != nil { this.Where(criterias...) this.rawSQL = nil } // pre trigger if t, isT := value.(PreDeleter); isT { err := t.PreDelete(this.GetDb()) if err != nil { return 0, err } } affectedRows, err := this.Execute() if err != nil { return 0, err } if affectedRows == 0 && mustSucceed { return 0, dbx.NewOptimisticLockFail(fmt.Sprintf("goSQL: Optimistic Lock Fail when deleting record for %+v", value)) } // post trigger if t, isT := value.(PostDeleter); isT { t.PostDelete(this.GetDb()) } return affectedRows, nil }
//Updates all the columns of the table to matching struct fields. //Returns the number of affected rows func (this *Update) Submit(instance interface{}) (int64, error) { var invalid bool typ := reflect.TypeOf(instance) if typ.Kind() == reflect.Ptr { typ = typ.Elem() if typ.Kind() != reflect.Struct { invalid = true } } else { invalid = true } if invalid { return 0, errors.New("The argument must be a struct pointer") } var mappings map[string]*EntityProperty var criterias []*Criteria if typ == this.lastType { mappings = this.lastMappings } else { mappings = PopulateMapping("", typ) criterias = make([]*Criteria, 0) this.criteria = nil this.lastMappings = mappings this.lastType = typ } var id interface{} var ver int64 var verColumn *Column elem := reflect.ValueOf(instance) if elem.Kind() == reflect.Ptr { elem = elem.Elem() } var marks map[string]bool markable, isMarkable := instance.(Markable) if isMarkable { marks = markable.Marks() } useMarks := len(marks) > 0 for e := this.table.GetColumns().Enumerator(); e.HasNext(); { column := e.Next().(*Column) alias := column.GetAlias() bp := mappings[alias] if bp != nil { val := bp.Get(elem) if val.Kind() == reflect.Ptr { val = val.Elem() } if column.IsKey() { if !val.IsValid() || (val.Kind() == reflect.Ptr && val.IsNil()) { return 0, errors.New(fmt.Sprintf("goSQL: Value for key property '%s' cannot be nil.", alias)) } if val.Kind() == reflect.Ptr { val = val.Elem() } id = val.Interface() if criterias != nil { criterias = append(criterias, column.Matches(Param(alias))) } this.SetParameter(alias, id) } else if column.IsVersion() { if !val.IsValid() || (val.Kind() == reflect.Ptr && val.IsNil()) { panic(fmt.Sprintf("goSQL: Value for version property '%s' cannot be nil.", alias)) } if val.Kind() == reflect.Ptr { val = val.Elem() } ver = val.Int() // if version is 0 it means an update where optimistic locking is ignored if ver != 0 { alias_old := alias + "_old" if criterias != nil { criterias = append(criterias, column.Matches(Param(alias_old))) } this.SetParameter(alias_old, ver) // increments the version this.Set(column, ver+1) verColumn = column } } else { var marked = useMarks && marks[column.GetAlias()] if val.IsValid() && (!useMarks || marked) { var isNil bool if val.Kind() == reflect.Ptr { isNil = val.IsNil() if isNil { if marked || acceptField(bp.Tag, nil) { this.Set(column, nil) } } else { val = val.Elem() } } if !isNil { v := val.Interface() switch T := v.(type) { case driver.Valuer: value, err := T.Value() if err != nil { return 0, err } if marked || acceptField(bp.Tag, value) { this.Set(column, value) } default: if marked || acceptField(bp.Tag, v) { this.Set(column, v) } } } } } } } if criterias != nil { this.Where(criterias...) this.rawSQL = nil } // pre trigger if t, isT := instance.(PreUpdater); isT { err := t.PreUpdate(this.GetDb()) if err != nil { return 0, err } } affectedRows, err := this.Execute() if err != nil { return 0, err } if verColumn != nil { if affectedRows == 0 { return 0, dbx.NewOptimisticLockFail(fmt.Sprintf("Optimistic Lock Error: Unable to UPDATE record with id=%v and version=%v for table %s", id, ver, this.GetTable().GetName())) } ver += 1 bp := mappings[verColumn.GetAlias()] bp.Set(elem, reflect.ValueOf(&ver)) } // post trigger if t, isT := instance.(PostUpdater); isT { t.PostUpdate(this.GetDb()) } if isMarkable { markable.Unmark() } return affectedRows, nil }
. "github.com/quintans/toolkit/ext" "github.com/quintans/toolkit/web/app" "crypto/tls" "fmt" "net" "net/smtp" "time" ) const FAULT_BIZ = "BIZ" var ( AbsentBoardFault = dbx.NewPersistenceFail(FAULT_BIZ, "The Board no longer exists") AbsentLaneFault = dbx.NewPersistenceFail(FAULT_BIZ, "The Lane no longer exists") OptimistickLockFault = dbx.NewOptimisticLockFail("Unable to apply changes due to a concurrent access. Try again.") ) var _ service.ITaskBoardService = &TaskBoardServiceImpl{} type TaskBoardServiceImpl struct { } func (this *TaskBoardServiceImpl) WhoAmI(c maze.IContext) (dto.IdentityDTO, error) { ctx := c.(*AppCtx) p := ctx.Principal identity := dto.IdentityDTO{} identity.Id = &p.UserId var name string ctx.Store.Query(T.USER).Column(T.USER_C_NAME). Where(T.USER_C_ID.Matches(p.UserId)).