{"id":14067756,"url":"https://github.com/r-dbi/dblog","last_synced_at":"2025-12-30T01:35:05.597Z","repository":{"id":47278932,"uuid":"173011512","full_name":"r-dbi/dblog","owner":"r-dbi","description":"Logging for DBI","archived":false,"fork":false,"pushed_at":"2025-05-03T05:46:22.000Z","size":320,"stargazers_count":10,"open_issues_count":6,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-03T06:26:32.457Z","etag":null,"topics":["database","dbi","logging","r"],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/r-dbi.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-02-28T00:22:08.000Z","updated_at":"2025-05-03T05:43:32.000Z","dependencies_parsed_at":"2024-01-13T07:04:02.013Z","dependency_job_id":"a1c00ae0-ee06-4e6b-90af-2d03f53a0637","html_url":"https://github.com/r-dbi/dblog","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/r-dbi/dblog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-dbi%2Fdblog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-dbi%2Fdblog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-dbi%2Fdblog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-dbi%2Fdblog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/r-dbi","download_url":"https://codeload.github.com/r-dbi/dblog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-dbi%2Fdblog/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267798625,"owners_count":24145727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","dbi","logging","r"],"created_at":"2024-08-13T07:05:45.737Z","updated_at":"2025-12-30T01:35:05.571Z","avatar_url":"https://github.com/r-dbi.png","language":"R","funding_links":[],"categories":["R"],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\npkgload::load_all()\n```\n\n# dblog\n\n\u003c!-- badges: start --\u003e\n[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental)\n[![CRAN status](https://www.r-pkg.org/badges/version/dblog)](https://cran.r-project.org/package=dblog)\n\u003c!-- badges: end --\u003e\n\nThe goal of dblog is to implement logging for arbitrary DBI backends, similarly to Perl's [DBI::Log](https://metacpan.org/pod/DBI::Log).\nThis is useful for troubleshooting and auditing codes that access a database.\nThe initial use case for this package is to help debugging DBItest tests.\n\n## Installation\n\nYou can install the released version of dblog from [CRAN](https://CRAN.R-project.org) with:\n\n``` r\ninstall.packages(\"dblog\")\n```\n\nInstall the development version from GitHub using\n\n``` r\n# install.packages(\"devtools\")\ndevtools::install_github(\"r-dbi/dblog\")\n```\n\n\n## Basic example\n\nThe `dblog` driver wraps arbitrary drivers:\n\n```{r init}\nlibrary(dblog)\ndrv \u003c- dblog(RSQLite::SQLite())\n```\n\n\nAll calls to DBI methods are logged, by default to the console.\n\n```{r console}\nconn \u003c- dbConnect(drv, file = \":memory:\")\ndbWriteTable(conn, \"iris\", iris[1:3, ])\ndata \u003c- dbGetQuery(conn, \"SELECT * FROM iris\")\ndbDisconnect(conn)\n\ndata\n```\n\nThe log is runnable R code!\nRun it in a fresh session to repeat the operations, step by step or in an otherwise controlled fashion.\n\ndblog is smart about DBI objects created or returned, and will assign a new variable name to each new object.\nCleared results or closed connections are not removed automatically.\n\n## Logging options\n\nLogging can be redirected to a file, optionally all outputs may be logged as well.\nFor example, use a collecting logger to output all calls and results after the fact.\n\n\n```{r collect}\ncollecting_logger \u003c- make_collect_logger()\n\ndrv \u003c- dblog(RSQLite::SQLite(), logger = collecting_logger)\nconn \u003c- dbConnect(drv, file = \":memory:\")\ndbWriteTable(conn, \"iris\", iris[1:3, ])\ndata \u003c- dbGetQuery(conn, \"SELECT * FROM iris\")\ndbDisconnect(conn)\n\ncollecting_logger$retrieve()\n\nev \u003c- evaluate::evaluate(collecting_logger$retrieve())\ncat(unlist(ev, use.names = FALSE), sep = \"\\n\")\n```\n\n## Logging complex operations\n\nThe full power is demonstrated when running with code where the underlying _DBI_ operations are not obvious:\n\n```{r dplyr}\nlibrary(dplyr)\n\ndrv \u003c- dblog(RSQLite::SQLite())\nconn \u003c- dbConnect(drv, file = \":memory:\")\ndbWriteTable(conn, \"iris\", iris[1:3, ])\n\nsrc \u003c- dbplyr::src_dbi(conn)\niris_tbl \u003c- tbl(src, \"iris\")\niris_tbl %\u003e%\n  summarize_if(is.numeric, mean)\n```\n\n## Inheritance hierarchy\n\nDespite the common suggestion to [prefer composition over inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance), the new logging classes are implemented as subclasses of the actual DBI classes.\nMoreover, the class definitions are created on demand: for each different database backend, different subclasses are defined, to make sure dispatch is routed to the right methods.\n\nThe reason for this is that other methods, unknown to this package, might dispatch on the DBI class.\nOne such example is _dbplyr_ that introduces specialized behaviors for many classes.\nThe `explain()` method calls the internal `db_explain()` method which uses `EXPLAIN QUERY PLAN` for SQLite connections but `EXPLAIN` for unspecified database connections.\nWithout inheritance, _dbplyr_ would use the default method.\nThis might lead to errors for other databases that do not understand `EXPLAIN`.\n\n```{r dplyr-explain}\niris_tbl %\u003e%\n  summarize_if(is.numeric, mean) %\u003e% \n  explain()\n```\n\n---\n\nPlease note that the 'dblog' project is released with a\n[Contributor Code of Conduct](CODE_OF_CONDUCT.md).\nBy contributing to this project, you agree to abide by its terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr-dbi%2Fdblog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fr-dbi%2Fdblog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr-dbi%2Fdblog/lists"}