- Notifications
You must be signed in to change notification settings - Fork12
Golang tag library to generate SOQL queries
License
forcedotcom/go-soql
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This package supports marshalling a golang struct into SOQL. Likejson
tags, this package providessoql
tags that you can use to annotate your golang structs. Once taggedMarshal
method will return SOQL query that will let you query the required Salesforce object using Salesforce API.
Please refer tointroduction to understand the basics. This blogpost also captures basics in little more detail.
Once you read through it you can refer to documentation below that covers features of this repo in more depth.
Start with usingsoql
tags on members of your golang structs.soql
is the main tag. There are following subtags supported:
selectClause // is the tag to be used when marking the struct to be considered for select clause in soql. whereClause // is the tag to be used when marking the struct to be considered for where clause in soql. orderByClause // is the tag to be used when marking the Order slice to be considered for order by clause in soql. limitClause // is the tag to be used when marking the *int to be considered for limit clause in soql. offsetClause // is the tag to be used when marking the *int to be considered for offset clause in soql. selectColumn // is the tag to be used for selecting a column in select clause. It should be used on members of struct that have been tagged with selectClause. selectChild // is the tag to be used when selecting from child tables. It should be used on members of struct that have been tagged with selectClause. likeOperator // is the tag to be used for "like" operator in where clause. It should be used on members of struct that have been tagged with whereClause. notLikeOperator // is the tag to be used for "not like" operator in where clause. It should be used on members of struct that have been tagged with whereClause. inOperator // is the tag to be used for "in" operator in where clause. It should be used on members of struct that have been tagged with whereClause. notInOperator // is the tag to be used for "not in" operator in where clause. It should be used on members of struct that have been tagged with whereClause. equalsOperator // is the tag to be used for "=" operator in where clause. It should be used on members of struct that have been tagged with whereClause. notEqualsOperator // is the tag to be used for "!=" operator in where clause. It should be used on members of struct that have been tagged with whereClause. nullOperator // is the tag to be used for " = null " or "!= null" operator in where clause. It should be used on members of struct that have been tagged with whereClause. greaterThanOperator // is the tag to be used for ">" operator in where clause. It should be used on members of struct that have been tagged with whereClause. lessThanOperator // is the tag to be used for "<" operator in where clause. It should be used on members of struct that have been tagged with whereClause. greaterThanOrEqualsToOperator // is the tag to be used for ">=" operator in where clause. It should be used on members of struct that have been tagged with whereClause. lessThanOrEqualsToOperator // is the tag to be used for "<=" operator in where clause. It should be used on members of struct that have been tagged with whereClause. greaterNextNDaysOperator // is the tag to be used for "> NEXT_N_DAYS:n" operator in where clause greaterOrEqualNextNDaysOperator // is the tag to be used for ">= NEXT_N_DAYS:n" operator in where clause equalsNextNDaysOperator // is the tag to be used for "= NEXT_N_DAYS:n" operator in where clause lessNextNDaysOperator // is the tag to be used for "< NEXT_N_DAYS:n" operator in where clause lessOrEqualNextNDaysOperator // is the tag to be used for "<= NEXT_N_DAYS:n" operator in where clause greaterLastNDaysOperator // is the tag to be used for "> LAST_N_DAYS:n" operator in where clause greaterOrEqualLastNDaysOperator // is the tag to be used for ">= LAST_N_DAYS:n" operator in where clause equalsLastNDaysOperator // is the tag to be used for "= LAST_N_DAYS:n" operator in where clause lessLastNDaysOperator // is the tag to be used for "< LAST_N_DAYS:n" operator in where clause lessOrEqualLastNDaysOperator // is the tag to be used for "<= LAST_N_DAYS:n" operator in where clause
Following are supported parameters:
fieldName // is the parameter to be used to specify the name of the field in underlying Salesforce object. It can be used with all tags listed above other than selectClause and whereClause. tableName // is the parameter to be used to specify the name of the table of underlying Salesforce Object. It can be be used only with selectClause.
IffieldName
andtableName
parameters are not provided then the name of the field will be used as default.
Lets take a look at one example of a simple non-nested struct and how it can be used to construct a soql query:
type TestSoqlStruct struct {SelectClause NonNestedStruct `soql:"selectClause,tableName=SM_SomeObject__c"`WhereClause TestQueryCriteria `soql:"whereClause"`OrderByClause []Order `soql:"orderByClause"`LimitClause *int `soql:"limitClause"`OffsetClause *int `soql:"offsetClause"`}type TestQueryCriteria struct {IncludeNamePattern []string `soql:"likeOperator,fieldName=Name__c"`Roles []string `soql:"inOperator,fieldName=Role__c"`}type NonNestedStruct struct {Name string `soql:"selectColumn,fieldName=Name__c"`SomeValue string `soql:"selectColumn,fieldName=SomeValue__c"`}
To use above structs to create SOQL query
limit := 5offset := 10soqlStruct := TestSoqlStruct{ WhereClause: TestQueryCriteria { IncludeNamePattern: []string{"foo", "bar"}, Roles: []string{"admin", "user"}, }, OrderByClause: []Order{Order{Field:"Name", IsDesc:true}}, LimitClause: &limit, OffsetClause: &offset,}soqlQuery, err := Marshal(soqlStruct)if err != nil { fmt.Printf("Error in marshaling: %s\n", err.Error())}fmt.Println(soqlQuery)
Above struct will result in following SOQL query:
SELECT Name__c,SomeValue__c FROM SM_SomeObject__C WHERE (Name__c LIKE '%foo%' OR Name__c LIKE '%bar%') AND Role__c IN ('admin','user') ORDER BY Name__c DESC LIMIT 5 OFFSET 10
This package supports child to parent as well as parent to child relationships. Here's a more complex example that includes both the relationships and how the soql query is marshalled:
type ComplexSoqlStruct struct {SelectClause ParentStruct `soql:"selectClause,tableName=SM_Parent__c"`WhereClause QueryCriteria `soql:"whereClause"`}type QueryCriteria struct {IncludeNamePattern []string `soql:"likeOperator,fieldName=Name__c"`Roles []string `soql:"inOperator,fieldName=Role__r.Name"`ExcludeNamePattern []string `soql:"notLikeOperator,fieldName=Name__c"`SomeType string `soql:"equalsOperator,fieldName=Some_Parent__r.Some_Type__c"`Status string `soql:"notEqualsOperator,fieldName=Status__c"`AllowNullValue *bool `soql:"nullOperator,fieldName=Value__c"`}type ParentStruct struct {ID string `soql:"selectColumn,fieldName=Id"`Name string `soql:"selectColumn,fieldName=Name__c"`NonNestedStruct NonNestedStruct `soql:"selectColumn,fieldName=NonNestedStruct__r"` // child to parent relationshipChildStruct TestChildStruct `soql:"selectChild,fieldName=Child__r"` // parent to child relationshipSomeNonSoqlMember string `json:"some_nonsoql_member"`}type NonNestedStruct struct {Name string `soql:"selectColumn,fieldName=Name"`SomeValue string `soql:"selectColumn,fieldName=SomeValue__c"`NonSoqlStruct NonSoqlStruct}type NonSoqlStruct struct {Key stringValue string}type TestChildStruct struct {SelectClause ChildStruct `soql:"selectClause,tableName=SM_Child__c"`WhereClause ChildQueryCriteria `soql:"whereClause"`}type ChildStruct struct {Version string `soql:"selectColumn,fieldName=Version__c"`}type ChildQueryCriteria struct {Name string `soql:"equalsOperator,fieldName=Name__c"`}allowNull := falsesoqlStruct := ComplexSoqlStruct{ SelectClause: ParentStruct{ ChildStruct: TestChildStruct{ WhereClause: ChildQueryCriteria{ Name: "some-name", }, }, }, WhereClause: QueryCriteria{ SomeType: "typeA", IncludeNamePattern: []string{"-foo", "-bar"}, Roles: []string{"admin", "user"}, ExcludeNamePattern: []string{"-far", "-baz"}, Status: "InActive", AllowNullValue: &allowNull, },}soqlQuery, err := soql.Marshal(soqlStruct)if err != nil { fmt.Printf("Error in marshalling: %s\n", err.Error())}fmt.Println(soqlQuery)
Above struct will result in following SOQL query:
SELECT Id,Name__c,NonNestedStruct__r.Name,NonNestedStruct__r.SomeValue__c,(SELECT SM_Child__c.Version__c FROM Child__r WHERE SM_Child__c.Name__c = 'some-name') FROM SM_Parent__c WHERE (Name__c LIKE '%-foo%' OR Name__c LIKE '%-bar%') AND Role__r.Name IN ('admin','user') AND ((NOT Name__c LIKE '%-far%') AND (NOT Name__c LIKE '%-baz%')) AND Some_Parent__r.Some_Type__c = 'typeA' AND Status__c != 'InActive' AND Value__c != null
You can find detailed usage inmarshaller_test.go
.
This package supports nested conditions withinWHERE
clauses as well. For example:
typecontactstruct {Namestring`soql:"selectColumn,fieldName=Name" json:"Name"`Emailstring`soql:"selectColumn,fieldName=Email" json:"Email"`Phonestring`soql:"selectColumn,fieldName=Phone" json:"Phone"`}typesoqlQuerystruct {SelectClausecontact`soql:"selectClause,tableName=Contact"`WhereClausequeryCriteria`soql:"whereClause"`}typequeryCriteriastruct {PositionpositionCriteria`soql:"subquery,joiner=OR"`ContactablecontactableCriteria`soql:"subquery,joiner=OR"`AlreadyContactedalreadyContactedSoqlQuery`soql:"subquery,joiner=NOT IN,fieldName=Name"`}typepositionCriteriastruct {Titlestring`soql:"equalsOperator,fieldName=Title"`DepartmentManagerdeptManagerCriteria`soql:"subquery"`}typedeptManagerCriteriastruct {Departmentstring`soql:"equalsOperator,fieldName=Department"`Title []string`soql:"likeOperator,fieldName=Title"`}typecontactableCriteriastruct {EmailOKemailCheck`soql:"subquery,joiner=and"`PhoneOKphoneCheck`soql:"subquery,joiner=and"`}typeemailCheckstruct {Emailbool`soql:"nullOperator,fieldName=Email"`EmailOptedOutbool`soql:"equalsOperator,fieldName=HasOptedOutOfEmail"`}typephoneCheckstruct {Phonebool`soql:"nullOperator,fieldName=Phone"`DoNotCallbool`soql:"equalsOperator,fieldName=DoNotCall"`}typealreadyContactedSoqlQuerystruct {SelectClausealreadyContacted`soql:"selectClause,tableName=Calls"`WhereClausealreadyContactedCriteria`soql:"whereClause"`}typealreadyContactedstruct {Namestring`soql:"selectColumn,fieldName=Name"`}typealreadyContactedCriteriastruct {IsContactedbool`soql:"equalsOperator,fieldName=IsContacted"`}soqlStruct:=soqlQuery{WhereClause:queryCriteria{Position:positionCriteria{Title:"Purchasing Manager",DepartmentManager:deptManagerCriteria{Department:"Accounting",Title: []string{"Manager"}, }, },Contactable:contactableCriteria{EmailOK:emailCheck{Email:false,EmailOptedOut:false, },PhoneOK:phoneCheck{Phone:false,DoNotCall:false, }, },AlreadyContacted:alreadyContactedSoqlQuery{WhereClause:alreadyContactedCriteria{IsContacted:true, } } },}query,err:=soql.Marshal(soqlStruct)iferr!=nil {fmt.Printf("Error in marshalling: %s\n",err.Error())}fmt.Println(soqlQuery)
The above code will generate this SOQL query:
SELECT Name,Email,PhoneFROM ContactWHERE (Title='Purchasing Manager'OR (Department='Accounting'AND TitleLIKE'%Manager%'))AND ((Email!=nullAND HasOptedOutOfEmail= false)OR (Phone!=nullAND DoNotCall= false))AND Name NOTIN (SELECT NameFROM CallsWHERE IsContacted= true)
Intended users of this package are developers writing clients to interact with Salesforce. They can now define golang structs, annotate them and generate SOQL queries to be passed to Salesforce API. Great thing about this is that the json structure of returned response matches with selectClause, so you can just unmarshal response into the golang struct that was annotated withselectClause
and now you have your query response directly available in golang struct.
This section explains each of the supported tags in detail
This section explains top level tags used in constructing SOQL query. Following snippet will be used as example for explaining these tags:
type TestSoqlStruct struct { SelectClause NonNestedStruct `soql:"selectClause,tableName=SM_SomeObject__c"` WhereClause TestQueryCriteria `soql:"whereClause"`}type TestQueryCriteria struct { IncludeNamePattern []string `soql:"likeOperator,fieldName=Name__c"` Roles []string `soql:"inOperator,fieldName=Role__c"`}type NonNestedStruct struct { Name string `soql:"selectColumn,fieldName=Name__c"` SomeValue string `soql:"selectColumn,fieldName=SomeValue__c"`}
selectClause
: This tag is used on the struct which should be considered for generating part of SOQL query that contains columns/fields that should be selected. It should be used only onstruct
type. If used on types other thanstruct
thenErrInvalidTag
error will be returned. This tag is associated withtableName
parameter. It specifies the name of the table (Salesforce object) from which the columns should be selected. If not specified name of the field is used as table name (Salesforce object). In the snippet aboveSelectClause
member ofTestSoqlStruct
is tagged withselectClause
to indicate that members inNonNestedStruct
should be considered as fields to be selected from Salesforce objectSM_SomeObject__c
.whereClause
: This tag is used on the struct which encapsulates the query criteria for SOQL query. There is an optional parameterjoiner
for this tag. In the snippet aboveWhereClause
member ofTestSoqlStruct
is tagged withwhereClause
to indicate that members inTestQueryCriteria
should be considered for generatingWHERE
clause in SOQL query. If there are more than one field inTestQueryCriteria
struct then they will be combined usingAND
logical operator. If thejoiner
parameter is set toor
(case insensitive), then the fields will be combined usingOR
logical operator. If thejoiner
parameter is set toand
(case insensitive) or is not set, then the fields will be combined usingAND
logical operator. If any other value is provided, thenErrInvalidTag
error will be returned. Thejoiner
parameter is only supported when usingMarshal
; when callingMarshalWhereClause
, the fields will always be combined with theAND
logical operator.orderByClause
: This tag is used on the slice ofOrder
to capture the ordering of columns and sort order. There are no parameters for this tag. Clients using this library can exposeOrder
struct from this library to their users if they wish to allow users of the client to control ordering of the result.limitClause
: This tag is used on the *int that describes the limit value for SOQL query. There are no parameters for this tag. Passingnil
here will omit theLIMIT
clause from the generated query. Passing a pointer to an integer value less than zero will cause an error.offsetClause
: This tag is used on the *int that describes the offset value for SOQL query. There are no parameters for this tag. Passingnil
here will omit theOFFSET
clause from the generated query. Passing a pointer to an integer value less than zero will cause an error.
This section explains the tags that should be used on members of struct tagged withselectClause
andwhereClause
. These tags indicate how the members of the struct should be used in generatingSELECT
andWHERE
clause.
This section explains the list of tags that can be used on members tagged withselectClause
. Following snippet will be used explaining these tags:
type ParentStruct struct {ID string `soql:"selectColumn,fieldName=Id"`Name string `soql:"selectColumn,fieldName=Name__c"`NonNestedStruct NonNestedStruct `soql:"selectColumn,fieldName=NonNestedStruct__r"` // child to parent relationshipChildStruct TestChildStruct `soql:"selectChild,fieldName=Child__r"` // parent to child relationshipSomeNonSoqlMember string `json:"some_nonsoql_member"`}type NonNestedStruct struct {Name string `soql:"selectColumn,fieldName=Name"`SomeValue string `soql:"selectColumn,fieldName=SomeValue__c"`NonSoqlStruct NonSoqlStruct}type TestChildStruct struct {SelectClause ChildStruct `soql:"selectClause,tableName=SM_Child__c"`WhereClause ChildQueryCriteria `soql:"whereClause"`}
selectColumn
: Members that are tagged with this tag will be considered in generating select clause of SOQL query. This tag is associated withfieldName
parameter. It specifies the name of the field of underlying Salesforce object. If not specified the name of the field is used as underlying Salesforce object field name. This tag can be used on primitive data types as well as user defined structs. If used on user defined structs likeNonNestedStruct
member inParentStruct
it will be treated as child to parent relationship and the value specified infieldName
parameter (or default value of name of the member itself) will be prefixed to the members of that struct (NonNestedStruct
in case of our example above).selectChild
: This tag is used on members which should be modelled as parent to child relation. It should be used onstruct
type only. If used on any other type thenErrInvalidTag
error will be returned. The member on which this tag is used should in turn consist of members tagged withselectClause
andwhereClause
. Please refer toChildStruct
member ofParentStruct
.
This section explains the list of tags that can be used on members tagged withwhereClause
. Following snippet will be used as example for explaining these tags:
type QueryCriteria struct {IncludeNamePattern []string `soql:"likeOperator,fieldName=Name__c"`ExcludeNamePattern []string `soql:"notLikeOperator,fieldName=Name__c"`Roles []string `soql:"inOperator,fieldName=Role__r.Name"`SomeType string `soql:"equalsOperator,fieldName=Some_Type__c"`SomeBoolType *bool `soql:"equalsOperator,fieldName=Some_Bool_Type__c"`Status string `soql:"notEqualsOperator,fieldName=Status__c"`AllowNullValue *bool `soql:"nullOperator,fieldName=Value__c"`NumOfCPUCores int `soql:"greaterThanOperator,fieldName=Num_of_CPU_Cores__c"`PhysicalCPUCount uint8 `soql:"greaterThanOrEqualsToOperator,fieldName=Physical_CPU_Count__c"`AllocationLatency float64 `soql:"lessThanOperator,fieldName=Allocation_Latency__c"`PvtTestFailCount int64 `soql:"lessThanOrEqualsToOperator,fieldName=Pvt_Test_Fail_Count__c"` UpdateDate time.Time `soql:"equalsOperator,fieldName=UpdateDate,format=2006-01-02"` Subquery sub `soql:"subquery"`}type sub struct { NumOfCPUCores int `soql:"lessThanOperator,fieldName=Num_of_CPU_Cores__c"`PhysicalCPUCount uint8 `soql:"lessThanOrEqualsToOperator,fieldName=Physical_CPU_Count__c"`}
likeOperator
: This tag is used on members which should be considered to construct field expressions in where clause usingLIKE
comparison operator. This tag should be used on member of type[]string
. Used on any other type,ErrInvalidTag
error will be returned. If there are more than one item in the slice then they will be combined usingOR
logical operator. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ IncludeNamePattern: []string{"-foo", "-bar"},})// whereClause will be: WHERE (Name__c LIKE '%-foo%' OR Name__c LIKE '%-bar%')
notLikeOperator
: This tag is used on members which should be considered to construct field expressions in where clause usingNOT LIKE
comparison operator. This tag should be used on member of type[]string
. Used on any other type,ErrInvalidTag
error will be returned. If there are more than one item in the slice then they will be combined usingAND
logical operator. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ ExcludeNamePattern: []string{"-far", "-baz"},})// whereClause will be: WHERE ((NOT Name__c LIKE '%-far%') AND (NOT Name__c LIKE '%-baz%'))
inOperator
: This tag is used on members which should be considered to construct field expressions in where clause usingIN
comparison operator. This tag should be used on member of type[]string
,[]int
,[]int8
,[]int16
,[]int32
,[]int64
,[]uint
,[]uint8
,[]uint16
,[]uint32
,[]uint64
,[]float32
,[]float64
,[]bool
or[]time.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ Roles: []string{"admin", "user"},})// whereClause will be: WHERE Role__r.Name IN ('admin','user')
notInOperator
: This tag is used on members which should be considered to construct field expressions in where clause usingNOT IN
comparison operator. This tag should be used on member of type[]string
,[]int
,[]int8
,[]int16
,[]int32
,[]int64
,[]uint
,[]uint8
,[]uint16
,[]uint32
,[]uint64
,[]float32
,[]float64
,[]bool
or[]time.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ ExcludeIDs: []string{"123", "456"},})// whereClause will be: WHERE Id NOT IN ('123','456')
equalsOperator
: This tag is used on members which should be considered to construct field expressions in where clause using=
comparison operator. This tag should be used on member of typestring
,int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,float32
,float64
,bool
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
,*float32
,*float64
,*bool
ortime.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ SomeType: "SomeValue",})// whereClause will be: WHERE Some_Type__c = 'SomeValue'
If pointers are used as data type then the field will be included in WHERE clause only if the variable is initialized. So in case below it will be included because the variable is initialized unlike example above.
b := truewhereClause, _ := MarshalWhereClause(QueryCriteria{ SomeType: "SomeValue", SomeBoolType: &b,})// whereClause will be: WHERE Some_Type__c = 'SomeValue' AND Some_Bool_Type__c = true
notEqualsOperator
: This tag is used on members which should be considered to construct field expressions in where clause using!=
comparison operator. This tag should be used on member of typestring
,int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,float32
,float64
,bool
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
,*float32
,*float64
,*bool
ortime.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ Status: "DOWN",})// whereClause will be: WHERE Status__c != 'DOWN'
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
nullOperator
: This tag is used on members which should be considered to construct field expressions in where clause using= null
or!= null
comparison operator. This tag should be used on member of type*bool
orbool
. Used on any other type,ErrInvalidTag
error will be returned. Recommended to use*bool
asbool
will always be initialized by golang tofalse
and will result in!= null
check even if not intended. Example will clarify this more:allowNull := truewhereClause, _ := MarshalWhereClause(QueryCriteria{ AllowNullValue: &allowNull,})// whereClause will be: WHERE Value__c = nullallowNull = falsewhereClause, _ := MarshalWhereClause(QueryCriteria{ AllowNullValue: &allowNull,})// whereClause will be: WHERE Value__c != null
greaterThanOperator
: This tag is used on members which should be considered to construct field expressions in where clause using>
comparison operator. This tag should be used on member of typestring
,int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,float32
,float64
,bool
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
,*float32
,*float64
,*bool
ortime.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ NumOfCPUCores: 8,})// whereClause will be: WHERE Num_of_CPU_Cores__c > 8
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
greaterThanOrEqualsToOperator
: This tag is used on members which should be considered to construct field expressions in where clause using>=
comparison operator. This tag should be used on member of typestring
,int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,float32
,float64
,bool
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
,*float32
,*float64
,*bool
ortime.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ PhysicalCPUCount: 4,})// whereClause will be: WHERE Physical_CPU_Count__c >= 4
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
lessThanOperator
: This tag is used on members which should be considered to construct field expressions in where clause using<
comparison operator. This tag should be used on member of typestring
,int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,float32
,float64
,bool
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
,*float32
,*float64
,*bool
ortime.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ AllocationLatency: 28.9,})// whereClause will be: WHERE Allocation_Latency__c < 28.9
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
lessThanOrEqualsToOperator
: This tag is used on members which should be considered to construct field expressions in where clause using<=
comparison operator. This tag should be used on member of typestring
,int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,float32
,float64
,bool
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
,*float32
,*float64
,*bool
ortime.Time
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ PvtTestFailCount: 32,})// whereClause will be: WHERE Pvt_Test_Fail_Count__c <= 32
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
greaterNextNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using>
comparison operator andNEXT_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate > NEXT_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
greaterOrEqualNextNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using>=
comparison operator andNEXT_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate >= NEXT_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
equalsNextNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using=
comparison operator andNEXT_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate = NEXT_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
lessNextNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using<
comparison operator andNEXT_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate < NEXT_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
lessOrEqualNextNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using<=
comparison operator andNEXT_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate <= NEXT_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
greaterLastNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using>
comparison operator andLAST_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate > LAST_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
greaterOrEqualLastNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using>=
comparison operator andLAST_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate >= LAST_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
equalsLastNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using=
comparison operator andLAST_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate = LAST_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
lessLastNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using<
comparison operator andLAST_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate < LAST_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
lessOrEqualLastNDaysOperator
: This tag is used on members which should be considered to field expressions in where clause using<=
comparison operator andLAST_N_DAYS
date literal. This tag should be used on member of typeint
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,*int
,*int8
,*int16
,*int32
,*int64
,*uint
,*uint8
,*uint16
,*uint32
,*uint64
. Used on any other type,ErrInvalidTag
error will be returned. Example will clarify this more:whereClause, _ := MarshalWhereClause(QueryCriteria{ CreatedDate: 5,})// whereClause will be: WHERE CreatedDate <= LAST_N_DAYS:5
Fields that are pointers will only be included if they are initialized else they will be skipped from WHERE clause.
If there are more than one fields in the struct tagged withwhereClause
then they will be combined usingAND
logical operator. This has been demonstrated in the code snippets inAdvanced usage.
subquery
: This tag is used on members which should be used to construct related sets of conditions wrapped in()
in the query. This tag should only be used on members of typestruct
. Used on any other type,ErrInvalidTag
error will be returned. Any of the above property tags (includingsubquery
) may be used in the designatedstruct
.
The following tag can be included for modifying the marshalling behavior:
format
: This tag can be included to specify the formatting oftime.Time
and*time.Time
fields when marshalled to aquery. If omitted, the default format "2006-01-02T15:04:05.000-0700" is used. A format of "2006-01-02" can be used whenforming a soql query against a Date type.whereClause, _ := MarshalWehereClause(QueryCriteria{ UpdateDate: time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC),})// whereClause will be: WHERE UpdateDate = 2009-11-17
This section explains the Order struct to be used for theorderByClause
.
type Order struct {Field stringIsDesc bool}
TheOrder
struct is part of this library and has two fields,Field
which is of type string andIsDesc
of type bool. Each struct represents a column from the select column list that should be included in theORDER BY
clause, as well as the sort order on that column. The value ofField
should be the name of the struct field with theselectColumn
tag, and setIsDesc
totrue
to specify the sort order on that column asDESC
(set it tofalse
forASC
). Create a slice ofOrder
structs and tag it with theorderByClause
soql tag to define theORDER BY
clause. Using the followingNestedStruct
as an example of theselectClause
:
type NonNestedStruct struct {Name string `soql:"selectColumn,fieldName=Name"`SomeValue string `soql:"selectColumn,fieldName=SomeValue__c"`NonSoqlStruct NonSoqlStruct}type NestedStruct struct {ID string `soql:"selectColumn,fieldName=Id"`Name string `soql:"selectColumn,fieldName=Name__c"`NonNestedStruct NonNestedStruct `soql:"selectColumn,fieldName=NonNestedStruct__r"`}
To order the query results using theName__c
field of the NestedStruct inASC
order andSomeValue__c
of theNonNestedStruct
field inDESC
order, the followingOrder
slice should be used:
order := []Order{Order{Field:"Name",IsDesc:false},Order{Field:"NonNestedStruct.SomeValue",IsDesc:true}}
To specify fields in nested structs, use the<parent>.<field>
dot notation.
The final soql query struct would look like:
type TestSoqlStruct struct { SelectClause NestedStruct `soql:"selectClause,tableName=SM_SomeObject__c"` OrderByClause []Order `soql:"orderByClause"`}
go-soql is BSD3 licensed. Here is the link to licensefile
You are welcome to contribute to this repo. Please create PR and send it for review. Please follow code of conduct as documentedhere
If you have a question, comment, bug report, feature request, etc. please open a GitHub issue.