You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2018/07/04 02:39:28 UTC
[trafficcontrol] 03/15: converted all packages to use db-less
interfaces
This is an automated email from the ASF dual-hosted git repository.
dangogh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit 084310b24bff938bf2d8c0b8602adbe45ddd8186
Author: Dylan Volz <Dy...@comcast.com>
AuthorDate: Tue Jun 26 17:08:29 2018 -0600
converted all packages to use db-less interfaces
---
.../traffic_ops_golang/api/shared_handlers.go | 46 +++++++
.../deliveryservice/deliveryservicesv12.go | 4 +-
.../deliveryservice/deliveryservicesv13.go | 4 +-
.../deliveryservice/servers/servers.go | 18 ++-
.../traffic_ops_golang/parameter/parameters.go | 146 ++++++---------------
.../parameter/parameters_test.go | 9 +-
.../physlocation/phys_locations.go | 100 +++-----------
.../physlocation/phys_locations_test.go | 10 +-
traffic_ops/traffic_ops_golang/profile/profiles.go | 108 ++++-----------
.../traffic_ops_golang/profile/profiles_test.go | 10 +-
.../profileparameter/profile_parameters.go | 79 +++--------
.../profileparameter/profile_parameters_test.go | 9 +-
traffic_ops/traffic_ops_golang/region/regions.go | 102 +++-----------
.../traffic_ops_golang/region/regions_test.go | 10 +-
traffic_ops/traffic_ops_golang/role/roles.go | 119 ++++-------------
traffic_ops/traffic_ops_golang/role/roles_test.go | 9 +-
traffic_ops/traffic_ops_golang/routes.go | 120 ++++++++---------
traffic_ops/traffic_ops_golang/server/servers.go | 114 ++++------------
.../traffic_ops_golang/server/servers_test.go | 3 +-
.../staticdnsentry/staticdnsentry.go | 19 ++-
traffic_ops/traffic_ops_golang/status/statuses.go | 103 +++------------
.../traffic_ops_golang/status/statuses_test.go | 10 +-
traffic_ops/traffic_ops_golang/types/types.go | 102 +++-----------
traffic_ops/traffic_ops_golang/types/types_test.go | 11 +-
24 files changed, 407 insertions(+), 858 deletions(-)
diff --git a/traffic_ops/traffic_ops_golang/api/shared_handlers.go b/traffic_ops/traffic_ops_golang/api/shared_handlers.go
index b01eb85..4a10cdb 100644
--- a/traffic_ops/traffic_ops_golang/api/shared_handlers.go
+++ b/traffic_ops/traffic_ops_golang/api/shared_handlers.go
@@ -162,6 +162,52 @@ func ReadHandler(typeFactory func(reqInfo *APIInfo) CRUDer) http.HandlerFunc {
}
}
+//this creates a handler function from the pointer to a struct implementing the Reader interface
+// this handler retrieves the user from the context
+// combines the path and query parameters
+// produces the proper status code based on the error code returned
+// marshals the structs returned into the proper response json
+func ReadOnlyHandler(typeFactory func(reqInfo *APIInfo) Reader) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ //create error function with ResponseWriter and Request
+ handleErrs := tc.GetHandleErrorsFunc(w, r)
+
+ inf, userErr, sysErr, errCode := NewInfo(r, nil, nil)
+ if userErr != nil || sysErr != nil {
+ HandleErr(w, r, errCode, userErr, sysErr)
+ return
+ }
+ defer inf.Close()
+
+ // Load the PathParams into the query parameters for pass through
+ params, err := GetCombinedParams(r)
+ if err != nil {
+ log.Errorf("unable to get parameters from request: %s", err)
+ handleErrs(http.StatusInternalServerError, err)
+ }
+
+ reader := typeFactory(inf)
+
+ results, errs, errType := reader.Read(params)
+ if len(errs) > 0 {
+ tc.HandleErrorsWithType(errs, errType, handleErrs)
+ return
+ }
+ resp := struct {
+ Response []interface{} `json:"response"`
+ }{results}
+
+ respBts, err := json.Marshal(resp)
+ if err != nil {
+ handleErrs(http.StatusInternalServerError, err)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ fmt.Fprintf(w, "%s", respBts)
+ }
+}
+
//this creates a handler function from the pointer to a struct implementing the Updater interface
//it must be immediately assigned to a local variable
// this generic handler encapsulates the logic for handling:
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index a783a90..aa0d36a 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -126,8 +126,8 @@ func GetXMLID(tx *sql.Tx, id int) (string, bool, error) {
// IsTenantAuthorized checks that the user is authorized for both the delivery service's existing tenant, and the new tenant they're changing it to (if different).
-func (ds *TODeliveryServiceV12) IsTenantAuthorized(user *auth.CurrentUser, tx *sqlx.Tx) (bool, error) {
- return isTenantAuthorized(user, tx, &ds.DeliveryServiceNullableV12)
+func (ds *TODeliveryServiceV12) IsTenantAuthorized(user *auth.CurrentUser) (bool, error) {
+ return isTenantAuthorized(user, ds.ReqInfo.Tx, &ds.DeliveryServiceNullableV12)
}
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
index 994d498..23d9d01 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
@@ -579,8 +579,8 @@ func (ds *TODeliveryServiceV13) Delete() (error, tc.ApiErrorType) {
}
// IsTenantAuthorized implements the Tenantable interface to ensure the user is authorized on the deliveryservice tenant
-func (ds *TODeliveryServiceV13) IsTenantAuthorized(user *auth.CurrentUser, tx *sqlx.Tx) (bool, error) {
- return ds.V12().IsTenantAuthorized(user, tx)
+func (ds *TODeliveryServiceV13) IsTenantAuthorized(user *auth.CurrentUser) (bool, error) {
+ return ds.V12().IsTenantAuthorized(user)
}
func filterAuthorized(dses []tc.DeliveryServiceNullableV13, user *auth.CurrentUser, db *sqlx.DB) ([]tc.DeliveryServiceNullableV13, error) {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index a497946..48406af 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -713,16 +713,20 @@ func dssSelectQuery() string {
return selectStmt
}
-type TODSSDeliveryService tc.DSSDeliveryService
-
-var dserviceRef = TODSSDeliveryService(tc.DSSDeliveryService{})
+type TODSSDeliveryService struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.DSSDeliveryService
+}
-func GetDServiceRef() *TODSSDeliveryService {
- return &dserviceRef
+func GetDSSDeliveryServiceReaderSingleton() func(reqInfo *api.APIInfo)api.Reader {
+ return func(reqInfo *api.APIInfo)api.Reader {
+ toReturn := TODSSDeliveryService{reqInfo, tc.DSSDeliveryService{}}
+ return &toReturn
+ }
}
// Read shows all of the delivery services associated with the specified server.
-func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (dss *TODSSDeliveryService) Read(params map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var err error = nil
orderby := params["orderby"]
serverId := params["id"]
@@ -734,7 +738,7 @@ func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, use
query := SDSSelectQuery()
log.Debugln("Query is ", query)
- rows, err := db.Queryx(query, serverId)
+ rows, err := dss.ReqInfo.Tx.Queryx(query, serverId)
if err != nil {
log.Errorf("Error querying DeliveryserviceServers: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
diff --git a/traffic_ops/traffic_ops_golang/parameter/parameters.go b/traffic_ops/traffic_ops_golang/parameter/parameters.go
index 87057e5..a948c01 100644
--- a/traffic_ops/traffic_ops_golang/parameter/parameters.go
+++ b/traffic_ops/traffic_ops_golang/parameter/parameters.go
@@ -49,57 +49,59 @@ var (
)
//we need a type alias to define functions on
-type TOParameter tc.ParameterNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOParameter(tc.ParameterNullable{})
+type TOParameter struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.ParameterNullable
+}
-func GetRefType() *TOParameter {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOParameter{reqInfo, tc.ParameterNullable{}}
+ return &toReturn
+ }
}
-func (parameter TOParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
+func (param TOParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
return []api.KeyFieldInfo{{IDQueryParam, api.GetIntKey}}
}
//Implementation of the Identifier, Validator interface functions
-func (parameter TOParameter) GetKeys() (map[string]interface{}, bool) {
- if parameter.ID == nil {
+func (param TOParameter) GetKeys() (map[string]interface{}, bool) {
+ if param.ID == nil {
return map[string]interface{}{IDQueryParam: 0}, false
}
- return map[string]interface{}{IDQueryParam: *parameter.ID}, true
+ return map[string]interface{}{IDQueryParam: *param.ID}, true
}
-func (parameter *TOParameter) SetKeys(keys map[string]interface{}) {
+func (param *TOParameter) SetKeys(keys map[string]interface{}) {
i, _ := keys[IDQueryParam].(int) //this utilizes the non panicking type assertion, if the thrown away ok variable is false i will be the zero of the type, 0 here.
- parameter.ID = &i
+ param.ID = &i
}
-func (parameter *TOParameter) GetAuditName() string {
- if parameter.Name != nil {
- return *parameter.Name
+func (param *TOParameter) GetAuditName() string {
+ if param.Name != nil {
+ return *param.Name
}
- if parameter.ID != nil {
- return strconv.Itoa(*parameter.ID)
+ if param.ID != nil {
+ return strconv.Itoa(*param.ID)
}
return "unknown"
}
-func (parameter *TOParameter) GetType() string {
- return "parameter"
+func (param *TOParameter) GetType() string {
+ return "param"
}
// Validate fulfills the api.Validator interface
-func (parameter TOParameter) Validate(db *sqlx.DB) []error {
-
+func (param TOParameter) Validate() []error {
// Test
// - Secure Flag is always set to either 1/0
// - Admin rights only
// - Do not allow duplicate parameters by name+config_file+value
errs := validation.Errors{
- NameQueryParam: validation.Validate(parameter.Name, validation.Required),
- ConfigFileQueryParam: validation.Validate(parameter.ConfigFile, validation.Required),
- ValueQueryParam: validation.Validate(parameter.Value, validation.Required),
+ NameQueryParam: validation.Validate(param.Name, validation.Required),
+ ConfigFileQueryParam: validation.Validate(param.ConfigFile, validation.Required),
+ ValueQueryParam: validation.Validate(param.Value, validation.Required),
}
return tovalidate.ToErrors(errs)
@@ -112,24 +114,8 @@ func (parameter TOParameter) Validate(db *sqlx.DB) []error {
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted parameter and have
//to be added to the struct
-func (pl *TOParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), pl)
+func (param *TOParameter) Create() (error, tc.ApiErrorType) {
+ resultRows, err := param.ReqInfo.Tx.NamedQuery(insertQuery(), param)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -164,14 +150,9 @@ func (pl *TOParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
return tc.DBError, tc.SystemError
}
- pl.SetKeys(map[string]interface{}{IDQueryParam: id})
- pl.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+ param.SetKeys(map[string]interface{}{IDQueryParam: id})
+ param.LastUpdated = &lastUpdated
+
return nil, tc.NoError
}
@@ -188,10 +169,10 @@ secure) VALUES (
return query
}
-func (parameter *TOParameter) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (param *TOParameter) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
- privLevel := user.PrivLevel
+ privLevel := param.ReqInfo.User.PrivLevel
// Query Parameters to Database Query column mappings
// see the fields mapped in the SQL query
@@ -210,7 +191,7 @@ func (parameter *TOParameter) Read(db *sqlx.DB, parameters map[string]string, us
query := selectQuery() + where + ParametersGroupBy() + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := param.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Parameters: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -244,25 +225,9 @@ func (parameter *TOParameter) Read(db *sqlx.DB, parameters map[string]string, us
//ParsePQUniqueConstraintError is used to determine if a parameter with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (pl *TOParameter) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- log.Debugf("about to run exec query: %s with parameter: %++v", updateQuery(), pl)
- resultRows, err := tx.NamedQuery(updateQuery(), pl)
+func (param *TOParameter) Update() (error, tc.ApiErrorType) {
+ log.Debugf("about to run exec query: %s with parameter: %++v", updateQuery(), param)
+ resultRows, err := param.ReqInfo.Tx.NamedQuery(updateQuery(), param)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -287,43 +252,22 @@ func (pl *TOParameter) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
}
}
log.Debugf("lastUpdated: %++v", lastUpdated)
- pl.LastUpdated = &lastUpdated
+ param.LastUpdated = &lastUpdated
if rowsAffected != 1 {
if rowsAffected < 1 {
return errors.New("no parameter found with this id"), tc.DataMissingError
}
return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
//The Parameter implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (pl *TOParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), pl)
- result, err := tx.NamedExec(deleteQuery(), pl)
+func (param *TOParameter) Delete() (error, tc.ApiErrorType) {
+ log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), param)
+ result, err := param.ReqInfo.Tx.NamedExec(deleteQuery(), param)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -339,12 +283,6 @@ func (pl *TOParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/parameter/parameters_test.go b/traffic_ops/traffic_ops_golang/parameter/parameters_test.go
index c638af3..9b465f9 100644
--- a/traffic_ops/traffic_ops_golang/parameter/parameters_test.go
+++ b/traffic_ops/traffic_ops_golang/parameter/parameters_test.go
@@ -24,14 +24,15 @@ import (
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
"encoding/json"
sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
)
func getTestParameters() []tc.ParameterNullable {
@@ -90,10 +91,14 @@ func TestGetParameters(t *testing.T) {
ts.Value,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"name": "1"}
+ user := auth.CurrentUser{PrivLevel:30}
- pps, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false),User:&user}
+ pps, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("parameter.Read expected: no errors, actual: %v", errs)
}
diff --git a/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go b/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go
index c204c9e..b579a99 100644
--- a/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go
+++ b/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go
@@ -28,7 +28,6 @@ import (
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
validation "github.com/go-ozzo/ozzo-validation"
@@ -37,13 +36,16 @@ import (
)
//we need a type alias to define functions on
-type TOPhysLocation tc.PhysLocationNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOPhysLocation(tc.PhysLocationNullable{})
+type TOPhysLocation struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.PhysLocationNullable
+}
-func GetRefType() *TOPhysLocation {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOPhysLocation{reqInfo, tc.PhysLocationNullable{}}
+ return &toReturn
+ }
}
func (pl TOPhysLocation) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -77,7 +79,7 @@ func (pl *TOPhysLocation) GetType() string {
return "physLocation"
}
-func (pl *TOPhysLocation) Validate(db *sqlx.DB) []error {
+func (pl *TOPhysLocation) Validate() []error {
errs := validation.Errors{
"address": validation.Validate(pl.Address, validation.Required),
"city": validation.Validate(pl.City, validation.Required),
@@ -93,7 +95,7 @@ func (pl *TOPhysLocation) Validate(db *sqlx.DB) []error {
return nil
}
-func (pl *TOPhysLocation) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (pl *TOPhysLocation) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -111,7 +113,7 @@ func (pl *TOPhysLocation) Read(db *sqlx.DB, parameters map[string]string, user a
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := pl.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying PhysLocations: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -160,25 +162,9 @@ JOIN region r ON pl.region = r.id`
//ParsePQUniqueConstraintError is used to determine if a phys_location with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (pl *TOPhysLocation) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (pl *TOPhysLocation) Update() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with phys_location: %++v", updateQuery(), pl)
- resultRows, err := tx.NamedQuery(updateQuery(), pl)
+ resultRows, err := pl.ReqInfo.Tx.NamedQuery(updateQuery(), pl)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -210,12 +196,6 @@ func (pl *TOPhysLocation) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.
}
return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
@@ -226,24 +206,8 @@ func (pl *TOPhysLocation) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted phys_location and have
//to be added to the struct
-func (pl *TOPhysLocation) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), pl)
+func (pl *TOPhysLocation) Create() (error, tc.ApiErrorType) {
+ resultRows, err := pl.ReqInfo.Tx.NamedQuery(insertQuery(), pl)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -280,36 +244,16 @@ func (pl *TOPhysLocation) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.
pl.SetKeys(map[string]interface{}{"id": id})
pl.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
//The PhysLocation implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (pl *TOPhysLocation) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
+func (pl *TOPhysLocation) Delete() (error, tc.ApiErrorType) {
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
log.Debugf("about to run exec query: %s with phys_location: %++v", deleteQuery(), pl)
- result, err := tx.NamedExec(deleteQuery(), pl)
+ result, err := pl.ReqInfo.Tx.NamedExec(deleteQuery(), pl)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -325,12 +269,6 @@ func (pl *TOPhysLocation) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go b/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go
index f9161f7..3cad4ec 100644
--- a/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go
+++ b/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go
@@ -26,8 +26,8 @@ import (
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
@@ -92,10 +92,14 @@ func TestGetPhysLocations(t *testing.T) {
ts.Zip,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"dsId": "1"}
- physLocations, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+ physLocations, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("physLocation.Read expected: no errors, actual: %v", errs)
}
@@ -129,7 +133,7 @@ func TestInterfaces(t *testing.T) {
func TestValidate(t *testing.T) {
p := TOPhysLocation{}
- errs := test.SortErrors(p.Validate(nil))
+ errs := test.SortErrors(p.Validate())
expected := test.SortErrors([]error{
errors.New("'state' cannot be blank"),
errors.New("'zip' cannot be blank"),
diff --git a/traffic_ops/traffic_ops_golang/profile/profiles.go b/traffic_ops/traffic_ops_golang/profile/profiles.go
index b7c6862..6b39006 100644
--- a/traffic_ops/traffic_ops_golang/profile/profiles.go
+++ b/traffic_ops/traffic_ops_golang/profile/profiles.go
@@ -47,14 +47,16 @@ const (
)
//we need a type alias to define functions on
-type TOProfile v13.ProfileNullable
-type TOParameter v13.ParameterNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOProfile{}
+type TOProfile struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ v13.ProfileNullable
+}
-func GetRefType() *TOProfile {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOProfile{reqInfo, v13.ProfileNullable{}}
+ return &toReturn
+ }
}
func (prof TOProfile) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -88,7 +90,7 @@ func (prof *TOProfile) GetType() string {
return "profile"
}
-func (prof *TOProfile) Validate(db *sqlx.DB) []error {
+func (prof *TOProfile) Validate() []error {
errs := validation.Errors{
NameQueryParam: validation.Validate(prof.Name, validation.Required),
DescriptionQueryParam: validation.Validate(prof.Description, validation.Required),
@@ -101,7 +103,7 @@ func (prof *TOProfile) Validate(db *sqlx.DB) []error {
return nil
}
-func (prof *TOProfile) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (prof *TOProfile) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -118,7 +120,7 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters map[string]string, user auth
query := selectProfilesQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := prof.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Profile: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -135,7 +137,7 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters map[string]string, user auth
// Attach Parameters if the 'id' parameter is sent
if _, ok := parameters[IDQueryParam]; ok {
- params, err := ReadParameters(db, parameters, user, p)
+ params, err := ReadParameters(prof.ReqInfo.Tx, parameters, prof.ReqInfo.User, p)
p.Parameters = params
if len(errs) > 0 {
log.Errorf("Error getting Parameters: %v", err)
@@ -166,7 +168,7 @@ LEFT JOIN cdn c ON prof.cdn = c.id`
return query
}
-func ReadParameters(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser, profile v13.ProfileNullable) ([]v13.ParameterNullable, []error) {
+func ReadParameters(tx *sqlx.Tx, parameters map[string]string, user *auth.CurrentUser, profile v13.ProfileNullable) ([]v13.ParameterNullable, []error) {
var rows *sqlx.Rows
privLevel := user.PrivLevel
@@ -174,7 +176,7 @@ func ReadParameters(db *sqlx.DB, parameters map[string]string, user auth.Current
queryValues["profile_id"] = *profile.ID
query := selectParametersQuery()
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Parameter: %v", err)
return nil, []error{tc.DBError}
@@ -221,25 +223,9 @@ WHERE pp.profile = :profile_id`
//ParsePQUniqueConstraintError is used to determine if a profile with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (prof *TOProfile) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (prof *TOProfile) Update() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with profile: %++v", updateQuery(), prof)
- resultRows, err := tx.NamedQuery(updateQuery(), prof)
+ resultRows, err := prof.ReqInfo.Tx.NamedQuery(updateQuery(), prof)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -270,12 +256,7 @@ func (prof *TOProfile) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
}
return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
@@ -286,24 +267,8 @@ func (prof *TOProfile) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted profile and have
//to be added to the struct
-func (prof *TOProfile) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), prof)
+func (prof *TOProfile) Create() (error, tc.ApiErrorType) {
+ resultRows, err := prof.ReqInfo.Tx.NamedQuery(insertQuery(), prof)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -340,36 +305,15 @@ func (prof *TOProfile) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
prof.SetKeys(map[string]interface{}{IDQueryParam: id})
prof.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
//The Profile implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (prof *TOProfile) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (prof *TOProfile) Delete() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with profile: %++v", deleteQuery(), prof)
- result, err := tx.NamedExec(deleteQuery(), prof)
+ result, err := prof.ReqInfo.Tx.NamedExec(deleteQuery(), prof)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -385,12 +329,6 @@ func (prof *TOProfile) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/profile/profiles_test.go b/traffic_ops/traffic_ops_golang/profile/profiles_test.go
index bf2fe08..b00ea6c 100644
--- a/traffic_ops/traffic_ops_golang/profile/profiles_test.go
+++ b/traffic_ops/traffic_ops_golang/profile/profiles_test.go
@@ -26,8 +26,8 @@ import (
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
@@ -93,10 +93,14 @@ func TestGetProfiles(t *testing.T) {
ts.Type,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"name": "1"}
- profiles, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+ profiles, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("profile.Read expected: no errors, actual: %v", errs)
}
@@ -130,7 +134,7 @@ func TestInterfaces(t *testing.T) {
func TestValidate(t *testing.T) {
p := TOProfile{}
- errs := test.SortErrors(p.Validate(nil))
+ errs := test.SortErrors(p.Validate())
expected := test.SortErrors([]error{
errors.New("'cdn' cannot be blank"),
errors.New("'description' cannot be blank"),
diff --git a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go
index 9920228..703d40c 100644
--- a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go
+++ b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go
@@ -29,7 +29,6 @@ import (
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/lib/go-tc/v13"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
validation "github.com/go-ozzo/ozzo-validation"
@@ -43,13 +42,16 @@ const (
)
//we need a type alias to define functions on
-type TOProfileParameter v13.ProfileParameterNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOProfileParameter(v13.ProfileParameterNullable{})
+type TOProfileParameter struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ v13.ProfileParameterNullable
+}
-func GetRefType() *TOProfileParameter {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOProfileParameter{reqInfo, v13.ProfileParameterNullable{}}
+ return &toReturn
+ }
}
func (pp TOProfileParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -93,7 +95,7 @@ func (pp *TOProfileParameter) SetKeys(keys map[string]interface{}) {
}
// Validate fulfills the api.Validator interface
-func (pp *TOProfileParameter) Validate(db *sqlx.DB) []error {
+func (pp *TOProfileParameter) Validate() []error {
errs := validation.Errors{
"profile": validation.Validate(pp.ProfileID, validation.Required),
@@ -110,24 +112,8 @@ func (pp *TOProfileParameter) Validate(db *sqlx.DB) []error {
//generic error message returned
//The insert sql returns the profile and lastUpdated values of the newly inserted profileparameter and have
//to be added to the struct
-func (pp *TOProfileParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), pp)
+func (pp *TOProfileParameter) Create() (error, tc.ApiErrorType) {
+ resultRows, err := pp.ReqInfo.Tx.NamedQuery(insertQuery(), pp)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -164,13 +150,6 @@ func (pp *TOProfileParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error,
}
pp.SetKeys(map[string]interface{}{ProfileIDQueryParam: profile, ParameterIDQueryParam: parameter})
- pp.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
@@ -183,7 +162,11 @@ parameter) VALUES (
return query
}
-func (pp *TOProfileParameter) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (pp *TOProfileParameter) Update() (error, tc.ApiErrorType) {
+ return errors.New("unimplemented"), tc.SystemError
+}
+
+func (pp *TOProfileParameter) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -202,7 +185,7 @@ func (pp *TOProfileParameter) Read(db *sqlx.DB, parameters map[string]string, us
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := pp.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Parameters: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -225,25 +208,9 @@ func (pp *TOProfileParameter) Read(db *sqlx.DB, parameters map[string]string, us
//The Parameter implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (pp *TOProfileParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (pp *TOProfileParameter) Delete() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), pp)
- result, err := tx.NamedExec(deleteQuery(), pp)
+ result, err := pp.ReqInfo.Tx.NamedExec(deleteQuery(), pp)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -259,12 +226,6 @@ func (pp *TOProfileParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error,
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go
index b11f64b..013ce3a 100644
--- a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go
+++ b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go
@@ -25,8 +25,8 @@ import (
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-tc/v13"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
@@ -78,10 +78,15 @@ func TestGetProfileParameters(t *testing.T) {
ts.ParameterID,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"profile": "1"}
- pps, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+
+ pps, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("profileparameter.Read expected: no errors, actual: %v", errs)
}
diff --git a/traffic_ops/traffic_ops_golang/region/regions.go b/traffic_ops/traffic_ops_golang/region/regions.go
index 730870a..b54598c 100644
--- a/traffic_ops/traffic_ops_golang/region/regions.go
+++ b/traffic_ops/traffic_ops_golang/region/regions.go
@@ -26,20 +26,22 @@ import (
"github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
"github.com/jmoiron/sqlx"
"github.com/lib/pq"
)
//we need a type alias to define functions on
-type TORegion tc.Region
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TORegion(tc.Region{})
+type TORegion struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.Region
+}
-func GetRefType() *TORegion {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TORegion{reqInfo, tc.Region{}}
+ return &toReturn
+ }
}
func (region TORegion) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -64,7 +66,7 @@ func (region *TORegion) GetType() string {
return "region"
}
-func (region *TORegion) Validate(db *sqlx.DB) []error {
+func (region *TORegion) Validate() []error {
errs := []error{}
if len(region.Name) < 1 {
errs = append(errs, errors.New(`Region 'name' is required.`))
@@ -72,7 +74,7 @@ func (region *TORegion) Validate(db *sqlx.DB) []error {
return errs
}
-func (region *TORegion) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (region *TORegion) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -90,7 +92,7 @@ func (region *TORegion) Read(db *sqlx.DB, parameters map[string]string, user aut
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := region.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Regions: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -128,25 +130,9 @@ JOIN division d ON r.division = d.id`
//ParsePQUniqueConstraintError is used to determine if a region with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (region *TORegion) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (region *TORegion) Update() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with region: %++v", updateQuery(), region)
- resultRows, err := tx.NamedQuery(updateQuery(), region)
+ resultRows, err := region.ReqInfo.Tx.NamedQuery(updateQuery(), region)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -177,12 +163,7 @@ func (region *TORegion) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
}
return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
@@ -193,24 +174,8 @@ func (region *TORegion) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted region and have
//to be added to the struct
-func (region *TORegion) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), region)
+func (region *TORegion) Create() (error, tc.ApiErrorType) {
+ resultRows, err := region.ReqInfo.Tx.NamedQuery(insertQuery(), region)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -246,36 +211,15 @@ func (region *TORegion) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
}
region.SetKeys(map[string]interface{}{"id": id})
region.LastUpdated = lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
//The Region implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (region *TORegion) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (region *TORegion) Delete() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with region: %++v", deleteQuery(), region)
- result, err := tx.NamedExec(deleteQuery(), region)
+ result, err := region.ReqInfo.Tx.NamedExec(deleteQuery(), region)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -291,12 +235,6 @@ func (region *TORegion) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/region/regions_test.go b/traffic_ops/traffic_ops_golang/region/regions_test.go
index 854f838..ad7cb6c 100644
--- a/traffic_ops/traffic_ops_golang/region/regions_test.go
+++ b/traffic_ops/traffic_ops_golang/region/regions_test.go
@@ -24,8 +24,8 @@ import (
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
@@ -59,8 +59,6 @@ func TestReadRegions(t *testing.T) {
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
- refType := GetRefType()
-
testRegions := getTestRegions()
cols := test.ColsFromStructByTag("db", tc.Region{})
rows := sqlmock.NewRows(cols)
@@ -73,10 +71,14 @@ func TestReadRegions(t *testing.T) {
ts.Name,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"id": "1"}
- regions, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+ regions, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("region.Read expected: no errors, actual: %v", errs)
}
diff --git a/traffic_ops/traffic_ops_golang/role/roles.go b/traffic_ops/traffic_ops_golang/role/roles.go
index 3871c8b..2cc8a37 100644
--- a/traffic_ops/traffic_ops_golang/role/roles.go
+++ b/traffic_ops/traffic_ops_golang/role/roles.go
@@ -29,7 +29,6 @@ import (
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/lib/go-tc/v13"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
validation "github.com/go-ozzo/ozzo-validation"
@@ -38,13 +37,16 @@ import (
)
//we need a type alias to define functions on
-type TORole v13.Role
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TORole{}
+type TORole struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ v13.Role
+}
-func GetRefType() *TORole {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TORole{reqInfo, v13.Role{}}
+ return &toReturn
+ }
}
func (role TORole) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -79,7 +81,7 @@ func (role *TORole) SetKeys(keys map[string]interface{}) {
}
// Validate fulfills the api.Validator interface
-func (role TORole) Validate(db *sqlx.DB) []error {
+func (role TORole) Validate() []error {
errs := validation.Errors{
"name": validation.Validate(role.Name, validation.Required),
"description": validation.Validate(role.Description, validation.Required),
@@ -88,8 +90,8 @@ func (role TORole) Validate(db *sqlx.DB) []error {
errsToReturn := tovalidate.ToErrors(errs)
checkCaps := `SELECT cap FROM UNNEST($1::text[]) AS cap WHERE NOT cap = ANY(ARRAY(SELECT c.name FROM capability AS c WHERE c.name = ANY($1)))`
var badCaps []string
- if db != nil {
- err := db.Select(&badCaps, checkCaps, pq.Array(role.Capabilities))
+ if role.ReqInfo.Tx != nil {
+ err := role.ReqInfo.Tx.Select(&badCaps, checkCaps, pq.Array(role.Capabilities))
if err != nil {
log.Errorf("got error from selecting bad capabilities: %v", err)
return []error{tc.DBError}
@@ -108,27 +110,11 @@ func (role TORole) Validate(db *sqlx.DB) []error {
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted role and have
//to be added to the struct
-func (role *TORole) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- if *role.PrivLevel > user.PrivLevel {
+func (role *TORole) Create() (error, tc.ApiErrorType) {
+ if *role.PrivLevel > role.ReqInfo.User.PrivLevel {
return errors.New("can not create a role with a higher priv level than your own"), tc.ForbiddenError
}
- resultRows, err := tx.NamedQuery(insertQuery(), role)
+ resultRows, err := role.ReqInfo.Tx.NamedQuery(insertQuery(), role)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -163,17 +149,11 @@ func (role *TORole) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
}
role.SetKeys(map[string]interface{}{"id": id})
//after we have role ID we can associate the capabilities:
- err, errType := role.createRoleCapabilityAssociations(tx)
+ err, errType := role.createRoleCapabilityAssociations(role.ReqInfo.Tx)
if err != nil {
return err, errType
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
@@ -209,7 +189,7 @@ func (role *TORole) deleteRoleCapabilityAssociations(tx *sqlx.Tx) (error, tc.Api
return nil, tc.NoError
}
-func (role *TORole) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (role *TORole) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -226,7 +206,7 @@ func (role *TORole) Read(db *sqlx.DB, parameters map[string]string, user auth.Cu
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := role.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Roles: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -253,30 +233,13 @@ func (role *TORole) Read(db *sqlx.DB, parameters map[string]string, user auth.Cu
//ParsePQUniqueConstraintError is used to determine if a role with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (role *TORole) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
-
- if *role.PrivLevel > user.PrivLevel {
+func (role *TORole) Update() (error, tc.ApiErrorType) {
+ if *role.PrivLevel > role.ReqInfo.User.PrivLevel {
return errors.New("can not create a role with a higher priv level than your own"), tc.ForbiddenError
}
log.Debugf("about to run exec query: %s with role: %++v\n", updateQuery(), role)
- result, err := tx.NamedExec(updateQuery(), role)
+ result, err := role.ReqInfo.Tx.NamedExec(updateQuery(), role)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -303,46 +266,24 @@ func (role *TORole) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
}
}
//remove associations
- err, errType := role.deleteRoleCapabilityAssociations(tx)
+ err, errType := role.deleteRoleCapabilityAssociations(role.ReqInfo.Tx)
if err != nil {
return err, errType
}
//create new associations
- err, errType = role.createRoleCapabilityAssociations(tx)
+ err, errType = role.createRoleCapabilityAssociations(role.ReqInfo.Tx)
if err != nil {
return err, errType
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
//The Role implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (role *TORole) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (role *TORole) Delete() (error, tc.ApiErrorType) {
assignedUsers := 0
- err = tx.Get(&assignedUsers, "SELECT COUNT(id) FROM tm_user WHERE role=$1", role.ID)
+ err := role.ReqInfo.Tx.Get(&assignedUsers, "SELECT COUNT(id) FROM tm_user WHERE role=$1", role.ID)
if err != nil {
log.Errorf("received error: %++v from assigned users check", err)
return tc.DBError, tc.SystemError
@@ -352,7 +293,7 @@ func (role *TORole) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
}
log.Debugf("about to run exec query: %s with role: %++v", deleteQuery(), role)
- result, err := tx.NamedExec(deleteQuery(), role)
+ result, err := role.ReqInfo.Tx.NamedExec(deleteQuery(), role)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -369,17 +310,11 @@ func (role *TORole) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
}
}
//remove associations
- err, errType := role.deleteRoleCapabilityAssociations(tx)
+ err, errType := role.deleteRoleCapabilityAssociations(role.ReqInfo.Tx)
if err != nil {
return err, errType
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/role/roles_test.go b/traffic_ops/traffic_ops_golang/role/roles_test.go
index 0c49961..7807371 100644
--- a/traffic_ops/traffic_ops_golang/role/roles_test.go
+++ b/traffic_ops/traffic_ops_golang/role/roles_test.go
@@ -96,8 +96,9 @@ func TestInterfaces(t *testing.T) {
func TestValidate(t *testing.T) {
// invalid name, empty domainname
n := "not_a_valid_role"
- r := TORole{Name: &n}
- errs := test.SortErrors(r.Validate(nil))
+ reqInfo := api.APIInfo{}
+ r := TORole{ReqInfo: &reqInfo, Role: v13.Role{Name: &n}}
+ errs := test.SortErrors(r.Validate())
expectedErrs := []error{
errors.New(`'description' cannot be blank`),
@@ -109,9 +110,9 @@ func TestValidate(t *testing.T) {
}
// name, domainname both valid
- r = TORole{Name: stringAddr("this is a valid name"), Description: stringAddr("this is a description"), PrivLevel: intAddr(30)}
+ r = TORole{ReqInfo: &reqInfo, Role: v13.Role{Name: stringAddr("this is a valid name"), Description: stringAddr("this is a description"), PrivLevel: intAddr(30)}}
expectedErrs = []error{}
- errs = r.Validate(nil)
+ errs = r.Validate()
if !reflect.DeepEqual(expectedErrs, errs) {
t.Errorf("expected %s, got %s", expectedErrs, errs)
}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index ed93d74..00edc23 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -46,16 +46,16 @@ import (
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/division"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/hwinfo"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/origin"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/physlocation"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/physlocation"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/ping"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/profile"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/profile"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/profileparameter"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/region"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/role"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/region"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/role"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/server"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/staticdnsentry"
- //"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/status"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/staticdnsentry"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/status"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/systeminfo"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/types"
@@ -139,37 +139,37 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.2, http.MethodPost, `user/login/?$`, wrapAccessLog(d.Secrets[0], auth.LoginHandler(d.DB, d.Config)), 0, NoAuth, nil}, {1.3, http.MethodPost, `user/login/?$`, auth.LoginHandler(d.DB, d.Config), 0, NoAuth, nil},
//Parameter: CRUD
- //{1.1, http.MethodGet, `parameters/?(\.json)?$`, api.ReadHandler(parameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `parameters/{id}$`, api.ReadHandler(parameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `parameters/{id}$`, api.UpdateHandler(parameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `parameters/?$`, api.CreateHandler(parameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `parameters/{id}$`, api.DeleteHandler(parameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `parameters/?(\.json)?$`, api.ReadHandler(parameter.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `parameters/{id}$`, api.ReadHandler(parameter.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `parameters/{id}$`, api.UpdateHandler(parameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `parameters/?$`, api.CreateHandler(parameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `parameters/{id}$`, api.DeleteHandler(parameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//Phys_Location: CRUD
- //{1.1, http.MethodGet, `phys_locations/?(\.json)?$`, api.ReadHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `phys_locations/trimmed/?(\.json)?$`, physlocation.GetTrimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `phys_locations/{id}$`, api.ReadHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `phys_locations/{id}$`, api.UpdateHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `phys_locations/?$`, api.CreateHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `phys_locations/{id}$`, api.DeleteHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `phys_locations/?(\.json)?$`, api.ReadHandler(physlocation.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `phys_locations/trimmed/?(\.json)?$`, physlocation.GetTrimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `phys_locations/{id}$`, api.ReadHandler(physlocation.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `phys_locations/{id}$`, api.UpdateHandler(physlocation.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `phys_locations/?$`, api.CreateHandler(physlocation.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `phys_locations/{id}$`, api.DeleteHandler(physlocation.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//Ping
{1.1, http.MethodGet, `ping$`, ping.PingHandler(), 0, NoAuth, nil},
//Profile: CRUD
- //{1.1, http.MethodGet, `profiles/?(\.json)?$`, api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `profiles/trimmed/?(\.json)?$`, profile.Trimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `profiles/{id}$`, api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `profiles/{id}$`, api.UpdateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `profiles/?$`, api.CreateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `profiles/{id}$`, api.DeleteHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-
- //Region: CRUD
- //{1.1, http.MethodGet, `regions/?(\.json)?$`, api.ReadHandler(region.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `regions/{id}$`, api.ReadHandler(region.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `regions/{id}$`, api.UpdateHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `regions/?$`, api.CreateHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `regions/{id}$`, api.DeleteHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `profiles/?(\.json)?$`, api.ReadHandler(profile.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `profiles/trimmed/?(\.json)?$`, profile.Trimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `profiles/{id}$`, api.ReadHandler(profile.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `profiles/{id}$`, api.UpdateHandler(profile.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `profiles/?$`, api.CreateHandler(profile.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `profiles/{id}$`, api.DeleteHandler(profile.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+
+ //Region: CRUDs
+ {1.1, http.MethodGet, `regions/?(\.json)?$`, api.ReadHandler(region.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `regions/{id}$`, api.ReadHandler(region.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `regions/{id}$`, api.UpdateHandler(region.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `regions/?$`, api.CreateHandler(region.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `regions/{id}$`, api.DeleteHandler(region.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
{1.1, http.MethodDelete, `deliveryservice_server/{dsid}/{serverid}`, dsserver.Delete, auth.PrivLevelReadOnly, Authenticated, nil},
@@ -178,10 +178,10 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.1, http.MethodGet, `deliveryserviceserver$`, dsserver.ReadDSSHandler(d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
{1.1, http.MethodPost,`deliveryservices/{xml_id}/servers$`, dsserver.GetCreateHandler( d.DB ) ,auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(dsserver.GetDServiceRef(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadOnlyHandler(dsserver.GetDSSDeliveryServiceReaderSingleton()),auth.PrivLevelReadOnly, Authenticated, nil},
{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, tc.Assigned),auth.PrivLevelReadOnly, Authenticated, nil},
{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, tc.Unassigned),auth.PrivLevelReadOnly, Authenticated, nil},
- ////{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.Tx, tc.Eligible),auth.PrivLevelReadOnly, Authenticated, nil},
+ //{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.Tx, tc.Eligible),auth.PrivLevelReadOnly, Authenticated, nil},
//Server
{1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},
@@ -193,28 +193,28 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.2, http.MethodGet, `servers/hostname/{hostName}/details/?(\.json)?$`, server.GetDetailHandler(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
//Server: CRUD
- //{1.1, http.MethodGet, `servers/?(\.json)?$`, api.ReadHandler(server.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `servers/{id}$`, api.ReadHandler(server.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `servers/{id}$`, api.UpdateHandler(server.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `servers/?$`, api.CreateHandler(server.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `servers/{id}$`, api.DeleteHandler(server.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `servers/?(\.json)?$`, api.ReadHandler(server.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `servers/{id}$`, api.ReadHandler(server.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `servers/{id}$`, api.UpdateHandler(server.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `servers/?$`, api.CreateHandler(server.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `servers/{id}$`, api.DeleteHandler(server.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//Status: CRUD
- //{1.1, http.MethodGet, `statuses/?(\.json)?$`, api.ReadHandler(status.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `statuses/{id}$`, api.ReadHandler(status.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `statuses/{id}$`, api.UpdateHandler(status.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `statuses/?$`, api.CreateHandler(status.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `statuses/{id}$`, api.DeleteHandler(status.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `statuses/?(\.json)?$`, api.ReadHandler(status.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `statuses/{id}$`, api.ReadHandler(status.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `statuses/{id}$`, api.UpdateHandler(status.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `statuses/?$`, api.CreateHandler(status.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `statuses/{id}$`, api.DeleteHandler(status.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//System
{1.1, http.MethodGet, `system/info/?(\.json)?$`, systeminfo.Handler(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
//Type: CRUD
- //{1.1, http.MethodGet, `types/?(\.json)?$`, api.ReadHandler(types.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `types/{id}$`, api.ReadHandler(types.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodPut, `types/{id}$`, api.UpdateHandler(types.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodPost, `types/?$`, api.CreateHandler(types.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- //{1.1, http.MethodDelete, `types/{id}$`, api.DeleteHandler(types.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `types/?(\.json)?$`, api.ReadHandler(types.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `types/{id}$`, api.ReadHandler(types.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPut, `types/{id}$`, api.UpdateHandler(types.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `types/?$`, api.CreateHandler(types.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `types/{id}$`, api.DeleteHandler(types.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//About
{1.3, http.MethodGet, `about/?(\.json)?$`, about.Handler(), auth.PrivLevelReadOnly, Authenticated, nil},
@@ -280,10 +280,10 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.3, http.MethodDelete, `origins/?$`, api.DeleteHandler(origin.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//Roles
- //{1.3, http.MethodGet, `roles/?(\.json)?$`, api.ReadHandler(role.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.3, http.MethodPut, `roles/?$`, api.UpdateHandler(role.GetRefType(), d.DB), auth.PrivLevelAdmin, Authenticated, nil},
- //{1.3, http.MethodPost, `roles/?$`, api.CreateHandler(role.GetRefType(), d.DB), auth.PrivLevelAdmin, Authenticated, nil},
- //{1.3, http.MethodDelete, `roles/?$`, api.DeleteHandler(role.GetRefType(), d.DB), auth.PrivLevelAdmin, Authenticated, nil},
+ {1.3, http.MethodGet, `roles/?(\.json)?$`, api.ReadHandler(role.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.3, http.MethodPut, `roles/?$`, api.UpdateHandler(role.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
+ {1.3, http.MethodPost, `roles/?$`, api.CreateHandler(role.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
+ {1.3, http.MethodDelete, `roles/?$`, api.DeleteHandler(role.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
//Delivery Services Regexes
{1.1, http.MethodGet, `deliveryservices_regexes/?(\.json)?$`, deliveryservicesregexes.Get(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
@@ -297,20 +297,20 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.3, http.MethodPost, `servers/{id}/deliveryservices$`, server.AssignDeliveryServicesToServerHandler(d.DB), auth.PrivLevelOperations, Authenticated, nil},
{1.3, http.MethodGet, `servers/{host_name}/update_status$`, server.GetServerUpdateStatusHandler(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- //{1.1, http.MethodGet, `staticdnsentries/?(\.json)?$`, api.ReadHandler(staticdnsentry.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodGet, `staticdnsentries/?(\.json)?$`, api.ReadOnlyHandler(staticdnsentry.GetReaderSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
//ProfileParameters
{1.1, http.MethodGet, `profiles/{id}/parameters/?(\.json)?$`, profileparameter.GetProfileID(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
{1.1, http.MethodGet, `profiles/{id}/unassigned_parameters/?(\.json)?$`, profileparameter.GetUnassigned(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
{1.1, http.MethodGet, `profiles/name/{name}/parameters/?(\.json)?$`, profileparameter.GetProfileName(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
{1.1, http.MethodGet, `parameters/profile/{name}/?(\.json)?$`, profileparameter.GetProfileName(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- {1.1, http.MethodPost, `profiles/name/{name}/parameters/?$`, profileparameter.PostProfileParamsByName, auth.PrivLevelOperations, Authenticated, nil},
- {1.1, http.MethodPost, `profiles/{id}/parameters/?$`, profileparameter.PostProfileParamsByID, auth.PrivLevelOperations, Authenticated, nil},
- {1.1, http.MethodGet, `profileparameters/?(\.json)?$`, api.ReadHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
- {1.1, http.MethodPost, `profileparameters/?$`, api.CreateHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
- {1.1, http.MethodPost, `profileparameter/?$`, profileparameter.PostProfileParam, auth.PrivLevelOperations, Authenticated, nil},
- {1.1, http.MethodPost, `parameterprofile/?$`, profileparameter.PostParamProfile, auth.PrivLevelOperations, Authenticated, nil},
- {1.1, http.MethodDelete, `profileparameters/{profileId}/{parameterId}$`, api.DeleteHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `profiles/name/{name}/parameters/?$`, profileparameter.PostProfileParamsByName(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `profiles/{id}/parameters/?$`, profileparameter.PostProfileParamsByID(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `profileparameters/?(\.json)?$`, api.ReadHandler(profileparameter.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+ {1.1, http.MethodPost, `profileparameters/?$`, api.CreateHandler(profileparameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `profileparameter/?$`, profileparameter.PostProfileParam(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodPost, `parameterprofile/?$`, profileparameter.PostParamProfile(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodDelete, `profileparameters/{profileId}/{parameterId}$`, api.DeleteHandler(profileparameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
//Tenants
diff --git a/traffic_ops/traffic_ops_golang/server/servers.go b/traffic_ops/traffic_ops_golang/server/servers.go
index cd82dc8..1ad8eea 100644
--- a/traffic_ops/traffic_ops_golang/server/servers.go
+++ b/traffic_ops/traffic_ops_golang/server/servers.go
@@ -39,13 +39,16 @@ import (
)
//we need a type alias to define functions on
-type TOServer v13.ServerNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOServer{}
+type TOServer struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ v13.ServerNullable
+}
-func GetRefType() *TOServer {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOServer{reqInfo, v13.ServerNullable{}}
+ return &toReturn
+ }
}
func (server TOServer) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -79,7 +82,7 @@ func (server *TOServer) GetType() string {
return "server"
}
-func (server *TOServer) Validate(db *sqlx.DB) []error {
+func (server *TOServer) Validate() []error {
noSpaces := validation.NewStringRule(tovalidate.NoSpaces, "cannot contain spaces")
@@ -104,7 +107,7 @@ func (server *TOServer) Validate(db *sqlx.DB) []error {
return errs
}
- rows, err := db.Query("select use_in_table from type where id=$1", server.TypeID)
+ rows, err := server.ReqInfo.Tx.Query("select use_in_table from type where id=$1", server.TypeID)
if err != nil {
log.Error.Printf("could not execute select use_in_table from type: %s\n", err)
errs = append(errs, tc.DBError)
@@ -123,7 +126,7 @@ func (server *TOServer) Validate(db *sqlx.DB) []error {
errs = append(errs, errors.New("invalid server type"))
}
- rows, err = db.Query("select cdn from profile where id=$1", server.ProfileID)
+ rows, err = server.ReqInfo.Tx.Query("select cdn from profile where id=$1", server.ProfileID)
if err != nil {
log.Error.Printf("could not execute select cdnID from profile: %s\n", err)
errs = append(errs, tc.DBError)
@@ -173,12 +176,12 @@ func (server TOServer) ChangeLogMessage(action string) (string, error) {
return message, nil
}
-func (server *TOServer) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (server *TOServer) Read(params map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
returnable := []interface{}{}
- privLevel := user.PrivLevel
+ privLevel := server.ReqInfo.User.PrivLevel
- servers, errs, errType := getServers(params, db, privLevel)
+ servers, errs, errType := getServers(params, server.ReqInfo.Tx, privLevel)
if len(errs) > 0 {
for _, err := range errs {
if err.Error() == `id cannot parse to integer` {
@@ -195,7 +198,7 @@ func (server *TOServer) Read(db *sqlx.DB, params map[string]string, user auth.Cu
return returnable, nil, tc.NoError
}
-func getServers(params map[string]string, db *sqlx.DB, privLevel int) ([]tc.ServerNullable, []error, tc.ApiErrorType) {
+func getServers(params map[string]string, tx *sqlx.Tx, privLevel int) ([]tc.ServerNullable, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
var err error
@@ -221,7 +224,7 @@ func getServers(params map[string]string, db *sqlx.DB, privLevel int) ([]tc.Serv
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err = db.NamedQuery(query, queryValues)
+ rows, err = tx.NamedQuery(query, queryValues)
if err != nil {
return nil, []error{fmt.Errorf("querying: %v", err)}, tc.SystemError
}
@@ -313,26 +316,9 @@ JOIN type t ON s.type = t.id`
//ParsePQUniqueConstraintError is used to determine if a cdn with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
-
+func (server *TOServer) Update() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with server: %++v", updateQuery(), server)
- resultRows, err := tx.NamedQuery(updateQuery(), server)
+ resultRows, err := server.ReqInfo.Tx.NamedQuery(updateQuery(), server)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -369,12 +355,7 @@ func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
}
server.SetKeys(map[string]interface{}{"id": id})
server.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
@@ -424,30 +405,13 @@ WHERE id=:id RETURNING last_updated`
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted server and have
//to be added to the struct
-func (server *TOServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
-
+func (server *TOServer) Create() (error, tc.ApiErrorType) {
if server.XMPPID == nil || *server.XMPPID == "" {
hostName := *server.HostName
server.XMPPID = &hostName
}
- resultRows, err := tx.NamedQuery(insertQuery(), server)
+ resultRows, err := server.ReqInfo.Tx.NamedQuery(insertQuery(), server)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -483,12 +447,7 @@ func (server *TOServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
}
server.SetKeys(map[string]interface{}{"id": id})
server.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
@@ -565,25 +524,9 @@ xmpp_passwd
//The Server implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (server *TOServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (server *TOServer) Delete() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with server: %++v", deleteServerQuery(), server)
- result, err := tx.NamedExec(deleteServerQuery(), server)
+ result, err := server.ReqInfo.Tx.NamedExec(deleteServerQuery(), server)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -599,12 +542,7 @@ func (server *TOServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/server/servers_test.go b/traffic_ops/traffic_ops_golang/server/servers_test.go
index bb4f008..43d4e05 100644
--- a/traffic_ops/traffic_ops_golang/server/servers_test.go
+++ b/traffic_ops/traffic_ops_golang/server/servers_test.go
@@ -157,10 +157,11 @@ func TestGetServersByCachegroup(t *testing.T) {
ts.XMPPPasswd,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
v := map[string]string{"cachegroup": "2"}
- servers, errs, errType := getServers(v, db, auth.PrivLevelAdmin)
+ servers, errs, errType := getServers(v, db.MustBegin(), auth.PrivLevelAdmin)
log.Debugln("%v-->", servers)
if len(errs) > 0 {
t.Errorf("getServers expected: no errors, actual: %v with error type: %s", errs, errType.String())
diff --git a/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go b/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go
index ac9f3b1..2c06d35 100644
--- a/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go
+++ b/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go
@@ -22,16 +22,23 @@ package staticdnsentry
import (
"github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
- "github.com/jmoiron/sqlx"
)
-type TOStaticDNSEntry tc.StaticDNSEntry
+type TOStaticDNSEntry struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.StaticDNSEntry
+}
-func GetRefType() *TOStaticDNSEntry { return &TOStaticDNSEntry{} }
+func GetReaderSingleton() func(reqInfo *api.APIInfo)api.Reader {
+ return func(reqInfo *api.APIInfo)api.Reader {
+ toReturn := TOStaticDNSEntry{reqInfo, tc.StaticDNSEntry{}}
+ return &toReturn
+ }
+}
-func (staticDNSEntry *TOStaticDNSEntry) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (staticDNSEntry *TOStaticDNSEntry) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
"deliveryservice": dbhelpers.WhereColumnInfo{"deliveryservice", nil}, // order by
}
@@ -42,7 +49,7 @@ func (staticDNSEntry *TOStaticDNSEntry) Read(db *sqlx.DB, parameters map[string]
}
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := staticDNSEntry.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying StaticDNSEntries: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
diff --git a/traffic_ops/traffic_ops_golang/status/statuses.go b/traffic_ops/traffic_ops_golang/status/statuses.go
index a9fa43b..d00aed9 100644
--- a/traffic_ops/traffic_ops_golang/status/statuses.go
+++ b/traffic_ops/traffic_ops_golang/status/statuses.go
@@ -28,7 +28,6 @@ import (
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
validation "github.com/go-ozzo/ozzo-validation"
@@ -37,13 +36,16 @@ import (
)
//we need a type alias to define functions on
-type TOStatus tc.StatusNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOStatus(tc.StatusNullable{})
+type TOStatus struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.StatusNullable
+}
-func GetRefType() *TOStatus {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOStatus{reqInfo, tc.StatusNullable{}}
+ return &toReturn
+ }
}
func (status TOStatus) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -77,14 +79,14 @@ func (status TOStatus) GetType() string {
return "status"
}
-func (status TOStatus) Validate(db *sqlx.DB) []error {
+func (status TOStatus) Validate() []error {
errs := validation.Errors{
"name": validation.Validate(status.Name, validation.NotNil, validation.Required),
}
return tovalidate.ToErrors(errs)
}
-func (status *TOStatus) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (status *TOStatus) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -102,7 +104,7 @@ func (status *TOStatus) Read(db *sqlx.DB, parameters map[string]string, user aut
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := status.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Status: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -139,25 +141,9 @@ FROM status s`
//ParsePQUniqueConstraintError is used to determine if a status with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (status *TOStatus) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (status *TOStatus) Update() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with status: %++v", updateQuery(), status)
- resultRows, err := tx.NamedQuery(updateQuery(), status)
+ resultRows, err := status.ReqInfo.Tx.NamedQuery(updateQuery(), status)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -190,12 +176,7 @@ func (status *TOStatus) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
}
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
@@ -206,24 +187,8 @@ func (status *TOStatus) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted status and have
//to be added to the struct
-func (status *TOStatus) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), status)
+func (status *TOStatus) Create() (error, tc.ApiErrorType) {
+ resultRows, err := status.ReqInfo.Tx.NamedQuery(insertQuery(), status)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -259,36 +224,15 @@ func (status *TOStatus) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
}
status.SetKeys(map[string]interface{}{"id": id})
status.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
//The Status implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (status *TOStatus) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (status *TOStatus) Delete() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with status: %++v", deleteQuery(), status)
- result, err := tx.NamedExec(deleteQuery(), status)
+ result, err := status.ReqInfo.Tx.NamedExec(deleteQuery(), status)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -304,12 +248,7 @@ func (status *TOStatus) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/status/statuses_test.go b/traffic_ops/traffic_ops_golang/status/statuses_test.go
index 3127450..7a684f1 100644
--- a/traffic_ops/traffic_ops_golang/status/statuses_test.go
+++ b/traffic_ops/traffic_ops_golang/status/statuses_test.go
@@ -24,8 +24,8 @@ import (
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
@@ -60,8 +60,6 @@ func TestReadStatuses(t *testing.T) {
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
- refType := GetRefType()
-
testStatuses := getTestStatuses()
cols := test.ColsFromStructByTag("db", tc.Status{})
rows := sqlmock.NewRows(cols)
@@ -74,10 +72,14 @@ func TestReadStatuses(t *testing.T) {
ts.Name,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"dsId": "1"}
- statuses, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+ statuses, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("status.Read expected: no errors, actual: %v", errs)
}
diff --git a/traffic_ops/traffic_ops_golang/types/types.go b/traffic_ops/traffic_ops_golang/types/types.go
index 7baaf52..f160f8b 100644
--- a/traffic_ops/traffic_ops_golang/types/types.go
+++ b/traffic_ops/traffic_ops_golang/types/types.go
@@ -28,7 +28,6 @@ import (
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
validation "github.com/go-ozzo/ozzo-validation"
@@ -37,13 +36,16 @@ import (
)
//we need a type alias to define functions on
-type TOType tc.TypeNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOType(tc.TypeNullable{})
+type TOType struct{
+ ReqInfo *api.APIInfo `json:"-"`
+ tc.TypeNullable
+}
-func GetRefType() *TOType {
- return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+ return func(reqInfo *api.APIInfo)api.CRUDer {
+ toReturn := TOType{reqInfo, tc.TypeNullable{}}
+ return &toReturn
+ }
}
func (typ TOType) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -77,7 +79,7 @@ func (typ *TOType) GetType() string {
return "type"
}
-func (typ *TOType) Validate(db *sqlx.DB) []error {
+func (typ *TOType) Validate() []error {
errs := validation.Errors{
"name": validation.Validate(typ.Name, validation.Required),
"description": validation.Validate(typ.Description, validation.Required),
@@ -89,7 +91,7 @@ func (typ *TOType) Validate(db *sqlx.DB) []error {
return nil
}
-func (typ *TOType) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (typ *TOType) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
var rows *sqlx.Rows
// Query Parameters to Database Query column mappings
@@ -107,7 +109,7 @@ func (typ *TOType) Read(db *sqlx.DB, parameters map[string]string, user auth.Cur
query := selectQuery() + where + orderBy
log.Debugln("Query is ", query)
- rows, err := db.NamedQuery(query, queryValues)
+ rows, err := typ.ReqInfo.Tx.NamedQuery(query, queryValues)
if err != nil {
log.Errorf("Error querying Types: %v", err)
return nil, []error{tc.DBError}, tc.SystemError
@@ -145,25 +147,9 @@ FROM type typ`
//ParsePQUniqueConstraintError is used to determine if a type with conflicting values exists
//if so, it will return an errorType of DataConflict and the type should be appended to the
//generic error message returned
-func (typ *TOType) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (typ *TOType) Update() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with type: %++v", updateQuery(), typ)
- resultRows, err := tx.NamedQuery(updateQuery(), typ)
+ resultRows, err := typ.ReqInfo.Tx.NamedQuery(updateQuery(), typ)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -194,12 +180,7 @@ func (typ *TOType) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
}
return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
@@ -210,24 +191,8 @@ func (typ *TOType) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
//generic error message returned
//The insert sql returns the id and lastUpdated values of the newly inserted type and have
//to be added to the struct
-func (typ *TOType) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
- resultRows, err := tx.NamedQuery(insertQuery(), typ)
+func (typ *TOType) Create() (error, tc.ApiErrorType) {
+ resultRows, err := typ.ReqInfo.Tx.NamedQuery(insertQuery(), typ)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -264,36 +229,15 @@ func (typ *TOType) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
typ.SetKeys(map[string]interface{}{"id": id})
typ.LastUpdated = &lastUpdated
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
+
return nil, tc.NoError
}
//The Type implementation of the Deleter interface
//all implementations of Deleter should use transactions and return the proper errorType
-func (typ *TOType) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
- rollbackTransaction := true
- tx, err := db.Beginx()
- defer func() {
- if tx == nil || !rollbackTransaction {
- return
- }
- err := tx.Rollback()
- if err != nil {
- log.Errorln(errors.New("rolling back transaction: " + err.Error()))
- }
- }()
-
- if err != nil {
- log.Error.Printf("could not begin transaction: %v", err)
- return tc.DBError, tc.SystemError
- }
+func (typ *TOType) Delete() (error, tc.ApiErrorType) {
log.Debugf("about to run exec query: %s with type: %++v", deleteQuery(), typ)
- result, err := tx.NamedExec(deleteQuery(), typ)
+ result, err := typ.ReqInfo.Tx.NamedExec(deleteQuery(), typ)
if err != nil {
log.Errorf("received error: %++v from delete execution", err)
return tc.DBError, tc.SystemError
@@ -309,12 +253,6 @@ func (typ *TOType) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
}
- err = tx.Commit()
- if err != nil {
- log.Errorln("Could not commit transaction: ", err)
- return tc.DBError, tc.SystemError
- }
- rollbackTransaction = false
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/types/types_test.go b/traffic_ops/traffic_ops_golang/types/types_test.go
index f69d5fe..252bed2 100644
--- a/traffic_ops/traffic_ops_golang/types/types_test.go
+++ b/traffic_ops/traffic_ops_golang/types/types_test.go
@@ -26,8 +26,8 @@ import (
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
- "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
"github.com/jmoiron/sqlx"
@@ -81,10 +81,15 @@ func TestGetType(t *testing.T) {
ts.UseInTable,
)
}
+ mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows)
+ mock.ExpectCommit()
v := map[string]string{"dsId": "1"}
- types, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+ reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+
+ types, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
if len(errs) > 0 {
t.Errorf("type.Read expected: no errors, actual: %v", errs)
}
@@ -118,7 +123,7 @@ func TestInterfaces(t *testing.T) {
func TestValidate(t *testing.T) {
p := TOType{}
- errs := test.SortErrors(p.Validate(nil))
+ errs := test.SortErrors(p.Validate())
expected := test.SortErrors([]error{
errors.New("'name' cannot be blank"),
errors.New("'description' cannot be blank"),