#' This class handles an SQL Query.
#'
#' This class represents an SQL query. It is used internally to generate an SQL
#' query string.
#'
#' @seealso \code{\link{BiodbRequestScheduler}}, \code{\link{BiodbRequest}}.
#'
#' @import R6
BiodbSqlQuery <- R6::R6Class("BiodbSqlQuery",
public=list(
#' @description
#' Initializer.
#' @return Nothing.
initialize=function() {
private$table <- character()
private$fields <- list()
private$distinct <- FALSE
private$join <- list()
private$where <- NULL
private$limit <- as.integer(0)
return(invisible(NULL))
},
#' @description
#' Set the table.
#' @param table The table name.
#' @return Nothing.
setTable=function(table) {
private$table <- table
return(invisible(NULL))
},
#' @description
#' Set the fields.
#' @param table The table name.
#' @param field A field name.
#' @return Nothing.
addField=function(table=NULL, field) {
private$fields <- c(private$fields, list(list(table=table, field=field)))
return(invisible(NULL))
},
#' @description
#' Set or unset distinct modifier.
#' @param distinct Either TRUE or FALSE for setting or unsetting the distinct
#' flag.
#' @return Nothing.
setDistinct=function(distinct) {
chk::chk_flag(distinct)
private$distinct <- as.logical(distinct)
return(invisible(NULL))
},
#' @description
#' Set results limit.
#' @param limit The limit to set, as an integer value.
#' @return Nothing.
setLimit=function(limit) {
chk::chk_whole_number(limit)
private$limit <- as.integer(limit)
return(invisible(NULL))
},
#' @description
#' Add a join.
#' @param table1 The first table.
#' @param field1 The field of the first table.
#' @param table2 The second table.
#' @param field2 The field of the second table.
#' @return Nothing.
addJoin=function(table1, field1, table2, field2) {
# Check if this join already exists
fct <- function(x) ((x$table1 == table1 && x$field1 == field1
&& x$table2 == table2 && x$field2 == field2)
|| (x$table1 == table1 && x$field1 == field1 && x$table2 == table2
&& x$field2 == field2))
duplicate <- any(vapply(private$join, fct, FUN.VALUE=TRUE))
# Append
if ( ! duplicate) {
lst <- list(table1=table1, field1=field1, table2=table2, field2=field2)
private$join <- c(private$join, list(lst))
}
return(invisible(NULL))
},
#' @description
#' Set the where clause.
#' @param expr A BiodbSqlExpr representing the "where" clause.
#' @return Nothing.
setWhere=function(expr) {
private$where <- expr
return(invisible(NULL))
},
#' @description
#' Builds and returns the join expression.
#' @return A character vector representing the join expression.
getJoin=function() {
join <- character()
for (j in private$join) {
j1 <- paste(DBI::dbQuoteIdentifier(DBI::ANSI(), j$table1),
DBI::dbQuoteIdentifier(DBI::ANSI(), j$field1), sep='.')
j2 <- paste(DBI::dbQuoteIdentifier(DBI::ANSI(), j$table2),
DBI::dbQuoteIdentifier(DBI::ANSI(), j$field2), sep='.')
join <- c(join, 'join', DBI::dbQuoteIdentifier(DBI::ANSI(), j$table1),
'on', j1, '=', j2)
}
return(join)
},
#' @description
#' Gets the where expression.
#' @return The BiodbSqlExpr instance representing the "where" clause.
getWhere=function() {
return(private$where)
},
#' @description
#' Gets the fields to retrieve.
#' @return A string containing the list of fields to retrieve.
getFields=function() {
fct <- function(x) {
field <- DBI::dbQuoteIdentifier(DBI::ANSI(), x$field)
if (is.null(x$table))
field
else
paste(DBI::dbQuoteIdentifier(DBI::ANSI(), x$table), field, sep='.')
}
fields <- vapply(private$fields, fct, FUN.VALUE='')
fields=paste(fields, collapse=', ')
return(fields)
},
#' @description
#' Generates the string representation of this query.
#' @return A string containing the full SQL query.
toString=function() {
query <- 'select'
# Set distinct modifier
if (private$distinct)
query <- c(query, 'distinct')
# Set fields
query <- c(query, self$getFields())
# Set table
query <- c(query, 'from',
DBI::dbQuoteIdentifier(DBI::ANSI(), private$table))
# Set join clause
query <- c(query, self$getJoin())
# Set where clause
if ( ! is.null(private$where)) {
where <- private$where$toString()
if (nchar(where) > 0)
query <- c(query, 'where', where)
}
# Set limit
if (private$limit > 0)
query <- c(query, 'limit', private$limit)
# Join all strings
query <- paste(query, collapse=' ')
# End query
query <- paste0(query, ';')
return(query)
}
),
private=list(
table=NULL,
fields=NULL,
distinct=NULL,
join=NULL,
where=NULL,
limit=NULL
))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.