Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Build dynamic SOQL queries In Apex/JSON

License

NotificationsYou must be signed in to change notification settings

mjyocca/apex-query

Repository files navigation

Build dynamic SOQL queries in Apex/JSON

Main Objectives

  • Build dynamic queries in Apex
  • Build dynamic queries in Javascript (that can be deserialized/mapped server side)
  • Ability to Mock Queries in Apex Testing
    • Helps with Apex Testing w/ out the need to commiting data to the database
  • Security First: CRUD | FLS | SOQL Injection Protection
    • CRUD/FLS ~WITH SECURITY_ENFORCED &Security.stripInaccessible

Current Unsupported Features

  • SOSL
  • Aggregate
  • TYPEOF
  • HAVING
  • FOR REFERENCE
  • FOR VIEW
  • FOR UPDATE

Examples

Testing

Can either pass in aList<SObject> or a class that extendsQueryMock class.

@isTestprivateclassSomeTest {privatestatictestMethodtestProcess() {List<Account>dummy =newList<Account>();for(Integeri =0;i <10;i++) {dummy.add(newAccount(Name='Test ' +i));        }Query.setMock(dummy);Test.startTest();            ...// assert test methodsTest.stopTest();    }}

Options

  • securityEnforced: AddsWITH SECURITY_ENFORCED to the query

    • Default: TRUE
  • stripInaccessible: Uses the built in stripInaccessible method based on the AccessType defined, after the query has run

    • Default: FALSE
  • flsAccess: AccessType Enum

    • Default: null
List<sObject>res =newQuery(newQuery.Options(false,// securityEnforcedtrue,// stripInaccessibleAccessType.READABLE    ))    .fromSObject('Contact')    .fields(newList<String>{'Id','Name'})    .run();

Basic

List<sObject>res =newQuery()    .fromSObject('Account')    .fields(newList<String>{'Id','Name'})    .run();

IN, NOT IN collection variables

Supports:

  • Map<Id, sObject>
  • List<sObject>
  • List<String>
  • List<Object>
  • Set<String>
  • Set<Id>
  • Set<Decimal>
List<String>recordIds =newList<String>{'001J000002Yzs4CIAR','001J000002Yzs4DIAR'};List<sObject>res =newQuery()    .fromSObject('Account')    .fields(newSet<String>{'Id','Name'})    .whereFilter('ID','IN',recordIds)    .run();
Map<Id,sObject>accts =newMap<Id,sObject>([SELECTIDFROMAccount]);List<sObject>res =newQuery()    .fromSObject('Account')    .fields(newList<String>{'Id','Name' })    .whereFilter('ID','IN',accts)    .limitRows(200)    .run();

toString Bind Variable Example

*If your collection variable is longer than 20 items, and wish to get the compiled query string, make sure to make use of thenew Query.bind(':varName').

Map<Id,sObject>accts =newMap<Id,sObject>([SELECTIDFROMAccount]);// variable name declared hereSet<Id>acctIds =accts.keySet();Queryq =newQuery()    .fromSObject('Account')    .fields(newList<String>{'Id','Name' })// is passed in here    .whereFilter('ID','IN',newQuery.bind(':acctIds'))    .limitRows(200);for(Accountsobj :Database.query(q.queryString())) {// processing here    }}

SubQuery

List<sObject>res =newQuery()    .fromSObject('Account')    .fields(newList<String>{'Id','Name'})    .subQuery('Opportunities',newList<String>{'Id','StageName'},null    )    .limitRows(200)    .run();

Cross Object Query

// optsQuery.Optionsopts =newQuery.Options(false,true,AccessType.READABLE    );// cross object filtersList<Query.Filter>contactFilters =newList<Query.Filter>();contactFilters.add(newQuery.Filter('LeadSource','=','Purchased List'));contactFilters.add(newQuery.Filter('DoNotCall','=',false));List<sObject>res =newQuery(opts)    .fromSObject('Account')    .fields(newList<String>{'Id','Name'})    .subQuery('Opportunities',newList<String>{'Id','StageName'})    .whereFilter('ID','NOT IN',newQuery.CXFilter('Contact','AccountId',contactFilters,'OR'    ))    .run();// runs/*SELECT Id, Name, (SELECT Id, StageName FROM Opportunities)FROM AccountWHERE ID NOT IN (SELECT AccountId FROM Contact WHERE LeadSource = 'Purchased List' OR DoNotCall = false)*/

Javascript

Construct dynamic queries in Javascript,

Object key/prop names are case insensitive. Should lead to less debugging and confusion.

*.js

constpayload=JSON.stringify({options:{securityEnforced:true,stringInaccessible:false,AccessType:'CREATABLE'},fields:['Id','Name'],subQueries:[{sObjectName:'Contacts',fields:['Id','Name'],condition:{filters:[{fieldName:'LeadSource',operator:'=',value:'Web'},{fieldName:'Name',operator:'=',value:'Jack Rogers'},{fieldName:'Email',operator:'!=',value:null}],logic:'(1 OR 2) AND 3'}}],sObjectName:'Account',condition:{filters:[{fieldName:'ID',operator:'IN',cxValue:{sObjectName:'Opportunity',fieldName:'AccountId',condition:{filters:[{fieldName:'StageName',operator:'=',value:'Closed Won'}]}}},{fieldName:'ID',operator:'NOT IN',cxValue:{sObjectName:'Contact',fieldName:'AccountId',condition:{filters:[{fieldName:'LeadSource',operator:'=',value:'Purchased List'},{fieldName:'DoNotCall',operator:'=',value:false}],logic:'OR'}}}],logic:'AND'},limitRows:200});/** **/visualforce.remoting.invokeAction(...,payload,(result,event)=>{..});

[ApexController].cls

publicclassApexController {@RemoteActionpublicstaticList<sObject>queryJSON(stringjsonStr) {/* Pass in json string */Queryq =newQuery().fromJSON(jsonStr);/* Can pass in Map<String, Object>        Map<String, Object> jsonMap = (Map<String, Object>)JSON.deserializeUntyped(jsonStr);        Query q = new Query().fromJSON(jsonMap);        */returnq.run();    }}

About

Build dynamic SOQL queries In Apex/JSON

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp