예제 #1
0
func (r *Router) generateUpdateSql(plan *Plan, stmt sqlparser.Statement) error {
	sqls := make(map[string][]string)
	node, ok := stmt.(*sqlparser.Update)
	if ok == false {
		return errors.ErrStmtConvert
	}
	if len(plan.RouteNodeIndexs) == 0 {
		return errors.ErrNoRouteNode
	}
	if len(plan.RouteTableIndexs) == 0 {
		buf := sqlparser.NewTrackedBuffer(nil)
		stmt.Format(buf)
		nodeName := r.Nodes[0]
		sqls[nodeName] = []string{buf.String()}
	} else {
		nodeCount := len(plan.RouteNodeIndexs)
		if 1 < nodeCount {
			golog.Error("Router", "generateUpdateSql", errors.ErrUpdateInMulti.Error(), 0,
				"RouteNodeIndexs", plan.RouteNodeIndexs)
			return errors.ErrUpdateInMulti
		}
		tableCount := len(plan.RouteTableIndexs)
		for i := 0; i < tableCount; i++ {
			buf := sqlparser.NewTrackedBuffer(nil)
			buf.Fprintf("update %v%v",
				node.Comments,
				node.Table,
			)
			fmt.Fprintf(buf, "_%04d", plan.RouteTableIndexs[i])
			buf.Fprintf(" set %v%v%v%v",
				node.Exprs,
				node.Where,
				node.OrderBy,
				node.Limit,
			)
			tableIndex := plan.RouteTableIndexs[i]
			nodeIndex := plan.Rule.TableToNode[tableIndex]
			nodeName := r.Nodes[nodeIndex]
			if _, ok := sqls[nodeName]; ok == false {
				sqls[nodeName] = make([]string, 0, tableCount)
			}
			sqls[nodeName] = append(sqls[nodeName], buf.String())
		}

	}
	plan.RewrittenSqls = sqls
	return nil
}
예제 #2
0
func (r *Router) generateSelectSql(plan *Plan, stmt sqlparser.Statement) error {
	sqls := make(map[string][]string)
	node, ok := stmt.(*sqlparser.Select)
	if ok == false {
		return errors.ErrStmtConvert
	}
	if len(plan.RouteNodeIndexs) == 0 {
		return errors.ErrNoRouteNode
	}
	if len(plan.RouteTableIndexs) == 0 {
		buf := sqlparser.NewTrackedBuffer(nil)
		stmt.Format(buf)
		nodeName := r.Nodes[0]
		sqls[nodeName] = []string{buf.String()}
	} else {
		tableCount := len(plan.RouteTableIndexs)
		for i := 0; i < tableCount; i++ {
			buf := sqlparser.NewTrackedBuffer(nil)
			buf.Fprintf("select %v%s%v from ",
				node.Comments,
				node.Distinct,
				node.SelectExprs,
			)
			switch v := (node.From[0]).(type) {
			case *sqlparser.AliasedTableExpr:
				if len(v.As) != 0 {
					fmt.Fprintf(buf, "%s_%04d AS %s",
						sqlparser.String(v.Expr),
						plan.RouteTableIndexs[i],
						string(v.As),
					)
				} else {
					fmt.Fprintf(buf, "%s_%04d",
						sqlparser.String(v.Expr),
						plan.RouteTableIndexs[i],
					)
				}
			case *sqlparser.JoinTableExpr:
				if ate, ok := (v.LeftExpr).(*sqlparser.AliasedTableExpr); ok {
					if len(ate.As) != 0 {
						fmt.Fprintf(buf, "%s_%04d AS %s",
							sqlparser.String(ate.Expr),
							plan.RouteTableIndexs[i],
							string(ate.As),
						)
					} else {
						fmt.Fprintf(buf, "%s_%04d",
							sqlparser.String(ate.Expr),
							plan.RouteTableIndexs[i],
						)
					}
				} else {
					fmt.Fprintf(buf, "%s_%04d",
						sqlparser.String(v.LeftExpr),
						plan.RouteTableIndexs[i],
					)
				}
				buf.Fprintf(" %s %v", v.Join, v.RightExpr)
				if v.On != nil {
					buf.Fprintf(" on %v", v.On)
				}
			default:
				fmt.Fprintf(buf, "%s_%04d",
					sqlparser.String(node.From[0]),
					plan.RouteTableIndexs[i],
				)
			}
			buf.Fprintf("%v%v%v%v%v%s",
				node.Where,
				node.GroupBy,
				node.Having,
				node.OrderBy,
				node.Limit,
				node.Lock,
			)

			tableIndex := plan.RouteTableIndexs[i]
			nodeIndex := plan.Rule.TableToNode[tableIndex]
			nodeName := r.Nodes[nodeIndex]
			if _, ok := sqls[nodeName]; ok == false {
				sqls[nodeName] = make([]string, 0, tableCount)
			}
			sqls[nodeName] = append(sqls[nodeName], buf.String())
		}

	}
	plan.RewrittenSqls = sqls
	return nil
}