Can i create a sql table populated with Salesforce objects? - salesforce

does Salesforce offer a way to obtain all Objects like Account, Contact etc and populate them in a SQL table with certain columns like
ObjectEntity, FieldName , FieldType ?

I'm pretty sure the only way to achieve this would be by using the Schema.sObjectType and Schema.sObjectField. Here is a link to the documentation for getting all sObjects. You will basically call the Schema.getGlobalDescribe() method which will return you a map of sObjectTypes with their sObject name as the key. Then you'll need to call getDesribe() on each sObjectType get the fields of the object from that Describe result. You'll again need to call getDescribe() on each sObjectField in order to have access to the columns you wanted (eg. FieldType). Here is the documentation on that You could save each DescribeFieldResult into a list that goes into a Map of > with the sObject name as the key, then you could do what you want with them... Put them in a table if you like. Keep in mind this is all going to be very expensive when it comes to CPU time. You may even run into some governor limits.
Here is a little example you can run using Execute Anonymous in the developer console where the sObject Name and all its field names and types are printed to the debug logs
Map<String, sObjectType> objects = Schema.getGlobalDescribe();
for(String objName : objects.keySet()){
system.debug('=======' + objName + '=========\n Fields: ');
sObjectType o = objects.get(objName);
DescribeSobjectResult oDRes = o.getDescribe();
Map<String, Schema.SObjectField> fields = dResult.fields.getMap();
for(Schema.SObjectField f : fields.values()){
DescribeFieldResult fDRes = f.getDescribe();
system.debug('name: ' + fDRes.getName() + ' | type: ' + fDRes.getType());
}
}
Hope this helps

Related

How to ignore null or empty values while using find() in Spring MongoRepository

I have a search functionality where there are different parameters and user can choose one or multiple parameters and ignore other parameters.
I want to use findByFirstNameAndLastNameAndAddressAndCountry() for this so that if any parameter is null or empty it can be ignored and the And condition get applied to other parameters
This can be a duplicate issue. You can do it using #Query annotation and your custom Query.
Ref: How to skip #Param in #Query if is null or empty in Spring Data JPA
#Query("select foo from Foo foo where foo.bar = :bar and "
+ "(:goo is null or foo.goo = :goo)")
public List<Foo> findByBarAndOptionalGoo(
#Param("bar") Bar bar,
#Param("goo") Optional<Goo> goo);
Use 'Query' and 'Criteria' option provided by Spring for MongoDB.
Query query = new Query();
if(!obj.getFirstName.isEmpty()){
Criteria criteria1 = Criteria.where('first_name').is(obj.getFirstName);
query.add(criteria1);
}

Using wildcards for column names in dynamic soql in apex

I have a scenario where my columns names can be of type genesis__prod__c/docgen__prod__c/lnd__prod__c,etc depending upon which package is using my solution package. Here genesis,docgen and are different product packages using my solution.
My solution needs to fetch any of these(genesis__prod__c/docgen__prod__c/lnd__prod__c) fields from there respective sObjects in there products.
I want to construct a generic query which will omit the namespace using a wildcard and only look for prod__c in specified sObject. With this, I don't have to hardcode any namespace in my query.
for eg., I don't want to form my query like this
String query = 'select Id,Name,docgen__CL_Product__c from '+ sObjectType + ' where id= \'' + appId + '\'';
List<sObject> runtimeDeterminedObject = Database.query(query+' LIMIT 1');
Here I have specifically mentioned docgen__CL_Product__c name to be fetched from a runtime resolved sObject name sObjectType w.r.t an appId
How can I form a query where I do not have to provide namespace docgen,genesis before prod__c. I do not want to write if-else for each product which can utilize my package.
Why don't you make the namespace a variable that gets appended to the query based on some condition? Not exactly what you're looking for, but I'm assuming there's some way to determine the environment and then based on that you can adjust the query dynamically:
String env = someCondition ? 'genesis__' : 'docgen__';
String query = 'select Id, Name, ' + env + 'CL_Product__c from '+ sObjectType + ' where id= \'' + appId + '\'';
List<sObject> runtimeDeterminedObject = Database.query(query+' LIMIT 1');

Filter Google Cloud Datastore entities by #id property in App Engine

I am trying to to a Query in App Engine based on the #id property of the entities and I keep getting this error
java.lang.IllegalArgumentException: __ key __ filter value must be a Key
this is how I am doing my Query
Filter f1 = new FilterPredicate("personId", FilterOperator.EQUAL,personId);
Filter f2 = new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN,newestCommentId);
Filter filter = CompositeFilterOperator.and(f1,f2);
Query<Record> query = ofy().load().type(Record.class).filter(filter)
.limit(limit).order("-"+ Entity.KEY_RESERVED_PROPERTY);
I want to get everything > the last comment id that is sent to the app engine method
the id field in the entity is this
#Id
Long id;
I tried using the id first but then I got an error saying that you cannot use a file who has #id and maybe I meant __ key __
so how do I execute this query?
You need to use a Key, not an id, in your filter. You can create a Key from this id and then pass to your filter.
Note that unless you increment IDs yourself, they are not guaranteed to grow as you add more entities.

Accessing new field value generated in SQL via dbContext

I'm using dbContext and I am running a SQL query that is rather complex (just showing a simple example below), so to avoid having to run the query twice to get a count, I am using COUNT AS to return the total number of records as per other advice on this site.
But, I haven't been able to figure out how to access the resulting property:
using (var db = new DMSContext())
{
string queryString = "select *, COUNT(1) OVER() AS TotalRecords FROM DMSMetas";
var Metas = db.DMSMetas.SqlQuery(queryString).ToList();
for (int i = 0; i <= Metas.Count - 1; i++)
{
var Item = Metas[i];
if (i == 0)
{
//Want to do this, but TotalRecords not part of the DMSMeta class. How to access the created column?
Console.WriteLine("Total records found: " + Item.TotalRecords);
}
}
}
In the sample above, the SQL query generates the extra field TotalRecords. When I run the query in Management Studio, the results are as expected. But how do I access the TotalRecords field through dbContext?
I also tried including the TotalRecords field as part of the DMSMeta class, but then the SQL query fails with the error that the TotalRecords field is specified twice. I tried creating a partial class for DMSMeta containing the TotalRecords field, but then the value remains the default value and is not updated during the query.
I also tried the following:
db.Entry(Item).Property("TotalRecords").CurrentValue
But that generated an error too. Any help would be much appreciated - I am sure I am missing something obvious! All I want is to figure out a way to access the total number of records returned by the query
you have to create a new class (not an entity class but a pure DAO class) DMSMetaWithCount (self explanatory ?) and then
context.Database.SqlQuery<DMSMetaWithCount>("select *, COUNT(1) OVER() AS TotalRecords FROM DMSMetas");
please note that
imho, select * is ALWAYS a bad practice.
you will have no tracking on the not entity new class

Salesforce SOQL describe table

Is there a way to fetch a list of all fields in a table in Salesforce? DESCRIBE myTable doesn't work, and SELECT * FROM myTable doesn't work.
From within Apex, you can get this by running the following Apex code snippet. If your table/object is named MyObject__c, then this will give you a Set of the API names of all fields on that object that you have access to (this is important --- even as a System Administrator, if certain fields on your table/object are not visible through Field Level Security to you, they will not show up here):
// Get a map of all fields available to you on the MyObject__c table/object
// keyed by the API name of each field
Map<String,Schema.SObjectField> myObjectFields
= MyObject__c.SObjectType.getDescribe().fields.getMap();
// Get a Set of the field names
Set<String> myObjectFieldAPINames = myObjectFields.keyset();
// Print out the names to the debug log
String allFields = 'ALL ACCESSIBLE FIELDS on MyObject__c:\n\n';
for (String s : myObjectFieldAPINames) {
allFields += s + '\n';
}
System.debug(allFields);
To finish this off, and achieve SELECT * FROM MYTABLE functionality, you would need to construct a dynamic SOQL query using these fields:
List<String> fieldsList = new List<String>(myObjectFieldAPINames);
String query = 'SELECT ';
// Add in all but the last field, comma-separated
for (Integer i = 0; i < fieldsList.size()-1; i++) {
query += fieldsList + ',';
}
// Add in the final field
query += fieldsList[fieldsList.size()-1];
// Complete the query
query += ' FROM MyCustomObject__c';
// Perform the query (perform the SELECT *)
List<SObject> results = Database.query(query);
the describeSObject API call returns all the metadata about a given object/table including its fields. Its available in the SOAP, REST & Apex APIs.
Try using Schema.FieldSet
Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();
Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();
complete documentation
Have you tried DESC myTable?
For me it works fine, it's also in the underlying tips in italic. Look:

Resources