soql/query.go (105 lines of code) (raw):

package soql import ( "encoding/json" "errors" "fmt" "net/http" "net/url" "github.com/elastic/go-sfdc" "github.com/elastic/go-sfdc/session" ) // Resource is the structure for the Salesforce // SOQL API resource. type Resource struct { session session.ServiceFormatter } // NewResource forms the Salesforce SOQL resource. The // session formatter is required to form the proper URLs and authorization // header. func NewResource(session session.ServiceFormatter) (*Resource, error) { if session == nil { return nil, errors.New("soql: session can not be nil") } return &Resource{ session: session, }, nil } // Query will call out to the Salesforce org for a SOQL. The results will // be the result of the query. The all parameter is for querying all records, // which include deleted records that are in the recycle bin. func (r *Resource) Query(querier QueryFormatter, all bool) (*QueryResult, error) { if querier == nil { return nil, errors.New("soql resource query: querier can not be nil") } request, err := r.queryRequest(querier, all) if err != nil { return nil, err } response, err := r.queryResponse(request) if err != nil { return nil, err } result, err := newQueryResult(response, r) if err != nil { return nil, err } return result, nil } func (r *Resource) next(recordURL string) (*QueryResult, error) { queryURL := r.session.InstanceURL() + recordURL request, err := http.NewRequest(http.MethodGet, queryURL, nil) if err != nil { return nil, err } request.Header.Add("Accept", "application/json") r.session.AuthorizationHeader(request) response, err := r.queryResponse(request) if err != nil { return nil, err } result, err := newQueryResult(response, r) if err != nil { return nil, err } return result, nil } func (r *Resource) queryRequest(querier QueryFormatter, all bool) (*http.Request, error) { query, err := querier.Format() if err != nil { return nil, err } endpoint := "/query" if all { endpoint += "All" } queryURL := r.session.ServiceURL() + endpoint + "/" form := url.Values{} form.Add("q", query) queryURL += "?" + form.Encode() request, err := http.NewRequest(http.MethodGet, queryURL, nil) if err != nil { return nil, err } request.Header.Add("Accept", "application/json") r.session.AuthorizationHeader(request) return request, nil } func (r *Resource) queryResponse(request *http.Request) (queryResponse, error) { response, err := r.session.Client().Do(request) if err != nil { return queryResponse{}, err } decoder := json.NewDecoder(response.Body) defer response.Body.Close() if response.StatusCode != http.StatusOK { var queryErrs []sfdc.Error err = decoder.Decode(&queryErrs) var errMsg error if err == nil { for _, queryErr := range queryErrs { errMsg = fmt.Errorf("insert response err: %s: %s", queryErr.ErrorCode, queryErr.Message) } } else { errMsg = fmt.Errorf("insert response err: %d %s", response.StatusCode, response.Status) } return queryResponse{}, errMsg } var resp queryResponse err = decoder.Decode(&resp) if err != nil { return queryResponse{}, err } return resp, nil }