Golang tag library to generate SOQL queries
BOSH release for ethereum
YAML for Go
A CLI for Cloud Foundry written in Go
THIS IS A READ-ONLY historic repository. Current development is at https://gerrit.hyperledger.org/r/#/admin/projects/fabric . pull requests not accepted
Mirror of Apache Karaf
This is BOSH release for cloud foundry routers
Easy SSH servers in Golang
The lil' gorouter stress test
issue openedforcedotcom/go-soql
Add support for avg/sum functions
As part of supporting aggregate functions add support for following functions:
AVG()
SUM()
Add avg and sum tag that can be used in selectClause structs as follows:
type TestSoqlStruct struct {
SelectClause NestedStruct `soql:"selectClause,tableName= Opportunity"`
GroupBy []string `soql:"groupByClause"`
}
type NestedStruct struct {
CampaignId string `soql:"selectColumn,fieldName= CampaignId"`
Average int `soql:"avg,fieldName= Amount"`
}
soqlStruct := TestSoqlStruct{
GroupBy: []string{"CampaignId"},
}
soqlQuery, err := Marshal(soqlStruct)
if err != nil {
fmt.Printf("Error in marshaling: %s\n", err.Error())
}
fmt.Println(soqlQuery)
This should result in SOQL as follows
SELECT CampaignId, AVG(Amount) FROM Opportunity GROUP BY CampaignId
Note that if fieldName is not specified then return ErrInvalidTag.
Same should apply for sum tag as well.
Allow avg and sum to be used only for supported primitive data types
created time in a month
issue openedforcedotcom/go-soql
As part of supporting aggregate functions add support for following functions:
MIN()
MAX()
Add min and max tag that can be used in selectClause structs as follows:
type TestSoqlStruct struct {
SelectClause NestedStruct `soql:"selectClause,tableName= Contact"`
GroupBy []string `soql:"groupByClause"`
}
type TestQueryCriteria struct {
IncludeNamePattern []string `soql:"likeOperator,fieldName=Name"`
}
type NestedStruct struct {
Count int `soql:"min,fieldName= CreatedDate"`
}
This should result in SOQL as follows
SELECT MIN(CreatedDate) FROM Contact WHERE Name LIKE '%a%'
Note that if fieldName is not specified then return ErrInvalidTag.
Same should apply for max tag as well.
Allow min and max to be used only for supported primitive data types
created time in a month
issue openedforcedotcom/go-soql
Add support for count function in SOQL
As part of supporting aggregate functions add support for following functions:
COUNT()
COUNT_DISTINCT()
Add count and countDistinct tag that can be used in selectClause structs as follows:
type TestSoqlStruct struct {
SelectClause NestedStruct `soql:"selectClause,tableName=Account"`
WhereClause TestQueryCriteria `soql:"whereClause"`
}
type TestQueryCriteria struct {
IncludeNamePattern []string `soql:"likeOperator,fieldName=Name"`
}
type NestedStruct struct {
Count int `soql:"count"`
}
This should result in SOQL as follows
SELECT COUNT() FROM Account WHERE Name LIKE '%a%'
Note that if fieldName is not specified then just COUNT() should be used. If fieldName is specified then that should be used.
type TestSoqlStruct struct {
SelectClause NestedStruct `soql:"selectClause,tableName=Account"`
WhereClause TestQueryCriteria `soql:"whereClause"`
}
type TestQueryCriteria struct {
IncludeNamePattern []string `soql:"likeOperator,fieldName=Name"`
}
type NestedStruct struct {
Count int `soql:"count,fieldName=Id"`
}
SELECT COUNT(Id) FROM Account WHERE Name LIKE '%a%'
Same should apply for countDistinct tag as well.
Note that if count or countDistinct is used without fieldName then there cannot be any other field in select clause as described here. If groupBy clause is used only then allow selectClause struct to have other fields. In case of error return ErrInvalidCountTag error.
Allow count and countDistinct to be used only for supported primitive data types
created time in a month
issue openedforcedotcom/go-soql
Add support for groupBy clause
Library should support GROUP BY clause. User should be able to annotate []string member of struct with groupBy tag. The values in the []string should be the names of the field of the struct that is tagged as selectClause. This will enable developers to take []string as parameter to their method where the users of their library can specify the name of the fields of the struct that is being returned to them on which they desire grouping. Below given is example of how this should work:
type TestSoqlStruct struct {
SelectClause NonNestedStruct `soql:"selectClause,tableName=SM_SomeObject__c"`
WhereClause TestQueryCriteria `soql:"whereClause"`
GroupBy []string `soql:"groupByClause"`
}
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
soqlStruct := TestSoqlStruct{
WhereClause: TestQueryCriteria {
IncludeNamePattern: []string{"foo", "bar"},
Roles: []string{"admin", "user"},
},
GroupBy: []string{"SomeValue"},
}
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,SomeValue__c FROM SM_SomeObject__C WHERE (Name__c LIKE '%foo%' OR Name__c LIKE '%bar%') AND Role__c IN ('admin','user') GROUP BY SomeValue___c
created time in a month
push eventforcedotcom/go-soql
commit sha b3fbefb845e35e3242ec5792a8f8607a2522ffb8
Add support for time.Time pointer * Adding support for *time.Time in WhereClause in case it's optional. * Test case for nil *time.Time
push time in a month
Pull request review commentforcedotcom/go-soql
Adding support for *time.Time in WhereClause in case it's optional.
type QueryCriteriaWithDateTimeType struct { CreatedDate time.Time `soql:"equalsOperator,fieldName=CreatedDate"` } +type QueryCriteriaWithPtrDateTimeType struct {+ CreatedDate *time.Time `soql:"equalsOperator,fieldName=CreatedDate"`
May be just add another time field here and the existing testcase will cover both nil and not nil cases.
comment created time in a month
Pull request review commentforcedotcom/go-soql
Adding support for *time.Time in WhereClause in case it's optional.
var _ = Describe("Marshaller", func() { }) }) + Context("when all clauses are pointers to date time data types", func() {
It will be good to add a testcase where timestamp pointer is nil and verify that it is not included in the where clause.
comment created time in a month
push eventforcedotcom/go-soql
commit sha 638ca0f2ee8d1b3b0c3ff13ec8e72df6d730f050
Allow subqueries to be pointers * Allowing pointers with "subquery" tag in order to support optional conditions in WhereClause. * Handling nil pointer and adding test cases * Improve readability
push time in a month
PR merged forcedotcom/go-soql
Allowing pointers with "subquery" tag in order to support optional subqueries in WhereClause. It will make behavior consistent with other conditions as they are allowed to be null.
pr closed time in a month
push eventforcedotcom/go-soql
commit sha 8cfa0f5833172b55f74b71e0a735627fd24188f4
Support for advanced WHERE clause * Add support for joining conditions using `OR` or `AND` * Add support for grouped conditions
push time in 2 months
issue closedforcedotcom/go-soql
Marshal SOQL queries with subfilters in the WHERE clause
Currently, I don't believe it's possible to generate a query like this:
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)
)
I have a project where I'd like to use this, so I've been experimenting with ways of doing subfilters. I think something like this would make sense:
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"`
}
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"`
}
// this would generate the soql query
soql.Marshal(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,
},
},
},
})
closed time in 2 months
t-margheimissue closedforcedotcom/go-soql
Marshal SOQL queries with OR operators between different columns
Marshal SOQL queries with OR operators between different columns. For example, I don't believe this query is currently marshal-able:
SELECT Name,Email,Phone
FROM Contact
WHERE Title = 'Purchasing Manager' OR Department = 'Accounting'
I've been playing with an implementation that I think might work and is in keeping with the current patterns: adding an optional clause tag called joiner for whereClause. If not set, the marshal function uses AND to join (to maintain current functionality). If it's set to OR (case insensitive), then it will separate the clauses with OR.
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 orSOQLQuery struct {
SelectClause contact `soql:"selectClause,tableName=Contact"`
WhereClause positionOrDeptCriteria `soql:"whereClause,joiner=OR"`
}
type positionOrDeptCriteria struct {
Title string `soql:"equalsOperator,fieldName=Title"`
Department string `soql:"equalsOperator,fieldName=Department"`
}
// this would generate the soql query
soql.Marshal(orSOQLQuery{
WhereClause: positionOrDeptCriteria{
Title: "Purchasing Manager",
Department: "Accounting",
},
})
closed time in 2 months
t-margheimissue commentforcedotcom/go-soql
Marshal SOQL queries with subfilters in the WHERE clause
#15
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
Build out subfilter and OR logical operator support
func marshalWhereClause(v interface{}, tableName string) (string, error) { // This will print whereClause as: // (Host_Name__c LIKE '%-db%' OR Host_Name__c LIKE '%-dbmgmt%') AND Role__r.Name IN ('db','dbmgmt') AND ((NOT Host_Name__c LIKE '%-core%') AND (NOT Host_Name__c LIKE '%-drp%')) AND Tech_Asset__r.Asset_Type_Asset_Type__c = 'SERVER' AND Last_Discovered_Date__c != null AND Num_of_CPU_Cores__c > 16 func MarshalWhereClause(v interface{}) (string, error) {- return marshalWhereClause(v, "")+ return marshalWhereClause(v, "", andCondition) } func getClauseKey(clauseTag string) string { tagItems := strings.Split(clauseTag, ",") return tagItems[0] } +func getJoiner(clauseTag string) (string, error) {+ tag := getTagValue(clauseTag, Joiner, "")+ switch strings.ToLower(tag) {+ case "or":+ return orCondition, nil+ case "and", "":+ return andCondition, nil+ default:
👍
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
Build out subfilter and OR logical operator support
type NonNestedStruct struct { 1. `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 on `struct` type. If used on types other than `struct` then `ErrInvalidTag` error will be returned. This tag is associated with `tableName` 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 above `SelectClause` member of `TestSoqlStruct` is tagged with `selectClause` to indicate that members in `NonNestedStruct` should be considered as fields to be selected from Salesforce object `SM_SomeObject__c`. -1. `whereClause`: This tag is used on the struct which encapsulates the query criteria for SOQL query. There are no parameters for this tag. In the snippet above `WhereClause` member of `TestSoqlStruct` is tagged with `whereClause` to indicate that members in `TestQueryCriteria` should be considered for generating `WHERE` clause in SOQL query. If there are more than one field in `TestQueryCriteria` struct then they will be combined using `AND` logical operator.+1. `whereClause`: This tag is used on the struct which encapsulates the query criteria for SOQL query. There is an optional parameter `joiner` for this tag. In the snippet above `WhereClause` member of `TestSoqlStruct` is tagged with `whereClause` to indicate that members in `TestQueryCriteria` should be considered for generating `WHERE` clause in SOQL query. If there are more than one field in `TestQueryCriteria` struct then they will be combined using `AND` logical operator. If the `joiner` parameter is set to `or`, then the fields will be combined using `OR` logical operator. Any other value including no value will use the `AND` logical operator. The `joiner` parameter is only supported when using `Marshal`; when calling `MarshalWhereClause`, the fields will always be combined with the `AND` logical operator.
Just need to fix the README to indicate that any other value than AND and OR will result in ErrInvalidTag.
comment created time in 2 months
issue commentforcedotcom/go-soql
Marshal SOQL queries with OR operators between different columns
Thanks @t-margheim for submitting the issue and corresponding PR. I think this is a great addition to this library.
comment created time in 2 months
issue commentforcedotcom/go-soql
Marshal SOQL queries with subfilters in the WHERE clause
Thanks @t-margheim for submitting the issue and corresponding PR
comment created time in 2 months
pull request commentforcedotcom/go-soql
Build out subfilter and OR logical operator support
Resolves #13 and #14
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
Build out subfilter and OR logical operator support
var _ = Describe("Marshaller", func() { Expect(actualQuery).To(Equal(expectedQuery)) }) })++ Context("when a struct with where clause with joiner=OR passed", func() {+ BeforeEach(func() {+ soqlStruct = orSOQLQuery{+ WhereClause: positionOrDeptCriteria{+ Title: "Purchasing Manager",+ Department: "Accounting",+ },+ }+ expectedQuery = "SELECT Name,Email,Phone FROM Contact WHERE Title = 'Purchasing Manager' OR Department = 'Accounting'"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with where clause with joiner=or passed", func() {+ BeforeEach(func() {+ soqlStruct = orLowerSOQLQuery{+ WhereClause: positionOrDeptCriteria{+ Title: "Purchasing Manager",+ Department: "Accounting",+ },+ }+ expectedQuery = "SELECT Name,Email,Phone FROM Contact WHERE Title = 'Purchasing Manager' OR Department = 'Accounting'"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with where clause with joiner=AND passed", func() {+ BeforeEach(func() {+ soqlStruct = andSOQLQuery{+ WhereClause: positionOrDeptCriteria{+ Title: "Purchasing Manager",+ Department: "Accounting",+ },+ }+ expectedQuery = "SELECT Name,Email,Phone FROM Contact WHERE Title = 'Purchasing Manager' AND Department = 'Accounting'"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with where clause with joiner=ELSE (an invalid value) passed", func() {+ BeforeEach(func() {+ soqlStruct = invalidJoinerSOQLQuery{+ WhereClause: positionOrDeptCriteria{+ Title: "Purchasing Manager",+ Department: "Accounting",+ },+ }+ expectedQuery = "SELECT Name,Email,Phone FROM Contact WHERE Title = 'Purchasing Manager' AND Department = 'Accounting'"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())
I think we should return ErrInvalidTag in this case. If value of joiner is anything other than or or and (case insensitive) then we should throw an error. It will prevent surprises for the user.
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
Build out subfilter and OR logical operator support
func marshalWhereClause(v interface{}, tableName string) (string, error) { fieldType := reflectedType.Field(i) clauseTag := fieldType.Tag.Get(SoqlTag) clauseKey := getClauseKey(clauseTag)- fieldName := getFieldName(clauseTag, fieldType.Name)- if fieldName == "" {- return "", ErrInvalidTag- }- fn, ok := clauseBuilderMap[clauseKey]- if !ok {- return "", ErrInvalidTag- }- columnName := fieldName- if tableName != "" {- columnName = tableName + period + fieldName- }- partialClause, err := fn(field.Interface(), columnName)- if err != nil {- return "", err+ var partialClause string+ if clauseKey == Subquery {+ if field.Kind() != reflect.Struct {+ return "", ErrInvalidTag+ }+ partialClause, err = marshalWhereClause(field.Interface(), tableName, getJoiner(clauseTag))+ if err != nil {+ return "", err+ }++ partialClause = "(" + partialClause + ")"
Use openBrace and closeBrace constants instead of ( and ) string literals
comment created time in 2 months
issue closedforcedotcom/go-soql
*bool is not supported in buildEqualsClause
There is an issue with boolean conditions in buildEqualsClause: when bool fields are initialized, they default to "false" if a condition is not present, which Is not necessarily desirable behavior. I suggest to add *bool support and ignore those field if they're nil.
closed time in 2 months
dmaykovissue commentforcedotcom/go-soql
*bool is not supported in buildEqualsClause
Closed by https://github.com/forcedotcom/go-soql/pull/12
comment created time in 2 months
push eventforcedotcom/go-soql
commit sha 5a4ce53c16df04bdc355a61cc4a4b9de187c552b
Add support for pointer data types in comparison operators
commit sha 7eb58e078f5a9ec06430daf8b3805429531574b1
Merge pull request #12 from forcedotcom/issues/9/bool-ptr-support-equals Add support for pointer data types in comparison operators
push time in 2 months
PR merged forcedotcom/go-soql
pr closed time in 2 months
PR opened forcedotcom/go-soql
pr created time in 2 months
create barnchforcedotcom/go-soql
branch : issues/9/bool-ptr-support-equals
created branch time in 2 months
push eventforcedotcom/go-soql
commit sha 4acb59b9acf19b550f151c76dcc074b8d332be35
Sanitize strings before using them in where clause
commit sha 1c94ce3a5a454a2a0b04b64f8cf7de7d9eb5e4ff
Merge pull request #11 from forcedotcom/issues/7/escape-single-quote Sanitize strings before using them in where clause
push time in 2 months
issue closedforcedotcom/go-soql
Escape Single Quotes in WHERE clauses
Where clauses with ' are not escaped, causing 400 bad requests (in the best case) for the likeOperator.
The following code outputs: SELECT Name FROM Account WHERE Name LIKE '%Blips 'n' Chitz%'
I would expect it to be: SELECT Name FROM Account WHERE Name LIKE '%Blips \'n\' Chitz%'
package main
import (
"github.com/forcedotcom/go-soql"
"log"
)
type Account struct {
Name string `soql:"selectColumn,fieldName=Name" json:"Name"`
}
type AccountQueryCriteria struct {
AccountName []string `soql:"likeOperator,fieldName=Name"`
}
type AccountSoqlQuery struct {
SelectClause Account `soql:"selectClause,tableName=Account"`
WhereClause AccountQueryCriteria `soql:"whereClause"`
}
func main() {
soqlStruct := AccountSoqlQuery{
SelectClause: Account{},
WhereClause: AccountQueryCriteria{
AccountName: []string{"Blips 'n' Chitz"},
},
}
soqlQuery, err := soql.Marshal(soqlStruct)
if err != nil {
log.Fatal(err)
}
log.Println(soqlQuery)
}
closed time in 2 months
asgainesissue closedforcedotcom/go-soql
Add support for limit and offset clause
Add support to tag int member with limitClause and offsetClause and include it in generated SOQL query. Here is how it should work:
type TestSoqlStruct struct {
SelectClause NonNestedStruct `soql:"selectClause,tableName=SM_SomeObject__c"`
WhereClause TestQueryCriteria `soql:"whereClause"`
Limit int `soql:"limitClause"`
Offset 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"`
}
o use above structs to create SOQL query
soqlStruct := TestSoqlStruct{
WhereClause: TestQueryCriteria {
IncludeNamePattern: []string{"foo", "bar"},
Roles: []string{"admin", "user"},
}
Limit: 10,
Offset: 5,
}
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,SomeValue__c FROM SM_SomeObject__C WHERE (Name__c LIKE '%foo%' OR Name__c LIKE '%bar%') AND Role__c IN ('admin','user') LIMIT 10 OFFSET 5
closed time in 2 months
atulkcissue commentforcedotcom/go-soql
Add support for limit and offset clause
Closed by https://github.com/forcedotcom/go-soql/pull/10
comment created time in 2 months
push eventforcedotcom/go-soql
commit sha 2a9aa5de5c75352c5da8104e4d45ff459a950564
Add support for limit and offset clauses * limit implemented * working my way through offset * offset working, just need to handle child select case * corrections to comments * added test cases for limit 0, offset 0, and limit and offset * better variable name in marshalIntValue * Updated so that LIMIT and OFFSET can be 0 * update readme to document limit and offset
commit sha 4acb59b9acf19b550f151c76dcc074b8d332be35
Sanitize strings before using them in where clause
push time in 2 months
push eventforcedotcom/go-soql
commit sha 2a9aa5de5c75352c5da8104e4d45ff459a950564
Add support for limit and offset clauses * limit implemented * working my way through offset * offset working, just need to handle child select case * corrections to comments * added test cases for limit 0, offset 0, and limit and offset * better variable name in marshalIntValue * Updated so that LIMIT and OFFSET can be 0 * update readme to document limit and offset
push time in 2 months
PR merged forcedotcom/go-soql
Added support for limit and offset with tests. I considered making offset on a child query an error since I don't believe Salesforce supports that behavior, but changed my mind so that select structs could be used as parents or children.
pr closed time in 2 months
Pull request review commentforcedotcom/go-soql
func marshalOrderByClause(v interface{}, tableName string, s interface{}) (strin } +// v is the limit value provided+func marshalLimitClause(v interface{}) (string, error) {+ s, err := marshalIntValue(v)+ if err != nil {+ return "", ErrInvalidLimitClause+ }+ return s, nil+}++// v is the offset value provided+func marshalOffsetClause(v interface{}) (string, error) {+ s, err := marshalIntValue(v)+ if err != nil {+ return "", ErrInvalidOffsetClause+ }+ return s, nil+}++func marshalIntValue(v interface{}) (string, error) {+ limit, ok := v.(int)+ if !ok {+ return "", errors.New("invalid type")+ }+ if limit < 0 {+ return "", errors.New("invalid value")+ }++ var vString string+ if limit > 0 {
Also, please make sure you update README to include limitClause and offsetClause details. Adding it to Advanced Usage section is sufficient.
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
func marshalOrderByClause(v interface{}, tableName string, s interface{}) (strin } +// v is the limit value provided+func marshalLimitClause(v interface{}) (string, error) {+ s, err := marshalIntValue(v)+ if err != nil {+ return "", ErrInvalidLimitClause+ }+ return s, nil+}++// v is the offset value provided+func marshalOffsetClause(v interface{}) (string, error) {+ s, err := marshalIntValue(v)+ if err != nil {+ return "", ErrInvalidOffsetClause+ }+ return s, nil+}++func marshalIntValue(v interface{}) (string, error) {+ limit, ok := v.(int)+ if !ok {+ return "", errors.New("invalid type")+ }+ if limit < 0 {+ return "", errors.New("invalid value")+ }++ var vString string+ if limit > 0 {
You are right, let's only allow int* for limitClause. For offsetClause it is ok to have both int and int*.
Adding func Int(v int) *int will feel little out of place for this library. I think we will leave it to the users of library to create pointers.
comment created time in 2 months
create barnchforcedotcom/go-soql
branch : issues/7/escape-single-quote
created branch time in 2 months
issue commentforcedotcom/go-soql
*bool is not supported in buildEqualsClause
Thanks for filing the issue. I will schedule this to be done in next couple of weeks. Sorry for the delay in response!
comment created time in 2 months
issue commentforcedotcom/go-soql
Escape Single Quotes in WHERE clauses
Thanks for filing the issue. I will schedule this to be done over next couple of weeks. Sorry for the delay in response.
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
const ( WhereClause = "whereClause" // OrderByClause is the tag to be used when marking the string slice to be considered for order by clause OrderByClause = "orderByClause"+ // LimitClause is the tag to be used when marking the string slice to be considered for limit clause
Need to fix the comment to indicate that limit clause will be used for int and not string slice
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
const ( WhereClause = "whereClause" // OrderByClause is the tag to be used when marking the string slice to be considered for order by clause OrderByClause = "orderByClause"+ // LimitClause is the tag to be used when marking the string slice to be considered for limit clause+ LimitClause = "limitClause"+ // OffsetClause is the tag to be used when marking the string slice to be considered for offset clause
Need to fix the comment as indicated above for LimitClause
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
var _ = Describe("Marshaller", func() { Expect(actualQuery).To(Equal(expectedQuery)) }) })++ Context("when a struct with limit value is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlLimitStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Limit: 5,+ }+ expectedQuery = "SELECT Id,Name__c,NonNestedStruct__r.Name,NonNestedStruct__r.SomeValue__c FROM SM_Logical_Host__c WHERE (Host_Name__c LIKE '%-db%' OR Host_Name__c LIKE '%-dbmgmt%') AND Role__r.Name IN ('db','dbmgmt') LIMIT 5"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct without limit value is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlLimitStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ }+ expectedQuery = "SELECT Id,Name__c,NonNestedStruct__r.Name,NonNestedStruct__r.SomeValue__c FROM SM_Logical_Host__c WHERE (Host_Name__c LIKE '%-db%' OR Host_Name__c LIKE '%-dbmgmt%') AND Role__r.Name IN ('db','dbmgmt')"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with invalid limit type is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlInvalidLimitStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Limit: "5",+ }+ })++ It("returns error", func() {+ Expect(err).To(Equal(ErrInvalidLimitClause))+ })+ })++ Context("when a struct with invalid limit value is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlLimitStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Limit: -5,+ }+ })++ It("returns error", func() {+ Expect(err).To(Equal(ErrInvalidLimitClause))+ })+ })++ Context("when a struct with multiple limit values is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlMultipleLimitStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Limit: 5,+ AlsoLimit: 15,+ }+ })++ It("returns error", func() {+ Expect(err).To(Equal(ErrMultipleLimitClause))+ })+ })++ Context("when a struct with limit inside a child relation is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlChildRelationLimitStruct{+ SelectClause: ParentLimitStruct{+ ChildStruct: ChildLimitStruct{+ Limit: 1,+ },+ },+ }+ expectedQuery = "SELECT Id,Name__c,(SELECT Application_Versions__c.Id,Application_Versions__c.Version__c FROM Application_Versions__r LIMIT 1) FROM SM_Logical_Host__c"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with limit inside a child relation is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlChildRelationLimitStruct{+ SelectClause: ParentLimitStruct{+ ChildStruct: ChildLimitStruct{+ Limit: 10,+ },+ },+ Limit: 25,+ }+ expectedQuery = "SELECT Id,Name__c,(SELECT Application_Versions__c.Id,Application_Versions__c.Version__c FROM Application_Versions__r LIMIT 10) FROM SM_Logical_Host__c LIMIT 25"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with offset value is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlOffsetStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Offset: 5,+ }+ expectedQuery = "SELECT Id,Name__c,NonNestedStruct__r.Name,NonNestedStruct__r.SomeValue__c FROM SM_Logical_Host__c WHERE (Host_Name__c LIKE '%-db%' OR Host_Name__c LIKE '%-dbmgmt%') AND Role__r.Name IN ('db','dbmgmt') OFFSET 5"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct without offset value is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlOffsetStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ }+ expectedQuery = "SELECT Id,Name__c,NonNestedStruct__r.Name,NonNestedStruct__r.SomeValue__c FROM SM_Logical_Host__c WHERE (Host_Name__c LIKE '%-db%' OR Host_Name__c LIKE '%-dbmgmt%') AND Role__r.Name IN ('db','dbmgmt')"+ })++ It("returns properly constructed soql query", func() {+ Expect(err).ToNot(HaveOccurred())+ Expect(actualQuery).To(Equal(expectedQuery))+ })+ })++ Context("when a struct with invalid offset type is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlInvalidOffsetStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Offset: "5",+ }+ })++ It("returns error", func() {+ Expect(err).To(Equal(ErrInvalidOffsetClause))+ })+ })++ Context("when a struct with invalid offset value is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlOffsetStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Offset: -5,+ }+ })++ It("returns error", func() {+ Expect(err).To(Equal(ErrInvalidOffsetClause))+ })+ })++ Context("when a struct with multiple offset values is passed", func() {+ BeforeEach(func() {+ soqlStruct = TestSoqlMultipleOffsetStruct{+ SelectClause: NestedStruct{},+ WhereClause: TestQueryCriteria{+ IncludeNamePattern: []string{"-db", "-dbmgmt"},+ Roles: []string{"db", "dbmgmt"},+ },+ Offset: 5,+ AlsoOffset: 15,+ }+ })++ It("returns error", func() {+ Expect(err).To(Equal(ErrMultipleOffsetClause))+ })+ })
I think following test cases should be added:
- Both limit and offset are present.
- When offset is 0
- When limit is 0
comment created time in 2 months
Pull request review commentforcedotcom/go-soql
func marshalOrderByClause(v interface{}, tableName string, s interface{}) (strin } +// v is the limit value provided+func marshalLimitClause(v interface{}) (string, error) {+ s, err := marshalIntValue(v)+ if err != nil {+ return "", ErrInvalidLimitClause+ }+ return s, nil+}++// v is the offset value provided+func marshalOffsetClause(v interface{}) (string, error) {+ s, err := marshalIntValue(v)+ if err != nil {+ return "", ErrInvalidOffsetClause+ }+ return s, nil+}++func marshalIntValue(v interface{}) (string, error) {+ limit, ok := v.(int)+ if !ok {+ return "", errors.New("invalid type")+ }+ if limit < 0 {+ return "", errors.New("invalid value")+ }++ var vString string+ if limit > 0 {
Since marshalIntValue will be used for both offset and limit this check would prevent us from having OFFSET 0 in the query.
comment created time in 2 months