gitlab.com/beacon-software/gadget@v0.0.0-20181217202115-54565ea1ed5e/database/qb/querybuilder_test.go (about)

     1  package qb
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  type person struct {
    11  	alias      string
    12  	ID         TableField
    13  	Name       TableField
    14  	AddressID  TableField
    15  	allColumns TableField
    16  }
    17  
    18  func (p *person) GetName() string {
    19  	return "person"
    20  }
    21  
    22  func (p *person) GetAlias() string {
    23  	return p.alias
    24  }
    25  
    26  func (p *person) PrimaryKey() TableField {
    27  	return p.ID
    28  }
    29  
    30  func (p *person) SortBy() (TableField, OrderDirection) {
    31  	return p.ID, Ascending
    32  }
    33  
    34  func (p *person) AllColumns() TableField {
    35  	return p.allColumns
    36  }
    37  
    38  func (p *person) ReadColumns() []TableField {
    39  	return []TableField{
    40  		p.ID,
    41  		p.Name,
    42  		p.AddressID,
    43  	}
    44  }
    45  
    46  func (p *person) WriteColumns() []TableField {
    47  	return p.ReadColumns()
    48  }
    49  
    50  func (p *person) Alias(alias string) *person {
    51  	return &person{
    52  		alias:      alias,
    53  		ID:         TableField{Name: "id", Table: alias},
    54  		Name:       TableField{Name: "name", Table: alias},
    55  		AddressID:  TableField{Name: "address_id", Table: alias},
    56  		allColumns: TableField{Name: "*", Table: alias},
    57  	}
    58  }
    59  
    60  var Person = (&person{}).Alias("person")
    61  
    62  type address struct {
    63  	alias      string
    64  	ID         TableField
    65  	Line       TableField
    66  	Line2      TableField
    67  	Province   TableField
    68  	Country    TableField
    69  	allColumns TableField
    70  }
    71  
    72  func (a *address) GetName() string {
    73  	return "address"
    74  }
    75  
    76  func (a *address) GetAlias() string {
    77  	return a.alias
    78  }
    79  
    80  func (a *address) PrimaryKey() TableField {
    81  	return a.ID
    82  }
    83  
    84  func (a *address) AllColumns() TableField {
    85  	return a.allColumns
    86  }
    87  
    88  func (a *address) SortBy() (TableField, OrderDirection) {
    89  	return a.ID, Ascending
    90  }
    91  
    92  func (a *address) ReadColumns() []TableField {
    93  	return []TableField{
    94  		a.ID,
    95  		a.Line,
    96  		a.Line2,
    97  		a.Province,
    98  		a.Country,
    99  	}
   100  }
   101  
   102  func (a *address) WriteColumns() []TableField {
   103  	return a.ReadColumns()
   104  }
   105  
   106  func (a *address) Alias(alias string) *address {
   107  	return &address{
   108  		alias:      alias,
   109  		ID:         TableField{Name: "id", Table: alias},
   110  		Line:       TableField{Name: "line", Table: alias},
   111  		Line2:      TableField{Name: "line2", Table: alias},
   112  		Province:   TableField{Name: "province", Table: alias},
   113  		Country:    TableField{Name: "country", Table: alias},
   114  		allColumns: TableField{Name: "*", Table: alias},
   115  	}
   116  }
   117  
   118  var Address = (&address{}).Alias("address")
   119  
   120  func TestQueryBuilderSimple(t *testing.T) {
   121  	assert := assert.New(t)
   122  	query := Select(Person.ID, Person.Name).From(Person)
   123  	actual, values, err := query.SQL(0, 0)
   124  	assert.NoError(err)
   125  	assert.Empty(values)
   126  	expected := fmt.Sprintf("SELECT `person`.`id`, `person`.`name` FROM `person` AS `person`")
   127  	assert.Equal(expected, actual)
   128  }
   129  
   130  func TestQueryBuilderTableAlias(t *testing.T) {
   131  	assert := assert.New(t)
   132  	table := Person.Alias("p")
   133  	query := Select(table.ID, table.Name).From(table)
   134  	actual, values, err := query.SQL(0, 0)
   135  	assert.NoError(err)
   136  	assert.Empty(values)
   137  	expected := fmt.Sprintf("SELECT `p`.`id`, `p`.`name` FROM `person` AS `p`")
   138  	assert.Equal(expected, actual)
   139  }
   140  
   141  func TestQueryBuilderDistinct(t *testing.T) {
   142  	assert := assert.New(t)
   143  	query := SelectDistinct(Person.ID, Person.Name).From(Person)
   144  	actual, values, err := query.SQL(0, 0)
   145  	assert.NoError(err)
   146  	assert.Empty(values)
   147  	expected := "SELECT DISTINCT `person`.`id`, `person`.`name` FROM `person` AS `person`"
   148  	assert.Equal(expected, actual)
   149  }
   150  
   151  func TestQueryBuilderSelectQuery_Where(t *testing.T) {
   152  	assert := assert.New(t)
   153  	query := Select(Person.ID, Person.Name).From(Person)
   154  	query.Where(Person.ID.Equal(Person.Name))
   155  
   156  	actual, values, err := query.SQL(0, 0)
   157  	assert.Empty(values)
   158  	assert.NoError(err)
   159  	assert.Equal("SELECT `person`.`id`, `person`.`name` FROM `person` AS `person` WHERE `person`.`id` = `person`.`name`", actual)
   160  }
   161  
   162  func TestQueryBuilderSelectQuery_WhereError(t *testing.T) {
   163  	assert := assert.New(t)
   164  	query := Select(Person.ID, Person.Name).From(Person)
   165  	query.Where(Person.AddressID.Equal(Address.ID))
   166  
   167  	_, _, err := query.SQL(0, 0)
   168  	assert.EqualError(err, NewMissingTablesError([]string{Address.GetName()}).Error())
   169  }
   170  
   171  func TestQueryBuilderSelectQuery_WhereValue(t *testing.T) {
   172  	assert := assert.New(t)
   173  	where := Person.ID.Equal(12)
   174  	query := Select(Person.ID, Person.Name).From(Person).Where(where)
   175  
   176  	actual, values, err := query.SQL(0, 0)
   177  	if assert.Equal(1, len(values)) {
   178  		assert.Equal(12, values[0])
   179  	}
   180  	assert.NoError(err)
   181  	assert.Equal("SELECT `person`.`id`, `person`.`name` FROM `person` AS `person` WHERE `person`.`id` = ?", actual)
   182  
   183  	where.And(Person.Name.NotEqual("Jim Bob"))
   184  	actual, values, err = query.SQL(12, 5)
   185  	if assert.Equal(2, len(values)) {
   186  		assert.Equal(12, values[0])
   187  		assert.Equal("Jim Bob", values[1])
   188  	}
   189  	assert.NoError(err)
   190  	assert.Equal("SELECT `person`.`id`, `person`.`name` "+
   191  		"FROM `person` AS `person` "+
   192  		"WHERE (`person`.`id` = ? AND `person`.`name` != ?) "+
   193  		"LIMIT 12 OFFSET 5", actual)
   194  }
   195  
   196  func TestQueryBuilderJoin(t *testing.T) {
   197  	assert := assert.New(t)
   198  
   199  	query := Select(Person.ID, Person.Name, Address.Line, Address.Country).From(Person)
   200  	query.InnerJoin(Address).On(Person.AddressID, Equal, Address.ID)
   201  	query.Where(Person.Name.NotEqual("Jim").And(FieldComparison(Address.ID, NotEqual, 12)))
   202  
   203  	actual, values, err := query.SQL(10, 0)
   204  	if assert.Equal(2, len(values)) {
   205  		assert.Equal("Jim", values[0])
   206  		assert.Equal(12, values[1])
   207  	}
   208  	assert.NoError(err)
   209  	assert.Equal("SELECT `person`.`id`, `person`.`name`, `address`.`line`, `address`.`country` "+
   210  		"FROM `person` AS `person` "+
   211  		"INNER JOIN `address` AS `address` ON `person`.`address_id` = `address`.`id` "+
   212  		"WHERE (`person`.`name` != ? AND `address`.`id` != ?) "+
   213  		"LIMIT 10 OFFSET 0", actual)
   214  }
   215  
   216  func TestQueryBuilderJoin_SQL_Outer(t *testing.T) {
   217  	assert := assert.New(t)
   218  
   219  	query := Select(Person.ID, Person.Name, Address.Line, Address.Country).From(Person)
   220  	query.OuterJoin(Left, Address).On(Person.AddressID, Equal, Address.ID)
   221  	query.Where(Person.Name.NotEqual("Jim").And(FieldComparison(Address.ID, NotEqual, 12)))
   222  
   223  	actual, values, err := query.SQL(10, 0)
   224  	if assert.Equal(2, len(values)) {
   225  		assert.Equal("Jim", values[0])
   226  		assert.Equal(12, values[1])
   227  	}
   228  	assert.NoError(err)
   229  	assert.Equal("SELECT `person`.`id`, `person`.`name`, `address`.`line`, `address`.`country` "+
   230  		"FROM `person` AS `person` "+
   231  		"LEFT OUTER JOIN `address` AS `address` ON `person`.`address_id` = `address`.`id` "+
   232  		"WHERE (`person`.`name` != ? AND `address`.`id` != ?) "+
   233  		"LIMIT 10 OFFSET 0", actual)
   234  }
   235  
   236  func TestQueryBuilderJoin_OnValue(t *testing.T) {
   237  	assert := assert.New(t)
   238  
   239  	query := Select(Person.ID, Person.Name, Address.Line, Address.Country).From(Person)
   240  	query.OuterJoin(Left, Address).On(Address.ID, Equal, "Bob")
   241  	query.Where(Person.Name.NotEqual("Jim").And(FieldComparison(Address.ID, NotEqual, 12)))
   242  
   243  	actual, values, err := query.SQL(10, 0)
   244  	assert.NoError(err)
   245  	if assert.Equal(3, len(values)) {
   246  		assert.Equal("Bob", values[0])
   247  		assert.Equal("Jim", values[1])
   248  		assert.Equal(12, values[2])
   249  	}
   250  	assert.Equal("SELECT `person`.`id`, `person`.`name`, `address`.`line`, `address`.`country` "+
   251  		"FROM `person` AS `person` "+
   252  		"LEFT OUTER JOIN `address` AS `address` ON `address`.`id` = ? "+
   253  		"WHERE (`person`.`name` != ? AND `address`.`id` != ?) "+
   254  		"LIMIT 10 OFFSET 0", actual)
   255  }
   256  
   257  func TestQueryBuilderSelectQuery_SQL_JoinFVError(t *testing.T) {
   258  	assert := assert.New(t)
   259  
   260  	query := Select(Person.ID, Person.Name, Address.Line, Address.Country).From(Person)
   261  	query.OuterJoin(Left, Address).On(Person.AddressID, Equal, "Bob")
   262  	query.Where(Person.Name.NotEqual("Jim").And(FieldComparison(Address.ID, NotEqual, 12)))
   263  	_, _, err := query.SQL(0, 0)
   264  	assert.EqualError(err, (&JoinError{joinTable: Address.GetName(), conditionTables: []string{Person.GetName()}}).Error())
   265  }
   266  
   267  func TestQueryBuilderSelectQuery_SQL_JoinFFError(t *testing.T) {
   268  	assert := assert.New(t)
   269  
   270  	query := Select(Person.ID, Person.Name, Address.Line, Address.Country).From(Person)
   271  	query.OuterJoin(Left, Address).On(Person.AddressID, Equal, Person.ID)
   272  	query.Where(Person.Name.NotEqual("Jim").And(FieldComparison(Address.ID, NotEqual, 12)))
   273  	_, _, err := query.SQL(0, 0)
   274  	assert.EqualError(err, (&JoinError{joinTable: Address.GetName(), conditionTables: []string{Person.GetName(), Person.GetName()}}).Error())
   275  }
   276  
   277  func TestQueryBuilderOrderBy_SQL(t *testing.T) {
   278  	assert := assert.New(t)
   279  
   280  	actual, values, err := Select(Person.ID, Person.Name).From(Person).OrderBy(Person.ID, Ascending).SQL(10, 10)
   281  	assert.NoError(err)
   282  	assert.Empty(values)
   283  	assert.Equal("SELECT `person`.`id`, `person`.`name` FROM `person` AS `person` ORDER BY `id` ASC LIMIT 10 OFFSET 10", actual)
   284  }
   285  
   286  func TestQueryBuilderOrderByMulti_SQL(t *testing.T) {
   287  	assert := assert.New(t)
   288  	query := Select(Person.ID, Person.Name).From(Person).OrderBy(Person.ID, Ascending)
   289  	query.OrderBy(Person.Name, Descending)
   290  	actual, values, err := query.SQL(10, 10)
   291  	assert.NoError(err)
   292  	assert.Empty(values)
   293  	assert.Equal("SELECT `person`.`id`, `person`.`name` FROM `person` AS `person` ORDER BY `id` ASC, `name` DESC LIMIT 10 OFFSET 10", actual)
   294  }
   295  
   296  func TestQueryBuilderFromNotSetError(t *testing.T) {
   297  	assert := assert.New(t)
   298  	query := Select(Person.ID)
   299  	query.Where(Person.ID.Equal(3))
   300  	_, _, err := query.SQL(0, 0)
   301  	assert.EqualError(err, NewValidationFromNotSetError().Error())
   302  }
   303  
   304  func TestQueryBuilderAlias(t *testing.T) {
   305  	assert := assert.New(t)
   306  	query := Select(Person.ID, Alias(Person.Name, "person_name")).From(Person)
   307  	actual, values, err := query.SQL(0, 10)
   308  	assert.NoError(err)
   309  	assert.Empty(values)
   310  	assert.Equal("SELECT `person`.`id`, `person`.`name` AS `person_name` FROM `person` AS `person`", actual)
   311  }
   312  
   313  func TestQueryBuilderCoalesce(t *testing.T) {
   314  	assert := assert.New(t)
   315  	query := Select(Person.ID, Coalesce(Person.Name, "", "coalesced")).From(Person)
   316  	actual, values, err := query.SQL(0, 10)
   317  	assert.NoError(err)
   318  	assert.Empty(values)
   319  	assert.Equal("SELECT `person`.`id`, COALESCE(`person`.`name`, '') AS `coalesced` FROM `person` AS `person`", actual)
   320  }
   321  
   322  func TestQueryBuilderGroupBy(t *testing.T) {
   323  	assert := assert.New(t)
   324  	query := Select(Person.ID, Person.Name, Person.AddressID).From(Person).GroupBy(Person.Name, Person.AddressID)
   325  	actual, values, err := query.SQL(0, 10)
   326  	assert.NoError(err)
   327  	assert.Empty(values)
   328  	assert.Equal("SELECT `person`.`id`, `person`.`name`, `person`.`address_id` FROM `person` AS `person`"+
   329  		" GROUP BY `person`.`name`, `person`.`address_id`", actual)
   330  }
   331  
   332  func TestSelectNotNull(t *testing.T) {
   333  	assert := assert.New(t)
   334  	query := Select(NotNull(Person.ID, "person_id_not_null"), Person.Name)
   335  	query.From(Person)
   336  	actual, values, err := query.SQL(0, 10)
   337  	assert.NoError(err)
   338  	assert.Empty(values)
   339  	assert.Equal("SELECT (`person`.`id` IS NOT NULL) AS `person_id_not_null`, `person`.`name` FROM `person` AS `person`", actual)
   340  }