// UpdateParallelByCondition executes UPDATE query to all of the shards with conditions func (xpr *XormParallel) UpdateParallelByCondition(objPtr interface{}, cond UpdateCondition) (int64, error) { // create session with the condition sessions := xpr.CreateUpdateSessions(cond) length := len(sessions) // execute query var errList []error results := make(chan int64, length) for _, s := range sessions { go func(s Session, obj interface{}) { defer s.Close() count, err := s.Update(obj) if err != nil { errList = append(errList, err) } results <- count }(s, objPtr) } // wait for the results var counts int64 for i := 0; i < length; i++ { v := <-results counts += v } if len(errList) > 0 { return counts, errors.NewErrParallelQuery(errList) } return counts, nil }
// FindParallelByCondition executes SELECT query to all of the shards with conditions func (xpr *XormParallel) FindParallelByCondition(listPtr interface{}, cond FindCondition) error { vt := reflect.TypeOf(listPtr) if vt.Kind() != reflect.Ptr { return errors.NewErrArgType("listPtr must be a pointer") } elem := vt.Elem() if elem.Kind() != reflect.Slice && elem.Kind() != reflect.Map { return errors.NewErrArgType("listPtr must be a pointer of slice or map") } // create session with the condition slaves := xpr.orm.Slaves(cond.Table) var sessions []Session for _, slave := range slaves { s := slave.NewSession() for _, w := range cond.Where { s.And(w.Statement, w.Args...) } for _, o := range cond.OrderBy { if o.OrderByDesc { s.Desc(o.Name) } else { s.Asc(o.Name) } } if cond.Limit > 0 { s.Limit(cond.Limit, cond.Offset) } sessions = append(sessions, s) } // execute query var errList []error results := make(chan reflect.Value, len(slaves)) for _, s := range sessions { list := reflect.New(elem) go func(s Session, list reflect.Value) { err := s.Find(list.Interface()) if err != nil { errList = append(errList, err) } results <- list }(s, list) } // wait for the results e := reflect.ValueOf(listPtr).Elem() for range slaves { v := <-results e.Set(reflect.AppendSlice(e, v.Elem())) } if len(errList) > 0 { return errors.NewErrParallelQuery(errList) } return nil }
// FindParallelByCondition executes SELECT query to all of the shards with conditions func (xpr *XormParallel) FindParallelByCondition(listPtr interface{}, cond FindCondition) error { vt := reflect.TypeOf(listPtr) if vt.Kind() != reflect.Ptr { return errors.NewErrArgType("listPtr must be a pointer") } elem := vt.Elem() if elem.Kind() != reflect.Slice && elem.Kind() != reflect.Map { return errors.NewErrArgType("listPtr must be a pointer of slice or map") } // create session with the condition sessions := xpr.CreateFindSessions(cond) length := len(sessions) // execute query var errList []error results := make(chan reflect.Value, length) for _, s := range sessions { list := reflect.New(elem) go func(s Session, list reflect.Value) { defer s.Close() err := s.Find(list.Interface()) if err != nil { errList = append(errList, err) } results <- list }(s, list) } // wait for the results e := reflect.ValueOf(listPtr).Elem() for i := 0; i < length; i++ { v := <-results e.Set(reflect.AppendSlice(e, v.Elem())) } if len(errList) > 0 { return errors.NewErrParallelQuery(errList) } return nil }
// FindParallel executes SELECT query to all of the shards func (xpr *XormParallel) FindParallel(listPtr interface{}, table interface{}, where string, args ...interface{}) error { vt := reflect.TypeOf(listPtr) if vt.Kind() != reflect.Ptr { return errors.NewErrArgType("listPtr must be a pointer") } elem := vt.Elem() if elem.Kind() != reflect.Slice && elem.Kind() != reflect.Map { return errors.NewErrArgType("listPtr must be a pointer of slice or map") } slaves := xpr.orm.Slaves(table) results := make(chan reflect.Value, len(slaves)) var errList []error for _, slave := range slaves { s := slave.NewSession() list := reflect.New(elem) go func(s Session, list reflect.Value) { s.And(where, args...) err := s.Find(list.Interface()) if err != nil { errList = append(errList, err) } results <- list }(s, list) } e := reflect.ValueOf(listPtr).Elem() for range slaves { v := <-results e.Set(reflect.AppendSlice(e, v.Elem())) } if len(errList) > 0 { return errors.NewErrParallelQuery(errList) } return nil }
// CountParallelByCondition executes SELECT COUNT(*) query to all of the shards with conditions func (xpr *XormParallel) CountParallelByCondition(objPtr interface{}, cond FindCondition) ([]int64, error) { vt := reflect.TypeOf(objPtr) if vt.Kind() != reflect.Ptr { return nil, errors.NewErrArgType("objPtr must be a pointer") } // create session with the condition sessions := xpr.CreateFindSessions(cond) length := len(sessions) // execute query var errList []error results := make(chan int64, length) for _, s := range sessions { go func(s Session) { defer s.Close() count, err := s.Count(objPtr) if err != nil { errList = append(errList, err) } results <- count }(s) } // wait for the results var counts []int64 for i := 0; i < length; i++ { v := <-results counts = append(counts, v) } if len(errList) > 0 { return counts, errors.NewErrParallelQuery(errList) } return counts, nil }