jagan-parthiban commented on code in PR #7408:
URL: https://github.com/apache/trafficcontrol/pull/7408#discussion_r1163917477


##########
traffic_ops/traffic_ops_golang/servicecategory/servicecategories.go:
##########
@@ -187,3 +191,317 @@ WHERE name=$2 RETURNING last_updated`
 func deleteQuery() string {
        return `DELETE FROM service_category WHERE name=:name`
 }
+
+// Get [Version : V5] function Process the *http.Request and writes the 
response. It uses GetServiceCategory function.
+func Get(w http.ResponseWriter, r *http.Request) {
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+
+       code := http.StatusOK
+       useIMS := false
+       config, e := api.GetConfig(r.Context())
+       if e == nil && config != nil {
+               useIMS = config.UseIMS
+       } else {
+               log.Warnf("Couldn't get config %v", e)
+       }
+
+       var maxTime *time.Time
+       var err error
+       var scList []tc.ServiceCategoryV5
+
+       tx := inf.Tx
+
+       scList, err, code, maxTime = GetServiceCategory(tx, inf.Params, useIMS, 
r.Header)
+       if code == http.StatusNotModified {
+               w.WriteHeader(code)
+               api.WriteResp(w, r, []tc.ServiceCategoryV5{})
+               return
+       }
+
+       if code == http.StatusBadRequest {
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, 
errors.New(err.Error()), nil)
+               return
+       }
+
+       if err != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
nil, errors.New("Service category errors: "+err.Error()))
+               return
+       }
+
+       if maxTime != nil && api.SetLastModifiedHeader(r, useIMS) {
+               api.AddLastModifiedHdr(w, *maxTime)
+       }
+
+       api.WriteResp(w, r, scList)
+}
+
+// GetServiceCategory [Version : V5] receives transactions from Get function 
and returns service_categories list.
+func GetServiceCategory(tx *sqlx.Tx, params map[string]string, useIMS bool, 
header http.Header) ([]tc.ServiceCategoryV5, error, int, *time.Time) {
+       var runSecond bool
+       var maxTime time.Time
+       scList := []tc.ServiceCategoryV5{}
+
+       selectQuery := `SELECT name, last_updated FROM service_category as sc`
+
+       // Query Parameters to Database Query column mappings
+       queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
+               "name": {Column: "sc.name", Checker: nil},
+       }
+       if _, ok := params["orderby"]; !ok {
+               params["orderby"] = "name"
+       }
+       where, orderBy, pagination, queryValues, errs := 
dbhelpers.BuildWhereAndOrderByAndPagination(params, queryParamsToQueryCols)
+       if len(errs) > 0 {
+               return nil, util.JoinErrs(errs), http.StatusBadRequest, nil
+       }
+
+       if useIMS {
+               runSecond, maxTime = TryIfModifiedSinceQuery(header, tx, where, 
queryValues)
+               if !runSecond {
+                       log.Debugln("IMS HIT")
+                       return scList, nil, http.StatusNotModified, &maxTime
+               }
+               log.Debugln("IMS MISS")
+       } else {
+               log.Debugln("Non IMS request")
+       }
+       query := selectQuery + where + orderBy + pagination
+       rows, err := tx.NamedQuery(query, queryValues)
+       if err != nil {
+               return nil, errors.New("service category read: error getting 
service category(ies): " + err.Error()), http.StatusInternalServerError, nil
+       }
+       defer rows.Close()
+
+       for rows.Next() {
+               sc := tc.ServiceCategoryV5{}
+               if err = rows.Scan(&sc.Name, &sc.LastUpdated); err != nil {
+                       return nil, errors.New("error getting service 
category(ies): " + err.Error()), http.StatusInternalServerError, nil
+               }
+               scList = append(scList, sc)
+       }
+
+       return scList, nil, http.StatusOK, &maxTime
+}
+
+// TryIfModifiedSinceQuery [Version : V5] function receives transactions and 
header from GetServiceCategory function and returns bool value if status is not 
modified.
+func TryIfModifiedSinceQuery(header http.Header, tx *sqlx.Tx, where string, 
queryValues map[string]interface{}) (bool, time.Time) {
+       var max time.Time
+       var imsDate time.Time
+       var ok bool
+       imsDateHeader := []string{}
+       runSecond := true
+       dontRunSecond := false
+
+       if header == nil {
+               return runSecond, max
+       }
+
+       imsDateHeader = header[rfc.IfModifiedSince]
+       if len(imsDateHeader) == 0 {
+               return runSecond, max
+       }
+
+       if imsDate, ok = rfc.ParseHTTPDate(imsDateHeader[0]); !ok {
+               log.Warnf("IMS request header date '%s' not parsable", 
imsDateHeader[0])
+               return runSecond, max
+       }
+
+       imsQuery := `SELECT max(last_updated) as t from service_category sc`
+       query := imsQuery + where
+       rows, err := tx.NamedQuery(query, queryValues)

Review Comment:
   Initially tried QueryRow but it was unsuccessful. Parent function using 
*sqlx and since QuerRow is a one sql operation which led to type miss match on 
arguments. BuildWhereAndOrderByAndPagination which gives queryValues of type 
map[string]WhereColumnInfo, QueryRow would not accept this format and conveting 
it led to unnecessary complexity.  Later referred Generic cruder and some other 
services in V4 and V5 which used NamedQuery in this scenario. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to