| 254 | } |
| 255 | |
| 256 | func getIndexes(db *sql.DB, schema, tableName string) (map[string]Index, error) { |
| 257 | query := fmt.Sprintf("SHOW INDEXES FROM `%s`.`%s`", schema, tableName) |
| 258 | rows, err := db.Query(query) |
| 259 | if err != nil { |
| 260 | return nil, err |
| 261 | } |
| 262 | |
| 263 | indexes := make(map[string]Index) |
| 264 | |
| 265 | for rows.Next() { |
| 266 | var i IndexField |
| 267 | var table, visible string |
| 268 | fields := []interface{}{&table, &i.NonUnique, &i.KeyName, &i.SeqInIndex, |
| 269 | &i.ColumnName, &i.Collation, &i.Cardinality, &i.SubPart, |
| 270 | &i.Packed, &i.Null, &i.IndexType, &i.Comment, &i.IndexComment, |
| 271 | } |
| 272 | |
| 273 | cols, err := rows.Columns() |
| 274 | if err == nil && len(cols) >= 14 && cols[13] == "Visible" { |
| 275 | fields = append(fields, &i.Visible) |
| 276 | } |
| 277 | if err == nil && len(cols) >= 15 && cols[14] == "Expression" { |
| 278 | fields = append(fields, &i.Expression) |
| 279 | } |
| 280 | |
| 281 | err = rows.Scan(fields...) |
| 282 | if err != nil { |
| 283 | return nil, fmt.Errorf("cannot read indexes: %s", err) |
| 284 | } |
| 285 | if index, ok := indexes[i.KeyName]; !ok { |
| 286 | indexes[i.KeyName] = Index{ |
| 287 | Name: i.KeyName, |
| 288 | Unique: !i.NonUnique, |
| 289 | Fields: []string{i.ColumnName}, |
| 290 | Visible: i.Visible == "YES" || visible == "", |
| 291 | Expression: i.Expression.String, |
| 292 | } |
| 293 | |
| 294 | } else { |
| 295 | index.Fields = append(index.Fields, i.ColumnName) |
| 296 | index.Unique = index.Unique || !i.NonUnique |
| 297 | } |
| 298 | } |
| 299 | if err := rows.Close(); err != nil { |
| 300 | return nil, errors.Wrap(err, "Cannot close query rows at getIndexes") |
| 301 | } |
| 302 | |
| 303 | return indexes, nil |
| 304 | } |
| 305 | |
| 306 | func getConstraints(db *sql.DB, schema, tableName string) ([]Constraint, error) { |
| 307 | query := "SELECT tc.CONSTRAINT_NAME, " + |