diff --git a/Project.toml b/Project.toml index a9260f3..94b83e6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "REDCap" uuid = "ba918724-fbf9-5e4a-a61c-87e95654e718" authors = ["Cory Cothrum", "Dilum Aluthge ", "Ashlin Harris "] -version = "2.3.0" +version = "2.4.0" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/src/api_methods/arms.jl b/src/api_methods/arms.jl index 3126d7b..e887a9f 100644 --- a/src/api_methods/arms.jl +++ b/src/api_methods/arms.jl @@ -1,3 +1,10 @@ +#TODO: consider changing all functions to the following form: +#= +function delete_arms(;kwargs...) + REDCap.request(;kwargs...) +end +=# + function delete_arms(; url=get_url(), token=get_token(), arms=nothing,) REDCap.request(; url=REDCap_url(url), @@ -15,7 +22,7 @@ end #All examples use JSON #TODO: what is the proper format for multi-item XML? I can't find this anywhere... # #TODO: is this ata paratamet required, given the action parameter? -function import_arms(; url=get_url(), token=get_token(), format=nothing, data=nothing, returnFormat=nothing, override=0,) +function import_arms(; url=get_url(), token=get_token(), format=nothing, data=nothing, returnFormat=nothing, override=nothing,) REDCap.request(; url=REDCap_url(url), data=REDCap_data(data,REDCap_format(format),xml_tag="arms"), diff --git a/src/api_methods/events.jl b/src/api_methods/events.jl index f2d3c86..6da0878 100644 --- a/src/api_methods/events.jl +++ b/src/api_methods/events.jl @@ -14,7 +14,7 @@ function export_events(; url=get_url(), token=get_token(), format=nothing, retur end #TODO: data parameter required? -function import_events(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, data=nothing, override=0,) +function import_events(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, data=nothing, override=nothing,) REDCap.request(; url=REDCap_url(url), diff --git a/src/api_methods/field_names.jl b/src/api_methods/field_names.jl index 7da6956..6410f5c 100644 --- a/src/api_methods/field_names.jl +++ b/src/api_methods/field_names.jl @@ -1,7 +1,11 @@ -function export_list_of_export_field_names(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, field=nothing) +#TODO: retire this old function name? +##TODO: what about export_fields? +function export_list_of_export_field_names(; url=get_url(), token=get_token(), format=nothing, field=nothing) #TODO: field could be a single entry or an array +##TODO: returnFormat has no effect, which I think is generally the case for export functions REDCap.request(; url=REDCap_url(url), - kwargs = (; token=REDCap_token(token), content=:exportFieldNames, format=REDCap_format(format), field, returnFormat=REDCap_format(returnFormat),), + kwargs = (; token=REDCap_token(token), content=:exportFieldNames, format=REDCap_format(format), field, ), ) end +export_field_names = export_list_of_export_field_names diff --git a/src/api_methods/file_repository.jl b/src/api_methods/file_repository.jl index 12aef54..481da7b 100644 --- a/src/api_methods/file_repository.jl +++ b/src/api_methods/file_repository.jl @@ -26,6 +26,7 @@ function export_list_of_folders(; url=get_url(), token=get_token(), format=nothi kwargs = (; token=REDCap_token(token), content=:fileRepository, action=:list, name, format=REDCap_format(format), folder_id, returnFormat=REDCap_format(returnFormat),), ) end +export_folders = export_list_of_folders function import_file_from_file_repository(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, name=nothing, file=nothing, folder_id=nothing,) REDCap.request(; diff --git a/src/api_methods/records.jl b/src/api_methods/records.jl index 24c97cb..c3c1fe7 100644 --- a/src/api_methods/records.jl +++ b/src/api_methods/records.jl @@ -7,11 +7,12 @@ function delete_records(; url=get_url(), token=get_token(), records, arm=nothing end #TODO: this format parameter allows odm, unlike most other format args -function export_records(; url=get_url(), token=get_token(), format=nothing, type=nothing, records=nothing, fields=nothing, forms=nothing, events=nothing, rawOrLabel=nothing, rawOrLabelHeaders=nothing, exportCheckboxLabel=false, returnFormat=nothing, exportSurveyFields=false, exportDataAccessGroups=false, filterLogic=nothing, dateRangeBegin=nothing, dateRangeEnd=nothing, csvDelimiter=nothing, decimalCharacter=nothing, exportBlankForGrayFormStatus=nothing) +# The REDCap_listlike turns an input like [:a, :b, :c] into "a, b, c" +# TODO: what other parameters need this sort of treatment? +function export_records(; url=get_url(), token=get_token(), format=nothing, type=nothing, records=nothing, fields=nothing, forms=nothing, events=nothing, rawOrLabel=nothing, rawOrLabelHeaders=nothing, exportCheckboxLabel=nothing, returnFormat=nothing, exportSurveyFields=nothing, exportDataAccessGroups=nothing, filterLogic=nothing, dateRangeBegin=nothing, dateRangeEnd=nothing, csvDelimiter=nothing, decimalCharacter=nothing, exportBlankForGrayFormStatus=nothing) REDCap.request( - data=REDCap_data(data,REDCap_format(format),xml_tag="records"), url=REDCap_url(url), - kwargs = (; token=REDCap_token(token), content=:record, format=REDCap_format(format), type, records, forms, events, rawOrLabel, rawOrLabelHeaders, exportCheckboxLabel, returnFormat=REDCap_format(returnFormat), exportSurveyFields, exportDataAccessGroups, filterLogic, dateRangeBegin, dateRangeEnd, csvDelimiter, decimalCharacter, exportBlankForGrayFormStatus,), + kwargs = (; token=REDCap_token(token), content=:record, format=REDCap_format(format), type, records, fields, forms, events, rawOrLabel, rawOrLabelHeaders, exportCheckboxLabel, returnFormat=REDCap_format(returnFormat), exportSurveyFields, exportDataAccessGroups, filterLogic, dateRangeBegin, dateRangeEnd, csvDelimiter, decimalCharacter, exportBlankForGrayFormStatus,), ) end diff --git a/src/export.jl b/src/export.jl index 88b6f1b..f176c28 100644 --- a/src/export.jl +++ b/src/export.jl @@ -13,8 +13,10 @@ delete_users, export_arms, export_DAGs, export_events, +export_field_names, export_file, export_file_from_file_repository, +export_folders, export_instrument_event_mappings, export_instruments, export_list_of_export_field_names, diff --git a/src/request.jl b/src/request.jl index 2c73c10..2e83f99 100644 --- a/src/request.jl +++ b/src/request.jl @@ -52,9 +52,11 @@ function generate_request_body(; data=nothing, odm=nothing, kwargs) end append_as_redcap_pair!(d::Dict, parameter::Symbol, value::Nothing) = nothing -function append_as_redcap_pair!(parameter::Symbol, value::Array) +function append_as_redcap_pair!(d::Dict, parameter::Symbol, value::Vector) for (i, item) in enumerate(value) - d[string(parameter,'[',i-1,']')] = string(item) + # I believe either method should work: + d[string(parameter)] = join(value, ',') + #d[string(parameter,'[',i-1,']')] = string(item) end end function append_as_redcap_pair!(d::Dict, parameter::Symbol, value) diff --git a/src/types.jl b/src/types.jl index 0836b94..39770de 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1,3 +1,4 @@ +#TODO: It might make sense to deprecate all internal types, instead checking values based on argument name REDCap_url(x) = occursin(r"^https:\/\/.*\/api\/$", x) ? URIs.URI(x) : throw(ArgumentError("Invalid REDCap url (must be \"https:// ... /api/\")")) REDCap_datetime(x::String) = DateTime(x,"yyyy-m-dd H:M") @@ -58,4 +59,3 @@ REDCap_data(x::NamedTuple, format::Union{REDCap_format,Nothing}; xml_tag=nothing REDCap_data(x::String, format::Union{REDCap_format, Nothing}; xml_tag=nothing) = x #TODO: handle large files? REDCap_data(x::IOStream, format::Union{REDCap_format, Nothing}; xml_tag=nothing) = read(x,String) - diff --git a/src/utils.jl b/src/utils.jl index b4ac144..cfeb8df 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,3 +1,4 @@ +#TODO: Add conversion functions (maybe functinos can accept a sink function get_token() if !haskey(ENV, "REDCAP_API_TOKEN") @error("No REDCap API token found") diff --git a/test/code/workflows/basic_demography.jl b/test/code/workflows/basic_demography.jl index 2934a7c..7bc57f4 100644 --- a/test/code/workflows/basic_demography.jl +++ b/test/code/workflows/basic_demography.jl @@ -19,7 +19,7 @@ field_names = export_list_of_export_field_names(token=demography_token, format=: ] import_records(token=demography_token,data=(record_id=1,first_name="A",last_name="Person")) -@test generate_next_record_name(token=demography_token) == "2" +@test "2" == generate_next_record_name(token=demography_token) for i in 2:4 import_records( token=demography_token, @@ -28,4 +28,6 @@ for i in 2:4 first_name = "A", last_name = "NotherPerson")) end -@test generate_next_record_name(token=demography_token) == "5" +@test "5" == generate_next_record_name(token=demography_token) +@test ["A","A","A","A"] == DataFrame(export_records(fields=[:age, :bmi, :first_name],token=demography_token,format=:json) |> JSON.parse).first_name +