github.com/cyverse/go-irodsclient@v0.13.2/irods/fs/resource.go (about) 1 package fs 2 3 import ( 4 "fmt" 5 "strconv" 6 7 "github.com/cyverse/go-irodsclient/irods/common" 8 "github.com/cyverse/go-irodsclient/irods/connection" 9 "github.com/cyverse/go-irodsclient/irods/message" 10 "github.com/cyverse/go-irodsclient/irods/types" 11 "github.com/cyverse/go-irodsclient/irods/util" 12 "golang.org/x/xerrors" 13 ) 14 15 // GetResource returns a resource for the name 16 func GetResource(conn *connection.IRODSConnection, name string) (*types.IRODSResource, error) { 17 if conn == nil || !conn.IsConnected() { 18 return nil, xerrors.Errorf("connection is nil or disconnected") 19 } 20 21 // lock the connection 22 conn.Lock() 23 defer conn.Unlock() 24 25 // query with AUTO_CLOSE option 26 query := message.NewIRODSMessageQueryRequest(1, 0, 0, 0x100) 27 query.AddSelect(common.ICAT_COLUMN_R_RESC_ID, 1) 28 query.AddSelect(common.ICAT_COLUMN_R_RESC_NAME, 1) 29 query.AddSelect(common.ICAT_COLUMN_R_ZONE_NAME, 1) 30 query.AddSelect(common.ICAT_COLUMN_R_TYPE_NAME, 1) 31 query.AddSelect(common.ICAT_COLUMN_R_CLASS_NAME, 1) 32 query.AddSelect(common.ICAT_COLUMN_R_LOC, 1) 33 query.AddSelect(common.ICAT_COLUMN_R_VAULT_PATH, 1) 34 query.AddSelect(common.ICAT_COLUMN_R_RESC_CONTEXT, 1) 35 query.AddSelect(common.ICAT_COLUMN_R_CREATE_TIME, 1) 36 query.AddSelect(common.ICAT_COLUMN_R_MODIFY_TIME, 1) 37 38 rescCondVal := fmt.Sprintf("= '%s'", name) 39 query.AddCondition(common.ICAT_COLUMN_R_RESC_NAME, rescCondVal) 40 41 queryResult := message.IRODSMessageQueryResponse{} 42 err := conn.Request(query, &queryResult, nil) 43 if err != nil { 44 return nil, xerrors.Errorf("failed to receive a resource query result message: %w", err) 45 } 46 47 err = queryResult.CheckError() 48 if err != nil { 49 return nil, xerrors.Errorf("received a data resource query error: %w", err) 50 } 51 52 // TODO: do we need to print out? 53 //if queryResult.ContinueIndex != 0 { 54 // logger.Debugf("resource query for %s would have continued, more than one result found", name) 55 //} 56 57 if queryResult.RowCount == 0 { 58 return nil, xerrors.Errorf("no row found") 59 } 60 61 if queryResult.AttributeCount > len(queryResult.SQLResult) { 62 return nil, xerrors.Errorf("failed to receive resource attributes - requires %d, but received %d attributes", queryResult.AttributeCount, len(queryResult.SQLResult)) 63 } 64 65 resource := &types.IRODSResource{} 66 67 for attr := 0; attr < queryResult.AttributeCount; attr++ { 68 sqlResult := queryResult.SQLResult[attr] 69 if len(sqlResult.Values) != queryResult.RowCount { 70 return nil, xerrors.Errorf("failed to receive resource rows - requires %d, but received %d attributes", queryResult.RowCount, len(sqlResult.Values)) 71 } 72 73 value := sqlResult.Values[0] 74 75 switch sqlResult.AttributeIndex { 76 case int(common.ICAT_COLUMN_R_RESC_ID): 77 objID, err := strconv.ParseInt(value, 10, 64) 78 if err != nil { 79 return nil, xerrors.Errorf("failed to parse resource id '%s': %w", value, err) 80 } 81 resource.RescID = objID 82 case int(common.ICAT_COLUMN_R_RESC_NAME): 83 resource.Name = value 84 case int(common.ICAT_COLUMN_R_ZONE_NAME): 85 resource.Zone = value 86 case int(common.ICAT_COLUMN_R_TYPE_NAME): 87 resource.Type = value 88 case int(common.ICAT_COLUMN_R_CLASS_NAME): 89 resource.Class = value 90 case int(common.ICAT_COLUMN_R_LOC): 91 resource.Location = value 92 case int(common.ICAT_COLUMN_R_VAULT_PATH): 93 resource.Path = value 94 case int(common.ICAT_COLUMN_R_RESC_CONTEXT): 95 resource.Context = value 96 case int(common.ICAT_COLUMN_R_CREATE_TIME): 97 cT, err := util.GetIRODSDateTime(value) 98 if err != nil { 99 return nil, xerrors.Errorf("failed to parse create time '%s': %w", value, err) 100 } 101 resource.CreateTime = cT 102 case int(common.ICAT_COLUMN_R_MODIFY_TIME): 103 mT, err := util.GetIRODSDateTime(value) 104 if err != nil { 105 return nil, xerrors.Errorf("failed to parse modify time '%s': %w", value, err) 106 } 107 resource.ModifyTime = mT 108 default: 109 // ignore 110 } 111 } 112 113 return resource, nil 114 } 115 116 // AddResourceMeta sets metadata of a resource to the given key values. 117 // metadata.AVUID is ignored 118 func AddResourceMeta(conn *connection.IRODSConnection, name string, metadata *types.IRODSMeta) error { 119 if conn == nil || !conn.IsConnected() { 120 return xerrors.Errorf("connection is nil or disconnected") 121 } 122 123 // lock the connection 124 conn.Lock() 125 defer conn.Unlock() 126 127 request := message.NewIRODSMessageAddMetadataRequest(types.IRODSResourceMetaItemType, name, metadata) 128 response := message.IRODSMessageModifyMetadataResponse{} 129 err := conn.RequestAndCheck(request, &response, nil) 130 if err != nil { 131 return xerrors.Errorf("received an add data resource meta error: %w", err) 132 } 133 return nil 134 } 135 136 // DeleteResourceMeta sets metadata of a resource to the given key values. 137 // The metadata AVU is selected on basis of AVUID if it is supplied, otherwise on basis of Name, Value and Units. 138 func DeleteResourceMeta(conn *connection.IRODSConnection, name string, metadata *types.IRODSMeta) error { 139 if conn == nil || !conn.IsConnected() { 140 return xerrors.Errorf("connection is nil or disconnected") 141 } 142 143 // lock the connection 144 conn.Lock() 145 defer conn.Unlock() 146 147 var request *message.IRODSMessageModifyMetadataRequest 148 149 if metadata.AVUID != 0 { 150 request = message.NewIRODSMessageRemoveMetadataByIDRequest(types.IRODSResourceMetaItemType, name, metadata.AVUID) 151 } else if metadata.Units == "" && metadata.Value == "" { 152 request = message.NewIRODSMessageRemoveMetadataWildcardRequest(types.IRODSResourceMetaItemType, name, metadata.Name) 153 } else { 154 request = message.NewIRODSMessageRemoveMetadataRequest(types.IRODSResourceMetaItemType, name, metadata) 155 } 156 157 response := message.IRODSMessageModifyMetadataResponse{} 158 err := conn.RequestAndCheck(request, &response, nil) 159 if err != nil { 160 return xerrors.Errorf("received a delete data resource meta error: %w", err) 161 } 162 return nil 163 }