diff --git a/server/cmd/server/main.go b/server/cmd/server/main.go index 3b74d49..f8c6bb9 100644 --- a/server/cmd/server/main.go +++ b/server/cmd/server/main.go @@ -60,7 +60,18 @@ func main() { } // apply pool settings from env for Meta (templates/jobs) db.ApplyPoolFromEnv(meta, "YMT_TEST_DB_") - r := api.NewRouter(meta, marketing, marketingAuth, ymt) + // Marketing Reseller DB + var resellerDB *sql.DB + if cfg.MarketingResellerDB.DSN() != "" { + resellerDB, err = db.ConnectMySQL(cfg.MarketingResellerDB.DSN()) + if err != nil { + log.Fatal(err) + } + log.Println("connecting Marketing Reseller MySQL:", cfg.MarketingResellerDB.Host+":"+cfg.MarketingResellerDB.Port, "db", cfg.MarketingResellerDB.Name) + } else { + resellerDB = marketing // fallback + } + r := api.NewRouter(meta, marketing, marketingAuth, resellerDB, ymt) addr := ":" + func() string { s := cfg.Port if s == "" { diff --git a/server/internal/api/resellers.go b/server/internal/api/resellers.go index a268835..0dd807a 100644 --- a/server/internal/api/resellers.go +++ b/server/internal/api/resellers.go @@ -1,72 +1,65 @@ package api import ( - "database/sql" - "net/http" - "strconv" - "strings" + "database/sql" + "net/http" + "strconv" + "strings" ) type ResellersAPI struct { - marketing *sql.DB + resellerDB *sql.DB } -func ResellersHandler(marketing *sql.DB) http.Handler { - api := &ResellersAPI{marketing: marketing} - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - p := strings.TrimPrefix(r.URL.Path, "/api/resellers") - if r.Method == http.MethodGet && p == "" { - api.list(w, r) - return - } - w.WriteHeader(http.StatusNotFound) - }) +func ResellersHandler(resellerDB *sql.DB) http.Handler { + api := &ResellersAPI{resellerDB: resellerDB} + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := strings.TrimPrefix(r.URL.Path, "/api/resellers") + if r.Method == http.MethodGet && p == "" { + api.list(w, r) + return + } + w.WriteHeader(http.StatusNotFound) + }) } func (a *ResellersAPI) list(w http.ResponseWriter, r *http.Request) { - creatorsParam := r.URL.Query().Get("creator") - q := r.URL.Query().Get("q") - limitStr := r.URL.Query().Get("limit") - limit := 2000 - if limitStr != "" { - if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { limit = n } - } - creators := []string{} - for _, s := range strings.Split(creatorsParam, ",") { - s = strings.TrimSpace(s) - if s != "" { creators = append(creators, s) } - } - if len(creators) == 0 { - ok(w, r, []map[string]interface{}{}) - return - } - ph := strings.Repeat("?,", len(creators)) - ph = strings.TrimSuffix(ph, ",") - sql1 := "SELECT DISTINCT reseller_id, COALESCE(reseller_name,'') AS name FROM plan WHERE reseller_id IS NOT NULL AND creator IN (" + ph + ")" - args := []interface{}{} - for _, c := range creators { args = append(args, c) } - if q != "" { - sql1 += " AND (CAST(reseller_id AS CHAR) LIKE ? OR reseller_name LIKE ?)" - like := "%" + q + "%" - args = append(args, like, like) - } - sql1 += " ORDER BY reseller_id ASC LIMIT ?" - args = append(args, limit) - rows, err := a.marketing.Query(sql1, args...) - if err != nil { - fail(w, r, http.StatusInternalServerError, err.Error()) - return - } - defer rows.Close() - out := []map[string]interface{}{} - for rows.Next() { - var id sql.NullInt64 - var name sql.NullString - if err := rows.Scan(&id, &name); err != nil { continue } - if !id.Valid { continue } - m := map[string]interface{}{"id": id.Int64, "name": name.String} - out = append(out, m) - } - ok(w, r, out) -} + q := r.URL.Query().Get("q") + limitStr := r.URL.Query().Get("limit") + limit := 2000 + if limitStr != "" { + if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { + limit = n + } + } + sql1 := "SELECT id, COALESCE(name,'') AS name FROM reseller WHERE 1=1" + args := []interface{}{} + if q != "" { + sql1 += " AND (CAST(id AS CHAR) LIKE ? OR name LIKE ?)" + like := "%" + q + "%" + args = append(args, like, like) + } + sql1 += " ORDER BY id ASC LIMIT ?" + args = append(args, limit) + rows, err := a.resellerDB.Query(sql1, args...) + if err != nil { + fail(w, r, http.StatusInternalServerError, err.Error()) + return + } + defer rows.Close() + out := []map[string]interface{}{} + for rows.Next() { + var id sql.NullInt64 + var name sql.NullString + if err := rows.Scan(&id, &name); err != nil { + continue + } + if !id.Valid { + continue + } + m := map[string]interface{}{"id": id.Int64, "name": name.String} + out = append(out, m) + } + ok(w, r, out) +} diff --git a/server/internal/api/router.go b/server/internal/api/router.go index 798b38a..9fec7af 100644 --- a/server/internal/api/router.go +++ b/server/internal/api/router.go @@ -6,7 +6,7 @@ import ( "os" ) -func NewRouter(metaDB *sql.DB, marketingDB *sql.DB, marketingAuthDB *sql.DB, ymtDB *sql.DB) http.Handler { +func NewRouter(metaDB *sql.DB, marketingDB *sql.DB, marketingAuthDB *sql.DB, resellerDB *sql.DB, ymtDB *sql.DB) http.Handler { mux := http.NewServeMux() mux.Handle("/api/templates", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB)))) mux.Handle("/api/templates/", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB)))) @@ -17,8 +17,8 @@ func NewRouter(metaDB *sql.DB, marketingDB *sql.DB, marketingAuthDB *sql.DB, ymt mux.Handle("/api/fields/", withAccess(withTrace(FieldsHandler(marketingDB, ymtDB)))) mux.Handle("/api/creators", withAccess(withTrace(CreatorsHandler(marketingAuthDB)))) mux.Handle("/api/creators/", withAccess(withTrace(CreatorsHandler(marketingAuthDB)))) - mux.Handle("/api/resellers", withAccess(withTrace(ResellersHandler(marketingDB)))) - mux.Handle("/api/resellers/", withAccess(withTrace(ResellersHandler(marketingDB)))) + mux.Handle("/api/resellers", withAccess(withTrace(ResellersHandler(resellerDB)))) + mux.Handle("/api/resellers/", withAccess(withTrace(ResellersHandler(resellerDB)))) mux.Handle("/api/plans", withAccess(withTrace(PlansHandler(marketingDB)))) mux.Handle("/api/plans/", withAccess(withTrace(PlansHandler(marketingDB)))) mux.Handle("/api/ymt/users", withAccess(withTrace(YMTUsersHandler(ymtDB)))) diff --git a/server/internal/config/config.go b/server/internal/config/config.go index 8653804..161de03 100644 --- a/server/internal/config/config.go +++ b/server/internal/config/config.go @@ -21,6 +21,7 @@ type App struct { Port string `yaml:"port"` MarketingDB DB `yaml:"marketing_db"` MarketingAuthorizationDB DB `yaml:"marketing_authorization_db"` + MarketingResellerDB DB `yaml:"marketing_reseller_db"` YMTDB DB `yaml:"ymt_db"` YMTTestDB DB `yaml:"ymt_test_db"` YMTKeyDecryptKeyB64 string `yaml:"ymt_key_decrypt_key_b64"`