irods_testbench_training_py.../client_metadata_example/test-meta.r

222 lines
9.5 KiB
R
Executable File

main() {
#### metadata examples ####
# before version 4.2.7 several microservices(functions) are required achieve metadata manipulation
# generally data structures of key pairs are created, applied or removed from the data-object/collection/resource
# from version 4.2.7 the msiModAVUMetadata microservice greatly simplifies metadata transformation
# for any version - retrieve metadata with sql like queries against the iRODS database, this is equivalent to the 'imeta ls' command
### metadata structures
# sample metadata in the % delimted format for msiString2KeyValPair
*str = "a=10%zebra=horse%hula=dance"
# load kvp structure from string
msiString2KeyValPair(*str, *kvp);
# add some keys with values
msiAddKeyVal(*kvp, "art", "crayon");
msiGetSystemTime(*Time, "human");
msiAddKeyVal(*kvp, "timestamp", *Time);
# print all keys and values
msiPrintKeyValPair("stdout", *kvp);
writeKeyValPairs("stdout", *kvp, " || ")
# print all keys
foreach(*kvp) {
writeLine("stdout", *kvp);
}
# print all keys with values
foreach(*i in *kvp) {
msiGetValByKey(*kvp,*i,*result);
writeLine("stdout", "1: *i = *result");
}
# print key=value where key like zeb*
# print key=value where value matches *Time (set with msiGetSystemTime above)
# print key=value where string value matches 10, convert to int and divide
foreach(*i in *kvp) {
msiGetValByKey(*kvp,*i,*result);
if (*i like "zeb*") then {
writeLine("stdout","2: *i = *result")
} else if (*result == *Time) then {
writeLine("stdout","2: *i = *result")
} else if (*result == "10") then {
*number=int("*result")/2
writeLine("stdout","2: *i = *number")
} else {
writeLine("stdout","2: no match")
}
}
# more conditional behaviour
foreach(*i in *kvp) {
msiGetValByKey(*kvp,*i,*result);
#if (*result == "dance" || *i == "art" || *i == "zebra") then { # this is a valid condition, however multiple OR with != / "not like" operators are not pre-evaluated correctly
if (*i == "a" && *result == str(10)) then { # must preceed the else statement or will not be matched
writeLine("stdout","3: AND *i = *result")
} else if (*result not like "dance") then {
writeLine("stdout","3: *i = *result")
}
}
## Add/Remove metadata for files(data objects) or directories(collections) ##
# print all session variables (rei) with msiGetSessionVarValue, when running the rule locally without script parameters the only useful variables are userNameClient= / rodsZoneClient=
# when run from the server rules engine, there are many more useful session variables
#msiGetSessionVarValue("all", "client");
# access the variables as $<variable name>
*testpath = "/$rodsZoneClient/home/$userNameClient"
*newfile = "/$rodsZoneClient/home/$userNameClient/test.txt"
# test for valid path, errorcode microservice is used to ensure the script does not exit on failure instead return boolean
*a = errorcode(msiObjStat(*testpath,*status)) >=0
writeLine("stdout","4: collection exists: *testpath *a")
# if path exists add/remove metadata
if (errorcode(msiObjStat(*testpath,*status)) >=0) then {
# remove file without sending to trash and unregister from database
if (errorcode(msiObjStat(*newfile,*status)) >=0) then {
msiDataObjUnlink("objPath=*newfile++++forceFlag=++++unreg=",*status)
writeLine("stdout","4: file removed: *newfile")
}
# create a file, forceFlag attribute required to overwrite file, resource can be specified here, note the field delimiter "destRescName=demoResc++++forceFlag="
*content = "test.txt content"
msiDataObjCreate(*newfile,"forceFlag=",*file_descriptor)
msiDataObjWrite(*file_descriptor,*content,*write_length)
msiDataObjClose(*file_descriptor,*status)
writeLine("stdout","4: file created: *newfile")
# apply metadata to object from kvp structure
msiAssociateKeyValuePairsToObj(*kvp,*newfile,"-d")
# get data object and collection from a full path string
#*filepath_element = ( size( (split(*newfile,"/")) ) )
#*file = (elem((split(*newfile,"/")), (*filepath_element - 1) ))
#*data_object = (elem( (split(*newfile,"/")), ( (size((split(*newfile,"/")))) - 1) ))
msiSplitPath(*newfile,*collection,*file)
# query iRODS db for metadata of file, load into a new key pair structure
*query = SELECT META_DATA_ATTR_NAME,META_DATA_ATTR_VALUE WHERE DATA_NAME = '*file' AND COLL_NAME = '*collection'
foreach(*row in *query) {
#msiPrintKeyValPair("stdout",*row)
#writeLine("stdout","next row")
msiGetValByKey(*row,"META_DATA_ATTR_NAME",*key);
msiGetValByKey(*row,"META_DATA_ATTR_VALUE",*value);
msiAddKeyVal(*query_kvp, *key, *value);
}
# create a new 'trimmed' metadata structure including the key pairs to be removed
foreach(*i in *query_kvp) {
#writeLine("stdout", "key is *i")
if (*i == "a" || *i == "art") then {
msiGetValByKey(*query_kvp,*i,*result)
writeLine("stdout","4: metadata to keep on *newfile, *i=*result")
} else {
msiGetValByKey(*query_kvp,*i,*result)
writeLine("stdout","4: metadata to remove from *newfile, *i=*result")
msiAddKeyVal(*new_kvp, *i, *result)
}
}
# remove key pairs listed in the new metadata structure from the data object
msiRemoveKeyValuePairsFromObj(*new_kvp,*newfile,"-d")
# create a new kvp structure, add key pairs
msiAddKeyVal(*kvp2, "company", "OCF");
msiAddKeyVal(*kvp2, "department", "Cloud");
msiGetSystemTime(*created_epoc, "unix")
msiAddKeyVal(*kvp2, "create_date_epoc", *created_epoc );
# get system time, load into list and grab elements based on position
msiGetFormattedSystemTime(*created,"human","%d-%02d-%02d-%02d-%02d-%02d")
writeLine("stdout", "4: year:" ++ " " ++ (elem((split(*created,"-")),0)) )
*year = elem((split(*created,"-")),0)
*month = elem((split(*created,"-")),1)
*day = elem((split(*created,"-")),2)
msiAddKeyVal(*kvp2, "create_year", *year );
msiAddKeyVal(*kvp2, "create_month", *month );
msiAddKeyVal(*kvp2, "create_day", *day );
# add meta data to the data object; -d file(data object), -C directory(collection)
msiAssociateKeyValuePairsToObj(*kvp2,*newfile,"-d");
# find files with metadata between an epoc date range
# supported operators
#>=
#<=
#=
#<
#>
#'1' '100'
#
# 2020(1575072000) - 2030(1890691200)
*query = SELECT DATA_NAME WHERE COLL_NAME = '*collection' AND META_DATA_ATTR_NAME = 'create_date_epoc' AND META_DATA_ATTR_VALUE BETWEEN '01575072000' '01890691200'
foreach(*row in *query) {
msiGetValByKey(*row,"DATA_NAME",*data_name)
writeLine("stdout", "4: file: " ++ "*data_name" ++ " created between 2020 - 2030" )
}
}
### msiModAVUMetadata - change metadata directly on the object/collection/resource ###
# this is new microservice as of version 4.2.7 and easy to use
# msiModAVUMetadata allows key, value and unit (AVU) manipulation, much like the imeta icommand
# assigning an additional attribute 'unit' to the key pair is useful and can be treated as a secondary value or left empty ""
# remove all key pairs directly from the data object
msiModAVUMetadata("-d","*newfile","rmw", "%", "%", "%")
# add new key pair directly to the data object
msiModAVUMetadata("-d","*newfile","add", "car", "ford", "string")
# change value for key directly on the data object
msiModAVUMetadata("-d","*newfile","set", "car", "toyoda", "string")
# remove key pair directly on the data object
msiModAVUMetadata("-d","*newfile","rm", "car", "toyoda", "string")
# wildcard remove key pairs directly on the data object
msiModAVUMetadata("-d","*newfile","add", "car", "subaru", "string")
msiModAVUMetadata("-d","*newfile","add", "car", "suzuki", "string")
msiModAVUMetadata("-d","*newfile","add", "car", "saab", "string")
msiModAVUMetadata("-d","*newfile","rmw", "car", "su%", "%")
#msiModAVUMetadata("-d","*newfile","rmw", "ca%", "%", "%")
# add some meta data with arbitrary unit types
msiModAVUMetadata("-d","*newfile","add", "catC", "yes", "damage")
msiModAVUMetadata("-d","*newfile","add", "price", "1200", "sterling")
## searching with metadata
# search for files in a collection where the key unit matches damage and the key value matches yes, return the filename key value key name with value yes and unit damage
*query = SELECT DATA_NAME,META_DATA_ATTR_NAME WHERE COLL_NAME = '*collection' AND META_DATA_ATTR_UNITS = 'damage' AND META_DATA_ATTR_VALUE like 'y%'
foreach(*row in *query) {
msiGetValByKey(*row,"DATA_NAME",*target_file)
msiGetValByKey(*row,"META_DATA_ATTR_NAME",*damage_type)
# search for car key value using the file name
*sub_query = SELECT META_DATA_ATTR_VALUE WHERE COLL_NAME = '*collection' AND DATA_NAME = '*target_file' AND META_DATA_ATTR_NAME = 'car'
foreach(*sub_row in *sub_query) {
msiGetValByKey(*sub_row,"META_DATA_ATTR_VALUE",*car)
# search for the price key value under threshold (string is dynamically evaluated as numeric)
*sub_query = SELECT META_DATA_ATTR_VALUE WHERE COLL_NAME = '*collection' AND DATA_NAME = '*target_file' AND META_DATA_ATTR_NAME = 'price' AND META_DATA_ATTR_VALUE < '1201'
foreach(*sub_row in *sub_query) {
msiGetValByKey(*sub_row,"META_DATA_ATTR_VALUE",*price)
#writeLine("stdout", *price)
}
# if price variable set, its value below 1201
if (errorcode(*price) >=0) then {
writeLine("stdout","5: writeoff: *damage_type *car £*price")
}
}
}
}
INPUT null
OUTPUT ruleExecOut