コード例 #1
0
ファイル: xorm_parallel.go プロジェクト: evalphobia/wizard
// 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
}
コード例 #2
0
ファイル: xorm_parallel.go プロジェクト: gitter-badger/wizard
// 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
}
コード例 #3
0
ファイル: xorm_parallel.go プロジェクト: evalphobia/wizard
// 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
}
コード例 #4
0
ファイル: xorm_parallel.go プロジェクト: kaneshin/wizard
// 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
}
コード例 #5
0
ファイル: xorm_parallel.go プロジェクト: evalphobia/wizard
// 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
}