parent
							
								
									4b22a55a75
								
							
						
					
					
						commit
						e8f48b5c15
					
				| @ -244,7 +244,7 @@ func (db *DB) Order(value interface{}) (tx *DB) { | ||||
| // Limit specify the number of records to be retrieved
 | ||||
| func (db *DB) Limit(limit int) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	tx.Statement.AddClause(clause.Limit{Limit: limit}) | ||||
| 	tx.Statement.AddClause(clause.Limit{Limit: &limit}) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -29,6 +29,7 @@ func BenchmarkSelect(b *testing.B) { | ||||
| func BenchmarkComplexSelect(b *testing.B) { | ||||
| 	user, _ := schema.Parse(&tests.User{}, &sync.Map{}, db.NamingStrategy) | ||||
| 
 | ||||
| 	limit10 := 10 | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		stmt := gorm.Statement{DB: db, Table: user.Table, Schema: user, Clauses: map[string]clause.Clause{}} | ||||
| 		clauses := []clause.Interface{ | ||||
| @ -43,7 +44,7 @@ func BenchmarkComplexSelect(b *testing.B) { | ||||
| 				clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"}), | ||||
| 			}}, | ||||
| 			clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}}, | ||||
| 			clause.Limit{Limit: 10, Offset: 20}, | ||||
| 			clause.Limit{Limit: &limit10, Offset: 20}, | ||||
| 			clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}}, | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -4,7 +4,7 @@ import "strconv" | ||||
| 
 | ||||
| // Limit limit clause
 | ||||
| type Limit struct { | ||||
| 	Limit  int | ||||
| 	Limit  *int | ||||
| 	Offset int | ||||
| } | ||||
| 
 | ||||
| @ -15,12 +15,12 @@ func (limit Limit) Name() string { | ||||
| 
 | ||||
| // Build build where clause
 | ||||
| func (limit Limit) Build(builder Builder) { | ||||
| 	if limit.Limit > 0 { | ||||
| 	if limit.Limit != nil && *limit.Limit >= 0 { | ||||
| 		builder.WriteString("LIMIT ") | ||||
| 		builder.WriteString(strconv.Itoa(limit.Limit)) | ||||
| 		builder.WriteString(strconv.Itoa(*limit.Limit)) | ||||
| 	} | ||||
| 	if limit.Offset > 0 { | ||||
| 		if limit.Limit > 0 { | ||||
| 		if limit.Limit != nil && *limit.Limit >= 0 { | ||||
| 			builder.WriteByte(' ') | ||||
| 		} | ||||
| 		builder.WriteString("OFFSET ") | ||||
| @ -33,7 +33,7 @@ func (limit Limit) MergeClause(clause *Clause) { | ||||
| 	clause.Name = "" | ||||
| 
 | ||||
| 	if v, ok := clause.Expression.(Limit); ok { | ||||
| 		if limit.Limit == 0 && v.Limit != 0 { | ||||
| 		if (limit.Limit == nil || *limit.Limit == 0) && (v.Limit != nil && *v.Limit != 0) { | ||||
| 			limit.Limit = v.Limit | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -8,6 +8,10 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| func TestLimit(t *testing.T) { | ||||
| 	limit0 := 0 | ||||
| 	limit10 := 10 | ||||
| 	limit50 := 50 | ||||
| 	limitNeg10 := -10 | ||||
| 	results := []struct { | ||||
| 		Clauses []clause.Interface | ||||
| 		Result  string | ||||
| @ -15,11 +19,15 @@ func TestLimit(t *testing.T) { | ||||
| 	}{ | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{ | ||||
| 				Limit:  10, | ||||
| 				Limit:  &limit10, | ||||
| 				Offset: 20, | ||||
| 			}}, | ||||
| 			"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit0}}, | ||||
| 			"SELECT * FROM `users` LIMIT 0", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}}, | ||||
| 			"SELECT * FROM `users` OFFSET 20", nil, | ||||
| @ -29,23 +37,23 @@ func TestLimit(t *testing.T) { | ||||
| 			"SELECT * FROM `users` OFFSET 30", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}, clause.Limit{Limit: 10}}, | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}, clause.Limit{Limit: &limit10}}, | ||||
| 			"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}}, | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}}, | ||||
| 			"SELECT * FROM `users` LIMIT 10 OFFSET 30", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Offset: -10}}, | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Offset: -10}}, | ||||
| 			"SELECT * FROM `users` LIMIT 10", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: -10}}, | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: &limitNeg10}}, | ||||
| 			"SELECT * FROM `users` OFFSET 30", nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: 50}}, | ||||
| 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: &limit50}}, | ||||
| 			"SELECT * FROM `users` LIMIT 50 OFFSET 30", nil, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| @ -185,7 +185,9 @@ func (db *DB) FindInBatches(dest interface{}, batchSize int, fc func(tx *DB, bat | ||||
| 	var totalSize int | ||||
| 	if c, ok := tx.Statement.Clauses["LIMIT"]; ok { | ||||
| 		if limit, ok := c.Expression.(clause.Limit); ok { | ||||
| 			totalSize = limit.Limit | ||||
| 			if limit.Limit != nil { | ||||
| 				totalSize = *limit.Limit | ||||
| 			} | ||||
| 
 | ||||
| 			if totalSize > 0 && batchSize > totalSize { | ||||
| 				batchSize = totalSize | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 robhafner
						robhafner