diff --git a/bootstrap/cmd.go b/bootstrap/cmd.go index bdf5a758..020b930a 100644 --- a/bootstrap/cmd.go +++ b/bootstrap/cmd.go @@ -61,6 +61,10 @@ func start() { log.Errorf("初始化阿里云盘出现错误,启动失败.") return } + if !InitModel() { + log.Errorf("初始化数据库出现错误,启动失败.") + return + } InitCache() InitCron() server() diff --git a/bootstrap/model.go b/bootstrap/model.go new file mode 100644 index 00000000..376a526c --- /dev/null +++ b/bootstrap/model.go @@ -0,0 +1,37 @@ +package bootstrap + +import ( + "github.com/Xhofe/alist/conf" + "github.com/Xhofe/alist/server/models" + "github.com/Xhofe/alist/utils" + log "github.com/sirupsen/logrus" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +func InitModel() bool { + log.Infof("初始化数据库...") + switch conf.Conf.Database.Type { + case "sqlite3":{ + needMigrate := !utils.Exists(conf.Conf.Database.DBFile) + db, err := gorm.Open(sqlite.Open(conf.Conf.Database.DBFile), &gorm.Config{}) + if err!=nil { + log.Errorf("连接数据库出现错误:%s", err.Error()) + return false + } + conf.DB = db + if needMigrate { + log.Infof("迁移数据库...") + err = conf.DB.AutoMigrate(&models.File{}) + if err !=nil { + log.Errorf("数据库迁移失败:%s",err.Error()) + return false + } + } + return true + } + default: + log.Errorf("不支持的数据库类型:%s", conf.Conf.Database.Type) + return false + } +} diff --git a/bootstrap/update.go b/bootstrap/update.go index 6905c797..b1045854 100644 --- a/bootstrap/update.go +++ b/bootstrap/update.go @@ -16,7 +16,7 @@ type GithubRelease struct { Body string `json:"body"` } -// check updtae +// check update func CheckUpdate() { log.Infof("检查更新...") url:="https://api.github.com/repos/Xhofe/alist/releases/latest" diff --git a/conf/config.go b/conf/config.go index 70a2d65e..fca4bc10 100644 --- a/conf/config.go +++ b/conf/config.go @@ -40,4 +40,14 @@ type Config struct { RefreshToken string `yaml:"refresh_token"` MaxFilesCount int `yaml:"max_files_count"` } `yaml:"ali_drive"` + Database struct{ + Type string `yaml:"type"` + User string `yaml:"user"` + Password string `yaml:"password"` + Host string `yaml:"host"` + Port int `yaml:"port"` + Name string `yaml:"name"` + TablePrefix string `yaml:"tablePrefix"` + DBFile string `yaml:"dBFile"` + } `yaml:"database"` } \ No newline at end of file diff --git a/conf/const.go b/conf/const.go index 6f899b69..97059f63 100644 --- a/conf/const.go +++ b/conf/const.go @@ -2,6 +2,7 @@ package conf import ( "github.com/patrickmn/go-cache" + "gorm.io/gorm" "net/http" ) @@ -17,6 +18,8 @@ var( Cache *cache.Cache // cache + DB *gorm.DB + Origins []string // allow origins ) diff --git a/go.mod b/go.mod index adfa0fbb..1865081c 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/golang/protobuf v1.4.3 // indirect github.com/json-iterator/go v1.1.10 // indirect github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-sqlite3 v1.14.6 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible @@ -19,4 +20,6 @@ require ( golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 // indirect google.golang.org/protobuf v1.25.0 // indirect gopkg.in/yaml.v2 v2.4.0 + gorm.io/driver/sqlite v1.1.4 + gorm.io/gorm v1.21.1 ) diff --git a/go.sum b/go.sum index 092693f0..b26bbd12 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -14,6 +15,7 @@ github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e/go.mod h1:VhW/C github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -43,8 +45,13 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -58,6 +65,10 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ic github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -66,9 +77,9 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/patrickmn/go-cache v1.0.0 h1:3gD5McaYs9CxjyK5AXGcq8gdeCARtd/9gJDUvVeaZ0Y= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= @@ -79,6 +90,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -124,6 +136,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -144,6 +157,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= @@ -152,6 +166,12 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= +gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= +gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.1 h1:ACwUZ+jzH8eG8zxgqTnMIdgWd+lGfCKZTUxL/uQ1ZQo= +gorm.io/gorm v1.21.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/server/models/file.go b/server/models/file.go new file mode 100644 index 00000000..7ea5a3c5 --- /dev/null +++ b/server/models/file.go @@ -0,0 +1,47 @@ +package models + +import ( + "fmt" + "github.com/Xhofe/alist/conf" + "time" +) + +type File struct { + ParentPath string `json:"parent_path" gorm:"index"` + FileExtension string `json:"file_extension"` + FileId string `json:"file_id"` + Name string `json:"name" gorm:"index"` + Type string `json:"type"` + UpdatedAt *time.Time `json:"updated_at"` + Category string `json:"category"` + ContentType string `json:"content_type"` + Size int64 `json:"size"` +} + +func (file *File) Create() error { + return conf.DB.Create(file).Error +} + +func GetFilesByParentPath(parentPath string) (*[]File,error) { + var files []File + if err := conf.DB.Where("parent_path = ?", parentPath).Find(&files).Error; err != nil { + return nil,err + } + return &files, nil +} + +func SearchByNameGlobal(keyword string) (*[]File, error) { + var files []File + if err := conf.DB.Where("name LIKE ?", fmt.Sprintf("%%%s%%", keyword)).Find(&files).Error; err != nil { + return nil,err + } + return &files, nil +} + +func SearchByNameInPath(keyword string, parentPath string) (*[]File, error) { + var files []File + if err := conf.DB.Where("parent_path LIKE ? AND name LIKE ?",fmt.Sprintf("%s%%", parentPath), fmt.Sprintf("%%%s%%", keyword)).Find(&files).Error; err != nil { + return nil,err + } + return &files, nil +} \ No newline at end of file diff --git a/utils/common.go b/utils/common.go new file mode 100644 index 00000000..d11b675c --- /dev/null +++ b/utils/common.go @@ -0,0 +1,57 @@ +package utils + +import ( + "errors" + "fmt" + "reflect" +) + +// copy interface val +func SimpleCopyProperties(dst, src interface{}) (err error) { + // 防止意外panic + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("%v", e) + } + }() + + dstType, dstValue := reflect.TypeOf(dst), reflect.ValueOf(dst) + srcType, srcValue := reflect.TypeOf(src), reflect.ValueOf(src) + + // dst必须结构体指针类型 + if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct { + return errors.New("dst type should be a struct pointer") + } + + // src必须为结构体或者结构体指针,.Elem()类似于*ptr的操作返回指针指向的地址反射类型 + if srcType.Kind() == reflect.Ptr { + srcType, srcValue = srcType.Elem(), srcValue.Elem() + } + if srcType.Kind() != reflect.Struct { + return errors.New("src type should be a struct or a struct pointer") + } + + // 取具体内容 + dstType, dstValue = dstType.Elem(), dstValue.Elem() + + // 属性个数 + propertyNums := dstType.NumField() + + for i := 0; i < propertyNums; i++ { + // 属性 + property := dstType.Field(i) + // 待填充属性值 + propertyValue := srcValue.FieldByName(property.Name) + + // 无效,说明src没有这个属性 || 属性同名但类型不同 + if !propertyValue.IsValid() || property.Type != propertyValue.Type() { + continue + } + + if dstValue.Field(i).CanSet() { + dstValue.Field(i).Set(propertyValue) + } + } + + return nil +}