github.com/octohelm/storage@v0.0.0-20240516030302-1ac2cc1ea347/pkg/sqlbuilder/def_table.go (about) 1 package sqlbuilder 2 3 import ( 4 "bytes" 5 "container/list" 6 "context" 7 "fmt" 8 "sort" 9 "text/scanner" 10 ) 11 12 func ColumnsAndValuesByFieldValues(t Table, fieldValues FieldValues) (cols ColumnCollection, args []interface{}) { 13 fieldNames := make([]string, 0) 14 for fieldName := range fieldValues { 15 fieldNames = append(fieldNames, fieldName) 16 } 17 18 sort.Strings(fieldNames) 19 20 cols = Cols() 21 22 for _, fieldName := range fieldNames { 23 if col := t.F(fieldName); col != nil { 24 cols.(ColumnCollectionManger).AddCol(col) 25 args = append(args, fieldValues[fieldName]) 26 } 27 } 28 return 29 } 30 31 func AssignmentsByFieldValues(t Table, fieldValues FieldValues) (assignments Assignments) { 32 for fieldName, value := range fieldValues { 33 col := t.F(fieldName) 34 if col != nil { 35 assignments = append(assignments, CastCol[any](col).By(Value(value))) 36 } 37 } 38 return 39 } 40 41 type TableDefinition interface { 42 T() Table 43 } 44 45 type TableExprParse interface { 46 Expr(query string, args ...any) *Ex 47 } 48 49 type TableWithTableName interface { 50 WithTableName(name string) Table 51 } 52 53 type Table interface { 54 SqlExpr 55 56 // TableName of table 57 TableName() string 58 59 // K 60 // get index by key name 61 // primaryKey could be use `pk` 62 K(k string) Key 63 // F 64 // get col by col name or struct field names 65 F(name string) Column 66 67 // Cols 68 // get cols by col names or struct field name 69 Cols(names ...string) ColumnCollection 70 71 // Keys 72 // get indexes by index names 73 Keys(names ...string) KeyCollection 74 } 75 76 func T(tableName string, tableDefinitions ...TableDefinition) Table { 77 t := &table{ 78 name: tableName, 79 ColumnCollection: &columns{}, 80 KeyCollection: &keys{}, 81 } 82 83 // col added first 84 for _, tableDef := range tableDefinitions { 85 switch d := tableDef.(type) { 86 case Column: 87 t.AddCol(d.Of(t)) 88 } 89 } 90 91 for _, tableDef := range tableDefinitions { 92 switch d := tableDef.(type) { 93 case Key: 94 t.AddKey(d.Of(t)) 95 } 96 } 97 98 return t 99 } 100 101 type table struct { 102 database string 103 name string 104 description []string 105 ColumnCollection 106 KeyCollection 107 } 108 109 func (t *table) AddCol(cols ...Column) { 110 for i := range cols { 111 t.ColumnCollection.(ColumnCollectionManger).AddCol(cols[i].Of(t)) 112 } 113 } 114 115 func (t *table) AddKey(keys ...Key) { 116 for i := range keys { 117 t.KeyCollection.(KeyCollectionManager).AddKey(keys[i].Of(t)) 118 } 119 } 120 121 func (t table) WithTableName(name string) Table { 122 newTable := &table{ 123 database: t.database, 124 name: name, 125 description: t.description, 126 } 127 128 newTable.ColumnCollection = t.ColumnCollection.Of(newTable) 129 newTable.KeyCollection = t.KeyCollection.Of(newTable) 130 131 return newTable 132 } 133 134 func (t *table) TableName() string { 135 return t.name 136 } 137 138 func (t *table) IsNil() bool { 139 return t == nil || len(t.name) == 0 140 } 141 142 func (t *table) Ex(ctx context.Context) *Ex { 143 return Expr(t.name).Ex(ctx) 144 } 145 146 func (t *table) Expr(query string, args ...interface{}) *Ex { 147 if query == "" { 148 return nil 149 } 150 151 n := len(args) 152 e := Expr("") 153 e.Grow(n) 154 155 s := &scanner.Scanner{} 156 s.Init(bytes.NewBuffer([]byte(query))) 157 158 queryCount := 0 159 160 for tok := s.Next(); tok != scanner.EOF; tok = s.Next() { 161 switch tok { 162 case '#': 163 fieldNameBuf := bytes.NewBuffer(nil) 164 165 e.WriteHolder(0) 166 167 for { 168 tok = s.Next() 169 170 if tok == scanner.EOF { 171 break 172 } 173 174 if (tok >= 'A' && tok <= 'Z') || 175 (tok >= 'a' && tok <= 'z') || 176 (tok >= '0' && tok <= '9') || 177 tok == '_' { 178 179 fieldNameBuf.WriteRune(tok) 180 continue 181 } 182 183 e.WriteQueryByte(byte(tok)) 184 185 break 186 } 187 188 if fieldNameBuf.Len() == 0 { 189 e.AppendArgs(t) 190 } else { 191 fieldName := fieldNameBuf.String() 192 col := t.F(fieldNameBuf.String()) 193 if col == nil { 194 panic(fmt.Errorf("missing field fieldName %s of table %s", fieldName, t.TableName())) 195 } 196 e.AppendArgs(col) 197 } 198 case '?': 199 e.WriteQueryByte(byte(tok)) 200 if queryCount < n { 201 e.AppendArgs(args[queryCount]) 202 queryCount++ 203 } 204 default: 205 e.WriteQueryByte(byte(tok)) 206 } 207 } 208 209 return e 210 } 211 212 type Tables struct { 213 l *list.List 214 tables map[string]*list.Element 215 } 216 217 func (tables *Tables) TableNames() (names []string) { 218 tables.Range(func(tab Table, idx int) bool { 219 names = append(names, tab.TableName()) 220 return true 221 }) 222 sort.Strings(names) 223 return 224 } 225 226 func (tables *Tables) Add(tabs ...Table) { 227 if tables.tables == nil { 228 tables.tables = map[string]*list.Element{} 229 tables.l = list.New() 230 } 231 232 for _, tab := range tabs { 233 if tab != nil { 234 if _, ok := tables.tables[tab.TableName()]; ok { 235 tables.Remove(tab.TableName()) 236 } 237 e := tables.l.PushBack(tab) 238 tables.tables[tab.TableName()] = e 239 } 240 } 241 } 242 243 func (tables *Tables) Table(tableName string) Table { 244 if tables.tables != nil { 245 if c, ok := tables.tables[tableName]; ok { 246 return c.Value.(Table) 247 } 248 } 249 return nil 250 } 251 252 func (tables *Tables) Remove(name string) { 253 if tables.tables != nil { 254 if e, exists := tables.tables[name]; exists { 255 tables.l.Remove(e) 256 delete(tables.tables, name) 257 } 258 } 259 } 260 261 func (tables Tables) Range(cb func(tab Table, idx int) bool) { 262 if tables.l != nil { 263 i := 0 264 for e := tables.l.Front(); e != nil; e = e.Next() { 265 if !cb(e.Value.(Table), i) { 266 break 267 } 268 i++ 269 } 270 } 271 }