From 6863310c8d014396a82a7313464b1b2c01692b83 Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Mon, 14 Oct 2024 15:20:06 +0200 Subject: [PATCH] Document classes (#36) * fixes to vignette * export class docs * rename vignette * add more roxygen * add instance docs * document module * add registry documentation --- R/Field.R | 39 ++-- R/Instance.R | 68 ++++++- R/InstanceAPI.R | 4 + R/InstanceSettings.R | 4 + R/Module.R | 30 ++- R/Record.R | 6 +- R/Registry.R | 38 +++- R/UserSettings.R | 4 + man/Field.Rd | 146 ++++++++++++++ man/Instance.Rd | 184 +++++++++++++++++ man/Module.Rd | 135 +++++++++++++ man/Record.Rd | 78 +++++++ man/Registry.Rd | 190 ++++++++++++++++++ tests/testthat/test-instance_api.R | 2 +- vignettes/{structure.qmd => architecture.qmd} | 6 +- 15 files changed, 887 insertions(+), 47 deletions(-) create mode 100644 man/Field.Rd create mode 100644 man/Instance.Rd create mode 100644 man/Module.Rd create mode 100644 man/Record.Rd create mode 100644 man/Registry.Rd rename vignettes/{structure.qmd => architecture.qmd} (96%) diff --git a/R/Field.R b/R/Field.R index 2f68952..5d1e86e 100644 --- a/R/Field.R +++ b/R/Field.R @@ -1,13 +1,15 @@ #' @title Field #' -#' @noRd -#' #' @description #' A field in a registry. Field <- R6::R6Class( # nolint object_name_linter "Field", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param type The type of the field. Can be one of: #' "IntegerField", "JSONField", "OneToOneField", "SmallIntegerField", #' "BigIntegerField", "AutoField", "BigAutoField", "BooleanField", "TextField", @@ -94,47 +96,58 @@ Field <- R6::R6Class( # nolint object_name_linter .related_module_name = NULL ), active = list( - #' @return The type of the field. + #' @field type (`character(1)`)\cr + #' The type of the field. type = function() { private$.type }, - #' @return The through value of the field. + #' @field through (`list()` or `NULL`)\cr + #' The through value of the field. through = function() { private$.through }, - #' @return The field name. + #' @field field_name (`character(1)`)\cr + #' The field name. field_name = function() { private$.field_name }, - #' @return The registry name. + #' @field registry_name (`character(1)`)\cr + #' The registry name. registry_name = function() { private$.registry_name }, - #' @return The column name. + #' @field column_name (`character(1)`)\cr + #' The column name. column_name = function() { private$.column_name }, - #' @return The module name. + #' @field module_name (`character(1)`)\cr + #' The module name. module_name = function() { private$.module_name }, - #' @return Whether the field is a link table. + #' @field is_link_table (`logical(1)`)\cr + #' Whether the field is a link table. is_link_table = function() { private$.is_link_table }, - #' @return The relation type. + #' @field relation_type (`character(1)` or `NULL`)\cr + #' The relation type. Can be one of: "one-to-many", "many-to-one", "many-to-many". relation_type = function() { private$.relation_type }, - #' @return The related field name. + #' @field related_field_name (`character(1)` or `NULL`)\cr + #' The related field name. related_field_name = function() { private$.related_field_name }, - #' @return The related registry name. + #' @field related_registry_name (`character(1)` or `NULL`)\cr + #' The related registry name. related_registry_name = function() { private$.related_registry_name }, - #' @return The related module name. + #' @field related_module_name (`character(1)` or `NULL`)\cr + #' The related module name. related_module_name = function() { private$.related_module_name } diff --git a/R/Instance.R b/R/Instance.R index e10cdcb..59dbc75 100644 --- a/R/Instance.R +++ b/R/Instance.R @@ -63,14 +63,43 @@ create_instance <- function(instance_settings) { #' @title Instance #' -#' @noRd -#' #' @description -#' A LaminDB instance. +#' Connect to a LaminDB instance using the [connect()] function. +#' The instance object provides access to the modules and registries +#' of the instance. +#' +#' @details +#' Note that by connecting to an instance via [connect()], you receive +#' a "richer" version of the Instance class documented here, providing +#' direct access to all core registries and additional modules. +#' See the vignette on "Package Architecture" for more information: +#' `vignette("architecture", package = "laminr")`. +#' +#' @examples +#' \dontrun{ +#' # Connect to an instance +#' db <- connect("laminlabs/cellxgene") +#' +#' # fetch an artifact +#' artifact <- db$Artifact$get("KBW89Mf7IGcekja2hADu") +#' +#' # describe the artifact +#' artifact$describe() +#' +#' # view field +#' artifact$id +#' +#' # load dataset +#' artifact$load() +#' } Instance <- R6::R6Class( # nolint object_name_linter "Instance", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param settings The settings for the instance #' @param api The API for the instance #' @param schema The schema for the instance @@ -92,24 +121,40 @@ Instance <- R6::R6Class( # nolint object_name_linter ) |> set_names(names(schema)) }, - #' Get the modules for the instance. + #' @description Get the modules for the instance. + #' + #' @return A list of [Module] objects. get_modules = function() { private$.module_classes }, - #' Get a module by name. + #' @description Get a module by name. + #' + #' @param module_name The name of the module. + #' + #' @return The [Module] object. get_module = function(module_name) { # todo: assert module exists private$.module_classes[[module_name]] }, - #' Get the names of the modules. Example: `c("core", "bionty")`. + #' @description Get the names of the modules. Example: `c("core", "bionty")`. + #' + #' @return A character vector of module names. get_module_names = function() { names(private$.module_classes) }, - #' Get instance settings. + #' @description Get instance settings. + #' + #' Note: This method is intended for internal use only and may be removed in the future. + #' + #' @return The settings for the instance. get_settings = function() { private$.settings }, - #' Get instance API. + #' @description Get instance API. + #' + #' Note: This method is intended for internal use only and may be removed in the future. + #' + #' @return The API for the instance. get_api = function() { private$.api }, @@ -118,7 +163,6 @@ Instance <- R6::R6Class( # nolint object_name_linter #' #' @param style Logical, whether the output is styled using ANSI codes print = function(style = TRUE) { - registries <- self$get_module("core")$get_registries() is_link_table <- purrr::map(registries, "is_link_table") |> @@ -206,11 +250,13 @@ Instance <- R6::R6Class( # nolint object_name_linter } key_value_strings <- make_key_value_strings( - mapping, quote_strings = FALSE + mapping, + quote_strings = FALSE ) make_class_string( - private$.settings$name, key_value_strings, style = style + private$.settings$name, key_value_strings, + style = style ) } ), diff --git a/R/InstanceAPI.R b/R/InstanceAPI.R index b6bbb99..3c8914a 100644 --- a/R/InstanceAPI.R +++ b/R/InstanceAPI.R @@ -8,6 +8,10 @@ InstanceAPI <- R6::R6Class( # nolint object_name_linter "API", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param instance_settings The settings for the instance #' Should have the following fields: #' - id: The ID of the instance diff --git a/R/InstanceSettings.R b/R/InstanceSettings.R index 65cb296..00f9b7e 100644 --- a/R/InstanceSettings.R +++ b/R/InstanceSettings.R @@ -9,6 +9,10 @@ InstanceSettings <- R6::R6Class( # nolint object_name_linter "InstanceSettings", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param settings A named list of settings for the instance initialize = function(settings) { expected_keys <- c( diff --git a/R/Module.R b/R/Module.R index a2a6cb0..4f27e1e 100644 --- a/R/Module.R +++ b/R/Module.R @@ -44,17 +44,20 @@ create_module <- function(instance, api, module_name, module_schema) { #' @title Module #' -#' @noRd -#' #' @description #' A LaminDB module containing one or more registries. Module <- R6::R6Class( # nolint object_name_linter "Module", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param instance The instance the module belongs to. #' @param api The API for the instance. #' @param module_name The name of the module. + #' @param module_schema The schema of the module. initialize = function(instance, api, module_name, module_schema) { private$.instance <- instance private$.api <- api @@ -74,25 +77,29 @@ Module <- R6::R6Class( # nolint object_name_linter ) |> set_names(names(module_schema)) }, - #' @description - #' Get the registries in the module. + #' @description Get the registries in the module. + #' + #' @return A list of [Registry] objects. get_registries = function() { private$.registry_classes }, - #' @description - #' Get a registry by name. + #' @description Get a registry by name. + #' + #' @param registry_name The name of the registry. + #' + #' @return A [Registry] object. get_registry = function(registry_name) { private$.registry_classes[[registry_name]] }, - #' @description - #' Get the names of the registries in the module. E.g. `c("User", "Artifact")`. + #' @description Get the names of the registries in the module. E.g. `c("User", "Artifact")`. + #' + #' @return A character vector of registry names. get_registry_names = function() { names(private$.registry_classes) }, - #' @description - #' Print a `Module` + #' @description Print a `Module` #' - #' @param style Logical, whether the output is styled using ANSI codes + #' @param style Logical, whether the output is styled using ANSI codes. print = function(style = TRUE) { registries <- self$get_registries() @@ -171,6 +178,7 @@ Module <- R6::R6Class( # nolint object_name_linter .registry_classes = NULL ), active = list( + #' @field name (`character(1)`)\cr #' Get the name of the module. name = function() { private$.module_name diff --git a/R/Record.R b/R/Record.R index e893db6..daa486b 100644 --- a/R/Record.R +++ b/R/Record.R @@ -47,14 +47,16 @@ create_record_class <- function(instance, registry, api) { #' @title Record #' -#' @noRd -#' #' @description #' A record from a registry. Record <- R6::R6Class( # nolint object_name_linter "Record", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param instance The instance the record belongs to. #' @param registry The registry the record belongs to. #' @param api The API for the instance. diff --git a/R/Registry.R b/R/Registry.R index 9286898..6f55ad5 100644 --- a/R/Registry.R +++ b/R/Registry.R @@ -1,13 +1,15 @@ #' @title Registry #' -#' @noRd -#' #' @description #' A registry in a module. Registry <- R6::R6Class( # nolint object_name_linter "Registry", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param instance The instance the registry belongs to. #' @param module The module the registry belongs to. #' @param api The API for the instance. @@ -50,6 +52,12 @@ Registry <- R6::R6Class( # nolint object_name_linter }, #' @description #' Get a record by ID or UID. + #' + #' @param id_or_uid The ID or UID of the record. + #' @param include_foreign_keys Logical, whether to include foreign keys in the record. + #' @param verbose Logical, whether to print verbose output. + #' + #' @return A [Record] object. get = function(id_or_uid, include_foreign_keys = FALSE, verbose = FALSE) { data <- private$.api$get_record( module_name = private$.module$name, @@ -63,21 +71,33 @@ Registry <- R6::R6Class( # nolint object_name_linter }, #' @description #' Get the fields in the registry. + #' + #' @return A list of [Field] objects. get_fields = function() { private$.fields }, #' @description #' Get a field by name. + #' + #' @param field_name The name of the field. + #' + #' @return A [Field] object. get_field = function(field_name) { private$.fields[[field_name]] }, #' @description #' Get the field names in the registry. + #' + #' @return A character vector of field names. get_field_names = function() { names(private$.fields) }, #' @description #' Get the record class for the registry. + #' + #' Note: This method is intended for internal use only and may be removed in the future. + #' + #' @return A [Record] class. get_record_class = function() { private$.record_class }, @@ -85,6 +105,8 @@ Registry <- R6::R6Class( # nolint object_name_linter #' Print a `Registry` #' #' @param style Logical, whether the output is styled using ANSI codes + #' + #' @return A character vector print = function(style = TRUE) { fields <- self$get_fields() # Remove hidden fields @@ -178,19 +200,23 @@ Registry <- R6::R6Class( # nolint object_name_linter .record_class = NULL ), active = list( - #' @return The instance the registry belongs to. + #' @field module ([Module])\cr + #' The instance the registry belongs to. module = function() { private$.module }, - #' @return The API for the instance. + #' @field name (`character(1)`)\cr + #' The API for the instance. name = function() { private$.registry_name }, - #' @return The class name for the registry. + #' @field class_name (`character(1)`)\cr + #' The class name for the registry. class_name = function() { private$.class_name }, - #' @return Whether the registry is a link table. + #' @field is_link_table (`logical(1)`)\cr + #' Whether the registry is a link table. is_link_table = function() { private$.is_link_table } diff --git a/R/UserSettings.R b/R/UserSettings.R index a0c474b..071b712 100644 --- a/R/UserSettings.R +++ b/R/UserSettings.R @@ -9,6 +9,10 @@ UserSettings <- R6::R6Class( # nolint object_name_linter "UserSettings", cloneable = FALSE, public = list( + #' @description + #' Creates an instance of this R6 class. This class should not be instantiated directly, + #' but rather by connecting to a LaminDB instance using the [connect()] function. + #' #' @param settings A named list of settings for the user initialize = function(settings) { expected_keys <- c( diff --git a/man/Field.Rd b/man/Field.Rd new file mode 100644 index 0000000..0a41589 --- /dev/null +++ b/man/Field.Rd @@ -0,0 +1,146 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Field.R +\name{Field} +\alias{Field} +\title{Field} +\description{ +A field in a registry. +} +\section{Active bindings}{ +\if{html}{\out{
}} +\describe{ +\item{\code{type}}{(\code{character(1)})\cr +The type of the field.} + +\item{\code{through}}{(\code{list()} or \code{NULL})\cr +The through value of the field.} + +\item{\code{field_name}}{(\code{character(1)})\cr +The field name.} + +\item{\code{registry_name}}{(\code{character(1)})\cr +The registry name.} + +\item{\code{column_name}}{(\code{character(1)})\cr +The column name.} + +\item{\code{module_name}}{(\code{character(1)})\cr +The module name.} + +\item{\code{is_link_table}}{(\code{logical(1)})\cr +Whether the field is a link table.} + +\item{\code{relation_type}}{(\code{character(1)} or \code{NULL})\cr +The relation type. Can be one of: "one-to-many", "many-to-one", "many-to-many".} + +\item{\code{related_field_name}}{(\code{character(1)} or \code{NULL})\cr +The related field name.} + +\item{\code{related_registry_name}}{(\code{character(1)} or \code{NULL})\cr +The related registry name.} + +\item{\code{related_module_name}}{(\code{character(1)} or \code{NULL})\cr +The related module name.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Field-new}{\code{Field$new()}} +\item \href{#method-Field-print}{\code{Field$print()}} +\item \href{#method-Field-to_string}{\code{Field$to_string()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Field-new}{}}} +\subsection{Method \code{new()}}{ +Creates an instance of this R6 class. This class should not be instantiated directly, +but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Field$new( + type, + through, + field_name, + registry_name, + column_name, + module_name, + is_link_table, + relation_type, + related_field_name, + related_registry_name, + related_module_name +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{type}}{The type of the field. Can be one of: +"IntegerField", "JSONField", "OneToOneField", "SmallIntegerField", +"BigIntegerField", "AutoField", "BigAutoField", "BooleanField", "TextField", +"DateTimeField", "ManyToManyField", "CharField", "ForeignKey"} + +\item{\code{through}}{If the relation type is one-to-many, many-to-one, or many-to-many, +This value will be a named list with keys 'left_key', 'right_key', 'link_table_name'.} + +\item{\code{field_name}}{The name of the field in the registry. Example: \code{"name"}.} + +\item{\code{registry_name}}{The name of the registry. Example: \code{"user"}.} + +\item{\code{column_name}}{The name of the column in the database. Example: \code{"name"}.} + +\item{\code{module_name}}{The name of the module. Example: \code{"core"}.} + +\item{\code{is_link_table}}{Whether the field is a link table.} + +\item{\code{relation_type}}{The type of relation. Can be NULL or one of: "one-to-one", "many-to-one", "many-to-many".} + +\item{\code{related_field_name}}{The name of the related field in the related registry. Example: \code{"name"}.} + +\item{\code{related_registry_name}}{The name of the related registry. Example: \code{"user"}.} + +\item{\code{related_module_name}}{The name of the related module. Example: \code{"core"}.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Field-print}{}}} +\subsection{Method \code{print()}}{ +Print a \code{Field} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Field$print(style = TRUE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Field-to_string}{}}} +\subsection{Method \code{to_string()}}{ +Create a string representation of a \code{Field} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Field$to_string(style = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector +} +} +} diff --git a/man/Instance.Rd b/man/Instance.Rd new file mode 100644 index 0000000..2d1e7c6 --- /dev/null +++ b/man/Instance.Rd @@ -0,0 +1,184 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Instance.R +\name{Instance} +\alias{Instance} +\title{Instance} +\description{ +Connect to a LaminDB instance using the \code{\link[=connect]{connect()}} function. +The instance object provides access to the modules and registries +of the instance. +} +\details{ +Note that by connecting to an instance via \code{\link[=connect]{connect()}}, you receive +a "richer" version of the Instance class documented here, providing +direct access to all core registries and additional modules. +See the vignette on "Package Architecture" for more information: +\code{vignette("architecture", package = "laminr")}. +} +\examples{ +\dontrun{ +# Connect to an instance +db <- connect("laminlabs/cellxgene") + +# fetch an artifact +artifact <- db$Artifact$get("KBW89Mf7IGcekja2hADu") + +# describe the artifact +artifact$describe() + +# view field +artifact$id + +# load dataset +artifact$load() +} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Instance-new}{\code{Instance$new()}} +\item \href{#method-Instance-get_modules}{\code{Instance$get_modules()}} +\item \href{#method-Instance-get_module}{\code{Instance$get_module()}} +\item \href{#method-Instance-get_module_names}{\code{Instance$get_module_names()}} +\item \href{#method-Instance-get_settings}{\code{Instance$get_settings()}} +\item \href{#method-Instance-get_api}{\code{Instance$get_api()}} +\item \href{#method-Instance-print}{\code{Instance$print()}} +\item \href{#method-Instance-to_string}{\code{Instance$to_string()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-new}{}}} +\subsection{Method \code{new()}}{ +Creates an instance of this R6 class. This class should not be instantiated directly, +but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$new(settings, api, schema)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{settings}}{The settings for the instance} + +\item{\code{api}}{The API for the instance} + +\item{\code{schema}}{The schema for the instance} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-get_modules}{}}} +\subsection{Method \code{get_modules()}}{ +Get the modules for the instance. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$get_modules()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A list of \link{Module} objects. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-get_module}{}}} +\subsection{Method \code{get_module()}}{ +Get a module by name. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$get_module(module_name)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{module_name}}{The name of the module.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +The \link{Module} object. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-get_module_names}{}}} +\subsection{Method \code{get_module_names()}}{ +Get the names of the modules. Example: \code{c("core", "bionty")}. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$get_module_names()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A character vector of module names. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-get_settings}{}}} +\subsection{Method \code{get_settings()}}{ +Get instance settings. + +Note: This method is intended for internal use only and may be removed in the future. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$get_settings()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +The settings for the instance. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-get_api}{}}} +\subsection{Method \code{get_api()}}{ +Get instance API. + +Note: This method is intended for internal use only and may be removed in the future. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$get_api()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +The API for the instance. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-print}{}}} +\subsection{Method \code{print()}}{ +Print an \code{Instance} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$print(style = TRUE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Instance-to_string}{}}} +\subsection{Method \code{to_string()}}{ +Create a string representation of an \code{Instance} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Instance$to_string(style = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector +} +} +} diff --git a/man/Module.Rd b/man/Module.Rd new file mode 100644 index 0000000..f55ba7e --- /dev/null +++ b/man/Module.Rd @@ -0,0 +1,135 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Module.R +\name{Module} +\alias{Module} +\title{Module} +\description{ +A LaminDB module containing one or more registries. +} +\section{Active bindings}{ +\if{html}{\out{
}} +\describe{ +\item{\code{name}}{(\code{character(1)})\cr +Get the name of the module.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Module-new}{\code{Module$new()}} +\item \href{#method-Module-get_registries}{\code{Module$get_registries()}} +\item \href{#method-Module-get_registry}{\code{Module$get_registry()}} +\item \href{#method-Module-get_registry_names}{\code{Module$get_registry_names()}} +\item \href{#method-Module-print}{\code{Module$print()}} +\item \href{#method-Module-to_string}{\code{Module$to_string()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Module-new}{}}} +\subsection{Method \code{new()}}{ +Creates an instance of this R6 class. This class should not be instantiated directly, +but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Module$new(instance, api, module_name, module_schema)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{instance}}{The instance the module belongs to.} + +\item{\code{api}}{The API for the instance.} + +\item{\code{module_name}}{The name of the module.} + +\item{\code{module_schema}}{The schema of the module.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Module-get_registries}{}}} +\subsection{Method \code{get_registries()}}{ +Get the registries in the module. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Module$get_registries()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A list of \link{Registry} objects. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Module-get_registry}{}}} +\subsection{Method \code{get_registry()}}{ +Get a registry by name. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Module$get_registry(registry_name)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{registry_name}}{The name of the registry.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \link{Registry} object. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Module-get_registry_names}{}}} +\subsection{Method \code{get_registry_names()}}{ +Get the names of the registries in the module. E.g. \code{c("User", "Artifact")}. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Module$get_registry_names()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A character vector of registry names. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Module-print}{}}} +\subsection{Method \code{print()}}{ +Print a \code{Module} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Module$print(style = TRUE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Module-to_string}{}}} +\subsection{Method \code{to_string()}}{ +Create a string representation of a \code{Module} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Module$to_string(style = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector +} +} +} diff --git a/man/Record.Rd b/man/Record.Rd new file mode 100644 index 0000000..133a9a1 --- /dev/null +++ b/man/Record.Rd @@ -0,0 +1,78 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Record.R +\name{Record} +\alias{Record} +\title{Record} +\description{ +A record from a registry. +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Record-new}{\code{Record$new()}} +\item \href{#method-Record-print}{\code{Record$print()}} +\item \href{#method-Record-to_string}{\code{Record$to_string()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Record-new}{}}} +\subsection{Method \code{new()}}{ +Creates an instance of this R6 class. This class should not be instantiated directly, +but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Record$new(instance, registry, api, data)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{instance}}{The instance the record belongs to.} + +\item{\code{registry}}{The registry the record belongs to.} + +\item{\code{api}}{The API for the instance.} + +\item{\code{data}}{The data for the record.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Record-print}{}}} +\subsection{Method \code{print()}}{ +Print a \code{Record} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Record$print(style = TRUE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Record-to_string}{}}} +\subsection{Method \code{to_string()}}{ +Create a string representation of a \code{Record} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Record$to_string(style = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector +} +} +} diff --git a/man/Registry.Rd b/man/Registry.Rd new file mode 100644 index 0000000..e6afefc --- /dev/null +++ b/man/Registry.Rd @@ -0,0 +1,190 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Registry.R +\name{Registry} +\alias{Registry} +\title{Registry} +\description{ +A registry in a module. +} +\section{Active bindings}{ +\if{html}{\out{
}} +\describe{ +\item{\code{module}}{(\link{Module})\cr +The instance the registry belongs to.} + +\item{\code{name}}{(\code{character(1)})\cr +The API for the instance.} + +\item{\code{class_name}}{(\code{character(1)})\cr +The class name for the registry.} + +\item{\code{is_link_table}}{(\code{logical(1)})\cr +Whether the registry is a link table.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Registry-new}{\code{Registry$new()}} +\item \href{#method-Registry-get}{\code{Registry$get()}} +\item \href{#method-Registry-get_fields}{\code{Registry$get_fields()}} +\item \href{#method-Registry-get_field}{\code{Registry$get_field()}} +\item \href{#method-Registry-get_field_names}{\code{Registry$get_field_names()}} +\item \href{#method-Registry-get_record_class}{\code{Registry$get_record_class()}} +\item \href{#method-Registry-print}{\code{Registry$print()}} +\item \href{#method-Registry-to_string}{\code{Registry$to_string()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-new}{}}} +\subsection{Method \code{new()}}{ +Creates an instance of this R6 class. This class should not be instantiated directly, +but rather by connecting to a LaminDB instance using the \code{\link[=connect]{connect()}} function. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$new(instance, module, api, registry_name, registry_schema)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{instance}}{The instance the registry belongs to.} + +\item{\code{module}}{The module the registry belongs to.} + +\item{\code{api}}{The API for the instance.} + +\item{\code{registry_name}}{The name of the registry.} + +\item{\code{registry_schema}}{The schema for the registry.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-get}{}}} +\subsection{Method \code{get()}}{ +Get a record by ID or UID. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$get(id_or_uid, include_foreign_keys = FALSE, verbose = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{id_or_uid}}{The ID or UID of the record.} + +\item{\code{include_foreign_keys}}{Logical, whether to include foreign keys in the record.} + +\item{\code{verbose}}{Logical, whether to print verbose output.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \link{Record} object. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-get_fields}{}}} +\subsection{Method \code{get_fields()}}{ +Get the fields in the registry. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$get_fields()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A list of \link{Field} objects. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-get_field}{}}} +\subsection{Method \code{get_field()}}{ +Get a field by name. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$get_field(field_name)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{field_name}}{The name of the field.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \link{Field} object. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-get_field_names}{}}} +\subsection{Method \code{get_field_names()}}{ +Get the field names in the registry. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$get_field_names()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A character vector of field names. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-get_record_class}{}}} +\subsection{Method \code{get_record_class()}}{ +Get the record class for the registry. + +Note: This method is intended for internal use only and may be removed in the future. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$get_record_class()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A \link{Record} class. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-print}{}}} +\subsection{Method \code{print()}}{ +Print a \code{Registry} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$print(style = TRUE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A character vector +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Registry-to_string}{}}} +\subsection{Method \code{to_string()}}{ +Create a string representation of a \code{Registry} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Registry$to_string(style = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{style}}{Logical, whether the output is styled using ANSI codes} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{cli::cli_ansi_string} if \code{style = TRUE} or a character vector +} +} +} diff --git a/tests/testthat/test-instance_api.R b/tests/testthat/test-instance_api.R index 433c0cc..a5d49cd 100644 --- a/tests/testthat/test-instance_api.R +++ b/tests/testthat/test-instance_api.R @@ -94,7 +94,7 @@ test_that("get_record fails gracefully", { # nolint start: commented_code # TODO: improve error messages for these cases expect_error( - api$get_record("core", "artifact", "foobar")#, + api$get_record("core", "artifact", "foobar") # , # regexp = "Error getting record: list index out of range" ) expect_error( diff --git a/vignettes/structure.qmd b/vignettes/architecture.qmd similarity index 96% rename from vignettes/structure.qmd rename to vignettes/architecture.qmd index 88b8cd5..e3e0142 100644 --- a/vignettes/structure.qmd +++ b/vignettes/architecture.qmd @@ -1,7 +1,7 @@ --- -title: "Package structure" +title: "Architecture" vignette: > - %\VignetteIndexEntry{Package structure} + %\VignetteIndexEntry{Architecture} %\VignetteEncoding{UTF-8} %\VignetteEngine{quarto::html} knitr: @@ -104,7 +104,7 @@ classDiagram ## Sugar syntax -The `laminr` package adds some sugar syntax to the `Instance` and `Registry` classes. This allows to directly access an instance's registies and a record's fields. +The `laminr` package adds some sugar syntax to the `Instance`, `Module`, and `Record` classes. This allows to directly access an instance's and module's registries and a record's fields. For instance, instead of writing: