| 234 | } |
| 235 | |
| 236 | func getLatestDatabaseVersion(ctx context.Context, conn *sql.Conn) (*semver.Version, error) { |
| 237 | query := `SELECT version FROM instance_change_history ORDER BY id DESC` |
| 238 | |
| 239 | var v string |
| 240 | if err := conn.QueryRowContext(ctx, query).Scan(&v); err != nil { |
| 241 | if err == sql.ErrNoRows { |
| 242 | return nil, nil |
| 243 | } |
| 244 | return nil, err |
| 245 | } |
| 246 | |
| 247 | version, err := semver.Make(v) |
| 248 | if err != nil { |
| 249 | return nil, errors.Wrapf(err, "invalid version %q", v) |
| 250 | } |
| 251 | return &version, nil |
| 252 | } |
| 253 | |
| 254 | // migrate3_13_21 migrates audit_log user references from users/{id} to users/{email} format. |
| 255 | // This is done in Go with batching to handle large audit_log tables efficiently. |