3

Is it possible to get a list of key prefixes for all Metadata types in Salesforce org. Not the standard objects or custom objects, but Metadata types e.g. AccountSettings, ApexPage, CustomObject etc (listed here: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_types_list.htm). Thank you!

2

You can't generally get the key prefixes of some objects (those that are not describe-able), but I've devised a workaround that actually (mosty) does just this. Here's the code:

Page

<apex:page controller="describe">
    <style>
        #output {
            display: table;
        }
        #output div {
            display: table-row;
        }
        #output div span {
            display: table-cell;
            padding: 2px;
        }
    </style>
    <script>
    var temp, parent;
    function processResults(data) {
        var index = 0, row, key, value;
        if(data) {
            while(index < data.validKeys.length) {
                row = document.createElement("div");
                key = document.createElement("span");
                value = document.createElement("span");
                key.appendChild(document.createTextNode(data.validKeys[index].key));
                value.appendChild(document.createTextNode(data.validKeys[index].value));
                row.appendChild(key);
                row.appendChild(value);
                temp.appendChild(row);
                index++;
            }
        } else {
            data = { nextValue: 0 };
        }
        if(data.nextValue!=null) {
            {!$RemoteAction.describe.getList}(data.nextValue, processResults);
        }
        if(data.nextValue==null) {
            data.nextValue = 262144;
            parent.appendChild(temp);
        }
        document.getElementById("progress").value = data.nextValue;
        row = document.getElementById("valuepercent");
        if(row.firstChild) row.removeChild(row.firstChild);
        key = parseInt(data.nextValue)/262144;
        key = Math.floor(key*10000)/100;
        row.appendChild(document.createTextNode(key+'%'));
    }
    window.addEventListener("load", function() { temp = document.getElementById("output"); parent = temp.parentNode; temp.parentNode.removeChild(temp); processResults(null); }, true);

    </script>
    <progress value="0" max="262143" id="progress"/>
    <span id="valuepercent"></span>
    <div id="output">

    </div>

</apex:page>

Controller

global class describe {
    global class KeyValuePair {
        global String key, value;
        global KeyValuePair(String k, String v) {
            key = k;
            value = v;
        }
    }
    global class Result {
        global Integer nextValue;
        global KeyValuePair[] validKeys;

        global Result() {
            validKeys = new KeyValuePair[0];
        }
    }

    @RemoteAction global static Result getList(Integer firstIndex) {
        Result result = new Result();
        String[] base62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        base62.remove(0);
        Integer a = (firstIndex & 258048) >> 12, b = (firstIndex & 4032) >> 6, c = (firstIndex & 63);
        while(Limits.getCpuTime()<1000) {
            try {
                String key = base62[a]+base62[b]+base62[c];
                Id value = Id.valueOf(key+'000000000000');
                result.validKeys.add(new KeyValuePair(key, String.valueOf(value.getSObjectType())));
            } catch(Exception e) { }
            c++;
            if(c>62) {
                b++;
                c = 0;
            }
            if(b>62) {
                a++;
                b = 0;
            }
            if(a>62) {
                result.nextValue = null;
                break;
            }
            result.nextValue = (a<<12)+(b<<6)+c;
        }
        return result;
    }
}

This code basically brute-forces every key prefix by way of Id.getSObjectType() to describe every single object in the system. It provides a very basic table that allows you to find any type of object that has a stable key prefix. It even includes some tables that I'm pretty sure we shouldn't be able to know about but have nevertheless been exposed to us.


Note: AccountSettings is a specific example of something that apparently doesn't have any key prefix at all. These are probably stored in some specific table that is a meta-table (contains a large number of settings that are all lumped into one). I would guess that the Organization table probably contains this information, but there's no documentation of how this data is organized. Other tables, like CustomObject, are actually aliased to a different type; for example, CustomObject is internally called CustomEntityDefinition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.