(sql string)
| 46 | } |
| 47 | |
| 48 | func parseBackupSQL(sql string) (*BackupConfig, error) { |
| 49 | matches := backupRegex.FindStringSubmatch(sql) |
| 50 | if matches == nil { |
| 51 | // No match means the SQL doesn't follow the expected pattern |
| 52 | return nil, nil |
| 53 | } |
| 54 | |
| 55 | // matches: |
| 56 | // [1] DbName |
| 57 | // [2] RemoteUri |
| 58 | // [3] Endpoint |
| 59 | // [4] AccessKeyId |
| 60 | // [5] SecretAccessKey |
| 61 | dbName := strings.TrimSpace(matches[1]) |
| 62 | remoteUri := strings.TrimSpace(matches[2]) |
| 63 | endpoint := strings.TrimSpace(matches[3]) |
| 64 | accessKeyId := strings.TrimSpace(matches[4]) |
| 65 | secretAccessKey := strings.TrimSpace(matches[5]) |
| 66 | |
| 67 | if dbName == "" { |
| 68 | return nil, fmt.Errorf("missing required backup configuration: DATABASE") |
| 69 | } |
| 70 | if remoteUri == "" { |
| 71 | return nil, fmt.Errorf("missing required backup configuration: TO '<URI>'") |
| 72 | } |
| 73 | if endpoint == "" { |
| 74 | return nil, fmt.Errorf("missing required backup configuration: ENDPOINT") |
| 75 | } |
| 76 | if accessKeyId == "" { |
| 77 | return nil, fmt.Errorf("missing required backup configuration: ACCESS_KEY_ID") |
| 78 | } |
| 79 | if secretAccessKey == "" { |
| 80 | return nil, fmt.Errorf("missing required backup configuration: SECRET_ACCESS_KEY") |
| 81 | } |
| 82 | |
| 83 | storageConfig, remotePath, err := storage.ConstructStorageConfig(remoteUri, endpoint, accessKeyId, secretAccessKey) |
| 84 | if err != nil { |
| 85 | return nil, fmt.Errorf("failed to construct storage configuration for backup: %w", err) |
| 86 | } |
| 87 | |
| 88 | return NewBackupConfig(dbName, remotePath, storageConfig), nil |
| 89 | } |
| 90 | |
| 91 | func (h *ConnectionHandler) executeBackup(backupConfig *BackupConfig) (string, error) { |
| 92 | sqlCtx, err := h.duckHandler.sm.NewContextWithQuery(context.Background(), h.mysqlConn, "") |
no test coverage detected