222 lines
9.5 KiB
R
Executable File
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
|
|
|