Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Rlabkey/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export(labkey.pipeline.getPipelineContainer)
export(labkey.pipeline.getProtocols)
export(labkey.pipeline.getFileStatus)
export(labkey.pipeline.startAnalysis)
export(labkey.query.import)

S3method(print, LabkeySession)
S3method(print, LabkeySchemaList)
Expand Down
9 changes: 6 additions & 3 deletions Rlabkey/R/labkey.domain.R
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,11 @@ labkey.domain.createAndLoad <- function(baseUrl=NULL, folderPath, name, descript
stop (paste("A value must be specified for each of baseUrl, folderPath, name, df or domainKind."))

if (is.null(options))
options <- list(strictFieldValidation = FALSE)
else
options <- list()

# Add option for study dataset and data class creation to skip validation check for required properties,
# see DataSetDomainKind.createDomain and ExperimentServiceImpl.createDataClass
if (domainKind == "StudyDatasetVisit" || domainKind == "StudyDatatsetDate" || domainKind == "DataClass")
options <- c(options, list(strictFieldValidation = FALSE))

if (is.null(schemaName))
Expand All @@ -241,7 +244,7 @@ labkey.domain.createAndLoad <- function(baseUrl=NULL, folderPath, name, descript
labkey.domain.create(baseUrl = baseUrl, folderPath = folderPath, domainKind = domainKind,
domainDesign = design, options = options)

labkey.insertRows(baseUrl = baseUrl, folderPath = folderPath, schemaName = schemaName, queryName= name, df)
labkey.query.import(baseUrl, folderPath, schemaName, queryName= name, toImport = df)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@labkey-klum What do you think of this change? The new labkey.query.import call is much faster then the labkey.insertRows or labkey.importRows calls. Do you recall any specific reason why the labkey.domain.createAndLoad would need to use the insertRows or do you think it is fine to change it to labkey.query.import?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, agreed that changing this to use the new query.import function will improve the perf on this function.

}

labkey.domain.createConditionalFormat <- function(queryFilter, bold=FALSE, italic=FALSE, strikeThrough=FALSE, textColor="", backgroundColor="")
Expand Down
49 changes: 49 additions & 0 deletions Rlabkey/R/labkey.query.import.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
##
# Copyright (c) 2013-2018 LabKey Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##

labkey.query.import <- function(baseUrl=NULL, folderPath, schemaName, queryName, toImport, options = NULL)
{
baseUrl=labkey.getBaseUrl(baseUrl)

## check required parameters
if (missing(baseUrl) || is.null(baseUrl) || missing(folderPath) || missing(schemaName) || missing(queryName) || missing(toImport))
stop (paste("A value must be specified for each of baseUrl, folderPath, schemaName, queryName, and toImport."))
if (!missing(options) & !is.list(options))
stop (paste("options must be a list data structure."))

## normalize the folder path
folderPath <- encodeFolderPath(folderPath)

## write the dataframe to a tempfile to post to the server
tf <- tempfile(fileext=".tsv")
write.table(toImport, file=tf, sep="\t", quote=FALSE, row.names=FALSE)

## build the options param list
if (is.null(options))
options <- list()
options <- c(options, list(schemaName=schemaName, queryName=queryName, file=upload_file(tf)))

## Execute via our standard POST function
url <- paste(baseUrl, "query", folderPath, "import.api", sep="")
rawdata <- labkey.post(url, options, encoding="multipart")
response <- fromJSON(rawdata, simplifyVector=FALSE, simplifyDataFrame=FALSE)

## delete the temp file
file.remove(tf)

return(response)
}

6 changes: 5 additions & 1 deletion Rlabkey/R/labkey.webdav.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ labkey.webdav.getByUrl <- function(url, localFilePath, overwrite=TRUE)
processResponse(response)
}

labkey.webdav.put <- function(localFile, baseUrl=NULL, folderPath, remoteFilePath, fileSet="@files")
labkey.webdav.put <- function(localFile, baseUrl=NULL, folderPath, remoteFilePath, fileSet="@files", description=NULL)
{
if (missing(localFile)) {
stop (paste("A value must be specified for localFile"))
Expand All @@ -84,6 +84,10 @@ labkey.webdav.put <- function(localFile, baseUrl=NULL, folderPath, remoteFilePat

pbody <- upload_file(localFile)

if (!is.null(description)) {
url <- paste0(url, "?description=", URLencode(description))
}

if (!is.null(.lkdefaults[["debug"]]) && .lkdefaults[["debug"]] == TRUE) {
print(paste0("URL: ", url))
response <- PUT(url=url, config=options, body=pbody, verbose(data_in=TRUE, info=TRUE, ssl=TRUE))
Expand Down
14 changes: 7 additions & 7 deletions Rlabkey/man/labkey.importRows.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ labkey.importRows(baseUrl, folderPath,
\arguments{
\item{baseUrl}{a string specifying the \code{baseUrl}for the labkey server}
\item{folderPath}{a string specifying the \code{folderPath} }
\item{schemaName}{a string specifying the \code{schemaName} for the query}
\item{queryName}{a string specifying the \code{queryName} }
\item{schemaName}{a string specifying the \code{schemaName} for the query}
\item{queryName}{a string specifying the \code{queryName} }
\item{toImport}{a data frame containing rows of data to be imported}
\item{na}{(optional) the value to convert NA's to, defaults to NULL}
}
\details{
Multiple rows of data can be imported in bulk. The \code{toImport} data frame must contain
values for each column in the dataset and must be created with the \code{stringsAsFactors} option
set to FALSE. The names of the data in the data frame must be the column names from the
LabKey Server.To import a value of NULL, use an empty string ("") in the data frame (regardless of the database column type).
Also, when importing data into a study dataset, the sequence number must be specified. \cr \cr
Note: requires LabKey server version 13.3 or greater.
LabKey Server. To import a value of NULL, use an empty string ("") in the data frame
(regardless of the database column type). Also, when importing data into a study dataset, the
sequence number must be specified.
}

\value{
Expand All @@ -35,8 +35,8 @@ number as passed in the request.
\author{Cory Nathe}
\seealso{
\code{\link{labkey.selectRows}}, \code{\link{labkey.executeSql}}, \code{\link{makeFilter}},
\code{\link{labkey.insertRows}}, \code{\link{labkey.updateRows}}, \cr
\code{\link{labkey.deleteRows}}
\code{\link{labkey.insertRows}}, \code{\link{labkey.updateRows}}, \code{\link{labkey.deleteRows}},
\code{\link{labkey.query.import}}
}
\examples{
\donttest{
Expand Down
1 change: 1 addition & 0 deletions Rlabkey/man/labkey.insertRows.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ inserted.
\code{\link{labkey.selectRows}}, \code{\link{labkey.executeSql}}, \code{\link{makeFilter}},
\code{\link{labkey.importRows}}, \code{\link{labkey.updateRows}}, \cr
\code{\link{labkey.deleteRows}},
\code{\link{labkey.query.import}},
\code{\link{labkey.provenance.createProvenanceParams}},
\code{\link{labkey.provenance.startRecording}},
\code{\link{labkey.provenance.addRecordingStep}},
Expand Down
80 changes: 80 additions & 0 deletions Rlabkey/man/labkey.query.import.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
\name{labkey.query.import}
\alias{labkey.query.import}
\title{Bulk import an R data frame into a LabKey Server table using file import.}
\description{
Bulk import an R data frame into a LabKey Server table using file import.
}
\usage{
labkey.query.import(baseUrl, folderPath,
schemaName, queryName, toImport, options = NULL)
}
\arguments{
\item{baseUrl}{a string specifying the \code{baseUrl}for the labkey server}
\item{folderPath}{a string specifying the \code{folderPath} }
\item{schemaName}{a string specifying the \code{schemaName} for the query}
\item{queryName}{a string specifying the \code{queryName}}
\item{toImport}{a data frame containing rows of data to be imported}
\item{options}{(optional) a list containing options specific to the import
action of the query}
}
\details{
This command mimics the "Import bulk data" option that you see in the LabKey server UI
for a table/query. It takes the passed in \code{toImport} data frame and writes it to a
temp file to be posted to the import action for the given LabKey query. It is very similar
to the \code{labkey.importRows} command but will be much more performant.
\cr \cr
Multiple rows of data can be imported in bulk using the \code{toImport} data frame.
The names of the data in the data frame must be the column names from the
LabKey Server.
\cr \cr
LabKey data types support different import options. The list of valid options for each
query will vary, but some common examples include:
\itemize{
\item{ \code{insertOption (string)} : Whether the import action should be done as an insert, creating new
rows for each provided row of the data frame, or a merge. When merging during import, any data you provide
for the rows representing records that already exist will replace the previous values.
Note that when updating an existing record, you only need to provide the columns you wish to update,
existing data for other columns will be left as is. Available options are "INSERT" and "MERGE".
Defaults to "INSERT".}
\item{ \code{auditBehavior (string)} : Set the level of auditing details for this import action.
Available options are "SUMMARY" and "DETAILED". SUMMARY - Audit log reflects that a change was made,
but does not mention the nature of the change. DETAILED - Provides full details on what change was made,
including values before and after the change. Defaults to the setting as specified by the LabKey query.}
\item{ \code{importLookupByAlternateKey (boolean)} : Allows lookup target rows to be resolved by values
rather than the target's primary key. This option will only be available for lookups that are
configured with unique column information. Defaults to FALSE.}
}
}

\value{
A list is returned with the row count for the number of affected rows. If options are provided,
additional details may be included in the response object related to those options.
}
\author{Cory Nathe}
\seealso{
\code{\link{labkey.insertRows}}, \code{\link{labkey.updateRows}}, \code{\link{labkey.importRows}}
}
\examples{
\donttest{

## Note that users must have the necessary permissions in the database
## to be able to modify data through the use of these functions
# library(Rlabkey)

df <- data.frame(
name=c("test1","test2","test3"),
customInt=c(1:3),
customString=c("aaa", "bbb", "ccc")
)

importedInfo <- labkey.query.import(
"http://localhost:8080/labkey",
folderPath="/apisamples", schemaName="samples", queryName="SampleType1",
toImport=df, options=list(insertOption = "MERGE", auditBehavior = "DETAILED")
)

importedInfo$rowCount

}
}
\keyword{IO}
6 changes: 6 additions & 0 deletions Rlabkey/man/labkey.setCurlOptions.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,10 @@ For Variable Name: enter RLABKEY_CAINFO_FILE\cr
For Variable Value: enter the path of the ca-bundle.crt you created above.\cr
Hit the Ok buttons to close all the windows.\cr
Now you can start R and begin working.

\cr \cr

This command can also be used to provide an alternate location / path to your
\code{.netrc} file. Example:\cr
\code{labkey.setCurlOptions(NETRC_FILE = '/path/to/alternate/_netrc')}
}
1 change: 1 addition & 0 deletions Rlabkey/man/labkey.updateRows.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ updated.
\code{\link{labkey.selectRows}}, \code{\link{labkey.executeSql}}, \code{\link{makeFilter}},
\code{\link{labkey.insertRows}}, \code{\link{labkey.importRows}}, \cr
\code{\link{labkey.deleteRows}},
\code{\link{labkey.query.import}},
\code{\link{labkey.provenance.createProvenanceParams}},
\code{\link{labkey.provenance.startRecording}},
\code{\link{labkey.provenance.addRecordingStep}},
Expand Down
6 changes: 4 additions & 2 deletions Rlabkey/man/labkey.webdav.put.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ labkey.webdav.put(
baseUrl=NULL,
folderPath,
remoteFilePath,
fileSet='@files'
)
fileSet='@files',
description=NULL
)
}
\arguments{
\item{localFile}{the local filepath to upload }
\item{baseUrl}{a string specifying the \code{baseUrl} for the labkey server}
\item{folderPath}{a string specifying the \code{folderPath} }
\item{remoteFilePath}{the destination path of this file on the remote server, relative to the folder root. }
\item{fileSet}{(optional) the name of file server fileSet, which is typically "@files" (the default value for this argument). In some cases this might be "@pipeline" or "@fileset". }
\item{description}{(optional) the description to attach to this file on the remote server. }
}
\details{
Upload a single file from the local machine to a LabKey Server using WebDAV.
Expand Down