forked from Sansui233/proxypool
/
proxy.go
109 lines (100 loc) · 2.85 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package database
import (
"github.com/godsun/proxypool/log"
"github.com/godsun/proxypool/pkg/proxy"
"gorm.io/gorm"
"time"
)
// 设置数据库字段,表名为默认为type名的复数。相比于原作者,不使用软删除特性
type Proxy struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
proxy.Base
Link string
Identifier string `gorm:"unique"`
}
func InitTables() {
if DB == nil {
err := connect()
if err != nil {
return
}
}
// Warnln: 自动迁移仅仅会创建表,缺少列和索引,并且不会改变现有列的类型或删除未使用的列以保护数据。
// 如更改表的Column请于数据库中操作
err := DB.AutoMigrate(&Proxy{})
if err != nil {
log.Errorln("\n\t\t[db/proxy.go] database migration failed")
panic(err)
}
}
func SaveProxyList(pl proxy.ProxyList) {
if DB == nil {
return
}
DB.Transaction(func(tx *gorm.DB) error {
// Set All Usable to false
if err := DB.Model(&Proxy{}).Where("useable = ?", true).Update("useable", "false").Error; err != nil {
log.Warnln("database: Reset useable to false failed: %s", err.Error())
}
// Create or Update proxies
for i := 0; i < pl.Len(); i++ {
p := Proxy{
Base: *pl[i].BaseInfo(),
Link: pl[i].Link(),
Identifier: pl[i].Identifier(),
}
p.Useable = true
if err := DB.Create(&p).Error; err != nil {
// Update with Identifier
if uperr := DB.Model(&Proxy{}).Where("identifier = ?", p.Identifier).Updates(&Proxy{
Base: proxy.Base{Useable: true, Name: p.Name},
}).Error; uperr != nil {
log.Warnln("\n\t\tdatabase: Update failed:"+
"\n\t\tdatabase: When Created item: %s"+
"\n\t\tdatabase: When Updated item: %s", err.Error(), uperr.Error())
}
}
}
log.Infoln("database: Updated")
return nil
})
}
// Get a proxy list consists of all proxies in database
func GetAllProxies() (proxies proxy.ProxyList) {
proxies = make(proxy.ProxyList, 0)
if DB == nil {
return nil
}
proxiesDB := make([]Proxy, 0)
DB.Select("link").Find(&proxiesDB)
for _, proxyDB := range proxiesDB {
if proxiesDB != nil {
p, err := proxy.ParseProxyFromLink(proxyDB.Link)
if err == nil && p != nil {
p.SetUseable(false)
proxies = append(proxies, p)
}
}
}
return
}
// Clear proxies unusable more than 1 week
func ClearOldItems() {
if DB == nil {
return
}
lastWeek := time.Now().Add(-time.Hour * 24 * 7)
if err := DB.Where("updated_at < ? AND useable = ?", lastWeek, false).Delete(&Proxy{}); err != nil {
var count int64
DB.Model(&Proxy{}).Where("updated_at < ? AND useable = ?", lastWeek, false).Count(&count)
if count == 0 {
log.Infoln("database: Nothing old to sweep") // TODO always this line?
} else {
log.Warnln("database: Delete old item failed: %s", err.Error.Error())
}
} else {
log.Infoln("database: Swept old and unusable proxies")
}
}