# Higher-level packages handle connections internally
# Example: some_package::get_data(artist)This vignette covers advanced patterns and edge cases when working with artcore.
Connection Pooling Patterns
Single Operation (Auto-managed)
For simple one-off operations, let the higher-level packages manage connections:
Multiple Operations (Shared Connection)
For batch operations, share a connection to reduce overhead:
cn <- dbc()
on.exit(dbd(cn))
# Pass connection to multiple functions
# Pass cn to functions that support it
stats <- DBI::dbGetQuery(cn, "SELECT * FROM app.artist_stats WHERE ...")
data <- DBI::dbGetQuery(cn, "SELECT * FROM app.artwork_index WHERE ...")
# ... more operations ...Transaction Blocks
For operations that must succeed or fail together:
CDN Batch Operations
Uploading Large Directories
For directories with many files, monitor progress:
# write_art_vault logs progress automatically
keys <- write_art_vault(artist, artwork, local_path = large_bundle)
#> ℹ art-vault Uploading 500 file(s) => uploads/88xxx.../99xxx.../
#> ℹ art-vault Progress: 100/500 files uploaded
#> ℹ art-vault Progress: 200/500 files uploaded
#> ...Verifying Large Uploads
After uploading many files, verify the count:
expected_count <- length(list.files(bundle_dir, recursive = TRUE))
actual_count <- cdn_count_keys(
paste0("uploads/", artist, "/", artwork),
bucket = "art-vault"
)
if (actual_count != expected_count) {
stop("Upload incomplete: expected ", expected_count, " got ", actual_count)
}Soft Delete with Verification
# Always dry run first
cdn_soft_delete(artist, artwork, dry_run = TRUE)
# Review the output, then execute
cdn_soft_delete(artist, artwork)
# Verify deletion
stopifnot(!has_prefix("art-vault", paste0("uploads/", artist, "/", artwork)))
stopifnot(!has_object("art-public", paste0("thumbnails/", artist, "/", artwork, ".jpeg")))UUID Validation
Validate Before Operations
# validate_uuid throws error for invalid format
validate_uuid(artist) # Returns TRUE or throws error
# Check prefix matches expected entity type
if (!startsWith(artist, "88")) {
stop("Expected artist UUID (prefix 88), got: ", substr(artist, 1, 2))
}Using Test UUIDs
Test UUIDs have extended prefixes for easy identification in production databases:
# Production UUID: 99xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Test UUID: 90000000-xxxx-xxxx-xxxx-xxxxxxxxxxxx
artwork <- gen_artwork_id(test = TRUE)
# Easy to find and clean up test data
# SELECT * FROM app.artwork_index WHERE art_uuid LIKE '90000000%'Error Handling Patterns
Graceful Degradation
get_thumbnail_url <- function(artist, artwork) {
key <- paste0("thumbnails/", artist, "/", artwork, ".jpeg")
if (has_object("art-public", key)) {
cdn_asset_url("art-public", key, signed = FALSE)
} else {
# Return placeholder instead of failing
cdn_asset_url("art-public", "site/images/placeholder.jpeg", signed = FALSE)
}
}Retry Logic for Transient Failures
upload_with_retry <- function(artist, artwork, local_path, max_attempts = 3) {
for (i in seq_len(max_attempts)) {
tryCatch(
{
return(write_art_vault(artist, artwork, local_path = local_path))
},
error = function(e) {
if (i == max_attempts) stop(e)
Sys.sleep(2^i) # Exponential backoff
message("Retry ", i, "/", max_attempts, ": ", conditionMessage(e))
}
)
}
}Working with Multiple Databases
Primary vs Marketing Database
# Primary database (default) - artwork, artists, analytics
cn_main <- dbc()
result <- DBI::dbGetQuery(cn_main, "SELECT * FROM app.artist_index LIMIT 5")
dbd(cn_main)
# Marketing database - leads, waitlist, whitepaper downloads
cn_site <- dbc("artsite")
leads <- DBI::dbGetQuery(cn_site, "SELECT * FROM waitlist.entries LIMIT 5")
dbd(cn_site)Performance Tips
Minimize Connection Overhead
Batch CDN Checks
# BAD: Individual checks
for (artwork in artworks) {
has_object("art-public", paste0("thumbnails/", artist, "/", artwork, ".jpeg"))
}
# GOOD: List once, filter locally
keys <- cdn_list_keys("art-public", paste0("thumbnails/", artist, "/"))
existing <- vapply(artworks, function(a) {
any(grepl(a, keys))
}, logical(1))Debugging
Enable Verbose Logging
artcore uses rdstools for logging. All operations log their actions:
✔ Connected user@host:5432/artalytics
ℹ (art-vault) Upload to Prefix -> uploads/88xxx.../99xxx.../
ℹ art-vault Uploading 5 file(s) => uploads/88xxx.../99xxx.../
✔ art-vault Vault upload complete: 5 objects
ℹ Disconnected
Check Environment State
# View all ART_* environment variables
env_vars <- Sys.getenv()
art_vars <- env_vars[grepl("^ART_", names(env_vars))]
print(art_vars)