invidious/cache.go (view raw)
1package invidious
2
3import (
4 "database/sql"
5 "log"
6 "time"
7
8 _ "github.com/mattn/go-sqlite3"
9)
10
11const dbConnectionString = "file:cache.sqlite?cache=shared&mode="
12
13func getDb(mode string) *sql.DB {
14 db, err := sql.Open("sqlite3", dbConnectionString+mode)
15 if err != nil {
16 log.Println("Could not open DB:", err)
17 return nil
18 }
19 db.SetMaxOpenConns(1)
20 return db
21}
22
23func InitDB() {
24 db := getDb("rwc")
25 defer db.Close()
26
27 _, err := db.Exec(createQueryVideos)
28 if err != nil {
29 log.Printf("%q: %s\n", err, createQueryVideos)
30 return
31 }
32 _, err = db.Exec(createQueryFormats)
33 if err != nil {
34 log.Printf("%q: %s\n", err, createQueryFormats)
35 return
36 }
37}
38
39func CacheVideoDB(v Video) {
40 db := getDb("rw")
41 defer db.Close()
42
43 cacheVideo, err := db.Prepare(cacheVideoQuery)
44 if err != nil {
45 log.Println("Could not cache video:", err)
46 return
47 }
48 defer cacheVideo.Close()
49
50 _, err = cacheVideo.Exec(v.VideoId, v.Title, v.Description, v.Uploader, v.Duration)
51 if err != nil {
52 log.Println("Could not cache video:", err)
53 return
54 }
55
56 for _, f := range v.Formats {
57 cacheFormat, err := db.Prepare(cacheFormatQuery)
58 if err != nil {
59 log.Println("Could not cache format:", err)
60 return
61 }
62 defer cacheVideo.Close()
63
64 _, err = cacheFormat.Exec(v.VideoId, f.Name, f.Height, f.Width, f.Url)
65 if err != nil {
66 log.Println("Could not cache format:", err)
67 return
68 }
69 }
70}
71
72func GetVideoDB(videoId string) (*Video, error) {
73 db := getDb("ro")
74 defer db.Close()
75
76 getVideo, err := db.Prepare(getVideoQuery)
77 if err != nil {
78 log.Println("Could not get video:", err)
79 return nil, err
80 }
81 defer getVideo.Close()
82
83 v := &Video{}
84 sixHoursAgo := time.Now().Add(-6 * time.Hour)
85 err = getVideo.QueryRow(videoId, sixHoursAgo).Scan(&v.VideoId, &v.Title, &v.Description, &v.Uploader, &v.Duration, &sql.NullString{})
86 if err != nil {
87 log.Println("Could not get video:", err)
88 return nil, err
89 }
90
91 getFormat, err := db.Prepare(getFormatQuery)
92 if err != nil {
93 log.Println("Could not get video:", err)
94 return nil, err
95 }
96 defer getFormat.Close()
97
98 response, err := getFormat.Query(videoId)
99 if err != nil {
100 log.Println("Could not get formats:", err)
101 return nil, err
102 }
103 defer response.Close()
104
105 for response.Next() {
106 f := Format{}
107 err := response.Scan(&f.VideoId, &f.Name, &f.Height, &f.Width, &f.Url)
108 if err != nil {
109 log.Println("Could not get formats:", err)
110 return nil, err
111 }
112 v.Formats = append(v.Formats, f)
113 }
114
115 return v, nil
116}
117
118func ClearDB() {
119 db := getDb("rw")
120 defer db.Close()
121
122 stmt, err := db.Prepare(clearQuery)
123 if err != nil {
124 log.Println("Could not clear DB:", err)
125 return
126 }
127 defer stmt.Close()
128
129 _, err = stmt.Exec()
130 if err != nil {
131 log.Println("Could not clear DB:", err)
132 return
133 }
134}