|
19 | 19 |
|
20 | 20 | #include "utils/json.h"
|
21 | 21 |
|
| 22 | +typedef struct ShowBackendRow |
| 23 | +{ |
| 24 | + const char *instance; |
| 25 | + const char *version; |
| 26 | + char backup_id[20]; |
| 27 | + char recovery_time[100]; |
| 28 | + const char *mode; |
| 29 | + const char *wal_mode; |
| 30 | + char tli[20]; |
| 31 | + char duration[20]; |
| 32 | + char data_bytes[20]; |
| 33 | + char start_lsn[20]; |
| 34 | + char stop_lsn[20]; |
| 35 | + const char *status; |
| 36 | +} ShowBackendRow; |
| 37 | + |
22 | 38 |
|
23 | 39 | static void show_instance_start(void);
|
24 | 40 | static void show_instance_end(void);
|
@@ -299,63 +315,194 @@ show_backup(time_t requested_backup_id)
|
299 | 315 | static void
|
300 | 316 | show_instance_plain(parray *backup_list, bool show_name)
|
301 | 317 | {
|
| 318 | +#define SHOW_FIELDS_COUNT 12 |
302 | 319 | int i;
|
| 320 | + const char *names[SHOW_FIELDS_COUNT] = |
| 321 | + { "Instance", "Version", "ID", "Recovery Time", |
| 322 | + "Mode", "WAL", "Current/Parent TLI", "Time", "Data", |
| 323 | + "Start LSN", "Stop LSN", "Status" }; |
| 324 | + const char *field_formats[SHOW_FIELDS_COUNT] = |
| 325 | + { " %-*s ", " %-*s ", " %-*s ", " %-*s ", |
| 326 | + " %-*s ", " %-*s ", " %-*s ", " %*s ", " %*s ", |
| 327 | + " %*s ", " %*s ", " %-*s "}; |
| 328 | + uint32 widths[SHOW_FIELDS_COUNT]; |
| 329 | + uint32 widths_sum = 0; |
| 330 | + ShowBackendRow *rows; |
| 331 | + |
| 332 | + for (i = 0; i < SHOW_FIELDS_COUNT; i++) |
| 333 | + widths[i] = strlen(names[i]); |
| 334 | + |
| 335 | + rows = (ShowBackendRow *) palloc(parray_num(backup_list) * |
| 336 | + sizeof(ShowBackendRow)); |
| 337 | + |
| 338 | + /* |
| 339 | + * Fill row values and calculate maximum width of each field. |
| 340 | + */ |
| 341 | + for (i = 0; i < parray_num(backup_list); i++) |
| 342 | + { |
| 343 | + pgBackup *backup = parray_get(backup_list, i); |
| 344 | + ShowBackendRow *row = &rows[i]; |
| 345 | + int cur = 0; |
| 346 | + |
| 347 | + /* Instance */ |
| 348 | + row->instance = instance_name; |
| 349 | + widths[cur] = Max(widths[cur], strlen(row->instance)); |
| 350 | + cur++; |
| 351 | + |
| 352 | + /* Version */ |
| 353 | + row->version = backup->server_version[0] ? |
| 354 | + backup->server_version : "----"; |
| 355 | + widths[cur] = Max(widths[cur], strlen(row->version)); |
| 356 | + cur++; |
| 357 | + |
| 358 | + /* ID */ |
| 359 | + snprintf(row->backup_id, lengthof(row->backup_id), "%s", |
| 360 | + base36enc(backup->start_time)); |
| 361 | + widths[cur] = Max(widths[cur], strlen(row->backup_id)); |
| 362 | + cur++; |
| 363 | + |
| 364 | + /* Recovery Time */ |
| 365 | + if (backup->recovery_time != (time_t) 0) |
| 366 | + time2iso(row->recovery_time, lengthof(row->recovery_time), |
| 367 | + backup->recovery_time); |
| 368 | + else |
| 369 | + StrNCpy(row->recovery_time, "----", 4); |
| 370 | + widths[cur] = Max(widths[cur], strlen(row->recovery_time)); |
| 371 | + cur++; |
| 372 | + |
| 373 | + /* Mode */ |
| 374 | + row->mode = pgBackupGetBackupMode(backup); |
| 375 | + widths[cur] = Max(widths[cur], strlen(row->mode)); |
| 376 | + cur++; |
| 377 | + |
| 378 | + /* WAL */ |
| 379 | + row->wal_mode = backup->stream ? "STREAM": "ARCHIVE"; |
| 380 | + widths[cur] = Max(widths[cur], strlen(row->wal_mode)); |
| 381 | + cur++; |
| 382 | + |
| 383 | + /* Current/Parent TLI */ |
| 384 | + snprintf(row->tli, lengthof(row->tli), "%u / %u", |
| 385 | + backup->tli, get_parent_tli(backup->tli)); |
| 386 | + widths[cur] = Max(widths[cur], strlen(row->tli)); |
| 387 | + cur++; |
| 388 | + |
| 389 | + /* Time */ |
| 390 | + if (backup->end_time != (time_t) 0) |
| 391 | + snprintf(row->duration, lengthof(row->duration), "%.*lfs", 0, |
| 392 | + difftime(backup->end_time, backup->start_time)); |
| 393 | + else |
| 394 | + StrNCpy(row->duration, "----", 4); |
| 395 | + widths[cur] = Max(widths[cur], strlen(row->duration)); |
| 396 | + cur++; |
| 397 | + |
| 398 | + /* Data */ |
| 399 | + pretty_size(backup->data_bytes, row->data_bytes, |
| 400 | + lengthof(row->data_bytes)); |
| 401 | + widths[cur] = Max(widths[cur], strlen(row->data_bytes)); |
| 402 | + cur++; |
| 403 | + |
| 404 | + /* Start LSN */ |
| 405 | + snprintf(row->start_lsn, lengthof(row->start_lsn), "%X/%X", |
| 406 | + (uint32) (backup->start_lsn >> 32), |
| 407 | + (uint32) backup->start_lsn); |
| 408 | + widths[cur] = Max(widths[cur], strlen(row->start_lsn)); |
| 409 | + cur++; |
| 410 | + |
| 411 | + /* Stop LSN */ |
| 412 | + snprintf(row->stop_lsn, lengthof(row->stop_lsn), "%X/%X", |
| 413 | + (uint32) (backup->stop_lsn >> 32), |
| 414 | + (uint32) backup->stop_lsn); |
| 415 | + widths[cur] = Max(widths[cur], strlen(row->stop_lsn)); |
| 416 | + cur++; |
| 417 | + |
| 418 | + /* Status */ |
| 419 | + row->status = status2str(backup->status); |
| 420 | + widths[cur] = Max(widths[cur], strlen(row->status)); |
| 421 | + } |
| 422 | + |
| 423 | + for (i = 0; i < SHOW_FIELDS_COUNT; i++) |
| 424 | + widths_sum += widths[i] + 2 /* two space */; |
303 | 425 |
|
304 | 426 | if (show_name)
|
305 | 427 | appendPQExpBuffer(&show_buf, "\nBACKUP INSTANCE '%s'\n", instance_name);
|
306 | 428 |
|
307 |
| - /* if you add new fields here, fix the header */ |
308 |
| - /* show header */ |
309 |
| - appendPQExpBufferStr(&show_buf, |
310 |
| - "============================================================================================================================================\n"); |
311 |
| - appendPQExpBufferStr(&show_buf, |
312 |
| - " Instance Version ID Recovery time Mode WAL Current/Parent TLI Time Data Start LSN Stop LSN Status \n"); |
313 |
| - appendPQExpBufferStr(&show_buf, |
314 |
| - "============================================================================================================================================\n"); |
| 429 | + /* |
| 430 | + * Print header. |
| 431 | + */ |
| 432 | + for (i = 0; i < widths_sum; i++) |
| 433 | + appendPQExpBufferChar(&show_buf, '='); |
| 434 | + appendPQExpBufferChar(&show_buf, '\n'); |
| 435 | + |
| 436 | + for (i = 0; i < SHOW_FIELDS_COUNT; i++) |
| 437 | + { |
| 438 | + appendPQExpBuffer(&show_buf, field_formats[i], widths[i], names[i]); |
| 439 | + } |
| 440 | + appendPQExpBufferChar(&show_buf, '\n'); |
315 | 441 |
|
| 442 | + for (i = 0; i < widths_sum; i++) |
| 443 | + appendPQExpBufferChar(&show_buf, '='); |
| 444 | + appendPQExpBufferChar(&show_buf, '\n'); |
| 445 | + |
| 446 | + /* |
| 447 | + * Print values. |
| 448 | + */ |
316 | 449 | for (i = 0; i < parray_num(backup_list); i++)
|
317 | 450 | {
|
318 |
| - pgBackup *backup = parray_get(backup_list, i); |
319 |
| - TimeLineID parent_tli; |
320 |
| - char timestamp[100] = "----"; |
321 |
| - char duration[20] = "----"; |
322 |
| - char data_bytes_str[10] = "----"; |
| 451 | + ShowBackendRow *row = &rows[i]; |
| 452 | + int cur = 0; |
323 | 453 |
|
324 |
| - if (backup->recovery_time != (time_t) 0) |
325 |
| - time2iso(timestamp, lengthof(timestamp), backup->recovery_time); |
326 |
| - if (backup->end_time != (time_t) 0) |
327 |
| - snprintf(duration, lengthof(duration), "%.*lfs", 0, |
328 |
| - difftime(backup->end_time, backup->start_time)); |
| 454 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 455 | + row->instance); |
| 456 | + cur++; |
329 | 457 |
|
330 |
| - /* |
331 |
| - * Calculate Data field, in the case of full backup this shows the |
332 |
| - * total amount of data. For an differential backup, this size is only |
333 |
| - * the difference of data accumulated. |
334 |
| - */ |
335 |
| - pretty_size(backup->data_bytes, data_bytes_str, |
336 |
| - lengthof(data_bytes_str)); |
| 458 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 459 | + row->version); |
| 460 | + cur++; |
337 | 461 |
|
338 |
| - /* Get parent timeline before printing */ |
339 |
| - parent_tli = get_parent_tli(backup->tli); |
| 462 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 463 | + row->backup_id); |
| 464 | + cur++; |
| 465 | + |
| 466 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 467 | + row->recovery_time); |
| 468 | + cur++; |
340 | 469 |
|
341 |
| - appendPQExpBuffer(&show_buf, |
342 |
| - " %-11s %-8s %-6s %-22s %-6s %-7s %3d / %-3d %5s %6s %2X/%-8X %2X/%-8X %-8s\n", |
343 |
| - instance_name, |
344 |
| - (backup->server_version[0] ? backup->server_version : "----"), |
345 |
| - base36enc(backup->start_time), |
346 |
| - timestamp, |
347 |
| - pgBackupGetBackupMode(backup), |
348 |
| - backup->stream ? "STREAM": "ARCHIVE", |
349 |
| - backup->tli, |
350 |
| - parent_tli, |
351 |
| - duration, |
352 |
| - data_bytes_str, |
353 |
| - (uint32) (backup->start_lsn >> 32), |
354 |
| - (uint32) backup->start_lsn, |
355 |
| - (uint32) (backup->stop_lsn >> 32), |
356 |
| - (uint32) backup->stop_lsn, |
357 |
| - status2str(backup->status)); |
| 470 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 471 | + row->mode); |
| 472 | + cur++; |
| 473 | + |
| 474 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 475 | + row->wal_mode); |
| 476 | + cur++; |
| 477 | + |
| 478 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 479 | + row->tli); |
| 480 | + cur++; |
| 481 | + |
| 482 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 483 | + row->duration); |
| 484 | + cur++; |
| 485 | + |
| 486 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 487 | + row->data_bytes); |
| 488 | + cur++; |
| 489 | + |
| 490 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 491 | + row->start_lsn); |
| 492 | + cur++; |
| 493 | + |
| 494 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 495 | + row->stop_lsn); |
| 496 | + cur++; |
| 497 | + |
| 498 | + appendPQExpBuffer(&show_buf, field_formats[cur], widths[cur], |
| 499 | + row->status); |
| 500 | + cur++; |
| 501 | + |
| 502 | + appendPQExpBufferChar(&show_buf, '\n'); |
358 | 503 | }
|
| 504 | + |
| 505 | + pfree(rows); |
359 | 506 | }
|
360 | 507 |
|
361 | 508 | /*
|
|
0 commit comments