14
14
* See the License for the specific language governing permissions and
15
15
* limitations under the License.
16
16
*/
17
-
18
17
package gplus
19
18
20
19
import (
21
20
"database/sql"
22
- "reflect"
23
-
24
21
"github.com/acmestack/gorm-plus/constants"
25
22
"gorm.io/gorm"
26
23
"gorm.io/gorm/schema"
27
24
"gorm.io/gorm/utils"
25
+ "reflect"
26
+ "strings"
28
27
)
29
28
30
29
var globalDb * gorm.DB
@@ -45,8 +44,7 @@ type Page[T any] struct {
45
44
type Dao [T any ] struct {}
46
45
47
46
func (dao Dao [T ]) NewQuery () (* QueryCond [T ], * T ) {
48
- q := & QueryCond [T ]{}
49
- return q , nil
47
+ return NewQuery [T ]()
50
48
}
51
49
52
50
func NewPage [T any ](current , size int ) * Page [T ] {
@@ -268,8 +266,11 @@ func paginate[T any](p *Page[T]) func(db *gorm.DB) *gorm.DB {
268
266
269
267
func buildCondition [T any ](q * QueryCond [T ], opts ... OptionFunc ) * gorm.DB {
270
268
db := getDb (opts ... )
269
+ // 这里清空参数,避免用户重复使用一个query条件
270
+ q .queryArgs = make ([]any , 0 )
271
271
resultDb := db .Model (new (T ))
272
272
if q != nil {
273
+
273
274
if len (q .distinctColumns ) > 0 {
274
275
resultDb .Distinct (q .distinctColumns )
275
276
}
@@ -278,19 +279,11 @@ func buildCondition[T any](q *QueryCond[T], opts ...OptionFunc) *gorm.DB {
278
279
resultDb .Select (q .selectColumns )
279
280
}
280
281
281
- if q .queryBuilder .Len () > 0 {
282
-
283
- if q .andNestBuilder .Len () > 0 {
284
- q .queryArgs = append (q .queryArgs , q .andNestArgs ... )
285
- q .queryBuilder .WriteString (q .andNestBuilder .String ())
286
- }
287
-
288
- if q .orNestBuilder .Len () > 0 {
289
- q .queryArgs = append (q .queryArgs , q .orNestArgs ... )
290
- q .queryBuilder .WriteString (q .orNestBuilder .String ())
291
- }
292
-
293
- resultDb .Where (q .queryBuilder .String (), q .queryArgs ... )
282
+ expressions := q .queryExpressions
283
+ if len (expressions ) > 0 {
284
+ var sqlBuilder strings.Builder
285
+ q .queryArgs = buildSqlAndArgs [T ](expressions , & sqlBuilder , q .queryArgs )
286
+ resultDb .Where (sqlBuilder .String (), q .queryArgs ... )
294
287
}
295
288
296
289
if q .orderBuilder .Len () > 0 {
@@ -316,29 +309,31 @@ func buildCondition[T any](q *QueryCond[T], opts ...OptionFunc) *gorm.DB {
316
309
return resultDb
317
310
}
318
311
319
- func getPkColumnName [T any ]() string {
320
- var entity T
321
- entityType := reflect .TypeOf (entity )
322
- numField := entityType .NumField ()
323
- var columnName string
324
- for i := 0 ; i < numField ; i ++ {
325
- field := entityType .Field (i )
326
- tagSetting := schema .ParseTagSetting (field .Tag .Get ("gorm" ), ";" )
327
- isPrimaryKey := utils .CheckTruth (tagSetting ["PRIMARYKEY" ], tagSetting ["PRIMARY_KEY" ])
328
- if isPrimaryKey {
329
- name , ok := tagSetting ["COLUMN" ]
330
- if ! ok {
331
- namingStrategy := schema.NamingStrategy {}
332
- name = namingStrategy .ColumnName ("" , field .Name )
312
+ func buildSqlAndArgs [T any ](expressions []any , sqlBuilder * strings.Builder , queryArgs []any ) []any {
313
+ for _ , v := range expressions {
314
+ // 判断是否是columnValue类型
315
+ switch segment := v .(type ) {
316
+ case * columnPointer :
317
+ sqlBuilder .WriteString (segment .getSqlSegment () + " " )
318
+ case * sqlKeyword :
319
+ sqlBuilder .WriteString (segment .getSqlSegment () + " " )
320
+ case * columnValue :
321
+ if segment .value == constants .And {
322
+ sqlBuilder .WriteString (segment .value .(string ) + " " )
323
+ continue
333
324
}
334
- columnName = name
335
- break
325
+ if segment .value != "" {
326
+ sqlBuilder .WriteString ("? " )
327
+ queryArgs = append (queryArgs , segment .value )
328
+ }
329
+ case * QueryCond [T ]:
330
+ sqlBuilder .WriteString (constants .LeftBracket + " " )
331
+ // 递归处理条件
332
+ queryArgs = buildSqlAndArgs [T ](segment .queryExpressions , sqlBuilder , queryArgs )
333
+ sqlBuilder .WriteString (constants .RightBracket + " " )
336
334
}
337
335
}
338
- if columnName == "" {
339
- return constants .DefaultPrimaryName
340
- }
341
- return columnName
336
+ return queryArgs
342
337
}
343
338
344
339
func getDb (opts ... OptionFunc ) * gorm.DB {
@@ -359,6 +354,14 @@ func getDb(opts ...OptionFunc) *gorm.DB {
359
354
return db
360
355
}
361
356
357
+ func getOption (opts []OptionFunc ) Option {
358
+ var config Option
359
+ for _ , op := range opts {
360
+ op (& config )
361
+ }
362
+ return config
363
+ }
364
+
362
365
func setSelectIfNeed (option Option , db * gorm.DB ) {
363
366
if len (option .Selects ) > 0 {
364
367
var columnNames []string
@@ -381,10 +384,27 @@ func setOmitIfNeed(option Option, db *gorm.DB) {
381
384
}
382
385
}
383
386
384
- func getOption (opts []OptionFunc ) Option {
385
- var config Option
386
- for _ , op := range opts {
387
- op (& config )
387
+ func getPkColumnName [T any ]() string {
388
+ var entity T
389
+ entityType := reflect .TypeOf (entity )
390
+ numField := entityType .NumField ()
391
+ var columnName string
392
+ for i := 0 ; i < numField ; i ++ {
393
+ field := entityType .Field (i )
394
+ tagSetting := schema .ParseTagSetting (field .Tag .Get ("gorm" ), ";" )
395
+ isPrimaryKey := utils .CheckTruth (tagSetting ["PRIMARYKEY" ], tagSetting ["PRIMARY_KEY" ])
396
+ if isPrimaryKey {
397
+ name , ok := tagSetting ["COLUMN" ]
398
+ if ! ok {
399
+ namingStrategy := schema.NamingStrategy {}
400
+ name = namingStrategy .ColumnName ("" , field .Name )
401
+ }
402
+ columnName = name
403
+ break
404
+ }
388
405
}
389
- return config
406
+ if columnName == "" {
407
+ return constants .DefaultPrimaryName
408
+ }
409
+ return columnName
390
410
}
0 commit comments