@@ -6,6 +6,7 @@ package builder
66
77import (
88"fmt"
9+ "math/rand"
910"testing"
1011
1112"github.com/stretchr/testify/assert"
@@ -203,3 +204,116 @@ func TestBuilder_Limit(t *testing.T) {
203204assert .EqualValues (t , 3 , len (args ))
204205fmt .Println (sql , args )
205206}
207+
208+ func BenchmarkBuilder_Limit (b * testing.B ) {
209+ for i := 0 ; i < b .N ; i ++ {
210+ b .StopTimer ()
211+ builder := randQuery (rand .Intn (1000 ) >= 500 , true )
212+ b .StartTimer ()
213+
214+ _ , _ , err := builder .ToSQL ()
215+ assert .NoError (b , err )
216+ }
217+ }
218+
219+ func TestRandQuery (t * testing.T ) {
220+ sql , args , err := randQuery (false , true ).ToSQL ()
221+ assert .NoError (t , err )
222+ fmt .Println (sql , args )
223+
224+ sql , args , err = randQuery (false , false ).ToSQL ()
225+ assert .NoError (t , err )
226+ fmt .Println (sql , args )
227+
228+ sql , args , err = randQuery (true , false ).ToSQL ()
229+ assert .NoError (t , err )
230+ fmt .Println (sql , args )
231+
232+ sql , args , err = randQuery (true , true ).ToSQL ()
233+ assert .NoError (t , err )
234+ fmt .Println (sql , args )
235+ }
236+
237+ // randQuery Generate a basic query for benchmark test. But be careful it's not a executable SQL in real db.
238+ func randQuery (allowUnion , allowLimit bool ) * Builder {
239+ b := randSimpleQuery (allowLimit )
240+ if allowUnion {
241+ r := rand .Intn (3 ) + 1
242+ for i := r ; i < r ; i ++ {
243+ b = b .Union ("all" , randSimpleQuery (allowLimit ))
244+ }
245+ }
246+
247+ return b
248+ }
249+
250+ func randSimpleQuery (allowLimit bool ) * Builder {
251+ b := Dialect (randDialect ()).Select (randSelects ()... ).From (randTableName (0 )).PK ("id" )
252+ b = randJoin (b , 3 )
253+ b = b .Where (randCond (b .selects , 3 ))
254+ if allowLimit {
255+ b = randLimit (b )
256+ }
257+
258+ return b
259+ }
260+
261+ func randDialect () string {
262+ dialects := []string {MYSQL , ORACLE , MSSQL , SQLITE , POSTGRES }
263+
264+ return dialects [rand .Intn (len (dialects ))]
265+ }
266+
267+ func randSelects () []string {
268+ selects := []string {"a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" }
269+
270+ if rand .Intn (1000 ) > 900 {
271+ return []string {"*" }
272+ }
273+
274+ rdx := rand .Intn (len (selects ) / 2 )
275+ return selects [rdx :]
276+ }
277+
278+ func randTableName (offset int ) string {
279+ return fmt .Sprintf ("table%v" , rand .Intn (10 )+ offset )
280+ }
281+
282+ func randJoin (b * Builder , lessThan int ) * Builder {
283+ if lessThan <= 0 {
284+ return b
285+ }
286+
287+ times := rand .Intn (lessThan )
288+
289+ for i := 0 ; i < times ; i ++ {
290+ tableName := randTableName (i * 10 )
291+ b = b .Join ("" , tableName , fmt .Sprintf ("%v.id = %v.id" , b .TableName (), tableName ))
292+ }
293+
294+ return b
295+ }
296+
297+ func randCond (selects []string , lessThan int ) Cond {
298+ if len (selects ) <= 0 {
299+ return nil
300+ }
301+
302+ cond := NewCond ()
303+
304+ times := rand .Intn (lessThan )
305+ for i := 0 ; i < times ; i ++ {
306+ cond = cond .And (Eq {selects [rand .Intn (len (selects ))]: "expected" })
307+ }
308+
309+ return cond
310+ }
311+
312+ func randLimit (b * Builder ) * Builder {
313+ r := rand .Intn (1000 ) + 1
314+ if r > 500 {
315+ return b .Limit (r , 1000 )
316+ } else {
317+ return b .Limit (r )
318+ }
319+ }
0 commit comments