github.com/blend/go-sdk@v1.20220411.3/db/column_collection_test.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package db 9 10 import ( 11 "reflect" 12 "testing" 13 "time" 14 15 "github.com/blend/go-sdk/assert" 16 ) 17 18 func Test_Columns(t *testing.T) { 19 its := assert.New(t) 20 21 var emptyColumnCollection ColumnCollection 22 firstOrDefaultNil := emptyColumnCollection.FirstOrDefault() 23 its.Nil(firstOrDefaultNil) 24 25 obj := myStruct{} 26 meta := Columns(obj) 27 28 its.NotNil(meta.Columns()) 29 its.NotEmpty(meta.Columns()) 30 31 its.Equal(9, meta.Len()) 32 33 readOnlyColumns := meta.ReadOnly() 34 its.Len(readOnlyColumns.Columns(), 1) 35 36 firstOrDefault := meta.FirstOrDefault() 37 its.NotNil(firstOrDefault) 38 39 firstCol := meta.FirstOrDefault() 40 its.Equal("my_struct", firstCol.TableName) 41 its.Equal("PrimaryKeyCol", firstCol.FieldName) 42 its.Equal("primary_key_column", firstCol.ColumnName) 43 its.True(firstCol.IsPrimaryKey) 44 its.True(firstCol.IsAuto) 45 its.False(firstCol.IsReadOnly) 46 47 secondCol := meta.Columns()[1] 48 its.Equal("auto_column", secondCol.ColumnName) 49 its.False(secondCol.IsPrimaryKey) 50 its.True(secondCol.IsAuto) 51 its.False(secondCol.IsReadOnly) 52 53 thirdCol := meta.Columns()[2] 54 its.Equal("InferredName", thirdCol.ColumnName) 55 its.False(thirdCol.IsPrimaryKey) 56 its.False(thirdCol.IsAuto) 57 its.False(thirdCol.IsReadOnly) 58 59 fourthCol := meta.Columns()[3] 60 its.Equal("Unique", fourthCol.ColumnName) 61 its.False(fourthCol.IsPrimaryKey) 62 its.True(fourthCol.IsUniqueKey) 63 its.False(fourthCol.IsAuto) 64 its.False(fourthCol.IsReadOnly) 65 66 fifthCol := meta.Columns()[4] 67 its.Equal("nullable", fifthCol.ColumnName) 68 its.False(fifthCol.IsPrimaryKey) 69 its.False(fifthCol.IsAuto) 70 its.False(fifthCol.IsReadOnly) 71 72 sixthCol := meta.Columns()[5] 73 its.Equal("InferredWithFlags", sixthCol.ColumnName) 74 its.False(sixthCol.IsPrimaryKey) 75 its.False(sixthCol.IsAuto) 76 its.True(sixthCol.IsReadOnly) 77 78 uks := meta.UniqueKeys() 79 its.Equal(1, uks.Len()) 80 } 81 82 func Test_ColumnNameCSV(t *testing.T) { 83 its := assert.New(t) 84 85 expected := "primary_key_column,auto_column,InferredName,Unique,nullable,InferredWithFlags,big_int,pointer_col,json_col" 86 actual := ColumnNamesCSV(myStruct{}) 87 its.Equal(expected, actual) 88 } 89 90 func Test_ColumnCollection_Copy(t *testing.T) { 91 its := assert.New(t) 92 93 obj := myStruct{} 94 meta := Columns(obj) 95 newMeta := meta.Copy() 96 its.False(meta == newMeta, "These pointers should not be the same.") 97 newMeta.columnPrefix = "foo_" 98 its.NotEqual(meta.columnPrefix, newMeta.columnPrefix) 99 } 100 101 func Test_ColumnCollection_CopyWithColumnPrefix(t *testing.T) { 102 its := assert.New(t) 103 104 obj := myStruct{} 105 meta := Columns(obj) 106 newMeta := meta.CopyWithColumnPrefix("foo_") 107 its.Equal("foo_", newMeta.columnPrefix) 108 its.False(meta == newMeta, "These pointers should not be the same.") 109 its.NotEqual(meta.columnPrefix, newMeta.columnPrefix) 110 } 111 112 func Test_ColumnCollection_Add(t *testing.T) { 113 its := assert.New(t) 114 115 obj := myStruct{} 116 meta := Columns(obj) 117 newMeta := meta.Copy() 118 its.Len(newMeta.columns, 9) 119 its.False(newMeta.HasColumn("testo")) 120 newMeta.Add(Column{ 121 FieldName: "Testo", 122 ColumnName: "testo", 123 }) 124 its.Len(newMeta.columns, 10) 125 its.True(newMeta.HasColumn("testo")) 126 } 127 128 func Test_ColumnCollection_Remove(t *testing.T) { 129 its := assert.New(t) 130 131 obj := myStruct{} 132 meta := Columns(obj) 133 newMeta := meta.Copy() 134 135 its.True(newMeta.HasColumn("primary_key_column")) 136 newMeta.Remove("primary_key_column") 137 its.False(newMeta.HasColumn("primary_key_column")) 138 } 139 140 func Test_ColumnCollection_InsertColumns(t *testing.T) { 141 its := assert.New(t) 142 143 obj := myStruct{} 144 meta := Columns(obj) 145 writeCols := meta.InsertColumns() 146 its.NotZero(writeCols.Len()) 147 } 148 149 func Test_ColumnCollection_Zero(t *testing.T) { 150 its := assert.New(t) 151 cols := Columns(columnsZeroTest{}) 152 153 emptyCols := cols.Zero(columnsZeroTest{}) 154 its.Equal(len(cols.columns), len(emptyCols.columns)) 155 156 stringValue := "test" 157 bytesValue := []byte(stringValue) 158 ts := time.Now().UTC() 159 setCols := cols.Zero(columnsZeroTest{ 160 Int: 1, 161 Float64: 1, 162 TimePtr: &ts, 163 StringPtr: &stringValue, 164 Bytes: bytesValue, 165 }) 166 its.Equal(2, len(setCols.columns)) 167 168 its.False(setCols.HasColumn("Int")) 169 its.False(setCols.HasColumn("Float64")) 170 its.False(setCols.HasColumn("TimePtr")) 171 its.False(setCols.HasColumn("StringPtr")) 172 its.False(setCols.HasColumn("Bytes")) 173 174 its.True(setCols.HasColumn("Time"), setCols.String()) 175 its.True(setCols.HasColumn("String"), setCols.String()) 176 177 allCols := cols.Zero(columnsZeroTest{ 178 Int: 1, 179 Float64: 1, 180 Time: ts, 181 TimePtr: &ts, 182 String: stringValue, 183 StringPtr: &stringValue, 184 Bytes: bytesValue, 185 }) 186 its.Empty(allCols.columns) 187 } 188 189 func Test_ColumnCollection_NotZero(t *testing.T) { 190 its := assert.New(t) 191 cols := Columns(columnsZeroTest{}) 192 193 emptyCols := cols.NotZero(columnsZeroTest{}) 194 its.Empty(emptyCols.columns) 195 196 stringValue := "test" 197 bytesValue := []byte(stringValue) 198 ts := time.Now().UTC() 199 setCols := cols.NotZero(columnsZeroTest{ 200 Int: 1, 201 Float64: 1, 202 TimePtr: &ts, 203 StringPtr: &stringValue, 204 Bytes: bytesValue, 205 }) 206 its.Equal(5, len(setCols.columns)) 207 208 its.True(setCols.HasColumn("Int")) 209 its.True(setCols.HasColumn("Float64")) 210 its.True(setCols.HasColumn("TimePtr")) 211 its.True(setCols.HasColumn("StringPtr")) 212 its.True(setCols.HasColumn("Bytes")) 213 214 its.False(setCols.HasColumn("Time"), setCols.String()) 215 its.False(setCols.HasColumn("String"), setCols.String()) 216 217 allCols := cols.NotZero(columnsZeroTest{ 218 Int: 1, 219 Float64: 1, 220 Time: ts, 221 TimePtr: &ts, 222 String: stringValue, 223 StringPtr: &stringValue, 224 Bytes: bytesValue, 225 }) 226 its.Len(allCols.columns, 7) 227 } 228 229 func Test_ColumnCollection_ColumnNamesCSVFromAlias(t *testing.T) { 230 its := assert.New(t) 231 232 columns := []Column{ 233 {ColumnName: "foo0"}, 234 {ColumnName: "foo1"}, 235 {ColumnName: "foo2"}, 236 } 237 238 withoutPrefix := &ColumnCollection{ 239 columns: columns, 240 } 241 242 its.Equal("buzz.foo0,buzz.foo1,buzz.foo2", withoutPrefix.ColumnNamesCSVFromAlias("buzz")) 243 244 withPrefix := &ColumnCollection{ 245 columns: columns, 246 columnPrefix: "bar_", 247 } 248 249 its.Equal("buzz.foo0 as bar_foo0,buzz.foo1 as bar_foo1,buzz.foo2 as bar_foo2", withPrefix.ColumnNamesCSVFromAlias("buzz")) 250 } 251 252 func Test_newColumnCacheKey(t *testing.T) { 253 its := assert.New(t) 254 255 its.Equal("db.cacheKeyEmpty", newColumnCacheKey(reflect.TypeOf(cacheKeyEmpty{}))) 256 its.Equal("db.cacheKeyWithTableName_with_table_name", newColumnCacheKey(reflect.TypeOf(cacheKeyWithTableName{}))) 257 its.Equal("db.cacheKeyWithColumMetaCacheKeyProvider_with_column_meta_cache_key", newColumnCacheKey(reflect.TypeOf(cacheKeyWithColumMetaCacheKeyProvider{}))) 258 } 259 260 // 261 // helper types 262 // 263 264 type cacheKeyEmpty struct{} 265 266 type cacheKeyWithTableName struct{} 267 268 func (j cacheKeyWithTableName) TableName() string { return "with_table_name" } 269 270 type cacheKeyWithColumMetaCacheKeyProvider struct{} 271 272 func (j cacheKeyWithColumMetaCacheKeyProvider) ColumnMetaCacheKey() string { 273 return "with_column_meta_cache_key" 274 } 275 276 type columnsZeroTest struct { 277 Int int 278 Float64 float64 279 String string 280 StringPtr *string 281 Time time.Time 282 TimePtr *time.Time 283 Bytes []byte 284 } 285 286 type EmbeddedMeta struct { 287 PrimaryKeyCol int `json:"pk" db:"primary_key_column,pk,serial"` 288 AutoCol string `json:"auto" db:"auto_column,auto"` 289 } 290 291 type subStruct struct { 292 Foo string `json:"foo"` 293 } 294 295 type myStruct struct { 296 EmbeddedMeta `db:",inline"` 297 InferredName string `json:"normal"` 298 Unique string `db:",uk"` 299 Excluded string `json:"-" db:"-"` 300 NullableCol string `json:"not_nullable" db:"nullable,nullable"` 301 InferredWithFlags string `db:",readonly"` 302 BigIntColumn int64 `db:"big_int"` 303 PointerColumn *int `db:"pointer_col"` 304 JSONColumn subStruct `db:"json_col,json"` 305 } 306 307 func (m myStruct) TableName() string { 308 return "my_struct" 309 }