44# ' Holds a special list of individual connector objects for consistent use of
55# ' connections in your project.
66# '
7- # ' @param ... Named individual [Connector] objects
7+ # ' @param ... Named individual [Connector] objects.
8+ # ' @param .metadata `list()` of named metadata to store in the `@metadata` property.
9+ # ' @param .datasources `list()` of datasource specifications to store in the `@datasources` property.
10+ # ' If `NULL` (default) will be derived based on `...` input.
811# '
912# ' @examples
1013# ' # Create connectors objects
1821# '
1922# ' cnts
2023# '
21- # ' # Print the individual connector for more information
24+ # ' # Print the individual Connector for more information
2225# '
2326# ' cnts$sdtm
2427# '
2528# ' cnts$adam
2629# '
27- # ' @export
28- connectors <- function (... ) {
29- x <- rlang :: list2(... )
30- ds_ <- x [[" datasources" ]]
30+ # ' @name connectors
31+ NULL
32+
33+ # ' @noRd
34+ construct_connectors <- function (
35+ ... ,
36+ .metadata = list (),
37+ .datasources = NULL
38+ ) {
39+ if (is.null(.datasources )) {
40+ cnts <- substitute(rlang :: list2(... ))
41+ .datasources <- connectors_to_datasources(cnts )
42+ }
43+
44+ S7 :: new_object(
45+ .parent = list (... ),
46+ metadata = .metadata ,
47+ datasources = datasources(.datasources )
48+ )
49+ }
3150
32- md_ <- if (is.null(x [[" .md" ]])) list () else x [[" .md" ]]
51+ # ' @noRd
52+ validate_named <- function (x ) {
53+ if (! rlang :: is_named2(x )) {
54+ return (" All elements must be named" )
55+ }
56+ }
57+
58+ # ' @noRd
59+ validate_datasources <- function (x ) {
60+ if (any(rlang :: have_name(x ))) {
61+ return (" All elements must be not be named" )
62+ }
3363
34- if (! is.null(ds_ ) && ! inherits(ds_ , " cnts_datasources" )) {
35- cli :: cli_abort(
36- " 'datasources' is a reserved name. It cannot be used as a name for a data source."
64+ if (
65+ any(
66+ vapply(
67+ X = x ,
68+ FUN = \(x ) ! setequal(c(" name" , " backend" ), names(x )),
69+ FUN.VALUE = logical (1 )
70+ )
3771 )
72+ ) {
73+ return (" Each datasource must have (only) 'name' and 'backend' specified" )
3874 }
3975
40- if (is.null(ds_ )) {
41- cnts <- substitute(rlang :: list2(... ))
42- datasources <- connectors_to_datasources(cnts )
43- } else {
44- datasources <- ds_
76+ if (
77+ any(
78+ vapply(
79+ X = x ,
80+ FUN = \(x ) ! " type" %in% names(x [[" backend" ]]),
81+ FUN.VALUE = logical (1 )
82+ )
83+ )
84+ ) {
85+ return (" Each datasource must have backend type specified" )
4586 }
87+ }
4688
47- checkmate :: assert_list(x = x , names = " named" )
4889
49- structure(
50- x [! (names(x ) %in% c(" datasources" , " .md" ))],
51- class = c(" connectors" ),
52- datasources = datasources ,
53- metadata = md_
54- )
90+ # ' @noRd
91+ validate_connectors <- function (x ) {
92+ if (! length(x )) {
93+ return (" At least one Connector must be supplied" )
94+ }
95+
96+ if (
97+ ! all(
98+ vapply(
99+ X = x ,
100+ FUN = \(x ) is_connector(x ),
101+ FUN.VALUE = logical (1 )
102+ )
103+ )
104+ ) {
105+ return (" All elements must be a Connector object" )
106+ }
107+
108+ if (length(x ) != length(x @ datasources )) {
109+ return (" Each 'Connector' must have a corresponding datasource" )
110+ }
111+
112+ validate_named(x )
55113}
56114
115+ # ' @noRd
116+ prop_metadata <- S7 :: new_property(
117+ class = S7 :: class_list ,
118+ getter = \(self ) self @ metadata ,
119+ validator = \(value ) validate_named(value )
120+ )
121+
122+ # ' @noRd
123+ datasources <- S7 :: new_class(
124+ name = " datasources" ,
125+ parent = S7 :: class_list ,
126+ validator = \(self ) validate_datasources(self )
127+ )
128+
129+ # ' @noRd
130+ prop_datasources <- S7 :: new_property(
131+ class = datasources ,
132+ getter = \(self ) self @ datasources
133+ )
134+
135+ # ' @rdname connectors
57136# ' @export
58- print.connectors <- function (x , ... ) {
137+ connectors <- S7 :: new_class(
138+ name = " connectors" ,
139+ parent = S7 :: class_list ,
140+ properties = list (
141+ metadata = prop_metadata ,
142+ datasources = prop_datasources
143+ ),
144+ constructor = construct_connectors ,
145+ validator = \(self ) validate_connectors(self )
146+ )
147+
148+ # ' @noRd
149+ S7 :: method(print , connectors ) <- function (x , ... ) {
59150 print_connectors(x , ... )
60151}
61152
153+ # ' @noRd
154+ S7 :: method(print , datasources ) <- function (x , ... ) {
155+ print_datasources(x , ... )
156+ }
157+
158+ # ' @noRd
159+ is_connectors <- function (x ) {
160+ S7 :: S7_inherits(x , connectors ) |
161+ S7 :: S7_inherits(x , nested_connectors )
162+ }
163+
62164# ' @noRd
63165print_connectors <- function (x , ... ) {
64166 classes <- x | >
@@ -95,11 +197,11 @@ print_connectors <- function(x, ...) {
95197 return (invisible (x ))
96198}
97199
98- # ' @export
99- print.cnts_datasources <- function (x , ... ) {
200+ # ' @noRd
201+ print_datasources <- function (x , ... ) {
100202 cli :: cli_h1(" Datasources" )
101203
102- for (ds in x [[ " datasources " ]] ) {
204+ for (ds in x ) {
103205 cli :: cli_h2(ds $ name )
104206 cli :: cli_ul()
105207 cli :: cli_li(" Backend Type: {.val {ds$backend$type}}" )
@@ -110,39 +212,5 @@ print.cnts_datasources <- function(x, ...) {
110212 cli :: cli_end()
111213 }
112214
113- return (x )
114- }
115-
116- # ' @noRd
117- as_datasources <- function (... ) {
118- structure(
119- ... ,
120- class = " cnts_datasources"
121- )
122- }
123-
124- # ' Create a nested connectors object
125- # '
126- # ' This function creates a nested connectors object from the provided arguments.
127- # '
128- # ' @param ... Any number of connectors object.
129- # '
130- # ' @return A list with class "nested_connectors" containing the provided arguments.
131- # ' @export
132- nested_connectors <- function (... ) {
133- x <- rlang :: list2(... )
134- structure(
135- x ,
136- class = c(" nested_connectors" )
137- )
138- }
139-
140- # ' @export
141- print.nested_connectors <- function (x , ... ) {
142- print_connectors(x , ... )
143- }
144-
145- # ' @noRd
146- is_connectors <- function (connectors ) {
147- inherits(connectors , " connectors" )
215+ return (invisible (x ))
148216}
0 commit comments