github.com/yongjacky/phoenix-go-orm-builder@v0.3.5/builder_test.go (about)

     1  // Copyright 2016 The Xorm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package builder
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  type MyInt int
    14  
    15  func TestBuilderCond(t *testing.T) {
    16  	var cases = []struct {
    17  		cond Cond
    18  		sql  string
    19  		args []interface{}
    20  	}{
    21  		{
    22  			Eq{"a": 1}.And(Like{"b", "c"}).Or(Eq{"a": 2}.And(Like{"b", "g"})),
    23  			"(a=? AND b LIKE ?) OR (a=? AND b LIKE ?)",
    24  			[]interface{}{1, "%c%", 2, "%g%"},
    25  		},
    26  		{
    27  			Eq{"a": 1}.Or(Like{"b", "c"}).And(Eq{"a": 2}.Or(Like{"b", "g"})),
    28  			"(a=? OR b LIKE ?) AND (a=? OR b LIKE ?)",
    29  			[]interface{}{1, "%c%", 2, "%g%"},
    30  		},
    31  		{
    32  			Eq{"d": []string{"e", "f"}},
    33  			"d IN (?,?)",
    34  			[]interface{}{"e", "f"},
    35  		},
    36  		{
    37  			Eq{"e": Select("id").From("f").Where(Eq{"g": 1})},
    38  			"e=(SELECT id FROM f WHERE g=?)",
    39  			[]interface{}{1},
    40  		},
    41  		{
    42  			Eq{"e": Expr("SELECT id FROM f WHERE g=?", 1)},
    43  			"e=(SELECT id FROM f WHERE g=?)",
    44  			[]interface{}{1},
    45  		},
    46  		{
    47  			Like{"a", "%1"}.And(Like{"b", "%2"}),
    48  			"a LIKE ? AND b LIKE ?",
    49  			[]interface{}{"%1", "%2"},
    50  		},
    51  		{
    52  			Like{"a", "%1"}.Or(Like{"b", "%2"}),
    53  			"a LIKE ? OR b LIKE ?",
    54  			[]interface{}{"%1", "%2"},
    55  		},
    56  		{
    57  			Neq{"d": "e"}.Or(Neq{"f": "g"}),
    58  			"d<>? OR f<>?",
    59  			[]interface{}{"e", "g"},
    60  		},
    61  		{
    62  			Neq{"d": []string{"e", "f"}},
    63  			"d NOT IN (?,?)",
    64  			[]interface{}{"e", "f"},
    65  		},
    66  		{
    67  			Neq{"e": Select("id").From("f").Where(Eq{"g": 1})},
    68  			"e<>(SELECT id FROM f WHERE g=?)",
    69  			[]interface{}{1},
    70  		},
    71  		{
    72  			Neq{"e": Expr("SELECT id FROM f WHERE g=?", 1)},
    73  			"e<>(SELECT id FROM f WHERE g=?)",
    74  			[]interface{}{1},
    75  		},
    76  		{
    77  			Lt{"d": 3},
    78  			"d<?",
    79  			[]interface{}{3},
    80  		},
    81  		{
    82  			Lt{"d": 3}.And(Lt{"e": 4}),
    83  			"d<? AND e<?",
    84  			[]interface{}{3, 4},
    85  		},
    86  		{
    87  			Lt{"d": 3}.Or(Lt{"e": 4}),
    88  			"d<? OR e<?",
    89  			[]interface{}{3, 4},
    90  		},
    91  		{
    92  			Lt{"e": Select("id").From("f").Where(Eq{"g": 1})},
    93  			"e<(SELECT id FROM f WHERE g=?)",
    94  			[]interface{}{1},
    95  		},
    96  		{
    97  			Lt{"e": Expr("SELECT id FROM f WHERE g=?", 1)},
    98  			"e<(SELECT id FROM f WHERE g=?)",
    99  			[]interface{}{1},
   100  		},
   101  		{
   102  			Lte{"d": 3},
   103  			"d<=?",
   104  			[]interface{}{3},
   105  		},
   106  		{
   107  			Lte{"d": 3}.And(Lte{"e": 4}),
   108  			"d<=? AND e<=?",
   109  			[]interface{}{3, 4},
   110  		},
   111  		{
   112  			Lte{"d": 3}.Or(Lte{"e": 4}),
   113  			"d<=? OR e<=?",
   114  			[]interface{}{3, 4},
   115  		},
   116  		{
   117  			Lte{"e": Select("id").From("f").Where(Eq{"g": 1})},
   118  			"e<=(SELECT id FROM f WHERE g=?)",
   119  			[]interface{}{1},
   120  		},
   121  		{
   122  			Lte{"e": Expr("SELECT id FROM f WHERE g=?", 1)},
   123  			"e<=(SELECT id FROM f WHERE g=?)",
   124  			[]interface{}{1},
   125  		},
   126  		{
   127  			Gt{"d": 3},
   128  			"d>?",
   129  			[]interface{}{3},
   130  		},
   131  		{
   132  			Gt{"d": 3}.And(Gt{"e": 4}),
   133  			"d>? AND e>?",
   134  			[]interface{}{3, 4},
   135  		},
   136  		{
   137  			Gt{"d": 3}.Or(Gt{"e": 4}),
   138  			"d>? OR e>?",
   139  			[]interface{}{3, 4},
   140  		},
   141  		{
   142  			Gt{"e": Select("id").From("f").Where(Eq{"g": 1})},
   143  			"e>(SELECT id FROM f WHERE g=?)",
   144  			[]interface{}{1},
   145  		},
   146  		{
   147  			Gt{"e": Expr("SELECT id FROM f WHERE g=?", 1)},
   148  			"e>(SELECT id FROM f WHERE g=?)",
   149  			[]interface{}{1},
   150  		},
   151  		{
   152  			Gte{"d": 3},
   153  			"d>=?",
   154  			[]interface{}{3},
   155  		},
   156  		{
   157  			Gte{"d": 3}.And(Gte{"e": 4}),
   158  			"d>=? AND e>=?",
   159  			[]interface{}{3, 4},
   160  		},
   161  		{
   162  			Gte{"d": 3}.Or(Gte{"e": 4}),
   163  			"d>=? OR e>=?",
   164  			[]interface{}{3, 4},
   165  		},
   166  		{
   167  			Gte{"e": Select("id").From("f").Where(Eq{"g": 1})},
   168  			"e>=(SELECT id FROM f WHERE g=?)",
   169  			[]interface{}{1},
   170  		},
   171  		{
   172  			Gte{"e": Expr("SELECT id FROM f WHERE g=?", 1)},
   173  			"e>=(SELECT id FROM f WHERE g=?)",
   174  			[]interface{}{1},
   175  		},
   176  		{
   177  			Between{"d", 0, 2},
   178  			"d BETWEEN ? AND ?",
   179  			[]interface{}{0, 2},
   180  		},
   181  		{
   182  			Between{"d", 0, Expr("CAST('2003-01-01' AS DATE)")},
   183  			"d BETWEEN ? AND CAST('2003-01-01' AS DATE)",
   184  			[]interface{}{0},
   185  		},
   186  		{
   187  			Between{"d", Expr("CAST('2003-01-01' AS DATE)"), 2},
   188  			"d BETWEEN CAST('2003-01-01' AS DATE) AND ?",
   189  			[]interface{}{2},
   190  		},
   191  		{
   192  			Between{"d", Expr("CAST('2003-01-01' AS DATE)"), Expr("CAST('2003-01-01' AS DATE)")},
   193  			"d BETWEEN CAST('2003-01-01' AS DATE) AND CAST('2003-01-01' AS DATE)",
   194  			[]interface{}{},
   195  		},
   196  		{
   197  			Between{"d", 0, 2}.And(Between{"e", 3, 4}),
   198  			"d BETWEEN ? AND ? AND e BETWEEN ? AND ?",
   199  			[]interface{}{0, 2, 3, 4},
   200  		},
   201  		{
   202  			Between{"d", 0, 2}.Or(Between{"e", 3, 4}),
   203  			"d BETWEEN ? AND ? OR e BETWEEN ? AND ?",
   204  			[]interface{}{0, 2, 3, 4},
   205  		},
   206  		{
   207  			Expr("a < ?", 1),
   208  			"a < ?",
   209  			[]interface{}{1},
   210  		},
   211  		{
   212  			Expr("a < ?", 1).And(Eq{"b": 2}),
   213  			"(a < ?) AND b=?",
   214  			[]interface{}{1, 2},
   215  		},
   216  		{
   217  			Expr("a < ?", 1).Or(Neq{"b": 2}),
   218  			"(a < ?) OR b<>?",
   219  			[]interface{}{1, 2},
   220  		},
   221  		{
   222  			IsNull{"d"},
   223  			"d IS NULL",
   224  			[]interface{}{},
   225  		},
   226  		{
   227  			IsNull{"d"}.And(IsNull{"e"}),
   228  			"d IS NULL AND e IS NULL",
   229  			[]interface{}{},
   230  		},
   231  		{
   232  			IsNull{"d"}.Or(IsNull{"e"}),
   233  			"d IS NULL OR e IS NULL",
   234  			[]interface{}{},
   235  		},
   236  		{
   237  			NotNull{"d"},
   238  			"d IS NOT NULL",
   239  			[]interface{}{},
   240  		},
   241  		{
   242  			NotNull{"d"}.And(NotNull{"e"}),
   243  			"d IS NOT NULL AND e IS NOT NULL",
   244  			[]interface{}{},
   245  		},
   246  		{
   247  			NotNull{"d"}.Or(NotNull{"e"}),
   248  			"d IS NOT NULL OR e IS NOT NULL",
   249  			[]interface{}{},
   250  		},
   251  		{
   252  			NotIn("a", 1, 2).And(NotIn("b", "c", "d")),
   253  			"a NOT IN (?,?) AND b NOT IN (?,?)",
   254  			[]interface{}{1, 2, "c", "d"},
   255  		},
   256  		{
   257  			In("a", 1, 2).Or(In("b", "c", "d")),
   258  			"a IN (?,?) OR b IN (?,?)",
   259  			[]interface{}{1, 2, "c", "d"},
   260  		},
   261  		{
   262  			In("a", []int{1, 2}).Or(In("b", []string{"c", "d"})),
   263  			"a IN (?,?) OR b IN (?,?)",
   264  			[]interface{}{1, 2, "c", "d"},
   265  		},
   266  		{
   267  			In("a", Expr("select id from x where name > ?", "b")),
   268  			"a IN (select id from x where name > ?)",
   269  			[]interface{}{"b"},
   270  		},
   271  		{
   272  			In("a", []MyInt{1, 2}).Or(In("b", []string{"c", "d"})),
   273  			"a IN (?,?) OR b IN (?,?)",
   274  			[]interface{}{MyInt(1), MyInt(2), "c", "d"},
   275  		},
   276  		{
   277  			In("a", []int{}),
   278  			"0=1",
   279  			[]interface{}{},
   280  		},
   281  		{
   282  			In("a", []int{1}),
   283  			"a IN (?)",
   284  			[]interface{}{1},
   285  		},
   286  		{
   287  			In("a", []int8{}),
   288  			"0=1",
   289  			[]interface{}{},
   290  		},
   291  		{
   292  			In("a", []int8{1}),
   293  			"a IN (?)",
   294  			[]interface{}{1},
   295  		},
   296  		{
   297  			In("a", []int16{}),
   298  			"0=1",
   299  			[]interface{}{},
   300  		},
   301  		{
   302  			In("a", []int16{1}),
   303  			"a IN (?)",
   304  			[]interface{}{1},
   305  		},
   306  		{
   307  			In("a", []int32{}),
   308  			"0=1",
   309  			[]interface{}{},
   310  		},
   311  		{
   312  			In("a", []int32{1}),
   313  			"a IN (?)",
   314  			[]interface{}{1},
   315  		},
   316  		{
   317  			In("a", []int64{}),
   318  			"0=1",
   319  			[]interface{}{},
   320  		},
   321  		{
   322  			In("a", []int64{1}),
   323  			"a IN (?)",
   324  			[]interface{}{1},
   325  		},
   326  		{
   327  			In("a", []uint{}),
   328  			"0=1",
   329  			[]interface{}{},
   330  		},
   331  		{
   332  			In("a", []uint{1}),
   333  			"a IN (?)",
   334  			[]interface{}{1},
   335  		},
   336  		{
   337  			In("a", []uint8{}),
   338  			"0=1",
   339  			[]interface{}{},
   340  		},
   341  		{
   342  			In("a", []uint8{1}),
   343  			"a IN (?)",
   344  			[]interface{}{1},
   345  		},
   346  		{
   347  			In("a", []uint16{}),
   348  			"0=1",
   349  			[]interface{}{},
   350  		},
   351  		{
   352  			In("a", []uint16{1}),
   353  			"a IN (?)",
   354  			[]interface{}{1},
   355  		},
   356  		{
   357  			In("a", []uint32{}),
   358  			"0=1",
   359  			[]interface{}{},
   360  		},
   361  		{
   362  			In("a", []uint32{1}),
   363  			"a IN (?)",
   364  			[]interface{}{1},
   365  		},
   366  		{
   367  			In("a", []uint64{}),
   368  			"0=1",
   369  			[]interface{}{},
   370  		},
   371  		{
   372  			In("a", []uint64{1}),
   373  			"a IN (?)",
   374  			[]interface{}{1},
   375  		},
   376  		{
   377  			In("a", []string{}),
   378  			"0=1",
   379  			[]interface{}{},
   380  		},
   381  		{
   382  			In("a", []interface{}{}),
   383  			"0=1",
   384  			[]interface{}{},
   385  		},
   386  		{
   387  			In("a", []MyInt{}),
   388  			"0=1",
   389  			[]interface{}{},
   390  		},
   391  		{
   392  			In("a", []interface{}{1, 2, 3}).And(Eq{"b": "c"}),
   393  			"a IN (?,?,?) AND b=?",
   394  			[]interface{}{1, 2, 3, "c"},
   395  		},
   396  		{
   397  			In("a", Select("id").From("b").Where(Eq{"c": 1})),
   398  			"a IN (SELECT id FROM b WHERE c=?)",
   399  			[]interface{}{1},
   400  		},
   401  		{
   402  			NotIn("a", Expr("select id from x where name > ?", "b")),
   403  			"a NOT IN (select id from x where name > ?)",
   404  			[]interface{}{"b"},
   405  		},
   406  		{
   407  			NotIn("a", []int{}),
   408  			"0=0",
   409  			[]interface{}{},
   410  		},
   411  		{
   412  			NotIn("a", []int{1}),
   413  			"a NOT IN (?)",
   414  			[]interface{}{1},
   415  		},
   416  		{
   417  			NotIn("a", []int8{}),
   418  			"0=0",
   419  			[]interface{}{},
   420  		},
   421  		{
   422  			NotIn("a", []int8{1}),
   423  			"a NOT IN (?)",
   424  			[]interface{}{1},
   425  		},
   426  		{
   427  			NotIn("a", []int16{}),
   428  			"0=0",
   429  			[]interface{}{},
   430  		},
   431  		{
   432  			NotIn("a", []int16{1}),
   433  			"a NOT IN (?)",
   434  			[]interface{}{1},
   435  		},
   436  		{
   437  			NotIn("a", []int32{}),
   438  			"0=0",
   439  			[]interface{}{},
   440  		},
   441  		{
   442  			NotIn("a", []int32{1}),
   443  			"a NOT IN (?)",
   444  			[]interface{}{1},
   445  		},
   446  		{
   447  			NotIn("a", []int64{}),
   448  			"0=0",
   449  			[]interface{}{},
   450  		},
   451  		{
   452  			NotIn("a", []int64{1}),
   453  			"a NOT IN (?)",
   454  			[]interface{}{1},
   455  		},
   456  		{
   457  			NotIn("a", []uint{}),
   458  			"0=0",
   459  			[]interface{}{},
   460  		},
   461  		{
   462  			NotIn("a", []uint{1}),
   463  			"a NOT IN (?)",
   464  			[]interface{}{1},
   465  		},
   466  		{
   467  			NotIn("a", []uint8{}),
   468  			"0=0",
   469  			[]interface{}{},
   470  		},
   471  		{
   472  			NotIn("a", []uint8{1}),
   473  			"a NOT IN (?)",
   474  			[]interface{}{1},
   475  		},
   476  		{
   477  			NotIn("a", []uint16{}),
   478  			"0=0",
   479  			[]interface{}{},
   480  		},
   481  		{
   482  			NotIn("a", []uint16{1}),
   483  			"a NOT IN (?)",
   484  			[]interface{}{1},
   485  		},
   486  		{
   487  			NotIn("a", []uint32{}),
   488  			"0=0",
   489  			[]interface{}{},
   490  		},
   491  		{
   492  			NotIn("a", []uint32{1}),
   493  			"a NOT IN (?)",
   494  			[]interface{}{1},
   495  		},
   496  		{
   497  			NotIn("a", []uint64{}),
   498  			"0=0",
   499  			[]interface{}{},
   500  		},
   501  		{
   502  			NotIn("a", []uint64{1}),
   503  			"a NOT IN (?)",
   504  			[]interface{}{1},
   505  		},
   506  		{
   507  			NotIn("a", []interface{}{}),
   508  			"0=0",
   509  			[]interface{}{},
   510  		},
   511  		{
   512  			NotIn("a", []string{}),
   513  			"0=0",
   514  			[]interface{}{},
   515  		},
   516  		{
   517  			NotIn("a", []MyInt{}),
   518  			"0=0",
   519  			[]interface{}{},
   520  		},
   521  		{
   522  			NotIn("a", []MyInt{1, 2}),
   523  			"a NOT IN (?,?)",
   524  			[]interface{}{1, 2},
   525  		},
   526  		{
   527  			NotIn("a", []interface{}{1, 2, 3}).And(Eq{"b": "c"}),
   528  			"a NOT IN (?,?,?) AND b=?",
   529  			[]interface{}{1, 2, 3, "c"},
   530  		},
   531  		{
   532  			NotIn("a", []interface{}{1, 2, 3}).Or(Eq{"b": "c"}),
   533  			"a NOT IN (?,?,?) OR b=?",
   534  			[]interface{}{1, 2, 3, "c"},
   535  		},
   536  		{
   537  			NotIn("a", Select("id").From("b").Where(Eq{"c": 1})),
   538  			"a NOT IN (SELECT id FROM b WHERE c=?)",
   539  			[]interface{}{1},
   540  		},
   541  		{
   542  			Or(Eq{"a": 1, "b": 2}, Eq{"c": 3, "d": 4}),
   543  			"(a=? AND b=?) OR (c=? AND d=?)",
   544  			[]interface{}{1, 2, 3, 4},
   545  		},
   546  		{
   547  			Not{Eq{"a": 1, "b": 2}},
   548  			"NOT (a=? AND b=?)",
   549  			[]interface{}{1, 2},
   550  		},
   551  		{
   552  			Not{Neq{"a": 1, "b": 2}},
   553  			"NOT (a<>? AND b<>?)",
   554  			[]interface{}{1, 2},
   555  		},
   556  		{
   557  			Not{Eq{"a": 1}.And(Eq{"b": 2})},
   558  			"NOT (a=? AND b=?)",
   559  			[]interface{}{1, 2},
   560  		},
   561  		{
   562  			Not{Neq{"a": 1}.And(Neq{"b": 2})},
   563  			"NOT (a<>? AND b<>?)",
   564  			[]interface{}{1, 2},
   565  		},
   566  		{
   567  			Not{Eq{"a": 1}}.And(Neq{"b": 2}),
   568  			"NOT a=? AND b<>?",
   569  			[]interface{}{1, 2},
   570  		},
   571  		{
   572  			Not{Eq{"a": 1}}.Or(Neq{"b": 2}),
   573  			"NOT a=? OR b<>?",
   574  			[]interface{}{1, 2},
   575  		},
   576  	}
   577  
   578  	for _, k := range cases {
   579  		sql, args, err := ToSQL(k.cond)
   580  		assert.NoError(t, err)
   581  		assert.EqualValues(t, k.sql, sql)
   582  
   583  		for i := 0; i < 10; i++ {
   584  			sql2, _, err := ToSQL(k.cond)
   585  			assert.NoError(t, err)
   586  			assert.EqualValues(t, sql, sql2)
   587  		}
   588  
   589  		assert.EqualValues(t, len(args), len(k.args))
   590  
   591  		if len(args) > 0 {
   592  			for i := 0; i < len(args); i++ {
   593  				assert.EqualValues(t, k.args[i], args[i])
   594  			}
   595  		}
   596  	}
   597  }
   598  
   599  func TestSubquery(t *testing.T) {
   600  	subb := Select("id").From("table_b").Where(Eq{"b": "a"})
   601  	b := Select("a, b").From("table_a").Where(
   602  		Eq{
   603  			"b_id": subb,
   604  			"id":   23,
   605  		},
   606  	)
   607  	sql, args, err := b.ToSQL()
   608  	assert.NoError(t, err)
   609  	assert.EqualValues(t, "SELECT a, b FROM table_a WHERE b_id=(SELECT id FROM table_b WHERE b=?) AND id=?", sql)
   610  	assert.EqualValues(t, []interface{}{"a", 23}, args)
   611  }
   612  
   613  // https://github.com/go-xorm/xorm/issues/820
   614  func TestExprCond(t *testing.T) {
   615  	b := Select("id").From("table1").Where(expr{sql: "a=? OR b=?", args: []interface{}{1, 2}}).Where(Or(Eq{"c": 3}, Eq{"d": 4}))
   616  	sql, args, err := b.ToSQL()
   617  	assert.NoError(t, err)
   618  	assert.EqualValues(t, "table1", b.TableName())
   619  	assert.EqualValues(t, "SELECT id FROM table1 WHERE (a=? OR b=?) AND (c=? OR d=?)", sql)
   620  	assert.EqualValues(t, []interface{}{1, 2, 3, 4}, args)
   621  }
   622  
   623  func TestBuilder_ToBoundSQL(t *testing.T) {
   624  	newSQL, err := Select("id").From("table").Where(In("a", 1, 2)).ToBoundSQL()
   625  	assert.NoError(t, err)
   626  	assert.EqualValues(t, "SELECT id FROM table WHERE a IN (1,2)", newSQL)
   627  }
   628  
   629  func TestBuilder_From2(t *testing.T) {
   630  	b := Select("id").From("table_b", "tb").Where(Eq{"b": "a"})
   631  	sql, args, err := b.ToSQL()
   632  	assert.NoError(t, err)
   633  	assert.EqualValues(t, "SELECT id FROM table_b tb WHERE b=?", sql)
   634  	assert.EqualValues(t, []interface{}{"a"}, args)
   635  
   636  	b = Select().From("table_b", "tb").Where(Eq{"b": "a"})
   637  	sql, args, err = b.ToSQL()
   638  	assert.NoError(t, err)
   639  	assert.EqualValues(t, "SELECT * FROM table_b tb WHERE b=?", sql)
   640  	assert.EqualValues(t, []interface{}{"a"}, args)
   641  }
   642  
   643  func TestBuilder_And(t *testing.T) {
   644  	b := Select("id").From("table_b", "tb").Where(Eq{"b": "a"}).And(Neq{"c": "d"})
   645  	sql, args, err := b.ToSQL()
   646  	assert.NoError(t, err)
   647  	assert.EqualValues(t, "SELECT id FROM table_b tb WHERE b=? AND c<>?", sql)
   648  	assert.EqualValues(t, []interface{}{"a", "d"}, args)
   649  }
   650  
   651  func TestBuilder_Or(t *testing.T) {
   652  	b := Select("id").From("table_b", "tb").Where(Eq{"b": "a"}).Or(Neq{"c": "d"})
   653  	sql, args, err := b.ToSQL()
   654  	assert.NoError(t, err)
   655  	assert.EqualValues(t, "SELECT id FROM table_b tb WHERE b=? OR c<>?", sql)
   656  	assert.EqualValues(t, []interface{}{"a", "d"}, args)
   657  }