...

Source file src/github.com/doug-martin/goqu/v9/delete_dataset_test.go

Documentation: github.com/doug-martin/goqu/v9

     1  package goqu_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/DATA-DOG/go-sqlmock"
     7  	"github.com/doug-martin/goqu/v9"
     8  	"github.com/doug-martin/goqu/v9/exp"
     9  	"github.com/doug-martin/goqu/v9/internal/errors"
    10  	"github.com/doug-martin/goqu/v9/internal/sb"
    11  	"github.com/doug-martin/goqu/v9/mocks"
    12  	"github.com/stretchr/testify/mock"
    13  	"github.com/stretchr/testify/suite"
    14  )
    15  
    16  type (
    17  	deleteTestCase struct {
    18  		ds      *goqu.DeleteDataset
    19  		clauses exp.DeleteClauses
    20  	}
    21  	deleteDatasetSuite struct {
    22  		suite.Suite
    23  	}
    24  )
    25  
    26  func (dds *deleteDatasetSuite) assertCases(cases ...deleteTestCase) {
    27  	for _, s := range cases {
    28  		dds.Equal(s.clauses, s.ds.GetClauses())
    29  	}
    30  }
    31  
    32  func (dds *deleteDatasetSuite) SetupSuite() {
    33  	noReturn := goqu.DefaultDialectOptions()
    34  	noReturn.SupportsReturn = false
    35  	goqu.RegisterDialect("no-return", noReturn)
    36  
    37  	limitOnDelete := goqu.DefaultDialectOptions()
    38  	limitOnDelete.SupportsLimitOnDelete = true
    39  	goqu.RegisterDialect("limit-on-delete", limitOnDelete)
    40  
    41  	orderOnDelete := goqu.DefaultDialectOptions()
    42  	orderOnDelete.SupportsOrderByOnDelete = true
    43  	goqu.RegisterDialect("order-on-delete", orderOnDelete)
    44  }
    45  
    46  func (dds *deleteDatasetSuite) TearDownSuite() {
    47  	goqu.DeregisterDialect("no-return")
    48  	goqu.DeregisterDialect("limit-on-delete")
    49  	goqu.DeregisterDialect("order-on-delete")
    50  }
    51  
    52  func (dds *deleteDatasetSuite) TestDelete() {
    53  	ds := goqu.Delete("test")
    54  	dds.IsType(&goqu.DeleteDataset{}, ds)
    55  	dds.Implements((*exp.Expression)(nil), ds)
    56  	dds.Implements((*exp.AppendableExpression)(nil), ds)
    57  }
    58  
    59  func (dds *deleteDatasetSuite) TestClone() {
    60  	ds := goqu.Delete("test")
    61  	dds.Equal(ds.Clone(), ds)
    62  }
    63  
    64  func (dds *deleteDatasetSuite) TestExpression() {
    65  	ds := goqu.Delete("test")
    66  	dds.Equal(ds.Expression(), ds)
    67  }
    68  
    69  func (dds *deleteDatasetSuite) TestDialect() {
    70  	ds := goqu.Delete("test")
    71  	dds.NotNil(ds.Dialect())
    72  }
    73  
    74  func (dds *deleteDatasetSuite) TestWithDialect() {
    75  	ds := goqu.Delete("test")
    76  	md := new(mocks.SQLDialect)
    77  	ds = ds.SetDialect(md)
    78  
    79  	dialect := goqu.GetDialect("default")
    80  	dialectDs := ds.WithDialect("default")
    81  	dds.Equal(md, ds.Dialect())
    82  	dds.Equal(dialect, dialectDs.Dialect())
    83  }
    84  
    85  func (dds *deleteDatasetSuite) TestPrepared() {
    86  	ds := goqu.Delete("test")
    87  	preparedDs := ds.Prepared(true)
    88  	dds.True(preparedDs.IsPrepared())
    89  	dds.False(ds.IsPrepared())
    90  	// should apply the prepared to any datasets created from the root
    91  	dds.True(preparedDs.Where(goqu.Ex{"a": 1}).IsPrepared())
    92  
    93  	defer goqu.SetDefaultPrepared(false)
    94  	goqu.SetDefaultPrepared(true)
    95  
    96  	// should be prepared by default
    97  	ds = goqu.Delete("test")
    98  	dds.True(ds.IsPrepared())
    99  }
   100  
   101  func (dds *deleteDatasetSuite) TestGetClauses() {
   102  	ds := goqu.Delete("test")
   103  	ce := exp.NewDeleteClauses().SetFrom(goqu.I("test"))
   104  	dds.Equal(ce, ds.GetClauses())
   105  }
   106  
   107  func (dds *deleteDatasetSuite) TestWith() {
   108  	from := goqu.From("cte")
   109  	bd := goqu.Delete("items")
   110  	dds.assertCases(
   111  		deleteTestCase{
   112  			ds: bd.With("test-cte", from),
   113  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")).
   114  				CommonTablesAppend(exp.NewCommonTableExpression(false, "test-cte", from)),
   115  		},
   116  		deleteTestCase{
   117  			ds:      bd,
   118  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   119  		},
   120  	)
   121  }
   122  
   123  func (dds *deleteDatasetSuite) TestWithRecursive() {
   124  	from := goqu.From("cte")
   125  	bd := goqu.Delete("items")
   126  	dds.assertCases(
   127  		deleteTestCase{
   128  			ds: bd.WithRecursive("test-cte", from),
   129  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")).
   130  				CommonTablesAppend(exp.NewCommonTableExpression(true, "test-cte", from)),
   131  		},
   132  		deleteTestCase{
   133  			ds:      bd,
   134  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   135  		},
   136  	)
   137  }
   138  
   139  func (dds *deleteDatasetSuite) TestFrom_withIdentifier() {
   140  	bd := goqu.Delete("items")
   141  	dds.assertCases(
   142  		deleteTestCase{
   143  			ds:      bd.From("items2"),
   144  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items2")),
   145  		},
   146  		deleteTestCase{
   147  			ds:      bd.From(goqu.C("items2")),
   148  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items2")),
   149  		},
   150  		deleteTestCase{
   151  			ds:      bd.From(goqu.T("items2")),
   152  			clauses: exp.NewDeleteClauses().SetFrom(goqu.T("items2")),
   153  		},
   154  		deleteTestCase{
   155  			ds:      bd.From("schema.table"),
   156  			clauses: exp.NewDeleteClauses().SetFrom(goqu.I("schema.table")),
   157  		},
   158  		deleteTestCase{
   159  			ds:      bd,
   160  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   161  		},
   162  	)
   163  
   164  	dds.PanicsWithValue(goqu.ErrBadFromArgument, func() {
   165  		goqu.Delete("test").From(true)
   166  	})
   167  }
   168  
   169  func (dds *deleteDatasetSuite) TestWhere() {
   170  	bd := goqu.Delete("items")
   171  	dds.assertCases(
   172  		deleteTestCase{
   173  			ds: bd.Where(goqu.Ex{"a": 1}),
   174  			clauses: exp.NewDeleteClauses().
   175  				SetFrom(goqu.C("items")).
   176  				WhereAppend(goqu.Ex{"a": 1}),
   177  		},
   178  		deleteTestCase{
   179  			ds: bd.Where(goqu.Ex{"a": 1}).Where(goqu.C("b").Eq("c")),
   180  			clauses: exp.NewDeleteClauses().
   181  				SetFrom(goqu.C("items")).
   182  				WhereAppend(goqu.Ex{"a": 1}).
   183  				WhereAppend(goqu.C("b").Eq("c")),
   184  		},
   185  		deleteTestCase{
   186  			ds:      bd,
   187  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   188  		},
   189  	)
   190  }
   191  
   192  func (dds *deleteDatasetSuite) TestClearWhere() {
   193  	bd := goqu.Delete("items").Where(goqu.Ex{"a": 1})
   194  	dds.assertCases(
   195  		deleteTestCase{
   196  			ds: bd.ClearWhere(),
   197  			clauses: exp.NewDeleteClauses().
   198  				SetFrom(goqu.C("items")),
   199  		},
   200  		deleteTestCase{
   201  			ds: bd,
   202  			clauses: exp.NewDeleteClauses().
   203  				SetFrom(goqu.C("items")).
   204  				WhereAppend(goqu.Ex{"a": 1}),
   205  		},
   206  	)
   207  }
   208  
   209  func (dds *deleteDatasetSuite) TestOrder() {
   210  	bd := goqu.Delete("items")
   211  	dds.assertCases(
   212  		deleteTestCase{
   213  			ds: bd.Order(goqu.C("a").Asc()),
   214  			clauses: exp.NewDeleteClauses().
   215  				SetFrom(goqu.C("items")).
   216  				SetOrder(goqu.C("a").Asc()),
   217  		},
   218  		deleteTestCase{
   219  			ds: bd.Order(goqu.C("a").Asc()).Order(goqu.C("b").Desc()),
   220  			clauses: exp.NewDeleteClauses().
   221  				SetFrom(goqu.C("items")).
   222  				SetOrder(goqu.C("b").Desc()),
   223  		},
   224  		deleteTestCase{
   225  			ds: bd.Order(goqu.C("a").Asc(), goqu.C("b").Desc()),
   226  			clauses: exp.NewDeleteClauses().
   227  				SetFrom(goqu.C("items")).
   228  				SetOrder(goqu.C("a").Asc(), goqu.C("b").Desc()),
   229  		},
   230  		deleteTestCase{
   231  			ds:      bd,
   232  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   233  		},
   234  	)
   235  }
   236  
   237  func (dds *deleteDatasetSuite) TestOrderAppend() {
   238  	bd := goqu.Delete("items").Order(goqu.C("a").Asc())
   239  	dds.assertCases(
   240  		deleteTestCase{
   241  			ds: bd.OrderAppend(goqu.C("b").Desc()),
   242  			clauses: exp.NewDeleteClauses().
   243  				SetFrom(goqu.C("items")).
   244  				SetOrder(goqu.C("a").Asc(), goqu.C("b").Desc()),
   245  		},
   246  		deleteTestCase{
   247  			ds: bd,
   248  			clauses: exp.NewDeleteClauses().
   249  				SetFrom(goqu.C("items")).
   250  				SetOrder(goqu.C("a").Asc()),
   251  		},
   252  	)
   253  }
   254  
   255  func (dds *deleteDatasetSuite) TestOrderPrepend() {
   256  	bd := goqu.Delete("items").Order(goqu.C("a").Asc())
   257  	dds.assertCases(
   258  		deleteTestCase{
   259  			ds: bd.OrderPrepend(goqu.C("b").Desc()),
   260  			clauses: exp.NewDeleteClauses().
   261  				SetFrom(goqu.C("items")).
   262  				SetOrder(goqu.C("b").Desc(), goqu.C("a").Asc()),
   263  		},
   264  		deleteTestCase{
   265  			ds: bd,
   266  			clauses: exp.NewDeleteClauses().
   267  				SetFrom(goqu.C("items")).
   268  				SetOrder(goqu.C("a").Asc()),
   269  		},
   270  	)
   271  }
   272  
   273  func (dds *deleteDatasetSuite) TestClearOrder() {
   274  	bd := goqu.Delete("items").Order(goqu.C("a").Asc())
   275  	dds.assertCases(
   276  		deleteTestCase{
   277  			ds:      bd.ClearOrder(),
   278  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   279  		},
   280  		deleteTestCase{
   281  			ds: bd,
   282  			clauses: exp.NewDeleteClauses().
   283  				SetFrom(goqu.C("items")).
   284  				SetOrder(goqu.C("a").Asc()),
   285  		},
   286  	)
   287  }
   288  
   289  func (dds *deleteDatasetSuite) TestLimit() {
   290  	bd := goqu.Delete("test")
   291  	dds.assertCases(
   292  		deleteTestCase{
   293  			ds: bd.Limit(10),
   294  			clauses: exp.NewDeleteClauses().
   295  				SetFrom(goqu.C("test")).
   296  				SetLimit(uint(10)),
   297  		},
   298  		deleteTestCase{
   299  			ds:      bd.Limit(0),
   300  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
   301  		},
   302  		deleteTestCase{
   303  			ds: bd.Limit(10).Limit(2),
   304  			clauses: exp.NewDeleteClauses().
   305  				SetFrom(goqu.C("test")).
   306  				SetLimit(uint(2)),
   307  		},
   308  		deleteTestCase{
   309  			ds:      bd.Limit(10).Limit(0),
   310  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
   311  		},
   312  		deleteTestCase{
   313  			ds:      bd,
   314  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
   315  		},
   316  	)
   317  }
   318  
   319  func (dds *deleteDatasetSuite) TestLimitAll() {
   320  	bd := goqu.Delete("test")
   321  	dds.assertCases(
   322  		deleteTestCase{
   323  			ds: bd.LimitAll(),
   324  			clauses: exp.NewDeleteClauses().
   325  				SetFrom(goqu.C("test")).
   326  				SetLimit(goqu.L("ALL")),
   327  		},
   328  		deleteTestCase{
   329  			ds: bd.Limit(10).LimitAll(),
   330  			clauses: exp.NewDeleteClauses().
   331  				SetFrom(goqu.C("test")).
   332  				SetLimit(goqu.L("ALL")),
   333  		},
   334  		deleteTestCase{
   335  			ds:      bd,
   336  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
   337  		},
   338  	)
   339  }
   340  
   341  func (dds *deleteDatasetSuite) TestClearLimit() {
   342  	bd := goqu.Delete("test").Limit(10)
   343  	dds.assertCases(
   344  		deleteTestCase{
   345  			ds:      bd.ClearLimit(),
   346  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
   347  		},
   348  		deleteTestCase{
   349  			ds:      bd,
   350  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")).SetLimit(uint(10)),
   351  		},
   352  	)
   353  }
   354  
   355  func (dds *deleteDatasetSuite) TestReturning() {
   356  	bd := goqu.Delete("items")
   357  	dds.assertCases(
   358  		deleteTestCase{
   359  			ds: bd.Returning("a"),
   360  			clauses: exp.NewDeleteClauses().
   361  				SetFrom(goqu.C("items")).
   362  				SetReturning(exp.NewColumnListExpression("a")),
   363  		},
   364  		deleteTestCase{
   365  			ds: bd.Returning(),
   366  			clauses: exp.NewDeleteClauses().
   367  				SetFrom(goqu.C("items")).
   368  				SetReturning(exp.NewColumnListExpression()),
   369  		},
   370  		deleteTestCase{
   371  			ds: bd.Returning(nil),
   372  			clauses: exp.NewDeleteClauses().
   373  				SetFrom(goqu.C("items")).
   374  				SetReturning(exp.NewColumnListExpression()),
   375  		},
   376  		deleteTestCase{
   377  			ds: bd.Returning("a").Returning("b"),
   378  			clauses: exp.NewDeleteClauses().
   379  				SetFrom(goqu.C("items")).
   380  				SetReturning(exp.NewColumnListExpression("b")),
   381  		},
   382  		deleteTestCase{
   383  			ds:      bd,
   384  			clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
   385  		},
   386  	)
   387  }
   388  
   389  func (dds *deleteDatasetSuite) TestReturnsColumns() {
   390  	ds := goqu.Delete("test")
   391  	dds.False(ds.ReturnsColumns())
   392  	dds.True(ds.Returning("foo", "bar").ReturnsColumns())
   393  }
   394  
   395  func (dds *deleteDatasetSuite) TestToSQL() {
   396  	md := new(mocks.SQLDialect)
   397  	ds := goqu.Delete("test").SetDialect(md)
   398  	c := ds.GetClauses()
   399  	sqlB := sb.NewSQLBuilder(false)
   400  	md.On("ToDeleteSQL", sqlB, c).Return(nil).Once()
   401  
   402  	sql, args, err := ds.ToSQL()
   403  	dds.Empty(sql)
   404  	dds.Empty(args)
   405  	dds.Nil(err)
   406  	md.AssertExpectations(dds.T())
   407  }
   408  
   409  func (dds *deleteDatasetSuite) TestToSQL_Prepared() {
   410  	md := new(mocks.SQLDialect)
   411  	ds := goqu.Delete("test").Prepared(true).SetDialect(md)
   412  	c := ds.GetClauses()
   413  	sqlB := sb.NewSQLBuilder(true)
   414  	md.On("ToDeleteSQL", sqlB, c).Return(nil).Once()
   415  
   416  	sql, args, err := ds.ToSQL()
   417  	dds.Empty(sql)
   418  	dds.Empty(args)
   419  	dds.Nil(err)
   420  	md.AssertExpectations(dds.T())
   421  }
   422  
   423  func (dds *deleteDatasetSuite) TestToSQL_WithError() {
   424  	md := new(mocks.SQLDialect)
   425  	ds := goqu.Delete("test").SetDialect(md)
   426  	c := ds.GetClauses()
   427  	ee := errors.New("expected error")
   428  	sqlB := sb.NewSQLBuilder(false)
   429  	md.On("ToDeleteSQL", sqlB, c).Run(func(args mock.Arguments) {
   430  		args.Get(0).(sb.SQLBuilder).SetError(ee)
   431  	}).Once()
   432  
   433  	sql, args, err := ds.ToSQL()
   434  	dds.Empty(sql)
   435  	dds.Empty(args)
   436  	dds.Equal(ee, err)
   437  	md.AssertExpectations(dds.T())
   438  }
   439  
   440  func (dds *deleteDatasetSuite) TestExecutor() {
   441  	mDB, _, err := sqlmock.New()
   442  	dds.NoError(err)
   443  
   444  	ds := goqu.New("mock", mDB).Delete("items").Where(goqu.Ex{"id": goqu.Op{"gt": 10}})
   445  
   446  	dsql, args, err := ds.Executor().ToSQL()
   447  	dds.NoError(err)
   448  	dds.Empty(args)
   449  	dds.Equal(`DELETE FROM "items" WHERE ("id" > 10)`, dsql)
   450  
   451  	dsql, args, err = ds.Prepared(true).Executor().ToSQL()
   452  	dds.NoError(err)
   453  	dds.Equal([]interface{}{int64(10)}, args)
   454  	dds.Equal(`DELETE FROM "items" WHERE ("id" > ?)`, dsql)
   455  
   456  	defer goqu.SetDefaultPrepared(false)
   457  	goqu.SetDefaultPrepared(true)
   458  
   459  	dsql, args, err = ds.Executor().ToSQL()
   460  	dds.NoError(err)
   461  	dds.Equal([]interface{}{int64(10)}, args)
   462  	dds.Equal(`DELETE FROM "items" WHERE ("id" > ?)`, dsql)
   463  }
   464  
   465  func (dds *deleteDatasetSuite) TestSetError() {
   466  	err1 := errors.New("error #1")
   467  	err2 := errors.New("error #2")
   468  	err3 := errors.New("error #3")
   469  
   470  	// Verify initial error set/get works properly
   471  	md := new(mocks.SQLDialect)
   472  	ds := goqu.Delete("test").SetDialect(md)
   473  	ds = ds.SetError(err1)
   474  	dds.Equal(err1, ds.Error())
   475  	sql, args, err := ds.ToSQL()
   476  	dds.Empty(sql)
   477  	dds.Empty(args)
   478  	dds.Equal(err1, err)
   479  
   480  	// Repeated SetError calls on Dataset should not overwrite the original error
   481  	ds = ds.SetError(err2)
   482  	dds.Equal(err1, ds.Error())
   483  	sql, args, err = ds.ToSQL()
   484  	dds.Empty(sql)
   485  	dds.Empty(args)
   486  	dds.Equal(err1, err)
   487  
   488  	// Builder functions should not lose the error
   489  	ds = ds.ClearLimit()
   490  	dds.Equal(err1, ds.Error())
   491  	sql, args, err = ds.ToSQL()
   492  	dds.Empty(sql)
   493  	dds.Empty(args)
   494  	dds.Equal(err1, err)
   495  
   496  	// Deeper errors inside SQL generation should still return original error
   497  	c := ds.GetClauses()
   498  	sqlB := sb.NewSQLBuilder(false)
   499  	md.On("ToDeleteSQL", sqlB, c).Run(func(args mock.Arguments) {
   500  		args.Get(0).(sb.SQLBuilder).SetError(err3)
   501  	}).Once()
   502  
   503  	sql, args, err = ds.ToSQL()
   504  	dds.Empty(sql)
   505  	dds.Empty(args)
   506  	dds.Equal(err1, err)
   507  }
   508  
   509  func TestDeleteDataset(t *testing.T) {
   510  	suite.Run(t, new(deleteDatasetSuite))
   511  }
   512  

View as plain text