Skip to main content
Directly return the field map.
Source Link
Daniel Ballinger
  • 103k
  • 40
  • 275
  • 601

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.

Update

I was thinking some more about this. If the interface is changed so that the versioned classes return the Schema.DescribeSObjectResult.fields.getMap() directly then it should be possible to see the results specific to the API version.

public interface DescribeFieldsApiVersioned {
    Map<String, Schema.DescribeFieldResult> getFields(Schema.sObjectType sObjectType);
}

If you want to make a deluxe version you could pass in the class name where you want to make the call from. Then use that to lookup the ApexClass.ApiVersion. Have a factory class the creates the correct DescribeApiVersioned implementer for that API version.

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.


If you want to make a deluxe version you could pass in the class name where you want to make the call from. Then use that to lookup the ApexClass.ApiVersion. Have a factory class the creates the correct DescribeApiVersioned implementer for that API version.

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.

Update

I was thinking some more about this. If the interface is changed so that the versioned classes return the Schema.DescribeSObjectResult.fields.getMap() directly then it should be possible to see the results specific to the API version.

public interface DescribeFieldsApiVersioned {
    Map<String, Schema.DescribeFieldResult> getFields(Schema.sObjectType sObjectType);
}

If you want to make a deluxe version you could pass in the class name where you want to make the call from. Then use that to lookup the ApexClass.ApiVersion. Have a factory class the creates the correct DescribeApiVersioned implementer for that API version.

added 269 characters in body
Source Link
Daniel Ballinger
  • 103k
  • 40
  • 275
  • 601

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.


If you want to make a deluxe version you could pass in the class name where you want to make the call from. Then use that to lookup the ApexClass.ApiVersion. Have a factory class the creates the correct DescribeApiVersioned implementer for that API version.

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.


If you want to make a deluxe version you could pass in the class name where you want to make the call from. Then use that to lookup the ApexClass.ApiVersion. Have a factory class the creates the correct DescribeApiVersioned implementer for that API version.

Source Link
Daniel Ballinger
  • 103k
  • 40
  • 275
  • 601

Crazy idea... Create a collection of Apex classes. One for every API version you are interested in getting metadata for. The sole purpose of that class is to call Schema.sObjectType.getDescribe() and return the result.

Very rough prototype:

public interface DescribeApiVersioned {
    Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType);   
}

public class DescribeApiVersioned42 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v42 = sObjectType.getDescribe();
        System.debug('Number of fields v42 : ' + v42.fields.getMap().size());
        return v42;
    }
}

public class DescribeApiVersioned38 implements DescribeApiVersioned {
    public Schema.DescribeSObjectResult getDescribe(Schema.sObjectType sObjectType) {
        Schema.DescribeSObjectResult v38 = sObjectType.getDescribe();
        System.debug('Number of fields v38 : ' + v38.fields.getMap().size());
        return v38;
    }
}

Then testing it with anonymous Apex from v42.0:

Schema.sObjectType t = ContentDocument.sObjectType;
DescribeApiVersioned v42 = new DescribeApiVersioned42();
DescribeApiVersioned v38 = new DescribeApiVersioned38();

Schema.DescribeSObjectResult cd42 = v42.getDescribe(t);
Schema.DescribeSObjectResult cd38 = v38.getDescribe(t);

System.debug('v42: ' + cd42.fields.getMap().size());
System.debug('v38: ' + cd38.fields.getMap().size());

Result:

13:08:15.2 (11189280)|USER_DEBUG|[4]|DEBUG|Number of fields v42 : 25
13:08:15.2 (11935260)|USER_DEBUG|[4]|DEBUG|Number of fields v38 : 24
13:08:15.2 (12562021)|USER_DEBUG|[8]|DEBUG|v42: 25
13:08:15.2 (12749702)|USER_DEBUG|[9]|DEBUG|v38: 25

Well dang. The v38.0 bounced back to 25 in the anonymous Apex. It appears Schema.DescribeSObjectResult alters its results depending on the API version of the class interacting with it. Not the API version of the class where it was called. All is not lost though. You would just need to push the code that builds the field set up from the describe results into the versioned class.