diff --git a/README.md b/README.md index 7724656..e2c1046 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ sqlBuilder.PaginateBySql(&data,&page) 注意: 1. sql-builder可以对sql进行占位符处理,@c表示条件,@o表示排序,@g表示分组,@s表示查询字段,分别对应sqlbuilder.Opts中的Conditions、Orders、Groups、Selects字段。 2. 占位符相比对应字段内的元素只能多,不能少,否则会报错。例如,在sql中有三个@c占位符,则Opts.Conditions中必须有不多于三个的元素。 +3. 可以使用InsertConditions等以Insert开头的方法,此时占位符应使用@c1,@c2等以数字结尾的字符。 示例: ``` diff --git a/db/add_sql.go b/db/add_sql.go index 10b994b..e4d303a 100644 --- a/db/add_sql.go +++ b/db/add_sql.go @@ -4,6 +4,8 @@ import ( "fmt" "reflect" "strings" + + "git.botann.com/lijun/sql-builder/util" ) func (s *SqlBuilder[T]) SetSql(sql string) { @@ -18,27 +20,57 @@ func (s *SqlBuilder[T]) Conditions(cond string, args ...interface{}) { cond, args = dealInCondition(cond, args) s.Opts.conditions = append(s.Opts.conditions, cond) s.Opts.args = append(s.Opts.args, args...) - s.buildCondition(cond) + s.buildCondition(util.ConditionPlaceholder, cond) +} + +func (s *SqlBuilder[T]) InsertConditions(symbol string, cond string, args ...interface{}) { + if strings.HasPrefix(cond, " and") { + cond = strings.Join(strings.Split(cond, " and")[1:], " and ") + } + cond, args = dealInCondition(cond, args) + s.Opts.conditions = append(s.Opts.conditions, cond) + s.Opts.args = append(s.Opts.args, args...) + s.buildCondition(symbol, cond) } func (s *SqlBuilder[T]) Selects(selects ...string) { s.Opts.selects = append(s.Opts.selects, selects...) - s.buildSelect(selects...) + s.buildSelect(util.SelectPlaceholder, selects...) +} + +func (s *SqlBuilder[T]) InsertSelects(symbol string, selects ...string) { + s.Opts.selects = append(s.Opts.selects, selects...) + s.buildSelect(symbol, selects...) } func (s *SqlBuilder[T]) Groups(groups ...string) { s.Opts.groups = append(s.Opts.groups, groups...) - s.buildGroup(groups...) + s.buildGroup(util.GroupPlaceholder, groups...) +} + +func (s *SqlBuilder[T]) InsertGroups(symbol string, groups ...string) { + s.Opts.groups = append(s.Opts.groups, groups...) + s.buildGroup(symbol, groups...) } func (s *SqlBuilder[T]) Orders(orders ...string) { s.Opts.orders = append(s.Opts.orders, orders...) - s.buildOrder(orders...) + s.buildOrder(util.OrderPlaceholder, orders...) +} + +func (s *SqlBuilder[T]) InsertOrders(symbol string, orders ...string) { + s.Opts.orders = append(s.Opts.orders, orders...) + s.buildOrder(symbol, orders...) } func (s *SqlBuilder[T]) Partitions(partitions ...string) { s.Opts.partitions = append(s.Opts.partitions, partitions...) - s.buildPartition(partitions...) + s.buildPartition(util.PartitionPlaceholder, partitions...) +} + +func (s *SqlBuilder[T]) InsertPartitions(symbol string, partitions ...string) { + s.Opts.partitions = append(s.Opts.partitions, partitions...) + s.buildPartition(symbol, partitions...) } func dealInCondition(cond string, args []interface{}) (string, []interface{}) { diff --git a/db/build.go b/db/build.go index 6a2ef74..8746141 100644 --- a/db/build.go +++ b/db/build.go @@ -2,6 +2,7 @@ package db import ( "fmt" + "regexp" "strings" "git.botann.com/lijun/sql-builder/util" @@ -23,61 +24,71 @@ func (s *SqlBuilder[T]) buildCountSql(sqls string) string { return fmt.Sprintf("select count(1) from (%s) as t", sqls) } -func (s *SqlBuilder[T]) buildSelect(selects ...string) { +func (s *SqlBuilder[T]) buildSelect(symbol string, selects ...string) { for _, v := range selects { if strings.HasPrefix(v, "select") { - s.Sql = strings.Replace(s.Sql, util.SelectPlaceholder, fmt.Sprintf("%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf("%s", v), 1) } else { - s.Sql = strings.Replace(s.Sql, util.SelectPlaceholder, fmt.Sprintf(",%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf(",%s", v), 1) } } } -func (s *SqlBuilder[T]) buildCondition(conds ...string) { +func (s *SqlBuilder[T]) buildCondition(symbol string, conds ...string) { for _, v := range conds { if strings.HasPrefix(v, "where") { - s.Sql = strings.Replace(s.Sql, util.ConditionPlaceholder, fmt.Sprintf(" %s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf(" %s", v), 1) } else { - s.Sql = strings.Replace(s.Sql, util.ConditionPlaceholder, fmt.Sprintf(" and %s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf(" and %s", v), 1) } } } -func (s *SqlBuilder[T]) buildGroup(groups ...string) { +func (s *SqlBuilder[T]) buildGroup(symbol string, groups ...string) { for _, v := range groups { if strings.HasPrefix(v, "group by") { - s.Sql = strings.Replace(s.Sql, util.GroupPlaceholder, fmt.Sprintf("%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf("%s", v), 1) } else { - s.Sql = strings.Replace(s.Sql, util.GroupPlaceholder, fmt.Sprintf(",%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf(",%s", v), 1) } } } -func (s *SqlBuilder[T]) buildOrder(orders ...string) { +func (s *SqlBuilder[T]) buildOrder(symbol string, orders ...string) { for _, v := range orders { if strings.HasPrefix(v, "order by") { - s.Sql = strings.Replace(s.Sql, util.OrderPlaceholder, fmt.Sprintf("%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf("%s", v), 1) } else { - s.Sql = strings.Replace(s.Sql, util.OrderPlaceholder, fmt.Sprintf(",%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf(",%s", v), 1) } } } // tdengine专用 -func (s *SqlBuilder[T]) buildPartition(partitions ...string) { +func (s *SqlBuilder[T]) buildPartition(symbol string, partitions ...string) { for _, v := range partitions { if strings.HasPrefix(v, "partition by") { - s.Sql = strings.Replace(s.Sql, util.PartitionPlaceholder, fmt.Sprintf("%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf("%s", v), 1) } else { - s.Sql = strings.Replace(s.Sql, util.PartitionPlaceholder, fmt.Sprintf(",%s", v), 1) + s.Sql = strings.Replace(s.Sql, symbol, fmt.Sprintf(",%s", v), 1) } } } func (s *SqlBuilder[T]) DeletePlaceholderSymbol() { - s.Sql = strings.Replace(s.Sql, util.SelectPlaceholder, "", -1) - s.Sql = strings.Replace(s.Sql, util.ConditionPlaceholder, "", -1) - s.Sql = strings.Replace(s.Sql, util.GroupPlaceholder, "", -1) - s.Sql = strings.Replace(s.Sql, util.OrderPlaceholder, "", -1) - s.Sql = strings.Replace(s.Sql, util.PartitionPlaceholder, "", -1) + s.deleteSymbol(util.SelectPlaceholder) + s.deleteSymbol(util.ConditionPlaceholder) + s.deleteSymbol(util.GroupPlaceholder) + s.deleteSymbol(util.OrderPlaceholder) + s.deleteSymbol(util.PartitionPlaceholder) +} + +func (s *SqlBuilder[T]) deleteSymbol(symbol string) { + pattern := fmt.Sprintf("%s\\d*", symbol) + re, err := regexp.Compile(pattern) + if err != nil { + fmt.Println("正则表达式编译错误:", err) + return + } + s.Sql = re.ReplaceAllString(s.Sql, "") } diff --git a/main_test.go b/main_test.go index 59106e1..5a5ac1b 100644 --- a/main_test.go +++ b/main_test.go @@ -75,17 +75,17 @@ func TestMain(m *testing.M) { inner join tcompany t2 on t1.investor_id = t2.autoseq and t2.del = 0 @c left join tinvestment_type t3 on t1.industry_category_id = t3.autoseq and t3.del = 0 left join tpreliminary_procedures t6 on t1.autoseq = t6.project_id - where t1.del = 0 @c @c @c @c @c + where t1.del = 0 @c @c @c @c @c1 @g` sqlb.Sql = slqs if company_id != 0 { - sqlb.Conditions("t2.autoseq = ?", company_id) + sqlb.InsertConditions("@c1", "t2.autoseq = ?", company_id) } sqlb.Groups("group by t1.autoseq") - fmt.Println(sqlb) var err error page := Page{PageIndex: 2, PageSize: 10} err = sqlb.PaginateBySql(&data, &page) + fmt.Println(sqlb.Sql) page.Data = &data fmt.Println(err, page.Data) }