Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -29,7 +29,20 @@ func GetProductPricingListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 180*time.Second)
|
||||
defer cancel()
|
||||
|
||||
rows, err := queries.GetProductPricingList(ctx)
|
||||
limit := 500
|
||||
if raw := strings.TrimSpace(r.URL.Query().Get("limit")); raw != "" {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 && parsed <= 10000 {
|
||||
limit = parsed
|
||||
}
|
||||
}
|
||||
offset := 0
|
||||
if raw := strings.TrimSpace(r.URL.Query().Get("offset")); raw != "" {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed >= 0 && parsed <= 1000000 {
|
||||
offset = parsed
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := queries.GetProductPricingList(ctx, limit+1, offset)
|
||||
if err != nil {
|
||||
if isPricingTimeoutLike(err, ctx.Err()) {
|
||||
log.Printf(
|
||||
@@ -54,16 +67,29 @@ func GetProductPricingListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Urun fiyatlandirma listesi alinamadi: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
hasMore := len(rows) > limit
|
||||
if hasMore {
|
||||
rows = rows[:limit]
|
||||
}
|
||||
|
||||
log.Printf(
|
||||
"[ProductPricing] trace=%s success user=%s id=%d count=%d duration_ms=%d",
|
||||
"[ProductPricing] trace=%s success user=%s id=%d limit=%d offset=%d count=%d has_more=%t duration_ms=%d",
|
||||
traceID,
|
||||
claims.Username,
|
||||
claims.ID,
|
||||
limit,
|
||||
offset,
|
||||
len(rows),
|
||||
hasMore,
|
||||
time.Since(started).Milliseconds(),
|
||||
)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
if hasMore {
|
||||
w.Header().Set("X-Has-More", "true")
|
||||
} else {
|
||||
w.Header().Set("X-Has-More", "false")
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(rows)
|
||||
}
|
||||
|
||||
|
||||
41
svc/routes/translation_perf.go
Normal file
41
svc/routes/translation_perf.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EnsureTranslationPerfIndexes creates helpful indexes for translation listing/search.
|
||||
// It is safe to run on each startup; failures are logged and do not stop the service.
|
||||
func EnsureTranslationPerfIndexes(db *sql.DB) {
|
||||
if db == nil {
|
||||
return
|
||||
}
|
||||
|
||||
statements := []string{
|
||||
`CREATE EXTENSION IF NOT EXISTS pg_trgm`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_mk_translator_t_key_lang ON mk_translator (t_key, lang_code)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_mk_translator_status_lang_updated ON mk_translator (status, lang_code, updated_at DESC)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_mk_translator_manual_status ON mk_translator (is_manual, status)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_mk_translator_source_type_expr ON mk_translator ((COALESCE(NULLIF(provider_meta->>'source_type',''),'dummy')))`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_mk_translator_source_text_trgm ON mk_translator USING gin (source_text_tr gin_trgm_ops)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_mk_translator_translated_text_trgm ON mk_translator USING gin (translated_text gin_trgm_ops)`,
|
||||
}
|
||||
|
||||
for _, stmt := range statements {
|
||||
if _, err := db.Exec(stmt); err != nil {
|
||||
log.Printf("[TranslationPerf] index_setup_warn sql=%q err=%v", summarizeSQL(stmt), err)
|
||||
continue
|
||||
}
|
||||
log.Printf("[TranslationPerf] index_ready sql=%q", summarizeSQL(stmt))
|
||||
}
|
||||
}
|
||||
|
||||
func summarizeSQL(sqlText string) string {
|
||||
s := strings.TrimSpace(sqlText)
|
||||
if len(s) <= 100 {
|
||||
return s
|
||||
}
|
||||
return s[:100] + "..."
|
||||
}
|
||||
@@ -143,6 +143,12 @@ func GetTranslationRowsHandler(db *sql.DB) http.HandlerFunc {
|
||||
limit = parsed
|
||||
}
|
||||
}
|
||||
offset := 0
|
||||
if raw := strings.TrimSpace(r.URL.Query().Get("offset")); raw != "" {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed >= 0 && parsed <= 1000000 {
|
||||
offset = parsed
|
||||
}
|
||||
}
|
||||
|
||||
clauses := []string{"1=1"}
|
||||
args := make([]any, 0, 8)
|
||||
@@ -202,6 +208,11 @@ ORDER BY t_key, lang_code
|
||||
if limit > 0 {
|
||||
query += fmt.Sprintf("LIMIT $%d", argIndex)
|
||||
args = append(args, limit)
|
||||
argIndex++
|
||||
}
|
||||
if offset > 0 {
|
||||
query += fmt.Sprintf(" OFFSET $%d", argIndex)
|
||||
args = append(args, offset)
|
||||
}
|
||||
|
||||
rows, err := db.Query(query, args...)
|
||||
|
||||
Reference in New Issue
Block a user