forcedotcom / go-soql

Golang tag library to generate SOQL queries
BSD 3-Clause "New" or "Revised" License
52 stars 12 forks source link

Add support for count function in SOQL #20

Open atulkc opened 4 years ago

atulkc commented 4 years ago

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"`
}

soqlStruct := TestSoqlStruct{
   WhereClause: TestQueryCriteria {
        IncludeNamePattern: []string{"a"},
    },
}
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 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

benflodge commented 2 years ago

As a workaround i have been using something like this:-

type TestSoqlStruct struct {
    SelectClause struct {
        Count string `soql:"selectColumn,fieldName=COUNT()"`
    } `soql:"selectClause,tableName=Account"`
    WhereClause TestQueryCriteria `soql:"whereClause`
}

Response: {"totalSize":1,"done":true,"records":[]}