## ----include = FALSE----------------------------------------------------------
# Evaluate chunks only where the ducklake DuckDB extension is already
# installed. The probe never downloads anything, so building this vignette
# needs no network access.
ducklake_available <- ducklake::ducklake_extension_available()
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = ducklake_available
)
# Use a unique temp directory for this vignette to avoid conflicts during R CMD check
vignette_temp_dir <- file.path(tempdir(), "data_inlining_vignette")
dir.create(vignette_temp_dir, showWarnings = FALSE, recursive = TRUE)
knitr::opts_knit$set(root.dir = vignette_temp_dir)

## ----setup, message = FALSE---------------------------------------------------
library(ducklake)
library(dplyr)

## ----create-lake, message = FALSE---------------------------------------------
# The ducklake extension only needs installing once per machine:
# install_ducklake()
attach_ducklake("sensor_lake", lake_path = vignette_temp_dir)

## ----create-table-------------------------------------------------------------
readings <- data.frame(
  sensor_id = 1:3,
  temperature = c(21.5, 22.1, 21.8),
  ts = as.POSIXct(
    c("2025-03-27 10:00:00", "2025-03-27 10:00:10", "2025-03-27 10:00:20"),
    tz = "UTC"
  )
)

with_transaction(
  create_table(readings, "readings"),
  author = "Sensor Team",
  commit_message = "Initial sensor readings"
)

## ----verify-no-parquet--------------------------------------------------------
conn <- get_ducklake_connection()
DBI::dbGetQuery(
  conn,
  sprintf("SELECT count(*) AS parquet_files FROM glob('%s/**/*.parquet');", vignette_temp_dir)
)

## ----query-inline-------------------------------------------------------------
get_ducklake_table("readings") |> collect()

## ----small-update-------------------------------------------------------------
# Add a calibrated temperature column
with_transaction(
  get_ducklake_table("readings") |>
    mutate(temp_calibrated = temperature - 0.3) |>
    replace_table("readings"),
  author = "Sensor Team",
  commit_message = "Add calibrated temperature"
)

get_ducklake_table("readings") |> collect()

## ----small-delete-------------------------------------------------------------
# Remove sensor 2's reading
with_transaction(
  get_ducklake_table("readings") |>
    filter(sensor_id != 2) |>
    replace_table("readings"),
  author = "Sensor Team",
  commit_message = "Remove faulty sensor 2 reading"
)

get_ducklake_table("readings") |> collect()

## ----large-insert-------------------------------------------------------------
# 50 rows — well above the default threshold of 10
large_batch <- data.frame(
  sensor_id = 101:150,
  temperature = rnorm(50, mean = 22, sd = 1),
  ts = seq(as.POSIXct("2025-03-28 00:00:00", tz = "UTC"), by = "10 sec", length.out = 50),
  temp_calibrated = rnorm(50, mean = 21.7, sd = 1)
)

with_transaction(
  create_table(large_batch, "readings_bulk"),
  author = "Sensor Team",
  commit_message = "Bulk sensor upload"
)

# This table has a Parquet file
DBI::dbGetQuery(
  conn,
  sprintf("SELECT count(*) AS parquet_files FROM glob('%s/**/*.parquet');", vignette_temp_dir)
)

## ----set-global---------------------------------------------------------------
# Increase the threshold for a streaming workload
set_inlining_row_limit(50)
get_inlining_row_limit()

## ----attach-limit, eval = FALSE-----------------------------------------------
# attach_ducklake(
#   "streaming_lake",
#   lake_path = "/data/streaming",
#   data_inlining_row_limit = 100
# )

## ----table-limit, eval = FALSE------------------------------------------------
# set_inlining_row_limit(100, table_name = "readings")

## ----disable-inline-----------------------------------------------------------
set_inlining_row_limit(0)
# All writes now go directly to Parquet, even single rows

## ----restore-default, include = FALSE-----------------------------------------
# Restore default for the rest of the vignette
set_inlining_row_limit(10)

## ----flush--------------------------------------------------------------------
flush_result <- flush_inlined_data()
flush_result

## ----post-flush---------------------------------------------------------------
get_ducklake_table("readings") |> collect()

## ----flush-table, eval = FALSE------------------------------------------------
# flush_inlined_data(table_name = "readings")

## ----checkpoint, eval = ducklake_available && .Platform$OS.type != "windows"----
checkpoint_ducklake()

## ----time-travel-setup--------------------------------------------------------
# Check available snapshots
snapshots <- list_table_snapshots("readings")
snapshots

## ----time-travel-query--------------------------------------------------------
# Query an earlier version
if (nrow(snapshots) > 0) {
  first_version <- snapshots$snapshot_id[1]
  get_ducklake_table_version("readings", first_version) |> collect()
}

## ----cleanup, include = FALSE-------------------------------------------------
try(detach_ducklake("sensor_lake"), silent = TRUE)

