package model import ( "crawler/config" "crawler/service" "database/sql" "encoding/json" "log" "strings" ) // 영화사 목록 검색 변수 type SearchCompanyListParams struct { Key string `form:"key" url:"key" binding:"required"` CurPage int `form:"curPage" url:"curPage,omitempty"` ItemPerPage int `form:"itemPerPage" url:"itemPerPage,omitempty"` CompanyNm string `form:"companyNm" url:"companyNm,omitempty"` CeoNm string `form:"ceoNm" url:"ceoNm,omitempty"` CompanyPartCd string `form:"companyPartCd" url:"companyPartCd,omitempty"` } // 영화사 목록 응답 변수 type SearchCompanyList struct { CompanyListResult struct { TotCnt int `json:"totCnt"` Source string `json:"source"` CompanyList []CompanyListInfo `json:"companyList"` } `json:"companyListResult"` } type CompanyListInfo struct { CompanyCd string `json:"companyCd"` CompanyNm string `json:"companyNm"` CompanyNmEn string `json:"companyNmEn"` CompanyPartNames string `json:"companyPartNames"` CeoNm string `json:"ceoNm"` FilmoNames string `json:"filmoNames"` } // 영화사 상세 검색 변수 type SearchCompanyInfoParams struct { Key string `form:"key" url:"key" binding:"required"` CompanyCd string `form:"companyCd" url:"companyCd" binding:"required"` } // 영화사 상세 응답 변수 type SearchCompanyInfo struct { CompanyInfoResult struct { Source string `json:"source"` CompanyInfo CompanyInfo `json:"companyInfo"` } `json:"companyInfoResult"` } type CompanyInfo struct { CompanyCd string `json:"companyCd"` CompanyNm string `json:"companyNm"` CompanyNmEn string `json:"companyNmEn"` CeoNm string `json:"ceoNm"` Parts []CompanyPart `json:"parts"` Filmos []CompanyFilmo `json:"filmos"` } type CompanyPart struct { CompanyPartNm string `json:"companyPartNm"` } type CompanyFilmo struct { MovieCd string `json:"movieCd"` MovieNm string `json:"movieNm"` CompanyPartNm string `json:"companyPartNm"` } // ---- DB 계층 (tb_company / tb_company_filmo) ---- type CompanyModel struct{} // tb_company 로우 type CompanyTable struct { CompanyID int CompanyCd string CompanyNm *string CompanyNmEn *string CeoNm *string CompanyPartNames *string Parts *string FilmoNames *string UpdatedAt *string CreatedAt string } func (this *CompanyModel) Total() int { var ( db = service.DB_MOVIEW conn = db.SQLDB query = "SELECT COUNT(*) FROM tb_company;" total = 0 ) err := conn.QueryRow(query).Scan(&total) if err != nil { db.SetErrorLog(err, query) return total } db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select total company") return total } func (this *CompanyModel) IsExists(companyCd string) bool { var ( db = service.DB_MOVIEW conn = db.SQLDB query = "SELECT IF(COUNT(*) <= 0, 0, 1) AS `exists` FROM tb_company WHERE company_cd = ?;" exists = false ) err := conn.QueryRow(query, companyCd).Scan(&exists) if err != nil { db.SetErrorLog(err, query) return exists } db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select exists company") return exists } // 목록 API 결과 upsert (company_part_names, filmo_names 채움) func (this *CompanyModel) Insert(list []CompanyListInfo) error { if len(list) <= 0 { return nil } var ( db = service.DB_MOVIEW conn = db.SQLDB query = ` INSERT INTO tb_company ( company_cd, company_nm, company_nm_en, ceo_nm, company_part_names, filmo_names, updated_at, created_at ) VALUES ` vals = []interface{}{} ) for _, row := range list { query += `(?, ?, ?, ?, ?, ?, NULL, NOW()),` vals = append(vals, row.CompanyCd, nullStr(row.CompanyNm), nullStr(row.CompanyNmEn), nullStr(row.CeoNm), nullStr(row.CompanyPartNames), nullStr(row.FilmoNames)) } query = query[0 : len(query)-1] query += ` ON DUPLICATE KEY UPDATE company_nm = VALUES(company_nm), company_nm_en = VALUES(company_nm_en), ceo_nm = VALUES(ceo_nm), company_part_names = VALUES(company_part_names), filmo_names = VALUES(filmo_names), updated_at = NOW(); ` stmt, err := conn.Prepare(query) if err != nil { db.SetErrorLog(err, query) return err } defer stmt.Close() _, err = stmt.Exec(vals...) if err != nil { db.SetErrorLog(err, query) return err } db.SetGeneralLog(config.GL_ACTION_WRITE, query, "insert company list") return nil } // 상세 API 결과 upsert (parts JSON 채움) func (this *CompanyModel) InsertInfo(info CompanyInfo) error { if info.CompanyCd == "" { return nil } var ( db = service.DB_MOVIEW conn = db.SQLDB query = ` INSERT INTO tb_company ( company_cd, company_nm, company_nm_en, ceo_nm, parts, updated_at, created_at ) VALUES (?, ?, ?, ?, ?, NULL, NOW()) ON DUPLICATE KEY UPDATE company_nm = VALUES(company_nm), company_nm_en = VALUES(company_nm_en), ceo_nm = VALUES(ceo_nm), parts = VALUES(parts), updated_at = NOW(); ` parts interface{} ) if len(info.Parts) > 0 { b, _ := json.Marshal(info.Parts) parts = string(b) } else { parts = nil } _, err := conn.Exec(query, info.CompanyCd, nullStr(info.CompanyNm), nullStr(info.CompanyNmEn), nullStr(info.CeoNm), parts) if err != nil { db.SetErrorLog(err, query) return err } db.SetGeneralLog(config.GL_ACTION_WRITE, query, "insert company info") return nil } // 필모그래피 upsert (tb_company_filmo) func (this *CompanyModel) InsertFilmos(companyCd string, filmos []CompanyFilmo) error { if companyCd == "" || len(filmos) <= 0 { return nil } var ( db = service.DB_MOVIEW conn = db.SQLDB query = ` INSERT INTO tb_company_filmo (company_cd, movie_cd, movie_nm, company_part_nm, created_at) VALUES ` vals = []interface{}{} ) for _, f := range filmos { if f.MovieCd == "" { continue } query += `(?, ?, ?, ?, NOW()),` vals = append(vals, companyCd, f.MovieCd, nullStr(f.MovieNm), nullStr(f.CompanyPartNm)) } if len(vals) == 0 { return nil } query = query[0 : len(query)-1] query += ` ON DUPLICATE KEY UPDATE movie_nm = VALUES(movie_nm); ` stmt, err := conn.Prepare(query) if err != nil { db.SetErrorLog(err, query) return err } defer stmt.Close() _, err = stmt.Exec(vals...) if err != nil { db.SetErrorLog(err, query) return err } db.SetGeneralLog(config.GL_ACTION_WRITE, query, "insert company filmo") return nil } // 상세(parts) 미수집 영화사 코드 조회 func (this *CompanyModel) CompanyInfoExcludeCodes() []string { var ( db = service.DB_MOVIEW conn = db.SQLDB query = `SELECT company_cd FROM tb_company WHERE parts IS NULL ORDER BY id ASC;` code []string ) rows, err := conn.Query(query) if err != nil && err != sql.ErrNoRows { db.SetErrorLog(err, query) return code } defer rows.Close() for rows.Next() { var cd string if err := rows.Scan(&cd); err != nil { log.Println(err) continue } code = append(code, cd) } db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select company_cd exclude codes") return code } func nullStr(s string) interface{} { if strings.TrimSpace(s) == "" { return nil } return s }