Skip to content

feat: tbl_format_setup() gains a setup argument that supports printing the header before the data for the body is available, e.g., for remote backends such as databases#686

Merged
krlmlr merged 6 commits into
mainfrom
f-duckplyr
Dec 14, 2024

Conversation

@krlmlr

@krlmlr krlmlr commented Nov 22, 2024

Copy link
Copy Markdown
Member

This supports printing the header before the body or footer is ready. Adding the setup argument to tbl_format_setup() was the easiest way I found to achieve this. The two commits are self-contained.

@krlmlr krlmlr changed the title f duckplyr Live printing Nov 22, 2024
@krlmlr krlmlr enabled auto-merge (squash) November 22, 2024 18:18
@krlmlr krlmlr changed the title Live printing feat: Print header first Nov 22, 2024
@krlmlr krlmlr disabled auto-merge November 22, 2024 18:20
@krlmlr

krlmlr commented Nov 23, 2024

Copy link
Copy Markdown
Member Author

This is likely to affect dbplyr by no longer showing the number of rows in the header if it's less than 21. I'd trade that for showing the header first. And I wonder if we should temporarily show the structure of the data too, and erase it (with \r?) when the body is ready.

@DavisVaughan DavisVaughan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels quite "spooky" to me

In particular I found relying on "did setup get evaluated or not" a bit hard to understand and document.

Is it possible that new_tbl_format_setup() could gain a boolean argument that identifies whether or not this is a "partial" setup?

Like:

  • If we see is.null(setup) then we do partial setup and return with partial = TRUE.
  • That causes tbl_format_setup() to get called again, but with !is.null(setup) this time (i.e. it gets the results of the original partial setup), so we do the full setup and return with partial = FALSE

Comment thread R/tbl-format.R
width = width,
...,
setup = {
setup_used <- TRUE

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a note in here about the fact that "If setup is evaluated by the tbl_format_setup() method, then that's our signal to recall tbl_format_setup() a second time"

Comment thread R/tbl-format.R
header <- tbl_format_header(x, setup)
body <- tbl_format_body(x, setup)
footer <- tbl_format_footer(x, setup)
header <- transform(tbl_format_header(x, setup))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does transform() do?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transform is writeLines when printing and identity when formatting. This is how we achieve incremental printing.

Adding a comment to that effect to the code.

Comment thread R/tbl-format-setup.R
#' This argument is mandatory for all implementations of this method.
#' @param ...
#' Extra arguments to [print.tbl()] or [format.tbl()].
#' @param setup

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth a news bullet

@krlmlr

krlmlr commented Nov 26, 2024

Copy link
Copy Markdown
Member Author

Thanks. I see how it's spooky, I couldn't think of a better way.

We want to be compatible with existing implementations of tbl_format_setup() who might not know or care about the new flow. We effectively implement a "pre-setup" (for just the header) and a "setup for real" (for the body and footer), the fallback being just one setup call. Should we do a new generic instead, or perhaps two new generics? What would they look like, what would the migration path look like?

@krlmlr krlmlr changed the title feat: Print header first feat: tbl_format_setup() gains a setup argument that supports printing the header before the data for the body is available, e.g., for remote backends such as databases Dec 7, 2024
@krlmlr krlmlr merged commit 73c00f6 into main Dec 14, 2024
@krlmlr krlmlr deleted the f-duckplyr branch December 14, 2024 15:11
@krlmlr

krlmlr commented Dec 14, 2024

Copy link
Copy Markdown
Member Author

Going with this implementation for now, we can revisit as needed.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Dec 15, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants