···1313 clears = 1
1414 }
1515 _, err := s.Conn.Exec(context.Background(), `
1616- INSERT INTO course_info (id, data_id, plays, tries, deaths, clears, likes, boos) VALUES (DEFAULT, $1, 1, $2, $3, $4, 0, 0)
1717- ON CONFLICT (data_id) DO UPDATE SET plays = course_info.plays + 1, tries = course_info.tries + $2, deaths = course_info.deaths + $3, clears = course_info.clears + $4
1616+ INSERT INTO course (id, data_id, plays, tries, deaths, clears) VALUES (DEFAULT, $1, 1, $2, $3, $4)
1717+ ON CONFLICT (data_id) DO UPDATE SET plays = course.plays + 1, tries = course.tries + $2, deaths = course.deaths + $3, clears = course.clears + $4, clear_rate = (course.clears::float / COALESCE(NULLIF(course.tries,0), 1)::float)
1818 `, result.DataId, result.Tries, result.Deaths, clears)
1919 return err
2020}
···2828 }
29293030 _, err := s.Conn.Exec(context.Background(), `
3131- INSERT INTO course_info (id, data_id, plays, tries, deaths, clears, likes, boos) VALUES (DEFAULT, $1, 0, 0, 0, 0, $2, $3)
3232- ON CONFLICT (data_id) DO UPDATE SET likes = course_info.likes + $2, boos = course_info.boos + $3
3131+ INSERT INTO course (id, data_id, likes, boos) VALUES (DEFAULT, $1, $2, $3)
3232+ ON CONFLICT (data_id) DO UPDATE SET likes = course.likes + $2, boos = course.boos + $3, like_ratio = (course.likes::float / COALESCE(NULLIF(course.plays,0), 1)::float), boo_ratio = (course.boos::float / COALESCE(NULLIF(course.plays,0), 1)::float)
3333 `, dataId, like, boo)
3434 return err
3535}
36363737func (s *DB) GetCourseInfoPlayStatsAndRatings(dataId int64) (int, int, int, int, int, int, error) {
3838- row := s.Conn.QueryRow(context.Background(), `SELECT plays, tries, deaths, clears, likes, boos FROM course_info WHERE data_id = $1`, dataId)
3838+ row := s.Conn.QueryRow(context.Background(), `SELECT plays, tries, deaths, clears, likes, boos FROM course WHERE data_id = $1`, dataId)
3939 var plays int
4040 var tries int
4141 var deaths int
+44-12
db/dyna/dyna.go
···920920func (s *DB) SearchCoursesAdvanced(current_pid datastore.Pid, dumpView *dump_view.DumpView, param view.SearchCoursesParam) ([]datastore.CourseInfo, []uint32, bool, error) {
921921 infos := []datastore.CourseInfo{}
922922923923- sortBy := "ORDER BY time_uploaded DESC"
923923+ sortBy := ""
924924 //sortBy := "ORDER BY id DESC"
925925 switch param.Advanced.SortType {
926926 case 0:
927927 // by popularity
928928- // TODO
929929- case 1:
930930- // by clear rate
931931- // TODO
928928+ sortBy = "ORDER BY likes DESC, plays DESC"
932929 case 2:
933930 // by popularity in multiplayer versus
934934- // TODO
931931+ // but use its as by time_uploaded
932932+ sortBy = "ORDER BY time_uploaded DESC"
933933+ case 1:
934934+ // by clear rate
935935+ sortBy = "ORDER BY clear_rate ASC, time_uploaded DESC"
936936+ case 10:
937937+ // popular tab
938938+ sortBy = "ORDER BY like_ratio DESC"
939939+ case 11:
940940+ // hot tab
941941+ sortBy = "ORDER BY boo_ratio ASC, plays DESC"
935942 }
936943937944 limitUploadDate := "AND time_uploaded IS NOT NULL"
···947954 limitUploadDate = fmt.Sprintf("AND time_uploaded > (CURRENT_DATE - INTERVAL '365 days')")
948955 case 3:
949956 // ALL
957957+ case 10:
958958+ // weekly
959959+ limitUploadDate = fmt.Sprintf("AND time_uploaded > (CURRENT_DATE - INTERVAL '7 days')")
960960+ case 11:
961961+ // monthly
962962+ limitUploadDate = fmt.Sprintf("AND time_uploaded > (CURRENT_DATE - INTERVAL '30 days')")
950963 }
951964952965 limitPlays := ""
···964977 case 3:
965978 // ALL
966979 }
967967- limitPlays = "" // TODO: we don't have plays field on course yet
968980969981 courseTheme := ""
970982 if param.Advanced.CourseTheme != 0xff {
···977989 }
978990979991 difficulty := ""
980980- if param.Advanced.Difficulty != 4 {
981981- difficulty = fmt.Sprintf("difficulty = %d AND ", param.Advanced.Difficulty)
992992+ /*
993993+ // ignore for now and just use clear_rate
994994+ if param.Advanced.Difficulty != 4 {
995995+ difficulty = fmt.Sprintf("difficulty = %d AND ", param.Advanced.Difficulty)
996996+ }
997997+ */
998998+ switch param.Advanced.Difficulty {
999999+ case 0:
10001000+ // easy
10011001+ difficulty = "clear_rate > 0.8 AND "
10021002+ case 1:
10031003+ // normal
10041004+ difficulty = "clear_rate > 0.4 AND clear_rate < 0.81 AND "
10051005+ case 2:
10061006+ // expert
10071007+ difficulty = "clear_rate > 0.2 AND clear_rate < 0.41 AND "
10081008+ case 3:
10091009+ // super expert
10101010+ //difficulty = "plays > 20 AND clear_rate < 0.2 AND "
10111011+ difficulty = "clear_rate < 0.2 AND "
10121012+ case 4:
10131013+ // ALL
9821014 }
98310159841016 byTags := ""
985985- if len(param.Advanced.Tags) != 16 {
10171017+ if len(param.Advanced.Tags) != 16 && len(param.Advanced.Tags) < 16 {
9861018 list := []string{}
9871019 for _, tagId := range param.Advanced.Tags {
9881020 list = append(list, strconv.Itoa(int(tagId)))
···9921024 }
99310259941026 rejectRegions := ""
995995- if len(param.Advanced.RejectRegions) != 0 {
10271027+ if len(param.Advanced.RejectRegions) != 0 && len(param.Advanced.RejectRegions) < 10 {
9961028 list := []string{}
9971029 for _, _id := range param.Advanced.RejectRegions {
9981030 list = append(list, strconv.Itoa(int(_id)))
···10231055}
1024105610251057func (s *DB) GetCoursesLatest(offset, size int) ([]datastore.CourseInfo, error) {
10261026- rows, err := s.Conn.Query(context.Background(), "SELECT data_id FROM course WHERE deleted = False AND time_uploaded IS NOT NULL ORDER BY id DESC LIMIT $1 OFFSET $2", size, offset)
10581058+ rows, err := s.Conn.Query(context.Background(), "SELECT data_id FROM course WHERE deleted = False AND time_uploaded IS NOT NULL ORDER BY time_uploaded DESC LIMIT $1 OFFSET $2", size, offset)
10271059 if err == pgx.ErrNoRows {
10281060 return []datastore.CourseInfo{}, nil
10291061 } else if err != nil {
+21
db/migrations/000003_course_searches.down.sql
···11+ALTER TABLE IF EXISTS course DROP COLUMN plays;
22+ALTER TABLE IF EXISTS course DROP COLUMN tries;
33+ALTER TABLE IF EXISTS course DROP COLUMN deaths;
44+ALTER TABLE IF EXISTS course DROP COLUMN clears;
55+ALTER TABLE IF EXISTS course DROP COLUMN likes;
66+ALTER TABLE IF EXISTS course DROP COLUMN boos;
77+ALTER TABLE IF EXISTS course DROP COLUMN like_ratio;
88+ALTER TABLE IF EXISTS course DROP COLUMN boo_ratio;
99+ALTER TABLE IF EXISTS course DROP COLUMN clear_rate;
1010+1111+CREATE TABLE IF NOT EXISTS course_info (
1212+ id BIGSERIAL primary key,
1313+ data_id BIGINT,
1414+ plays INTEGER,
1515+ tries INTEGER,
1616+ deaths INTEGER,
1717+ clears INTEGER,
1818+ likes INTEGER,
1919+ boos INTEGER,
2020+ UNIQUE (data_id)
2121+);
+10
db/migrations/000003_course_searches.up.sql
···11+DROP TABLE IF EXISTS course_info;
22+ALTER TABLE IF EXISTS course ADD COLUMN plays INTEGER DEFAULT 0;
33+ALTER TABLE IF EXISTS course ADD COLUMN tries INTEGER DEFAULT 0;
44+ALTER TABLE IF EXISTS course ADD COLUMN deaths INTEGER DEFAULT 0;
55+ALTER TABLE IF EXISTS course ADD COLUMN clears INTEGER DEFAULT 0;
66+ALTER TABLE IF EXISTS course ADD COLUMN likes INTEGER DEFAULT 0;
77+ALTER TABLE IF EXISTS course ADD COLUMN boos INTEGER DEFAULT 0;
88+ALTER TABLE IF EXISTS course ADD COLUMN like_ratio FLOAT DEFAULT 0;
99+ALTER TABLE IF EXISTS course ADD COLUMN boo_ratio FLOAT DEFAULT 0;
1010+ALTER TABLE IF EXISTS course ADD COLUMN clear_rate FLOAT DEFAULT 0;