forked from neo4j-rstats/neo4r
-
Notifications
You must be signed in to change notification settings - Fork 0
/
call_api.R
139 lines (124 loc) · 4.38 KB
/
call_api.R
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
132
133
134
135
136
137
138
139
clean_query <- function(query) {
res <- gsub("^\\/\\/.+$", "\n", query, perl = TRUE)
res <- gsub("\n", " ", res)
res <- gsub("\"", "'", res)
res
}
#' @importFrom jsonlite toJSON
to_json_neo <- function(query, include_stats, meta, type, params) {
toJSON(
list(
statement = query,
includeStats = include_stats,
meta = meta,
resultDataContents = list(type),
parameters = params
),
auto_unbox = TRUE
)
}
#' Call Neo4J API
#'
#' @param query The cypher query
#' @param con A NEO4JAPI connection object
#' @param type Return the result as row or as graph
#' @param output Use "json" if you want the output to be printed as JSON
#' @param include_stats Should the stats about the transaction be included?
#' @param include_meta Should the stats about the transaction be included?
#' @param format Format of the output
#' @param params Parameters to pass along the query
#'
#' @importFrom glue glue
#' @importFrom attempt stop_if_not
#' @importFrom httr POST status_code add_headers
#'
#' @return the result from the Neo4J Call
#' @export
call_neo4j <- function(query, con,
type = c("row", "graph"),
output = c("r", "json", "raw"),
include_stats = FALSE,
include_meta = FALSE,
format = c("std", "table"),
params = NULL) {
# browser()
stop_if_not(
con, ~"Neo4JAPI" %in% class(.x),
"Please use a Neo4JAPI object."
)
# Ensure the inputs are the one we expect
output <- match.arg(output)
format <- match.arg(format)
type <- match.arg(type)
# Clean the query to prevent weird mess up with " and stuffs
query_clean <- clean_query(query)
# Transform the query to a Neo4J JSON format
query_jsonised <- to_json_neo(query_clean, include_stats, include_meta, type, params)
# Unfortunately I was not able to programmatically convert everything to JSON
body <- glue('{"statements" : [ %query_jsonised% ]}', .open = "%", .close = "%")
# Calling the API
res <- POST(
url = glue("{con$url}/db/data/transaction/commit?includeStats=true"),
add_headers(.headers = c(
"Content-Type" = "application/json",
"accept" = "application/json",
# "X-Stream" = "true",
"Authorization" = paste0("Basic ", con$auth)
)),
body = body
)
# Verify the status code is 200
stop_if_not(status_code(res), ~.x == 200, "API error")
# return(res)
# Return the parsed output, to json or to R
if (output == "json") {
toJSON(lapply(content(res)$results, function(x) x$data), pretty = TRUE)
} else if (output == "raw") {
content(res)
} else {
parse_api_results(
res = res,
type = type, format = format,
include_stats = include_stats,
meta = include_meta
)
}
}
# con <- neo4j_api$new(url = "http://localhost:7474/", user = "neo4j", password = "pouetpouet")
# call_api(query = 'MATCH (n:user) RETURN COUNT (n) AS user_count;', con)
# to_json_neo('MATCH (n:user) RETURN COUNT (n) AS user_count;', TRUE, "row")
# a <- toJSON(list(statement = to_json_neo('MATCH (n:user) RETURN COUNT (n) AS user_count;', TRUE, "row")))
# cat(a)
# glue('plop {query}')
# clean_input <- function(vec){
# vec <- gsub("^\\/\\/.+$", "\n", vec, perl = TRUE)
# vec <- paste(gsub("\n", " ", vec), collapse = " ")
# vec <- gsub(";", ";%", vec)
# vec <- gsub("\"", "\'", vec)
# unlist(strsplit(vec, "%"))
# }
# # For debug only
#
# call_api <- function(query, con, format = c("r", "json"), meta = FALSE, with_browser = FALSE, as_one = FALSE, res_api = FALSE){
# if (with_browser){
# browser()
# }
# query <- clean_query(query)
# format <- match.arg(format)
# url <- glue("{con$url}/db/data/transaction/commit")
# res <- POST(url = url,
# add_headers(.headers = c("Content-Type"="application/json",
# "accept"="application/json",
# #"X-Stream" = "true",
# "Authorization"= paste0("Basic ", auth))),
# body = glue('{"statements" : [ { "statement" : "%query%"} ]}', .open = "%", .close = "%"))
# stop_if_not(status_code(res), ~ .x == 200, "API error")
# if (res_api){
# return(res)
# }
# if (format == "json"){
# toJSON(lapply(content(res)$results, function(x) x$data), pretty = TRUE)
# } else {
# parse_api_results(res, meta)
# }
# }