Skip to content

Commit 756d278

Browse files
authored
Merge pull request #2 from ralmond/NoMongo
No mongo
2 parents 028c37f + 73f58c1 commit 756d278

15 files changed

+228
-41
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*~
2+
3+
makeDBuri.Rd~

ChangeLog

+26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
2020-04-04 Russell Almond <ralmond@Cherry>
2+
3+
* R/Message.R (markAsProcessed): stupid missing ! causing infinite
4+
loop. Fixed test to die on excessive loops.
5+
6+
2020-03-17 Russell Almond <ralmond@Cherry>
7+
8+
* R/Message.R (makeDBuri): Moved this code here as it seems to be
9+
used just about every time we make a mongo connetion.
10+
(makeDBuri): Added protocol arguement
11+
12+
* R/Listeners.R (ListenerSet): Added trap for blank URI to make
13+
no-Mongo version.
14+
15+
2020-02-19 Russell Almond <ralmond@Cherry>
16+
17+
* R/Message.R (ununboxer): using sapply instead of lapply in
18+
ununboxer causes it to simplify lists of length one in strange
19+
ways. Can I change sapply to lapply here? NO. This breaks lots
20+
of other things.
21+
22+
2020-02-12 Rusell Almond <ralmond@Cherry>
23+
24+
* R/Message.R (saveRec, markAsProcessed, markAsError): Changed so
25+
that these would not save if the col argument is NULL.
26+
127
2019-12-20 Rusell Almond <ralmond@Cherry>
228

329
* R/Message.R (markAsError): Added " to ' conversion to error

DESCRIPTION

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: Proc4
2-
Version: 0.4-6
3-
Date: 2019/12/20
2+
Version: 0.4-7
3+
Date: 2020/03/17
44
Title: Four Process Assessment Database and Dispatcher
55
Author: Russell Almond
66
Maintainer: Russell Almond <[email protected]>

NAMESPACE

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ importFrom("utils", "limitedLabels")
99
export(P4Message)
1010
exportClasses(P4Message)
1111
export(m_id,app,uid,context,timestamp,sender,mess,details,all.equal.P4Message,
12-
processed, markAsProcessed, processingError, markAsError)
12+
processed, markAsProcessed, processingError, markAsError,
13+
makeDBuri)
1314
exportMethods(m_id,app,uid,context,timestamp,sender,mess,details,
1415
toString,show, processed, processingError)
1516

@@ -22,8 +23,9 @@ exportMethods(as.json,as.jlist)
2223
export(receiveMessage,isListener,ListenerSet,notifyListeners,
2324
InjectionListener,UpdateListener,UpsertListener,CaptureListener,
2425
TableListener)
25-
exportClasses(ListenerSet,MongoDB,CaptureListener, InjectionListener,
26-
UpdateListener,UpsertListener,TableListener,name)
26+
exportClasses(ListenerSet,MongoDB,CaptureListener,
27+
InjectionListener,
28+
UpdateListener,UpsertListener,TableListener,name)
2729
exportMethods(isListener,receiveMessage,notifyListeners,name)
2830

2931
export(withFlogging)

R/Listeners.R

+3-2
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ ListenerSet <-
379379
function(sender="sender",
380380
dbname="test",
381381
dburi="mongodb://localhost",
382-
listeners=list(),colname="Messages",
382+
listeners=list(),
383+
colname="Messages",
383384
...) {
384385
callSuper(sender=sender,db=NULL,
385386
dburi=dburi,dbname=dbname,
@@ -392,7 +393,7 @@ ListenerSet <-
392393
## Listener/Message Methods
393394
ListenerSet$methods(
394395
messdb = function () {
395-
if (is.null(db)) {
396+
if (is.null(db) && nchar(dburi) > 0L) {
396397
db <<- mongo(colname,dbname,dburi)
397398
}
398399
db

R/Message.R

+61-26
Original file line numberDiff line numberDiff line change
@@ -100,42 +100,54 @@ setMethod("as.jlist",c("P4Message","list"), function(obj,ml,serialize=TRUE) {
100100
})
101101

102102
saveRec <- function (mess, col, serialize=TRUE) {
103-
jso <- as.json(mess,serialize)
104-
if (is.na(mess@"_id")) {
105-
## Insert
106-
col$insert(jso)
107-
it <- col$iterate(jso,'{"_id":true}',limit=1)
108-
mess@"_id" <- it$one()$"_id"
109-
names(mess@"_id") <- "oid" ## Aids in extraction
110-
} else {
111-
if (col$count(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""))) {
112-
## Replace
113-
col$update(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""),
114-
paste('{"$set":',jso,'}',sep=""))
115-
} else {
116-
## ID is out of date, insert and get new ID.
103+
if (!is.null(col)) {
104+
jso <- as.json(mess,serialize)
105+
if (is.na(mess@"_id")) {
106+
## Insert
117107
col$insert(jso)
118108
it <- col$iterate(jso,'{"_id":true}',limit=1)
119109
mess@"_id" <- it$one()$"_id"
120110
names(mess@"_id") <- "oid" ## Aids in extraction
111+
} else {
112+
if (col$count(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""))) {
113+
## Replace
114+
col$update(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""),
115+
paste('{"$set":',jso,'}',sep=""))
116+
} else {
117+
## ID is out of date, insert and get new ID.
118+
col$insert(jso)
119+
it <- col$iterate(jso,'{"_id":true}',limit=1)
120+
mess@"_id" <- it$one()$"_id"
121+
names(mess@"_id") <- "oid" ## Aids in extraction
122+
}
121123
}
124+
} else {
125+
flog.trace("DB is null, not saving message.")
122126
}
123127
mess
124128
}
125129

126130
markAsProcessed <- function (mess,col) {
127131
processed(mess) <- TRUE
128-
col$update(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""),
129-
'{"$set": {"processed":true}}')
132+
if (!is.null(col)) {
133+
col$update(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""),
134+
'{"$set": {"processed":true}}')
135+
} else {
136+
flog.trace("DB is null, not saving message.")
137+
}
130138
mess
131139
}
132140

133141
markAsError <- function (mess,col, e) {
134142
processingError(mess) <- e
135-
col$update(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""),
136-
paste('{"$set": {"pError":"',
137-
chartr("\"","'", #Problem with interior quotes.
138-
encodeString(toString(e))),'"}}',sep=""))
143+
if (!is.null(col)) {
144+
col$update(paste('{"_id":{"$oid":"',mess@"_id",'"}}',sep=""),
145+
paste('{"$set": {"pError":"',
146+
chartr("\"","'", #Problem with interior quotes.
147+
encodeString(toString(e))),'"}}',sep=""))
148+
} else {
149+
flog.trace("DB is null, not saving message.")
150+
}
139151
mess
140152
}
141153

@@ -170,14 +182,14 @@ cleanMessageJlist <- function (rec) {
170182

171183
parseMessage<- function (rec) {
172184
rec <- cleanMessageJlist(rec)
173-
new("P4Message","_id"=ununboxer(rec$"_id"),
174-
app=as.vector(ununboxer(rec$app)),
175-
uid=as.vector(ununboxer(rec$uid)),
185+
new("P4Message","_id"=as.character(ununboxer(rec$"_id")),
186+
app=as.character(ununboxer(rec$app)),
187+
uid=as.character(ununboxer(rec$uid)),
176188
context=as.vector(ununboxer(rec$context)),
177-
sender=as.vector(ununboxer(rec$sender)),
178-
mess=as.vector(ununboxer(rec$mess)),
189+
sender=as.character(ununboxer(rec$sender)),
190+
mess=as.character(ununboxer(rec$mess)),
179191
timestamp=as.POSIXlt(ununboxer(rec$timestamp)),
180-
processed=ununboxer(rec$processed),
192+
processed=as.logical(ununboxer(rec$processed)),
181193
pError=rec$pError,
182194
data=parseData(rec$data))
183195
}
@@ -378,3 +390,26 @@ all.equal.P4Message <- function (target, current, ...,checkTimestamp=FALSE,check
378390
if (length(msg)==0L) TRUE
379391
else msg
380392
}
393+
394+
###
395+
## This is a construction I find myself using in a lot of places to
396+
## build up the "mongodb://" URI for the database.
397+
398+
makeDBuri <- function(username="",password="", host="localhost",
399+
port="",protocol="mongodb") {
400+
## Setup DB URI
401+
security <- ""
402+
if (nchar(username) > 0L) {
403+
if (nchar(password) > 0L)
404+
security <- paste(username,password,sep=":")
405+
else
406+
security <- username
407+
}
408+
if (nchar(port) > 0L)
409+
host <- paste(host,port,sep=":")
410+
else
411+
host <- host
412+
if (nchar(security) > 0L)
413+
host <- paste(security,host,sep="@")
414+
paste(paste(protocol,":/",sep=""),host,sep="/")
415+
}

man/ListenerSet.Rd

+8-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ All reference classes extend and inherit methods from
4444
When the notifier is called it performs the following functions:
4545
\enumerate{
4646
\item{It saves the message to the collection represented by
47-
\code{messdb()}.}
47+
\code{messdb()}. If \code{messdb()} is \code{NULL} (\code{dburi}
48+
is the empty string) then the messages is not saved.}
4849
\item{It calls the \code{\link{receiveMessage}} method on each of
4950
the objects in the listener list.}
5051
\item{It logs the messages sent using the
@@ -103,9 +104,13 @@ showClass("ListenerSet")
103104
\item{\code{sender}:}{Object of class \code{character}:the name of
104105
the source of the messages. }
105106
\item{\code{dburi}:}{Object of class \code{character}: the URI for
106-
the \code{\link[mongolite]{mongo}} database.}
107+
the \code{\link[mongolite]{mongo}} database. If null, then no
108+
recording of messages to a database is done (except possibly in
109+
the listeners).}
110+
\item{\code{dbname}:}{Object of class \code{character}: the name of
111+
the database in which messages should be logged.}
107112
\item{\code{colname}:}{Object of class \code{character}: the name of
108-
the column in which messages should be logged.}
113+
the collection in which messages should be logged.}
109114
\item{\code{listeners}:}{A named \code{list} of
110115
\code{\linkS4class{Listener}} objects, that is objects for which
111116
\code{\link{isListener}} is true.}

man/MongoDB-class.Rd

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
\Rdversion{1.1}
33
\docType{class}
44
\alias{MongoDB-class}
5+
\alias{MongoDB}
56

67
\title{Class \code{"MongoDB"}}
78
\description{

man/Proc4-package.Rd

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ There are five major features of this package documented below:
141141
it is a listener.
142142

143143
Four listeners are currently implemented (see
144-
\code{\link{ListenerConstructors}} or the individal listener classes):
144+
\code{\link{Listener}} or the individal listener classes):
145145
\describe{
146146
\item{\code{CaptureListener}}{Creates an object of class
147147
\code{\linkS4class{CaptureListener}} which stores the messages in
@@ -162,7 +162,7 @@ There are five major features of this package documented below:
162162

163163
The \code{\link{ListenerSet}} class is a mixin to associate a
164164
collection of listeners with an object (the
165-
\code{\link[EIEvent]{EIEngine}} and \code{\link[EABN]{EAEngine}}
165+
\code{\link[EIEvent]{EIEngine}} and \code{\link[EABN]{BNEngine}}
166166
classes use this). The generic function \code{\link{notifyListeners}}
167167
can be called. This logs information about the message (see logging
168168
system above), save a copy of the message in a \dQuote{Messages}

man/TableListener-class.Rd

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
\alias{TableListener-class}
55
\alias{isListener,TableListener-method}
66
\alias{receiveMessage,TableListener-method}
7+
\alias{name,TableListener-method}
78

89
\title{Class \code{"TableListener"}}
910
\description{
@@ -26,6 +27,9 @@
2627
the message is in the \code{messSet}, it adds a row to its
2728
internal table using the fields specified in \code{fieldlist}.
2829
(See details.) }
30+
\item{name}{\code{signature(x = "TableListener")}: returns the name
31+
of the table. This is usually also the filename where the table
32+
will be stored. }
2933
}
3034
}
3135
\references{

man/as.json.Rd

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ as.jlist(obj,ml, serialize=TRUE)
2121
\arguments{
2222
\item{x}{An (S4) object to be serialized.}
2323
\item{obj}{The object being serialized}
24-
\item{ml}{A list of fields of the object.}
24+
\item{ml}{A list of fields of the object; usually \code{attributes(obj)}.}
2525
\item{serialize}{A logical flag. If true,
2626
\code{\link[jsonlite]{serializeJSON}} is used to protect the
2727
\code{data} field (and other objects which might contain complex R

man/makeDBuri.Rd

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
\name{makeDBuri}
2+
\alias{makeDBuri}
3+
\title{Creates the URI needed to connect to a mongo database.}
4+
\description{
5+
6+
This function formats the universal record indicator (URI) for
7+
connecting to a Mongo database. It is mostly a utility function for
8+
formatting the string.
9+
10+
}
11+
\usage{
12+
makeDBuri(username = "", password = "", host = "localhost", port = "",
13+
protocol="mongodb")
14+
}
15+
\arguments{
16+
\item{username}{The name of the database user (login credential), or
17+
an empty string if no username is required.}
18+
\item{password}{The name of the database password (login credential), or
19+
an empty string if no password is required.}
20+
\item{host}{The name or IP address of the system hosting the database.}
21+
\item{port}{The port to be used for connections. Note that the
22+
port for a default configuration of mongo is 27018. This can be
23+
left blank to use the default port.}
24+
\item{protocol}{A character scalar giving the protocol to use when
25+
connecting, e.g., \dQuote{mongodb}.}
26+
}
27+
\value{
28+
29+
A character string giving the database URI which can be passed to the
30+
\code{\link[mongolite]{mongo}} function to create a database
31+
collection handle.
32+
33+
Note that the password is stored in clear text, so appropriate care
34+
should be taken with the result of this function.
35+
36+
}
37+
\author{Russell Almond}
38+
\seealso{
39+
40+
\code{\link{MongoDB}}, \code{\link[mongolite]{mongo}}
41+
42+
This is an input argument to a number of other classes which use mongo
43+
connections.
44+
45+
}
46+
\examples{
47+
48+
stopifnot(makeDBuri()=="mongodb://localhost")
49+
50+
stopifnot(makeDBuri(user="admin",password="secret")==
51+
"mongodb://admin:secret@localhost")
52+
## No password
53+
stopifnot(makeDBuri(user="admin")==
54+
"mongodb://admin@localhost")
55+
56+
stopifnot(makeDBuri(host="example.com",port=12345) ==
57+
"mongodb://example.com:12345")
58+
59+
}
60+
\keyword{ interface }
61+
\keyword{ database }

man/markAsProcessed.Rd

+8-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ processingError(x)
2727
\item{mess}{An object of class \code{\linkS4class{P4Message}} to be
2828
modified. }
2929
\item{col}{A \code{\link[mongolite]{mongo}} collection where the
30-
message queue is stored.
30+
message queue is stored. This can also be \code{NULL} in which case
31+
the message will not be saved to the database.
3132
}
3233
\item{e}{An object indicating the error occurred. Note this could be
3334
either a string giving the error message of an object of an error
@@ -110,14 +111,20 @@ mess2 <- saveRec(mess2,col,FALSE)
110111

111112
mess <- getOneRec(buildJQuery(app="adder", processed=FALSE),
112113
col, parseMessage, sort = c(timestamp = 1))
114+
iterations <- 0
113115
while (!is.null(mess)) {
116+
if (iterations > 4L)
117+
stop ("Test not terminating, flag not being set?")
118+
iterations <- iterations + 1
119+
print(mess)
114120
print(details(mess))
115121
out <- try(print(details(mess)$x+details(mess)$y))
116122
if (is(out,'try-error'))
117123
mess <- markAsError(mess,col,out)
118124
mess <- markAsProcessed(mess,col)
119125
mess <- getOneRec(buildJQuery(app="adder", processed=FALSE),
120126
col, parseMessage, sort = c(timestamp = 1))
127+
121128
}
122129

123130
mess1a <- getOneRec(buildJQuery(app="adder",uid="One"),col,parseMessage)

0 commit comments

Comments
 (0)