-
Notifications
You must be signed in to change notification settings - Fork 1
/
pushing.Rmd
132 lines (98 loc) · 2.98 KB
/
pushing.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
---
title: "Pushing"
author: "Janko Thyson"
date: "Thursday, October 29, 2014"
output:
pdf_document
---
```{r, echo=FALSE}
suppressMessages(require("reactr"))
```
**NOT FINISHED YET**
The underlying registry mechanism of `reactr` ensures that **references** of the invisible instances/objects of class [ReactiveObject.S3](../R/ReactiveObject.S3) or [ReactiveShinyObject](../R/ReactiveShinyObject) are stored in a registry object (see vignette [Registry](./registry.pdf) for details).
Besides being a prerequisite for the caching mechanism that allows the specification of bi-directional bindings (see vignette [Bi-Directional Bindings](./bidirectional_bindings.pdf), this also facilitates the use of a **push paradigm** with respect to reactivity or the way that object state changes are propagation throughout the system.
Below is a short example that illustrates how the push mechanism works.
## Scenario description
We set up a very simple example:
- there exists a reactive object that other objects can reference: `x_1`
- each modification of `x_1` should trigger two events in a **push** manner:
1. Update a database table
2. Send an E-Mail to a certain address
## Implementation
Ensure that required packages are loaded
```{r, message=FALSE}
pkgs <- c("dplyr", "sendmailR", "RSQLite", "sqldf")
. <- sapply(pkgs, function(pkg) {
if (!suppressWarnings(require(pkg, character.only = TRUE))) {
install.packages(pkg)
require(pkg, character.only = TRUE)
}
invisible(NULL)
})
```
Create reactive object that others can reference:
```{r}
setReactive(id = "x_1", value = 1)
```
Define the actual core functions for
- the database update
- sending the E-Mail
```{r}
updateDatabase <- function(
id,
value,
con = file.path(tempdir(), "testdb.sqlite")
) {
my_db <- src_sqlite(path = con, create = TRUE)
# dbRemoveTable(db, id)
this <- data.frame(time = as.character(Sys.time()), value = value)
if (!id %in% dbListTables(my_db$con)) {
copy_to(my_db, this, id, temporary = FALSE) # need to set temporary to FALSE
}
sql <- sprintf(
'INSERT INTO %s VALUES (%s, %s)',
id, paste0("\"", Sys.time(), "\""), value
)
dbSendQuery(my_db$con, sql)
# dbReadTable(my_db$con, id)
message("Updated database")
TRUE
}
sendEmail <- function(id, value, con) {
}
```
Database connection settings
```{r}
con <- file.path(tempdir(), "testdb.sqlite")
my_db <- src_sqlite(path = con, create = TRUE)
try(dbReadTable(my_db$con, "x_1"), silent = TRUE)
```
Push in action
```{r}
setReactive(
id = "pushToDatabase",
value = function() {
"object-ref: {id: x_1}"
updateDatabase(
id = "x_1",
value = x_1,
con = file.path(tempdir(), "testdb.sqlite")
)
TRUE
},
push = TRUE
)
x_1 <- 2
x_1 <- 3
x_1 <- 4
x_1 <- 5
## Inspect database //
dbReadTable(my_db$con, "x_1")
```
Note that we never explicitly called `pushToDatabase`.
It was called whenever `x_1` changed.
Clean up
```{r, message=FALSE}
rmReactive("x_1")
rmReactive("x_2")
```