#!/usr/bin/env sampy """ An example script showing how to find all of the descendants of a specified SAM data file. Usage: CLI: ./GetFileDescendants.py [--dataTier=] \ [--appName=] [--appVersion=] \ [--before=] [--since=] \ fileName API: # make sure that $SAM_DIR/examples is in your python path #!/usr/bin/env sampy from GetFileDescendants import getFileDescendants gfd = getFileDescendants() physicalFileAttributeList = gfd(args='fileName', dataTier='dataTierHere', before='dd-mmm-yyyy', since='dd-mmm-yyyy', appName='appNameHere', appVersion='v_whatever_here') """ import os import sys import string import SAM from Sam import sam from SamUtility.DbDerivedClient import DbDerivedClient from SamStruct.SamTime import SamTime from SamStruct.DataFilePhysicalAttributes import DataFilePhysicalAttributes from SamStruct.DataFilePhysicalAttributesList import DataFilePhysicalAttributesList from SamException import SamExceptions from SamUserApi_CommandInterface import SamUserApi_CommandInterface class getFileDescendants(SamUserApi_CommandInterface): def __init__(self): SamUserApi_CommandInterface.__init__( self, commandParameters = { 'verb' : ['get children'], 'allowedOptions' : ['%s=' % SAM.attrDataTier, '%s=' % SAM.attrAppName, '%s=' % SAM.attrAppVersion, 'since=', 'before=', ], 'allowedArgCount' : 1, 'apiReturns' : DataFilePhysicalAttributesList, 'description' : {'args' : 'filename for which you which to see the specified descendants', SAM.attrDataTier : 'restrict the list to the descendants with this dataTier', SAM.attrAppName : 'restrict the list to the descendants produced by this appName', SAM.attrAppVersion : 'restrict the list to the descendants produced by this appVersion', 'since' : 'restrict the list to those files created since this date', 'before' : 'restrict the list to those files created before this date', }, 'restrictedTypeOptions' : {'since' : SamTime, 'before' : SamTime}, 'helpText' : """ Get a list of descendants of the given file, filtered by dataTier, application, and/or creation date. """, }) def cliProcessResults(self, listOfFiles): if listOfFiles: listOfFileNames = map(lambda(x): x.getFileName(), listOfFiles) stringifiedListOfFiles = string.join(listOfFileNames, '\n') else: stringifiedListOfFiles = "No files found." return SamUserApi_CommandInterface.cliProcessResults(self, stringifiedListOfFiles) def implementation(self, argDict, argList): self.db = DbDerivedClient('DbDataFiles') parentFile = argList[0] dataTier = argDict.get(SAM.attrDataTier) appName = argDict.get(SAM.attrAppName) appVersion = argDict.get(SAM.attrAppVersion) since = argDict.get('since') before = argDict.get('before') theWhereDict = {} # which filters? if dataTier is not None: dbDataTiers = DbDerivedClient('DbDataTiers') try: dataTierId = dbDataTiers.getOne(['dataTierId'], {'dataTier':dataTier}) except SamExceptions.DbMinRowsException: raise SamExceptions.DataTierNotFound("No such dataTier: '%s'" % dataTier) theWhereDict.update({'dataTierId':dataTierId}) if appName is not None or appVersion is not None: dbAppFamilies = DbDerivedClient('DbApplicationFamilies') if appName is not None and appVersion is not None: rows = dbAppFamilies.get(['applFamilyId'], {'applName':appName, 'version' :appVersion}) elif appName is not None: rows = dbAppFamilies.get(['applFamilyId'], {'applName':appName}) else: rows = dbAppFamilies.get(['applFamilyId'], {'version' :appVersion}) if rows and rows[0]: applFamilyIdList = map(lambda(x): x[0], rows) theWhereDict.update({'applFamilyId': {'oper' : 'in (%s)' % string.join(map(lambda(x): str(x), applFamilyIdList), ', ')}}) if before is not None or since is not None: if before is not None and since is not None: theWhereDict.update({'createDate' : {'oper' : "between '%s' and '%s'" % (since.byFormat(SAM.SamTimeFormat_DateFormat), before.byFormat(SAM.SamTimeFormat_DateFormat))}}) elif before is not None: theWhereDict.update({'createDate' : {'oper' : "< '%s'" % before.byFormat(SAM.SamTimeFormat_DateFormat)}}) else: theWhereDict.update({'createDate' : {'oper' : "> '%s'" % since.byFormat(SAM.SamTimeFormat_DateFormat)}}) # get the parentFileId try: parentFileId = self.db.getOne(['fileId'], {'fileName':parentFile}) except SamExceptions.DbMinRowsException: raise SamExceptions.DataFileNotFound("No such file: '%s'" % parentFile) # all children of all generations: allGenerations = [] # loop through the parents and all children: children = self._getChildrenOf(parentFileId) allGenerations += children while children != []: new_children = [] for fileId in children: parent = fileId offspring = self._getChildrenOf(parent) allGenerations += offspring new_children += offspring children = new_children # ok, now we have a list of allGenerations, filter returnList = DataFilePhysicalAttributesList() if allGenerations: allGenerationsFileIdList = string.join(map(lambda(x): str(x), allGenerations), ', ') theWhereDict.update({'fileId' : {'oper' : 'in (%s)' % allGenerationsFileIdList}}) fileIdList = [] rows = self.db.get(['fileId'], theWhereDict) # now convert to datafilePhysicalAttributesList if rows and rows[0]: fileIdList = map(lambda(x): x[0], rows) theQuery = """ select distinct df.file_id, df.file_name, df.file_size_in_bytes, df.crc_value, crc.crc_type_desc, df.event_count from data_files df, crc_types crc where df.file_id in (%s) and df.crc_type_id = crc.crc_type_id """ % string.join(map(lambda(x): str(x), fileIdList), ', ') rows = self.db.query(theQuery) if rows and rows[0]: returnList = map(lambda(x): DataFilePhysicalAttributes(fileId=x[0], fileName=x[1], fileSize="%sB" % x[2], crcValue=x[3], crcType=x[4], eventCount=x[5]), rows) return returnList def _getChildrenOf(self, fileId): """ Get all direct children of the specified fileId """ returnList = [] theQuery = """ select fl.file_id_dest from file_lineages fl where fl.file_id_source = %s """ % fileId rows = self.db.query(theQuery) if rows and rows[0]: returnList = map(lambda(x): x[0], rows) return returnList def main(args): return getFileDescendants().dispatch(args) if __name__ == "__main__": sys.exit(main(sys.argv[1:]))