From f97738f0c6156434042f3d1959bb1b4332a6ff56 Mon Sep 17 00:00:00 2001 From: Valentin Kuznetsov Date: Sun, 6 Dec 2020 13:07:45 -0500 Subject: [PATCH] Add executeNew --- dbs/datasets.go | 47 ++++++++++++++++++++++++++++++++++ dbs/dbs.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ web/handlers.go | 13 +++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/dbs/datasets.go b/dbs/datasets.go index 10208efc..5549b0d9 100644 --- a/dbs/datasets.go +++ b/dbs/datasets.go @@ -3,6 +3,7 @@ package dbs import ( "database/sql" "fmt" + "net/http" "strings" ) @@ -128,3 +129,49 @@ func (API) DatasetAccessTypes(params Record) []Record { // use generic query API to fetch the results from DB return executeAll(stm+where, args...) } + +// Datasets API +func (API) DatasetsNew(params Record, w http.ResponseWriter) error { + // variables we'll use in where clause + var args []interface{} + where := "WHERE " + + // parse detail arugment + detail := getSingleValue(params, "detail") + + // parse is_dataset_valid argument + isValid := getSingleValue(params, "is_dataset_valid") + if isValid == "" { + isValid = "1" + } + where += fmt.Sprintf("D.IS_DATASET_VALID = %s", placeholder("is_dataset_valid")) + args = append(args, isValid) + + // parse dataset argument + datasets := getValues(params, "dataset") + genSQL := "" + if len(datasets) > 1 { + where += fmt.Sprintf(" AND D.DATASET in (SELECT TOKEN FROM TOKEN_GENERATOR)") + var vals []string + genSQL, vals = tokens(datasets) + for _, d := range vals { + args = append(args, d, d, d) // append three values since tokens generates placeholders for them + } + } else if len(datasets) == 1 { + op, val := opVal(datasets[0]) + where += fmt.Sprintf(" AND D.DATASET %s %s", op, placeholder("dataset")) + args = append(args, val) + } + + // get SQL statement from static area + stm := getSQL("datasets") + cols := []string{"dataset_id", "dataset", "prep_id", "xtcrosssection", "creation_date", "create_by", "last_modification_date", "last_modified_by", "primary_ds_name", "primary_ds_type", "processed_ds_name", "data_tier_name", "dataset_access_type", "acquisition_era_name", "processing_version", "physics_group_name"} + vals := []interface{}{new(sql.NullInt64), new(sql.NullString), new(sql.NullString), new(sql.NullFloat64), new(sql.NullInt64), new(sql.NullString), new(sql.NullInt64), new(sql.NullString), new(sql.NullString), new(sql.NullString), new(sql.NullString), new(sql.NullString), new(sql.NullString), new(sql.NullString), new(sql.NullInt64), new(sql.NullString)} + if strings.ToLower(detail) != "true" { + stm = getSQL("datasets_short") + cols = []string{"dataset"} + vals = []interface{}{new(sql.NullString)} + } + // use generic query API to fetch the results from DB + return executeNew(w, genSQL+stm+where, cols, vals, args...) +} diff --git a/dbs/dbs.go b/dbs/dbs.go index bc55fdb1..27bfa603 100644 --- a/dbs/dbs.go +++ b/dbs/dbs.go @@ -5,6 +5,7 @@ package dbs import ( "database/sql" "encoding/json" + "errors" "fmt" "io/ioutil" "log" @@ -342,3 +343,70 @@ func errorRecord(msg string) []Record { out = append(out, erec) return out } + +// similar to executeAll function but it takes explicit set of columns and values +func executeNew(w http.ResponseWriter, stm string, cols []string, vals []interface{}, args ...interface{}) error { + enc := json.NewEncoder(w) + + if utils.VERBOSE > 1 { + log.Println(stm, args) + } + tx, err := DB.Begin() + if err != nil { + msg := fmt.Sprintf("unable to obtain transaction %v", err) + return errors.New(msg) + } + defer tx.Rollback() + // rows, err := DB.Query(stm, args...) + rows, err := tx.Query(stm, args...) + if err != nil { + msg := fmt.Sprintf("DB.Query, query='%s' args='%v' error=%v", stm, args, err) + return errors.New(msg) + } + defer rows.Close() + + // loop over rows + for rows.Next() { + err := rows.Scan(vals...) + if err != nil { + msg := fmt.Sprintf("rows.Scan, vals='%v', error=%v", vals, err) + return errors.New(msg) + } + rec := make(Record) + for i, _ := range cols { + vvv := vals[i] + switch val := vvv.(type) { + case *sql.NullString: + v, e := val.Value() + if e == nil { + rec[cols[i]] = v + } + case *sql.NullInt64: + v, e := val.Value() + if e == nil { + rec[cols[i]] = v + } + case *sql.NullFloat64: + v, e := val.Value() + if e == nil { + rec[cols[i]] = v + } + case *sql.NullBool: + v, e := val.Value() + if e == nil { + rec[cols[i]] = v + } + default: + rec[cols[i]] = val + } + } + err = enc.Encode(rec) + if err != nil { + return err + } + } + if err = rows.Err(); err != nil { + return err + } + return nil +} diff --git a/web/handlers.go b/web/handlers.go index 6caa8de6..1dff654b 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -156,7 +156,18 @@ func DatatiersHandler(w http.ResponseWriter, r *http.Request) (int, int64, error // DatasetsHandler func DatasetsHandler(w http.ResponseWriter, r *http.Request) (int, int64, error) { - return DBSGetHandler(w, r, "datasets") + // return DBSGetHandler(w, r, "datasets") + status := http.StatusOK + var params dbs.Record + for k, v := range r.Form { + params[k] = v + } + var api dbs.API + err := api.DatasetsNew(params, w) + if err != nil { + return http.StatusInternalServerError, 0, err + } + return status, 0, nil } // BlocksHandler