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