### Marshal SOQL Query Example Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshal.md Example demonstrating how to use the Marshal function to create a SOQL query from a Go struct. Ensure all necessary structs and tags are defined correctly. ```go package main import ( "fmt" "github.com/forcedotcom/go-soql" ) type SelectColumns struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` } type QueryCriteria struct { Status string `soql:"equalsOperator,fieldName=Status__c"` } type QueryStruct struct { SelectClause soql.SelectColumns `soql:"selectClause,tableName=Account"` WhereClause QueryCriteria `soql:"whereClause"` } func main() { limit := 10 query := QueryStruct{ SelectClause: SelectColumns{}, WhereClause: QueryCriteria{ Status: "Active", }, } soqlQuery, err := soql.Marshal(query) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println(soqlQuery) // Output: SELECT Id,Name__c FROM Account WHERE Status__c = 'Active' } ``` -------------------------------- ### SOQL Date Range Example Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Shows how to define start and end dates for filtering data within a specific range in SOQL queries. Uses the standard `time` package. ```go // Date range start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) end := time.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC) ``` -------------------------------- ### SOQL Pagination Example Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Illustrates setting LIMIT and OFFSET values for pagination in SOQL queries. These are typically integers. ```go // Pagination limit := 10 offset := 20 ``` -------------------------------- ### Example Scenario for ErrMultipleLimitClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Demonstrates a struct with duplicate limitClause tags, which triggers the ErrMultipleLimitClause error. ```go type BadQuery struct { SelectClause SelectColumns `soql:"selectClause,tableName=Account"` Limit1 *int `soql:"limitClause"` Limit2 *int `soql:"limitClause"` // WRONG: duplicate limitClause } ``` -------------------------------- ### SOQL List Membership Example Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Demonstrates how to use a slice of strings for list membership conditions (e.g., IN clause) in SOQL queries. ```go // List membership roles: []string{"admin", "user"} ``` -------------------------------- ### Example Scenario for ErrMultipleOrderByClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Demonstrates a struct with duplicate orderByClause tags, which triggers the ErrMultipleOrderByClause error. ```go type BadQuery struct { SelectClause SelectColumns `soql:"selectClause,tableName=Account"` OrderBy1 []soql.Order `soql:"orderByClause"` OrderBy2 []soql.Order `soql:"orderByClause"` // WRONG: duplicate orderByClause } ``` -------------------------------- ### Example Usage of Order Struct Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/types.md Demonstrates how to create and use `Order` structs for single, multiple, and nested field sorting in SOQL queries. Shows how to integrate `OrderByClause` into a query struct. ```go // Single field, ascending order order := soql.Order{Field: "Name", IsDesc: false} // Multiple fields in slice orders := []soql.Order{ {Field: "Department", IsDesc: false}, {Field: "Salary", IsDesc: true}, } // Nested field ordering orders := []soql.Order{ {Field: "Address.City", IsDesc: false}, } // Use in query type SoqlQuery struct { SelectClause SelectColumns `soql:"selectClause,tableName=Employee"` WhereClause QueryCriteria `soql:"whereClause"` OrderByClause []soql.Order `soql:"orderByClause"` } query := SoqlQuery{ OrderByClause: []soql.Order{ {Field: "Name", IsDesc: false}, {Field: "HireDate", IsDesc: true}, }, } ``` -------------------------------- ### Example Scenarios for ErrInvalidLimitClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Demonstrates scenarios causing ErrInvalidLimitClause, including incorrect type for limitClause and negative limit values. ```go // Scenario 1: Wrong type for limitClause type BadQuery struct { LimitValue int `soql:"limitClause"` // WRONG: should be *int, not int } ``` ```go // Scenario 2: Negative limit value limit := -5 type BadQuery struct { LimitClause *int `soql:"limitClause"` } query := BadQuery{LimitClause: &limit} // WRONG: negative value soqlQuery, err := soql.Marshal(query) // Error: ErrInvalidLimitClause ``` -------------------------------- ### SOQL Query for Account Source Source: https://github.com/forcedotcom/go-soql/blob/master/docs/introduction.md An example SOQL query to retrieve Account records where the AccountSource is either 'Advertisement' or 'Data.com'. ```sql SELECT Name,AccountNumber,AccountSource,BillingAddress,HasOptedOutOfEmail,LastActivityDate,NumberOfEmployees FROM Account WHERE AccountSource IN ('Advertisement', 'Data.com') ``` -------------------------------- ### Make HTTP GET Request to Salesforce Query API Source: https://github.com/forcedotcom/go-soql/blob/master/docs/introduction.md Construct and execute an HTTP GET request to the Salesforce query endpoint using the generated SOQL. Handles response reading and JSON unmarshalling. ```go values := url.Values{} values.Set("q", soqlQuery) // soqlQuery variable defined in code snippet above path := fmt.Sprintf("/services/data/v44.0/query?%s",values.Encode()) serverURL := "https://.salesforce.com" req, err := http.NewRequest(http.MethodGet, serverURL+path, nil) if err != nil { // Handle error case } req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") httpClient := &http.Client{} resp, err := httpClient.Do(req) if err != nil { // Handle error case } payload, err := ioutil.ReadAll(resp.Body) if err != nil { // Handle error case } var queryResponse QueryResponse err = json.Unmarshal(payload, &queryResponse) if err != nil { // Handle error case } ``` -------------------------------- ### Using OrderByClause in a Full SOQL Query Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalorderbyclause.md Shows how to integrate the generated ORDER BY clause into a complete SOQL query using the Marshal function. This example includes select, where, order by, limit, and offset clauses. ```go type SelectColumns struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` } type QueryCriteria struct { Status string `soql:"equalsOperator,fieldName=Status__c"` } type SoqlQuery struct { SelectClause SelectColumns `soql:"selectClause,tableName=Account" WhereClause QueryCriteria `soql:"whereClause" OrderByClause []soql.Order `soql:"orderByClause" } limit := 10 offset := 0 query := SoqlQuery{ SelectClause: SelectColumns{}, WhereClause: QueryCriteria{Status: "Active"}, OrderByClause: []soql.Order{ {Field: "Name", IsDesc: false}, }, } soqlQuery, err := soql.Marshal(query) if err != nil { log.Fatal(err) } fmt.Println(soqlQuery) // Output: SELECT Id,Name__c FROM Account WHERE Status__c = 'Active' ORDER BY Name__c ASC LIMIT 10 OFFSET 0 ``` -------------------------------- ### Example Scenarios for ErrInvalidOrderByClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Illustrates scenarios leading to ErrInvalidOrderByClause, such as incorrect type for orderByClause, empty field name in Order, or wrong parameter type to MarshalOrderByClause. ```go // Scenario 1: Wrong type for orderByClause field type BadQuery struct { SelectClause SelectColumns `soql:"selectClause,tableName=Account"` OrderBy string `soql:"orderByClause"` // WRONG: should be []Order } ``` ```go // Scenario 2: Empty field name in Order orders := []soql.Order{ {Field: "", IsDesc: false}, // WRONG: empty field name } ``` ```go // Scenario 3: Wrong parameter type to MarshalOrderByClause orders := []soql.Order{{Field: "Name", IsDesc: false}} clause, err := soql.MarshalOrderByClause(orders, "NotAStruct") // Error: ErrInvalidOrderByClause ``` -------------------------------- ### Pagination with LIMIT and OFFSET Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/index.md Configure LIMIT and OFFSET clauses by including pointer fields for these clauses in your query struct. This allows for controlling the number of records returned and the starting point. ```go type Query struct { SelectClause SelectClause `soql:"selectClause,tableName=Account" WhereClause Criteria `soql:"whereClause" OrderByClause []soql.Order `soql:"orderByClause" LimitClause *int `soql:"limitClause" OffsetClause *int `soql:"offsetClause" } limit := 100 offset := 0 ``` -------------------------------- ### Example Scenarios for ErrInvalidSelectColumnOrderByClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Illustrates scenarios leading to ErrInvalidSelectColumnOrderByClause, including non-existent fields in Order, and selectClause structs lacking selectColumn fields. ```go type SelectColumns struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` } // Scenario 1: Field doesn't exist in selectClause orders := []soql.Order{ {Field: "NonExistent", IsDesc: false}, // WRONG: NonExistent not in SelectColumns } clause, err := soql.MarshalOrderByClause(orders, SelectColumns{}) // Error ``` ```go // Scenario 2: Struct with no selectColumn fields type EmptySelect struct { Value string // No soql tag } orders := []soql.Order{{Field: "Value", IsDesc: false}} clause, err := soql.MarshalOrderByClause(orders, EmptySelect{}) // Error ``` -------------------------------- ### ErrMultipleWhereClause: Duplicate whereClause tags Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Example of a struct containing two fields tagged 'whereClause', which is an invalid configuration. ```go type BadQuery struct { SelectClause SelectColumns `soql:"selectClause,tableName=Account"` Where1 QueryCriteria `soql:"whereClause"` Where2 QueryCriteria `soql:"whereClause"` // WRONG: duplicate whereClause } ``` -------------------------------- ### ErrMultipleSelectClause: Duplicate selectClause tags Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Example of a struct with two fields tagged 'selectClause', which is not permitted. ```go type BadQuery struct { SelectA SelectColumns `soql:"selectClause,tableName=Table1"` SelectB SelectColumns `soql:"selectClause,tableName=Table2"` // WRONG: duplicate selectClause WhereClause QueryCriteria `soql:"whereClause"` } ``` -------------------------------- ### Error Handling Example for SOQL Marshaling Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/types.md This snippet demonstrates how to handle specific errors returned by the `soql.Marshal` function using a switch statement. It covers common errors like `ErrNoSelectClause`, `ErrInvalidTag`, and `ErrMultipleWhereClause`. ```go soqlQuery, err := soql.Marshal(myStruct) if err != nil { switch err { case soql.ErrNoSelectClause: log.Fatal("Struct must contain selectClause field") case soql.ErrInvalidTag: log.Fatal("Invalid soql tag or operator-type mismatch") case soql.ErrMultipleWhereClause: log.Fatal("Struct contains multiple whereClause fields") default: log.Fatalf("Marshaling error: %v", err) } } ``` -------------------------------- ### SOQL LIKE Operator Example Source: https://github.com/forcedotcom/go-soql/blob/master/README.md The `likeOperator` tag is used for `LIKE` comparisons in the WHERE clause. It must be applied to a `[]string` type. Multiple strings in the slice are combined with `OR`. ```go whereClause, _ := MarshalWhereClause(QueryCriteria{ IncludeNamePattern: []string{"-", "-"}, }) // whereClause will be: WHERE (Name__c LIKE '%-foo%' OR Name__c LIKE '%-bar%') ``` -------------------------------- ### SOQL Query with Multiple WHERE Conditions Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Combine multiple conditions in the WHERE clause of a SOQL query using different operators like equals, IN, and greater than. This example uses the 'github.com/forcedotcom/go-soql' library. ```go type QueryCriteria struct { Status string `soql:"equalsOperator,fieldName=Status__c"` Roles []string `soql:"inOperator,fieldName=Role__c" MinScore int `soql:"greaterThanOperator,fieldName=Score__c" } type MyQuery struct { SelectClause SelectClause `soql:"selectClause,tableName=Employee" WhereClause QueryCriteria `soql:"whereClause" } query := MyQuery{ SelectClause: SelectClause{}, WhereClause: QueryCriteria{ Status: "Active", Roles: []string{"engineer", "manager"}, MinScore: 75, }, } result, _ := soql.Marshal(query) // Output: SELECT Id,Name FROM Employee WHERE Status__c = 'Active' AND Role__c IN ('engineer','manager') AND Score__c > 75 ``` -------------------------------- ### Define Go Structs for SOQL Queries with Subqueries Source: https://github.com/forcedotcom/go-soql/blob/master/README.md Define Go structs with `soql` annotations to represent complex SOQL queries, including nested conditions and subqueries. This example demonstrates how to structure these structs for a 'Contact' object with various criteria. ```go type contact struct { Name string `soql:"selectColumn,fieldName=Name" json:"Name"` Email string `soql:"selectColumn,fieldName=Email" json:"Email"` Phone string `soql:"selectColumn,fieldName=Phone" json:"Phone"` } type soqlQuery struct { SelectClause contact `soql:"selectClause,tableName=Contact"` WhereClause queryCriteria `soql:"whereClause"` } type queryCriteria struct { Position positionCriteria `soql:"subquery,joiner=OR"` Contactable contactableCriteria `soql:"subquery,joiner=OR"` AlreadyContacted alreadyContactedSoqlQuery `soql:"subquery,joiner=NOT IN,fieldName=Name"` } type positionCriteria struct { Title string `soql:"equalsOperator,fieldName=Title"` DepartmentManager deptManagerCriteria `soql:"subquery"` } type deptManagerCriteria struct { Department string `soql:"equalsOperator,fieldName=Department"` Title []string `soql:"likeOperator,fieldName=Title"` } type contactableCriteria struct { EmailOK emailCheck `soql:"subquery,joiner=and"` PhoneOK phoneCheck `soql:"subquery,joiner=and"` } type emailCheck struct { Email bool `soql:"nullOperator,fieldName=Email"` EmailOptedOut bool `soql:"equalsOperator,fieldName=HasOptedOutOfEmail"` } type phoneCheck struct { Phone bool `soql:"nullOperator,fieldName=Phone"` DoNotCall bool `soql:"equalsOperator,fieldName=DoNotCall"` } type alreadyContactedSoqlQuery struct { SelectClause alreadyContacted `soql:"selectClause,tableName=Calls"` WhereClause alreadyContactedCriteria `soql:"whereClause"` } type alreadyContacted struct { Name string `soql:"selectColumn,fieldName=Name"` } type alreadyContactedCriteria struct { IsContacted bool `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) if err != nil { fmt.Printf("Error in marshalling: %s\n", err.Error()) } fmt.Println(soqlQuery) ``` -------------------------------- ### Basic SOQL Query Generation with Struct Tags Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/README.md Demonstrates how to define a Go struct with `soql` tags to represent a SOQL query and then use `soql.Marshal` to generate the SOQL string. Error handling for the marshaling process is also shown. ```go // Define struct with soql tags type Query struct { SelectClause SelectStruct `soql:"selectClause,tableName=Account"` WhereClause CriteriaStruct `soql:"whereClause"` } // Generate SOQL query soqlQuery, err := soql.Marshal(query) if err != nil { // Handle error - see errors.md } // Use query with Salesforce API fmt.Println(soqlQuery) ``` -------------------------------- ### ErrNilValue: Nil query struct Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Example scenario where a nil pointer is passed to soql.Marshal, resulting in an ErrNilValue. ```go var query *QueryStruct soqlQuery, err := soql.Marshal(query) // Error: ErrNilValue ``` -------------------------------- ### Import Go-SOQL Library Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/README.md Import the necessary Go-SOQL package to use its functionalities in your project. ```go import "github.com/forcedotcom/go-soql" ``` -------------------------------- ### Basic SOQL Configuration with Select and Where Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Define a basic SOQL query structure for selecting columns and applying a WHERE clause. This is useful for simple queries. ```go type SelectStruct struct { ID string `soql:"selectColumn,fieldName=Id" Name string `soql:"selectColumn,fieldName=Name__c" } type WhereStruct struct { Status string `soql:"equalsOperator,fieldName=Status__c" } type MyQuery struct { SelectClause SelectStruct `soql:"selectClause,tableName=Account" WhereClause WhereStruct `soql:"whereClause" } ``` -------------------------------- ### Advanced SOQL Configuration with Pagination and Ordering Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Configure a SOQL query with pagination (LIMIT and OFFSET) and ordering. Use this for queries requiring specific result set constraints. ```go type MyQuery struct { SelectClause SelectStruct `soql:"selectClause,tableName=Contact" WhereClause WhereStruct `soql:"whereClause,joiner=AND" OrderByClause []soql.Order `soql:"orderByClause" LimitClause *int `soql:"limitClause" OffsetClause *int `soql:"offsetClause" } limit := 100 offset := 0 query := MyQuery{ OrderByClause: []soql.Order{ {Field: "Name", IsDesc: false}, {Field: "CreatedDate", IsDesc: true}, }, LimitClause: &limit, OffsetClause: &offset, } ``` -------------------------------- ### Basic SOQL Query Marshaling Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Demonstrates the basic usage of the `soql.Marshal` function to convert a Go struct into a SOQL query string. Error handling is omitted for brevity. ```go // Basic query result, _ := soql.Marshal(QueryStruct{}) ``` -------------------------------- ### Basic SOQL Query Construction Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Construct a simple SELECT-FROM-WHERE SOQL query using Go structs and the go-soql library. Ensure the 'github.com/forcedotcom/go-soql' package is imported. ```go package main import ( "fmt" "github.com/forcedotcom/go-soql" ) type SelectClause struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name" Email string `soql:"selectColumn,fieldName=Email" } type Criteria struct { Status string `soql:"equalsOperator,fieldName=Status__c"` } type ContactQuery struct { SelectClause SelectClause `soql:"selectClause,tableName=Contact" WhereClause Criteria `soql:"whereClause" } func main() { query := ContactQuery{ SelectClause: SelectClause{}, WhereClause: Criteria{ Status: "Active", }, } result, err := soql.Marshal(query) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println(result) // Output: SELECT Id,Name,Email FROM Contact WHERE Status__c = 'Active' } ``` -------------------------------- ### SOQL NOT LIKE Operator Example Source: https://github.com/forcedotcom/go-soql/blob/master/README.md The `notLikeOperator` tag is used for `NOT LIKE` comparisons in the WHERE clause. It must be applied to a `[]string` type. Multiple strings in the slice are combined with `AND`. ```go whereClause, _ := MarshalWhereClause(QueryCriteria{ ExcludeNamePattern: []string{"-", "-"}, }) // whereClause will be: WHERE ((NOT Name__c LIKE '%-far%') AND (NOT Name__c LIKE '%-baz%')) ``` -------------------------------- ### Basic Ordering with MarshalOrderByClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalorderbyclause.md Demonstrates basic ascending order for a single field. Ensure the SelectColumns struct is defined to map SOQL fields. ```go type SelectColumns struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` } orders := []soql.Order{ {Field: "Name", IsDesc: false}, } clause, err := soql.MarshalOrderByClause(orders, SelectColumns{}) if err != nil { log.Fatal(err) } fmt.Println(clause) // Output: Name__c ASC ``` -------------------------------- ### Generate SOQL Select Clause Source: https://github.com/forcedotcom/go-soql/blob/master/docs/introduction.md Generates the SELECT clause part of a SOQL query from a Go struct. This example shows how to generate the column names without any WHERE conditions. ```go soqlQuery, err := soql.MarshalSelectClause(Account{}, "") ``` -------------------------------- ### Configure LIMIT Clause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Marks a field for the LIMIT clause. Must be a pointer to int. A nil pointer results in no LIMIT clause. The default is nil. ```go type MyQuery struct { LimitClause *int `soql:"limitClause"` } ``` -------------------------------- ### Date Range Query with SOQL Operators Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/tag-operators.md Define a date range for SOQL queries by using greaterThanOperator for the start date and lessThanOperator for the end date, specifying the date format. ```go type Criteria struct { StartDate time.Time `soql:"greaterThanOperator,fieldName=CreatedDate,format=2006-01-02"` EndDate time.Time `soql:"lessThanOperator,fieldName=CreatedDate,format=2006-01-02" } start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) end := time.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC) criteria := Criteria{StartDate: start, EndDate: end} // Output: CreatedDate > 2024-01-01 AND CreatedDate < 2024-12-31 ``` -------------------------------- ### SOQL ORDER BY Clause Marshaling Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Demonstrates marshaling an ORDER BY clause using `soql.MarshalOrderByClause`. It requires a slice of order definitions and a struct for context. ```go // Just ORDER BY order, _ := soql.MarshalOrderByClause(orders, SelectStruct{}) ``` -------------------------------- ### Pagination with LIMIT and OFFSET in Go Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Add pagination to query results by specifying LIMIT and OFFSET values. Ensure OrderByClause is used with LIMIT/OFFSET for predictable results. ```Go type MyQuery struct { SelectClause SelectClause `soql:"selectClause,tableName=Account" WhereClause Criteria `soql:"whereClause" OrderByClause []soql.Order `soql:"orderByClause" LimitClause *int `soql:"limitClause" OffsetClause *int `soql:"offsetClause" } limit := 100 offset := 50 query := MyQuery{ SelectClause: SelectClause{}, WhereClause: Criteria{ Status: "Active", }, OrderByClause: []soql.Order{ {Field: "Name", IsDesc: false}, }, LimitClause: &limit, OffsetClause: &offset, } result, _ := soql.Marshal(query) // Output: SELECT Id,Name FROM Account WHERE Status__c = 'Active' ORDER BY Name ASC LIMIT 100 OFFSET 50 ``` -------------------------------- ### Marshal Basic SOQL Query Source: https://github.com/forcedotcom/go-soql/blob/master/README.md Constructs a SOQL query string from the defined `TestSoqlStruct`. Ensure the `Marshal` function is imported and available. ```go limit := 5 offset := 10 soqlStruct := 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) ``` -------------------------------- ### Empty Order Clause Handling Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalorderbyclause.md Demonstrates that providing an empty slice for the order clause results in an empty string for the generated clause. This is useful when ordering is optional. ```go type SelectColumns struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` } // Empty slice returns empty string orders := []soql.Order{} clause, err := soql.MarshalOrderByClause(orders, SelectColumns{}) if err != nil { log.Fatal(err) } fmt.Println(clause) // Output: (empty string) ``` -------------------------------- ### Multiple Fields with Different Directions Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalorderbyclause.md Shows how to order by multiple fields, specifying ascending or descending for each. The SelectColumns struct should include all fields used in ordering. ```go type SelectColumns struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` CreatedDate string `soql:"selectColumn,fieldName=CreatedDate__c"` } orders := []soql.Order{ {Field: "Name", IsDesc: false}, {Field: "CreatedDate", IsDesc: true}, } clause, err := soql.MarshalOrderByClause(orders, SelectColumns{}) if err != nil { log.Fatal(err) } fmt.Println(clause) // Output: Name__c ASC,CreatedDate__c DESC ``` -------------------------------- ### Check for NULL and NOT NULL with *bool Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/tag-operators.md Use a pointer to bool (*bool) to distinguish between a field being explicitly set to false (not null) and being omitted (nil). A true value results in '= null', and a false value results in '!= null'. ```go type Criteria struct { HasValue *bool `soql:"nullOperator,fieldName=Value__c"` } // Check for NULL hasValue := true clause1, _ := soql.MarshalWhereClause(Criteria{HasValue: &hasValue}) // Output: Value__c = null // Check for NOT NULL hasValue = false clause2, _ := soql.MarshalWhereClause(Criteria{HasValue: &hasValue}) // Output: Value__c != null ``` -------------------------------- ### Go SOQL Build Dynamic Queries Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Constructs SOQL queries dynamically based on runtime conditions, allowing for optional parameters. ```go func BuildQuery(status *string, minScore *int, roles []string) (string, error) { type SelectClause struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name"` Score string `soql:"selectColumn,fieldName=Score__c"` } type Criteria struct { Status *string `soql:"equalsOperator,fieldName=Status__c"` MinScore *int `soql:"greaterThanOperator,fieldName=Score__c"` Roles []string `soql:"inOperator,fieldName=Role__c"` } type Query struct { SelectClause SelectClause `soql:"selectClause,tableName=Employee"` WhereClause Criteria `soql:"whereClause"` } query := Query{ SelectClause: SelectClause{}, WhereClause: Criteria{ Status: status, MinScore: minScore, Roles: roles, }, } return soql.Marshal(query) } // Use with optional parameters status := "Active" minScore := 80 roles := []string{"engineer", "manager"} result, _ := BuildQuery(&status, &minScore, roles) // Includes all conditions result, _ := BuildQuery(&status, nil, nil) // Only includes Status condition ``` -------------------------------- ### SOQL Tag Parameters Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Understand the common parameters used with SOQL tags to customize query generation. These include field names, table names, joiners, and date formats. ```go fieldName=FieldName__c // Salesforce field name ``` ```go tableName=TableName__c // Salesforce object name ``` ```go joiner=AND|OR|IN|NOT IN // Condition combiner ``` ```go format=2006-01-02 // time.Time format ``` -------------------------------- ### Query Child Records with Sub-query Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Demonstrates how to define and marshal a query that includes child relationships using nested structs. Ensure the child relationship field is correctly mapped. ```go type ChildSelect struct { Version string `soql:"selectColumn,fieldName=Version__c"` Release string `soql:"selectColumn,fieldName=Release__c"` } type ChildWhere struct { IsActive bool `soql:"equalsOperator,fieldName=IsActive__c"` } type ChildQuery struct { SelectClause ChildSelect `soql:"selectClause,tableName=Version__c"` WhereClause ChildWhere `soql:"whereClause"` } type AccountSelect struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name"` Versions ChildQuery `soql:"selectChild,fieldName=Versions__r"` } type AccountQuery struct { SelectClause AccountSelect `soql:"selectClause,tableName=Account"` } query := AccountQuery{ SelectClause: AccountSelect{}, } result, _ := soql.Marshal(query) // Output: SELECT Id,Name,(SELECT Version__c.Version__c,Version__c.Release__c FROM Versions__r WHERE Version__c.IsActive__c = true) FROM Account ``` -------------------------------- ### SOQL Configuration with Parent and Child Relationships Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Define SOQL queries that traverse parent and child relationships. This allows fetching related data in a single query. ```go type AddressStruct struct { City string `soql:"selectColumn,fieldName=City__c" State string `soql:"selectColumn,fieldName=State__c" } type ChildStruct struct { Version string `soql:"selectColumn,fieldName=Version__c" } type ChildQueryStruct struct { SelectClause ChildStruct `soql:"selectClause,tableName=Versions__c" WhereClause ChildWhere `soql:"whereClause" } type SelectStruct struct { ID string `soql:"selectColumn,fieldName=Id" Name string `soql:"selectColumn,fieldName=Name" Address AddressStruct `soql:"selectColumn,fieldName=Address__r"" Children ChildQueryStruct `soql:"selectChild,fieldName=Versions__r" } ``` -------------------------------- ### Order by Nested Struct Fields Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Demonstrates ordering results by fields within nested parent structs using dot notation. Ensure the struct tags correctly map to the SOQL field names. ```go type Address struct { City string `soql:"selectColumn,fieldName=City__c"` State string `soql:"selectColumn,fieldName=State__c"` } type Contact struct { Name string `soql:"selectColumn,fieldName=Name__c"` Address Address `soql:"selectColumn,fieldName=Address__r"` } orders := []soql.Order{ {Field: "Address.State", IsDesc: false}, // Nested field using dot notation {Field: "Address.City", IsDesc: true}, {Field: "Name", IsDesc: false}, } clause, _ := soql.MarshalOrderByClause(orders, Contact{}) ``` -------------------------------- ### Configure ORDER BY Clause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Marks a field as the ORDER BY specification. Must be a slice of Order structs. Field references must correspond to selectColumn field names. A nil or empty slice results in no ORDER BY clause. ```go type MyQuery struct { OrderByClause []soql.Order `soql:"orderByClause"` } ``` -------------------------------- ### Configure OFFSET Clause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Marks a field for the OFFSET clause. Must be a pointer to int. A nil pointer results in no OFFSET clause. The default is nil. ```go type MyQuery struct { OffsetClause *int `soql:"offsetClause"` } ``` -------------------------------- ### Sort by Multiple Fields Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Shows how to define multiple sorting criteria for a SOQL query using the `soql.Order` type. The order of elements in the slice determines the sort precedence. ```go type SelectClause struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` Department string `soql:"selectColumn,fieldName=Department__c"` Salary string `soql:"selectColumn,fieldName=Salary__c"` } orders := []soql.Order{ {Field: "Department", IsDesc: false}, // Primary sort: ASC {Field: "Salary", IsDesc: true}, // Secondary sort: DESC {Field: "Name", IsDesc: false}, // Tertiary sort: ASC } clause, _ := soql.MarshalOrderByClause(orders, SelectClause{}) // Output: Department__c ASC,Salary__c DESC,Name__c ASC ``` -------------------------------- ### SOQL Select Clause Output Source: https://github.com/forcedotcom/go-soql/blob/master/docs/introduction.md The resulting string from generating a SOQL select clause, listing the fields to be selected. ```text Name,AccountNumber,AccountSource,BillingAddress,HasOptedOutOfEmail,LastActivityDate,NumberOfEmployees ``` -------------------------------- ### Generate Complete SOQL Query Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Use Marshal to generate a complete SOQL query from a struct. Ensure the struct is properly defined with SOQL tags. ```go // Generate complete SOQL query soqlQuery, err := soql.Marshal(struct) ``` -------------------------------- ### Define Basic SOQL Structs Source: https://github.com/forcedotcom/go-soql/blob/master/README.md Defines structs for a simple SOQL query including select, where, order by, limit, and offset clauses. These structs use `soql` tags to map fields to SOQL components. ```go 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" } ``` -------------------------------- ### Common SOQL Constants Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Access predefined constants for SOQL clauses, columns, and operators. These constants simplify query construction and improve code readability. ```go soql.SoqlTag // "soql" soql.SelectClause // "selectClause" soql.SelectColumn // "selectColumn" soql.WhereClause // "whereClause" soql.DateTimeFormat // "2006-01-02T15:04:05.000-0700" // Operators soql.LikeOperator soql.InOperator soql.EqualsOperator soql.GreaterThanOperator soql.NullOperator // ... and 17 more operator constants ``` -------------------------------- ### Ordering Nested (Parent Relationship) Fields Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalorderbyclause.md Illustrates ordering by fields within a nested or parent relationship. Use dot notation in the Field name to specify nested fields, and ensure the struct definition reflects the relationship. ```go type Address struct { City string `soql:"selectColumn,fieldName=City__c"` State string `soql:"selectColumn,fieldName=State__c"` } type Contact struct { ID string `soql:"selectColumn,fieldName=Id"` Name string `soql:"selectColumn,fieldName=Name__c"` Address Address `soql:"selectColumn,fieldName=Address__r"` } orders := []soql.Order{ {Field: "Address.City", IsDesc: false}, {Field: "Name", IsDesc: true}, } clause, err := soql.MarshalOrderByClause(orders, Contact{}) if err != nil { log.Fatal(err) } fmt.Println(clause) // Output: Address__r.City__c ASC,Name__c DESC ``` -------------------------------- ### Basic Select Clause Generation Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalselectclause.md Generates a basic SELECT clause from a struct with `selectColumn` tags. Use this for simple field selections. ```go type Contact struct { ID string `soql:"selectColumn,fieldName=Id" Name string `soql:"selectColumn,fieldName=Name" Email string `soql:"selectColumn,fieldName=Email" } clause, err := soql.MarshalSelectClause(Contact{}, "") if err != nil { log.Fatal(err) } fmt.Println(clause) // Output: Id,Name,Email ``` -------------------------------- ### Scenario: Wrong type for offsetClause Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Illustrates the incorrect usage of offsetClause where an `int` is used instead of `*int`. ```go // Scenario 1: Wrong type for offsetClause type BadQuery struct { Offset int `soql:"offsetClause"` // WRONG: should be *int, not int } ``` -------------------------------- ### Generated SOQL Query from Go Structs Source: https://github.com/forcedotcom/go-soql/blob/master/README.md This SQL query is the output generated by marshalling the Go structs defined previously. It demonstrates how the annotations translate into a valid SOQL statement with subqueries. ```sql SELECT Name,Email,Phone FROM Contact WHERE (Title = 'Purchasing Manager' OR (Department = 'Accounting' AND Title LIKE '%Manager%')) AND ((Email != null AND HasOptedOutOfEmail = false) OR (Phone != null AND DoNotCall = false)) AND Name NOT IN (SELECT Name FROM Calls WHERE IsContacted = true) ``` -------------------------------- ### SOQL Time and Date Formats Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Utilize predefined formats for handling dates and times in SOQL queries. Supports default Salesforce datetime, date-only, ISO 8601, and custom formats. ```go // Default (Salesforce datetime with milliseconds and timezone) format=2006-01-02T15:04:05.000-0700 // Date only format=2006-01-02 // ISO 8601 with timezone format=2006-01-02T15:04:05Z07:00 // Custom format format=01/02/2006 // MM/DD/YYYY ``` -------------------------------- ### ErrNoSelectClause: Missing selectClause tag Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Illustrates a struct that has SOQL tags but is missing the mandatory 'selectClause' tag. ```go type BadQuery struct { // Missing: SelectClause SelectColumns `soql:"selectClause,tableName=..."` WhereClause QueryCriteria `soql:"whereClause"` // WRONG: has whereClause but no selectClause } ``` -------------------------------- ### SOQL Tag Parameters Source: https://github.com/forcedotcom/go-soql/blob/master/README.md Specifies the parameters that can be used with SOQL tags to define field and table names. If not provided, the field name is used as the default. ```go 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. ``` -------------------------------- ### SOQL SELECT Clause Marshaling Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/quick-reference.md Shows how to marshal only the SELECT clause of a SOQL query using `soql.MarshalSelectClause`. Requires a struct representing the fields to select and an optional table name. ```go // Just SELECT cols, _ := soql.MarshalSelectClause(SelectStruct{}, "") ``` -------------------------------- ### String Pattern Matching with LIKE and NOT LIKE Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Use the `likeOperator` and `notLikeOperator` tags to generate SOQL LIKE and NOT LIKE clauses. The values are automatically wrapped in '%' wildcards. ```go type Criteria struct { IncludeNames []string `soql:"likeOperator,fieldName=Name__c"` ExcludeNames []string `soql:"notLikeOperator,fieldName=Name__c"` } criteria := Criteria{ IncludeNames: []string{"John", "Jane"}, ExcludeNames: []string{"Test", "Demo"}, } clause, _ := soql.MarshalWhereClause(criteria) // Output: (Name__c LIKE '%John%' OR Name__c LIKE '%Jane%') AND ((NOT Name__c LIKE '%Test%') AND (NOT Name__c LIKE '%Demo%')) ``` -------------------------------- ### Using `nullOperator` for null checks Source: https://github.com/forcedotcom/go-soql/blob/master/README.md Use the `nullOperator` tag with `bool` or `*bool` types for `= null` or `!= null` comparisons. Using `*bool` is recommended to avoid unexpected `!= null` results due to Go's default initialization of booleans to `false`. ```go allowNull := true whereClause, _ := MarshalWhereClause(QueryCriteria{ AllowNullValue: &allowNull, }) // whereClause will be: WHERE Value__c = null ``` ```go allowNull = false whereClause, _ := MarshalWhereClause(QueryCriteria{ AllowNullValue: &allowNull, }) // whereClause will be: WHERE Value__c != null ``` -------------------------------- ### Build Complex Subquery with Nested Conditions Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Illustrates constructing a SOQL query with nested conditions and subquery joiners (OR/AND). This is useful for building intricate WHERE clauses. ```go type PositionCriteria struct { Title string `soql:"equalsOperator,fieldName=Title__c"` Department string `soql:"equalsOperator,fieldName=Department__c"` } type ContactableCriteria struct { HasEmail bool `soql:"nullOperator,fieldName=Email__c"` HasPhone bool `soql:"nullOperator,fieldName=Phone__c"` } type QueryCriteria struct { Position PositionCriteria `soql:"subquery,joiner=OR" Contactable ContactableCriteria `soql:"subquery,joiner=AND" } type MyQuery struct { SelectClause SelectClause `soql:"selectClause,tableName=Contact" WhereClause QueryCriteria `soql:"whereClause" } criteria := MyQuery{ SelectClause: SelectClause{}, WhereClause: QueryCriteria{ Position: PositionCriteria{ Title: "Manager", Department: "Sales", }, Contactable: ContactableCriteria{ HasEmail: true, HasPhone: true, }, }, } result, _ := soql.Marshal(criteria) ``` -------------------------------- ### Handle SOQL Marshalling Errors in Go Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/errors.md Use this pattern to catch and handle specific errors returned by `soql.Marshal`. It includes cases for common issues like missing clauses, invalid tags, duplicate clauses, pagination problems, and nil pointers. ```go soqlQuery, err := soql.Marshal(myStruct) if err != nil { switch err { case soql.ErrNoSelectClause: // Handle missing selectClause case soql.ErrInvalidTag: // Handle tag-type mismatch or invalid operator case soql.ErrMultipleWhereClause, soql.ErrMultipleSelectClause: // Handle duplicate clause tags case soql.ErrInvalidOrderByClause, soql.ErrInvalidSelectColumnOrderByClause: // Handle ORDER BY issues case soql.ErrInvalidLimitClause, soql.ErrInvalidOffsetClause: // Handle pagination issues case soql.ErrNilValue: // Handle nil pointer default: // Handle other errors } } ``` -------------------------------- ### Configure SELECT Clause Columns Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/configuration.md Use `selectColumn` to mark fields for inclusion in SOQL SELECT clauses. For parent relationships, use a nested struct with the `selectColumn` tag. ```go type SelectClause struct { Name string `soql:"selectColumn,fieldName=Name__c" ChildRel Address `soql:"selectColumn,fieldName=Address__r"` // Nested struct for parent relationship } ``` -------------------------------- ### Numeric Comparisons with >, <, >=, <= Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/examples.md Use comparison operator tags like `greaterThanOperator`, `lessThanOperator`, `greaterThanOrEqualsToOperator` to generate SOQL numeric comparison clauses. ```go type Criteria struct { MinCores int `soql:"greaterThanOperator,fieldName=CPU_Cores__c"` MaxCores int `soql:"lessThanOperator,fieldName=CPU_Cores__c"` MinMemory int `soql:"greaterThanOrEqualsToOperator,fieldName=Memory_GB__c"` } criteria := Criteria{ MinCores: 4, MaxCores: 16, MinMemory: 8, } clause, _ := soql.MarshalWhereClause(criteria) // Output: CPU_Cores__c > 4 AND CPU_Cores__c < 16 AND Memory_GB__c >= 8 ``` -------------------------------- ### Date Operators with Custom Format Source: https://github.com/forcedotcom/go-soql/blob/master/_autodocs/api-reference-marshalwhereclause.md Specify a `format` parameter for date fields to control the output format in the WHERE clause. ```go type QueryCriteria struct { UpdateDate time.Time `soql:"equalsOperator,fieldName=UpdateDate,format=2006-01-02"` } date := time.Date(2021, 6, 15, 0, 0, 0, 0, time.UTC) clause, err := soql.MarshalWhereClause(QueryCriteria{UpdateDate: date}) // Output: UpdateDate = 2021-06-15 ```