Giter Club home page Giter Club logo

infuser's Introduction

Travis Build Status Coverage Status CRAN_Status_Badge Downloads

infuser is a simple and very basic templating engine for R. It replaces parameters within templates with specified values. Templates can be either contained in a string or in a file.

Installation

install.packages("infuser")

If you want to use the most up-to-date version, install using devtools::install_github.

devtools::install_github("Bart6114/infuser")

Hello World

A simple Hello World example that makes use of the magrittr piping workflow.

library(magrittr)
library(infuser)

"Hello {{var1}}!" %>%
  infuse(var1="world")

## Hello world!

Usage

Working with character strings as templates

Let's have a look at an example string.

my_sql<-"SELECT * FROM Customers
WHERE Year = {{year}}
AND Month = {{month|3}};"

Here the variable parameters are enclosed by {{ and }} characters. See ?infuse to use your own specification.

From now on, we suppose the character string my_sql is our template. To show the parameters requested by the template you can run the following.

library(infuser)
variables_requested(my_sql, verbose = TRUE)

## Variables requested by template:

## >> year

## >> month (default = 3)

To fill in the template simply provide the requested parameters.

  infuse(my_sql, year=2016, month=8)

## SELECT * FROM Customers
## WHERE Year = 2016
## AND Month = 8;

You can also provide a named list with the requested parameters.

my_list<- 
  list(year=2016,
       month=8)

infuse(my_sql, my_list)

## SELECT * FROM Customers
## WHERE Year = 2016
## AND Month = 8;

If a default value is available in the template, it will be used if the parameter is not specified.

infuse(my_sql, year=2016)

## SELECT * FROM Customers
## WHERE Year = 2016
## AND Month = 3;

Working with text files as templates

Just like we're using a string here, a text file can be used. An example text file can be found in the package as follows:

example_file<-
  system.file("extdata", "sql1.sql", package="infuser")

example_file

## [1] "/Library/Frameworks/R.framework/Versions/3.3/Resources/library/infuser/extdata/sql1.sql"

Again, we can check which parameters are requested by the template.

variables_requested(example_file, verbose = TRUE)

## Variables requested by template:

## >> month (default = 3)

## >> year

And provide their values.

infuse(example_file, year = 2016, month = 12)

## SELECT LAT_N, CITY, TEMP_F
## FROM STATS, STATION
## WHERE MONTH = 12
## AND YEAR = 2016
## AND STATS.ID = STATION.ID
## ORDER BY TEMP_F;

Infusing vectors

It is quite easy to infuse a vector.

years <- c(2013,2014,2015)
sql_string <- "SELECT * FROM T1 WHERE Year IN ({{years}})"

infuse(sql_string, years=years)

## SELECT * FROM T1 WHERE Year IN (2013,2014,2015)

You can also specify the collapse character.

infuse(sql_string, years=years, collapse_char = ";")

## SELECT * FROM T1 WHERE Year IN (2013;2014;2015)

Processing / transforming your inputs

A transform_function can be specified in the infuse command. This allows for pre-processing of the parameter values before inserting them in the template.

What we don't want to happen is the following:

sql<-"INSERT INTO Students (Name) VALUES ({{name}})"
name <- "Robert'); DROP TABLE Students;--"

infuse(sql, name = name)

## INSERT INTO Students (Name) VALUES (Robert'); DROP TABLE Students;--)

Yikes! A way to solve this is to specify your own custom transform function.

my_transform_function<-function(v){
  # replace single quotes with double quotes
  v<-gsub("'", "''", v)
  # encloses the string in single quotes
  v<-paste0("'",v,"'")
  
  return(v)
}

infuse(sql, name = name, transform_function = my_transform_function)

## INSERT INTO Students (Name) VALUES ('Robert''); DROP TABLE Students;--')

Of course you can also use functions from other packages. Specifically for SQL I advise you to take a look at the dbplyr::build_sql function.

infuse(sql, name = name, transform_function = dbplyr::build_sql)

## Warning: Installed Rcpp (0.12.12) different from Rcpp used to build dplyr (0.12.11).
## Please reinstall dplyr to avoid random crashes or undefined behavior.

## INSERT INTO Students (Name) VALUES ('Robert''); DROP TABLE Students;--')

Issues / questions

Simply create a new issue at this GitHub repository.

Changes

v.0.2.8

  • added strict parameter to infuser, if set to TRUE will stop processing in case of incomplete set of supplied template parameters

v.0.2.7

  • change dpyr::build_sql to dbplyr::build_sql

v.0.2.6

  • set readLines's warn parameter to FALSE

v.0.2.5

  • fixed bug/typo related to #10

v.0.2.4

  • fixed testing to adhere to new testthat standards

v.0.2.2

  • dropped key_value_list parameter (will be interpreted automatically)
  • fixed passing of the variable_identifier
  • ability to make variable_identifier persistent

v.0.2.1

  • fixed: incorrect replacement of parameters with same prefix

v.0.2.0

  • consolidating adjustments and releasing version on CRAN

v.0.1.4

  • updated print function for output of infuse (uses cat for now on)

v0.1.3

  • added optional collapse_char argument to infuse command

v0.1.2

  • added optional key_value_list argument to infuse command

v0.1.1

  • added optional transform_function argument to infuse command

infuser's People

Contributors

bart6114 avatar mschubert avatar zachmayer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

infuser's Issues

passing parameter values through a file

great package, but is it possible to pass parameter values in a file rather than in function? this would make it far easier in cases where a large number of values have to be instantiated in the template

control flow?

Awesome package. Does this package currently support control flow?

Something like

SELECT *
FROM FAKE_TABLE
WHERE ds = '2016-08-01'
{% if capped %}
AND dim_is_capped
{% else %}
AND NOT dim_is_capped
{% endif %}

where capped controls what goes to the WHERE clause.

misplaced brackets in `read_template`

In this function read_template the following line (line 16, in helpers.R)

} else if(is.character(file_or_string) && nchar(file_or_string > 0)){

should it not be nchar(file_or_string) > 0 instead of nchar(file_or_string > 0) , I have a huge string which was returning NA for the logical operation. I am yet to figure out which specific part of the string is causing this behaviour. Will post that as a test case, once I figure it out.

Suggestion for parameters

Hello
Very nice package. Does the job. One suggestion, in the call to infuse which is

infuse<-function (file_or_string, ..., variable_identifier = c("{{", 
"}}"), default_char = "|", verbose = FALSE) 

Could the function take an argument, say args_as_list which if non null (or not missing) becomes params_supplied ? So, code like

 params_supplied  = if(missing(args_as_list)) list(...) else args_as_list

Sometimes i build my substitution in a list and rather not have to use do.call.
Cheers

issues when using specific variable_identifier

Thanks for this great package.

I have an issue when using the parameter "variable_identifier" with the 'infuse' function. It does not seem to be taken into account.
However, function 'variables_requested' works as expected with specific parameter 'variable_identifier'. It seems that function 'infuse' does not pass along the parameter 'variable_identifier' to sub call to function 'variable_requested'.

Example:
my_sql<-"SELECT * FROM Customers WHERE Year = ${year} AND Month = ${month};"
variables_requested(my_sql, variable_identifier = c("${","}"), verbose = TRUE)
infuse(my_sql, year=2015, month=2, variable_identifier = c("${","}"), verbose=TRUE)

I hope it make sense.
best,

Vincent.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.