This is an automated email from the git hooks/post-receive script. New commit to branch bow-v2-go in repository bow. See https://gitlab.nuiton.org/chorem/bow.git commit 73e6fc1bf56feb043c38e64a7c03ea482a9bbf19 Author: Benjamin <poussin@codelutin.com> Date: Sun May 17 11:42:49 2020 +0200 ajout timing dans les logs modif back pour le renommage de tag --- go.mod | 1 + go.sum | 6 ++++++ pkg/http/bookmarkResource.go | 21 ++++++++++++++++++++ pkg/http/router.go | 19 ++++++++++++++---- pkg/repository/bookmarkRepository.go | 11 +++++++++++ pkg/repository/database.go | 37 +++++++++++++++++++++++++++--------- pkg/utils/utils.go | 12 ++++++++++++ 7 files changed, 94 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 3e4a88c..d6dd960 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/jackc/pgtype v1.3.0 github.com/jackc/pgx/v4 v4.6.0 github.com/jackc/tern v1.10.2 + github.com/mitchellh/go-server-timing v1.0.0 github.com/pkg/errors v0.9.1 // indirect golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect diff --git a/go.sum b/go.sum index fd87830..8ef6f3d 100644 --- a/go.sum +++ b/go.sum @@ -8,9 +8,13 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/felixge/httpsnoop v1.0.0 h1:gh8fMGz0rlOv/1WmRZm7OgncIOTsAj21iNJot48omJQ= +github.com/felixge/httpsnoop v1.0.0/go.mod h1:3+D9sFq0ahK/JeJPhCBUV1xlf4/eIYrUQaxulT0VzX8= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang/gddo v0.0.0-20180823221919-9d8ff1c67be5 h1:yrv1uUvgXH/tEat+wdvJMRJ4g51GlIydtDpU9pFjaaI= +github.com/golang/gddo v0.0.0-20180823221919-9d8ff1c67be5/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -82,6 +86,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mitchellh/go-server-timing v1.0.0 h1:cdHk4f7lxjwbRqTSGZFw8PCeoNYXGp4T4Sdr8wT+Xlw= +github.com/mitchellh/go-server-timing v1.0.0/go.mod h1:RdipKQzCJaL4HyxFQBINbf4XoDdZKkSshqw9Bbsx1ic= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/pkg/http/bookmarkResource.go b/pkg/http/bookmarkResource.go index 0e19afe..05737cb 100644 --- a/pkg/http/bookmarkResource.go +++ b/pkg/http/bookmarkResource.go @@ -86,6 +86,27 @@ func getTags(w http.ResponseWriter, r *http.Request) { io.WriteString(w, json) } +/* +renameTag utilise les valeurs dans le path 'oldName' 'newName' pour renommer +un tag. +return json {"count": <nombre de bookmark impacte>} +*/ +func renameTag(w http.ResponseWriter, r *http.Request) { + currentUser := r.Context().Value(constant.User).(model.BowUser) + + oldName := mux.Vars(r)["oldName"] + newName := mux.Vars(r)["newName"] + + count, err := repository.RenameTag(currentUser, oldName, newName) + if err != nil { + utils.Throw(w, err) + return + } + + w.Header().Add("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]int64{"count": count}) +} + func addOneVisit(w http.ResponseWriter, r *http.Request) { currentUser := r.Context().Value(constant.User).(model.BowUser) id := mux.Vars(r)["id"] diff --git a/pkg/http/router.go b/pkg/http/router.go index 04a0c55..706618a 100644 --- a/pkg/http/router.go +++ b/pkg/http/router.go @@ -5,10 +5,10 @@ import ( "io" "log" "net/http" + "os" + "path/filepath" "strings" "time" - "path/filepath" - "os" "gitlab.chorem.org/chorem/bow/pkg/constant" "gitlab.chorem.org/chorem/bow/pkg/model" @@ -59,6 +59,7 @@ func Start(bowPublicURL string, addr string) { s.HandleFunc("/bookmarks", getBookmarks).Methods(http.MethodGet, http.MethodOptions) s.HandleFunc("/bookmarks", addBookmark).Methods(http.MethodPost, http.MethodOptions) s.HandleFunc("/bookmarks/tags", getTags).Methods(http.MethodGet, http.MethodOptions) + s.HandleFunc("/bookmarks/tags/{oldName}/{newName}", renameTag).Methods(http.MethodPut, http.MethodOptions) s.HandleFunc("/bookmarks/{id}", getBookmark).Methods(http.MethodGet, http.MethodOptions) s.HandleFunc("/bookmarks/{id}", deleteBookmark).Methods(http.MethodDelete, http.MethodOptions) s.HandleFunc("/bookmarks/{id}", updateBookmark).Methods(http.MethodPut, http.MethodOptions) @@ -89,14 +90,19 @@ func handler404(w http.ResponseWriter, r *http.Request) { func logAll(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - log.Println("logAll") - log.Println(r) + query := r.URL.Query() + debug := query.Get("bow_debug") + + if (os.Getenv("BOW_DEBUG") == "true" || debug == "true") { + log.Println("logAll", r) + } next.ServeHTTP(w, r) }) } func cors(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Timing-Allow-Origin", r.Header.Get("Origin")) w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) w.Header().Set("Access-Control-Allow-Credentials", "true") if r.Method == http.MethodOptions { @@ -139,6 +145,7 @@ func authentication(next http.Handler) http.Handler { return } + authTime := time.Now() canBeAppToken := false // 1 as query param @@ -204,7 +211,11 @@ func authentication(next http.Handler) http.Handler { ctx := context.WithValue(r.Context(), constant.User, user) r = r.WithContext(ctx) + utils.Duration("authentication", authTime) + + restTime := time.Now() next.ServeHTTP(w, r) + utils.Duration("rest", restTime) }) } diff --git a/pkg/repository/bookmarkRepository.go b/pkg/repository/bookmarkRepository.go index 4aeb0f1..750a741 100644 --- a/pkg/repository/bookmarkRepository.go +++ b/pkg/repository/bookmarkRepository.go @@ -58,6 +58,17 @@ func BookmarkJSON(currentUser model.BowUser, id string, uri string, tags string, return result, nil } +func RenameTag(currentUser model.BowUser, oldName string, newName string) (int64, error) { + tagArray := "{" + oldName + "}" + q := &query{sql: `UPDATE bookmark SET tags=array_replace(tags, '$2, $3) where tags @> $1::text[]`} + count, err := q.execOnNRow(currentUser, tagArray, oldName, newName) + if err != nil { + return 0, utils.NewHTTPError500(err, currentUser) + } + + return count, nil +} + /* TagsJSON retourne la liste des tags qui match le filtre le format de retour est celui d'opensearch diff --git a/pkg/repository/database.go b/pkg/repository/database.go index e4ff5f7..5753f0d 100644 --- a/pkg/repository/database.go +++ b/pkg/repository/database.go @@ -196,16 +196,29 @@ func (q *query) setPostSQL(sql string, arguments ...interface{}) { } func (q *query) execOnOneRow(currentUser model.BowUser, arguments ...interface{}) error { + _, err := q.exec(currentUser, 1, 1, arguments...) + return err +} + +func (q *query) execOnNRow(currentUser model.BowUser, arguments ...interface{}) (int64, error) { + return q.exec(currentUser, 0, -1, arguments...) +} + +/* +exec execute la query, si le nombre de ligne modifier n'est pas minRow <= N <= maxRow alors +la query est rollbacké. Si maxRow < minRow alors il n'y a pas de contrainte sur le max +*/ +func (q *query) exec(currentUser model.BowUser, minRow int64, maxRow int64, arguments ...interface{}) (int64, error) { tx, err := db.Begin(context.Background()) if err != nil { - return utils.NewHTTPError500(err, currentUser) + return 0, utils.NewHTTPError500(err, currentUser) } defer tx.Rollback(context.Background()) if q.presql != "" { _, err = db.Exec(context.Background(), q.presql, pgx.QuerySimpleProtocol(true)) if err != nil { - return utils.NewHTTPError500(err, currentUser) + return 0, utils.NewHTTPError500(err, currentUser) } } @@ -214,33 +227,39 @@ func (q *query) execOnOneRow(currentUser model.BowUser, arguments ...interface{} SET ROLE "%[1]s"; `, currentUser.ID)) if err != nil { - return utils.NewHTTPError500(err, currentUser) + return 0, utils.NewHTTPError500(err, currentUser) } } modif, err := db.Exec(context.Background(), q.sql, arguments...) if err != nil { - return utils.NewHTTPError500(err, currentUser) + return 0, utils.NewHTTPError500(err, currentUser) + } + + + nbModif := modif.RowsAffected() + if nbModif < minRow { + return 0, utils.NewHTTPError(fmt.Sprintf("SQL query modify %v row and is less than %v required. Query '%v' args '%v'", nbModif, minRow, q.sql, arguments), currentUser, 404) } - if modif.RowsAffected() != 1 { - return utils.NewHTTPError(fmt.Sprintf("User not found '%v'", arguments), currentUser, 404) + if minRow <= maxRow && nbModif > maxRow { + return 0, utils.NewHTTPError(fmt.Sprintf("SQL query modify %v row and is more than %v requited . Query '%v' args '%v'", nbModif, maxRow, q.sql, arguments), currentUser, 404) } if q.postsql != "" { _, err = db.Exec(context.Background(), q.postsql, pgx.QuerySimpleProtocol(true)) if err != nil { - return utils.NewHTTPError500(err, currentUser) + return 0, utils.NewHTTPError500(err, currentUser) } } err = tx.Commit(context.Background()) if err != nil { - return utils.NewHTTPError500(err, currentUser) + return 0, utils.NewHTTPError500(err, currentUser) } - return nil + return nbModif, nil } /* diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index d7dad83..4cffc0d 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,7 +1,9 @@ package utils import ( + "log" "strings" + "time" ) /* @@ -15,3 +17,13 @@ func RemoveTagReturn(s string) string { return c }, s) } + +// TrackTime start time tracking duration +func TrackTime(msg string) (string, time.Time) { + return msg, time.Now() +} + +// Duration compute duration from TrackTime +func Duration(msg string, start time.Time) { + log.Printf("Timing %v: %v\n", msg, time.Since(start)) +} \ No newline at end of file -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.