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 }