rimashah25 commented on code in PR #7575:
URL: https://github.com/apache/trafficcontrol/pull/7575#discussion_r1253319515


##########
traffic_ops/traffic_ops_golang/routing/routes.go:
##########
@@ -345,10 +345,10 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
                {Version: api.Version{Major: 5, Minor: 0}, Method: 
http.MethodGet, Path: `system/info/?$`, Handler: systeminfo.Get, 
RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: nil, 
Authenticated: Authenticated, Middlewares: nil, ID: 42104747531},
 
                //Type: CRUD

Review Comment:
   nit: Since this is the first time for creating this functions (in API v5), I 
don't think you need to specify `V5` in the functions.



##########
traffic_ops/traffic_ops_golang/types/types.go:
##########
@@ -211,3 +214,238 @@ func deleteQuery() string {
 WHERE id=:id`
        return query
 }
+
+// GetV5 [Version :V5] - GetV5 will retrieve a list of types for APIv5
+func GetV5(w http.ResponseWriter, r *http.Request) {
+       var runSecond bool
+       var maxTime time.Time
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       tx := inf.Tx
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx.Tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+
+       // Query Parameters to Database Query column mappings
+       queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
+               "name":       {Column: "typ.name"},
+               "id":         {Column: "typ.id", Checker: api.IsInt},
+               "useInTable": {Column: "typ.use_in_table"},
+       }
+       if _, ok := inf.Params["orderby"]; !ok {
+               inf.Params["orderby"] = "name"
+       }
+       where, orderBy, pagination, queryValues, errs := 
dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToQueryCols)
+       if len(errs) > 0 {
+               api.HandleErr(w, r, tx.Tx, http.StatusBadRequest, 
util.JoinErrs(errs), nil)
+       }
+
+       if inf.Config.UseIMS {
+               runSecond, maxTime = ims.TryIfModifiedSinceQuery(tx, r.Header, 
queryValues, SelectMaxLastUpdatedQuery(where))
+               if !runSecond {
+                       log.Debugln("IMS HIT")
+                       api.AddLastModifiedHdr(w, maxTime)
+                       w.WriteHeader(http.StatusNotModified)
+                       return
+               }
+               log.Debugln("IMS MISS")
+       } else {
+               log.Debugln("Non IMS request")
+       }
+
+       query := selectQuery() + where + orderBy + pagination
+       rows, err := tx.NamedQuery(query, queryValues)
+       if err != nil {
+               api.HandleErr(w, r, tx.Tx, http.StatusInternalServerError, nil, 
fmt.Errorf("type get: error getting type(s): %w", err))
+       }
+       defer log.Close(rows, "unable to close DB connection")
+
+       typ := tc.TypeV5{}
+       typeList := []tc.TypeV5{}
+       for rows.Next() {
+               if err = rows.Scan(&typ.ID, &typ.Name, &typ.Description, 
&typ.UseInTable, &typ.LastUpdated); err != nil {
+                       api.HandleErr(w, r, tx.Tx, 
http.StatusInternalServerError, nil, fmt.Errorf("error getting type(s): %w", 
err))
+               }
+               typeList = append(typeList, typ)
+       }
+
+       api.WriteResp(w, r, typeList)
+       return
+}
+
+// CreateType [Version : V5] - CreateTypeV5 function creates the type with the 
passed data.
+func CreateTypeV5(w http.ResponseWriter, r *http.Request) {
+       typ := tc.TypeV5{}
+
+       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()
+       tx := inf.Tx.Tx
+
+       typ, readValErr := readAndValidateJsonStructV5(r)
+       if readValErr != nil {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, readValErr, nil)
+               return
+       }
+
+       if typ.UseInTable != "server" {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, fmt.Errorf("can 
not create type."), nil)
+               return
+       }
+
+       // check if type already exists
+       var exists bool
+       err := tx.QueryRow(`SELECT EXISTS(SELECT * from type where name = $1)`, 
typ.Name).Scan(&exists)
+
+       if err != nil {
+               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("error: %w, when checking if type with name %s exists", err, 
typ.Name))
+               return
+       }
+       if exists {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, fmt.Errorf("type 
name '%s' already exists.", typ.Name), nil)
+               return
+       }
+
+       // create type
+       query := `INSERT INTO type (name, description, use_in_table) VALUES 
($1, $2, $3) RETURNING id,last_updated`
+       err = tx.QueryRow(query, typ.Name, typ.Description, 
typ.UseInTable).Scan(&typ.ID, &typ.LastUpdated)
+       if err != nil {
+               if errors.Is(err, sql.ErrNoRows) {
+                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
fmt.Errorf("error: %w in creating type with name: %s", err, typ.Name), nil)
+                       return
+               }
+               usrErr, sysErr, code := api.ParseDBError(err)
+               api.HandleErr(w, r, tx, code, usrErr, sysErr)
+               return
+       }
+       alerts := tc.CreateAlerts(tc.SuccessLevel, "type was created.")
+       w.Header().Set("Location", fmt.Sprintf("/api/%d.%d/type?name=%s", 
inf.Version.Major, inf.Version.Minor, typ.Name))
+       api.WriteAlertsObj(w, r, http.StatusCreated, alerts, typ)
+       return
+}
+
+// UpdateType [Version : V5] - UpdateTypeV5 function updates name & 
description of the type passed.
+func UpdateTypeV5(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()
+       tx := inf.Tx.Tx
+
+       typ, readValErr := readAndValidateJsonStructV5(r)
+       if readValErr != nil {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, readValErr, nil)
+               return
+       }
+
+       requestedId := inf.Params["id"]
+       // check if the entity was already updated
+       userErr, sysErr, errCode = api.CheckIfUnModifiedByName(r.Header, 
inf.Tx, requestedId, "type")

Review Comment:
   You are passing the `id` to check, so you should use `api.CheckIfUnModified` 
which check for `id` columnn. `api.CheckIfUnModifiedByName` check for `name` 
column



-- 
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