(statement string, backupItem *storepb.PriorBackupDetail_Item)
| 381 | } |
| 382 | |
| 383 | func extractStatement(statement string, backupItem *storepb.PriorBackupDetail_Item) (string, error) { |
| 384 | if backupItem == nil { |
| 385 | return "", errors.Errorf("backup item is nil") |
| 386 | } |
| 387 | |
| 388 | parseResults, err := parseTSQLStatements(statement) |
| 389 | if err != nil { |
| 390 | return "", errors.Wrapf(err, "failed to parse statement") |
| 391 | } |
| 392 | |
| 393 | var originalSQL []string |
| 394 | for _, parsedStatement := range parseResults { |
| 395 | node, ok := GetOmniNode(parsedStatement.AST) |
| 396 | if !ok || node == nil || !isRestorableDML(node) { |
| 397 | continue |
| 398 | } |
| 399 | start, end := statementPositions(parsedStatement.Start, parsedStatement.Text, dmlNodeLoc(node)) |
| 400 | if !inRange(start, end, backupItem.StartPosition, backupItem.EndPosition) { |
| 401 | continue |
| 402 | } |
| 403 | sql := strings.TrimSuffix(sourceFromLoc(parsedStatement.Text, dmlNodeLoc(node)), ";") |
| 404 | originalSQL = append(originalSQL, sql) |
| 405 | } |
| 406 | if len(originalSQL) == 0 { |
| 407 | return "", nil |
| 408 | } |
| 409 | |
| 410 | // Join with semicolons and add a trailing semicolon |
| 411 | return strings.Join(originalSQL, ";\n") + ";", nil |
| 412 | } |
| 413 | |
| 414 | func isRestorableDML(node ast.Node) bool { |
| 415 | switch node.(type) { |
no test coverage detected