Skip to content

Commit fb79c26

Browse files
committed
Add sync files struct
1 parent 4d2276b commit fb79c26

5 files changed

Lines changed: 180 additions & 21 deletions

File tree

SyncFiles.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"database/sql"
6+
"fmt"
7+
"io/ioutil"
8+
"os"
9+
"sync"
10+
11+
"github.com/JojiiOfficial/gaw"
12+
)
13+
14+
func syncFiles(dryRun, noconfirm bool) error {
15+
// List locally available files
16+
files, err := ioutil.ReadDir(config.Server.PathConfig.FileStore)
17+
if err != nil {
18+
return err
19+
}
20+
21+
// Get Local files+ID
22+
rows, err := db.Table("files").Where("deleted_at is NULL").Select("id, local_name").Rows()
23+
if err != nil {
24+
return err
25+
}
26+
27+
var untrackedInFS []int64 // Database file rows without local file
28+
var untrackedInDB []string // Local files which don't have any reference in database
29+
var wg sync.WaitGroup
30+
31+
wg.Add(2)
32+
cerr := make(chan error, 2)
33+
34+
go func() {
35+
untrackedInFS, err = searchLocalFS(rows, files)
36+
cerr <- err
37+
wg.Done()
38+
}()
39+
40+
go func() {
41+
untrackedInDB, err = searchDB(files)
42+
cerr <- err
43+
wg.Done()
44+
}()
45+
46+
wg.Wait()
47+
close(cerr)
48+
49+
for i := range cerr {
50+
if i != nil {
51+
return i
52+
}
53+
}
54+
55+
if len(untrackedInDB) == 0 && len(untrackedInFS) == 0 {
56+
fmt.Println("Nothing to do")
57+
return nil
58+
}
59+
60+
fmt.Println()
61+
fmt.Printf("Found %d files missing in local filesystem\n", len(untrackedInFS))
62+
fmt.Printf("Found %d files untracked in database\n", len(untrackedInDB))
63+
64+
if dryRun {
65+
return nil
66+
}
67+
68+
if !noconfirm {
69+
if y, _ := gaw.ConfirmInput("\nDelete all untracked files? [y/n/a]> ", bufio.NewReader(os.Stdin)); !y {
70+
return nil
71+
}
72+
}
73+
74+
fmt.Println("Deleting...")
75+
76+
return nil
77+
}
78+
79+
// Returns a slice of FileIDs which have no local file
80+
func searchLocalFS(rows *sql.Rows, files []os.FileInfo) ([]int64, error) {
81+
var untrackedInFS []int64
82+
83+
var fileName string
84+
var id int64
85+
for rows.Next() {
86+
if err := rows.Scan(&id, &fileName); err != nil {
87+
return nil, err
88+
}
89+
90+
if !hasLocalFile(files, fileName) {
91+
untrackedInFS = append(untrackedInFS, id)
92+
}
93+
}
94+
95+
return untrackedInFS, nil
96+
}
97+
98+
// Returns a slice of local files which don't have a reference in DB
99+
func searchDB(localFiles []os.FileInfo) ([]string, error) {
100+
var untrackedInDB []string
101+
var i, j, end int
102+
103+
for {
104+
if i >= len(localFiles) {
105+
break
106+
}
107+
end = i + 1000000
108+
109+
if end > len(localFiles) {
110+
end = len(localFiles)
111+
}
112+
113+
var res []string
114+
fmt.Println(i, end)
115+
if err := db.Table("files").Where("local_name NOT IN (?) AND deleted_at IS NULL", fifoToStr(localFiles[i:end])).Select("local_name").Find(&res).Error; err != nil {
116+
return nil, err
117+
}
118+
119+
untrackedInDB = append(untrackedInDB, res...)
120+
i = end + 1
121+
j++
122+
}
123+
124+
return untrackedInDB, nil
125+
}
126+
127+
func fifoToStr(f []os.FileInfo) []string {
128+
s := make([]string, len(f))
129+
for i := range f {
130+
s[i] = f[i].Name()
131+
}
132+
return s
133+
}
134+
135+
func hasLocalFile(localFiles []os.FileInfo, name string) bool {
136+
for i := range localFiles {
137+
if localFiles[i].Name() == name {
138+
return true
139+
}
140+
}
141+
142+
return false
143+
}

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@ require (
1414
github.com/gabriel-vasile/mimetype v1.1.1
1515
github.com/gorilla/mux v1.7.4
1616
github.com/h2non/filetype v1.1.0
17-
github.com/jackc/pgx/v4 v4.7.2 // indirect
17+
github.com/jackc/pgx/v4 v4.8.0 // indirect
18+
github.com/jinzhu/gorm v1.9.15 // indirect
1819
github.com/lib/pq v1.7.0 // indirect
1920
github.com/mattn/go-colorable v0.1.7 // indirect
2021
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
2122
github.com/sbani/go-humanizer v0.3.1
2223
github.com/sirupsen/logrus v1.6.0
2324
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 // indirect
24-
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
25+
golang.org/x/sys v0.0.0-20200727154430-2d971f7391a4 // indirect
2526
gopkg.in/yaml.v2 v2.3.0 // indirect
26-
gorm.io/driver/postgres v0.2.5
27-
gorm.io/gorm v0.2.22
27+
gorm.io/driver/postgres v0.2.6
28+
gorm.io/gorm v0.2.24
2829
)

go.sum

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr
5959
github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
6060
github.com/jackc/pgconn v1.6.1 h1:lwofaXKPbIx6qEaK8mNm7uZuOwxHw+PnAFGDsDFpkRI=
6161
github.com/jackc/pgconn v1.6.1/go.mod h1:g8mKMqmSUO6AzAvha7vy07g1rbGOlc7iF0nU0ei83hc=
62-
github.com/jackc/pgconn v1.6.2 h1:ifRs/oHByR6NfEXfusvjoTqX/KcSvDYNFASoK/wXKfs=
63-
github.com/jackc/pgconn v1.6.2/go.mod h1:w2pne1C2tZgP+TvjqLpOigGzNqjBgQW9dUw/4Chex78=
62+
github.com/jackc/pgconn v1.6.3 h1:4Ks3RKvSvKPolXZsnLQTDAsokDhgID14Cv4ehECmzlY=
63+
github.com/jackc/pgconn v1.6.3/go.mod h1:w2pne1C2tZgP+TvjqLpOigGzNqjBgQW9dUw/4Chex78=
6464
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
6565
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
6666
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
@@ -88,8 +88,8 @@ github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkAL
8888
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
8989
github.com/jackc/pgtype v1.4.0 h1:pHQfb4jh9iKqHyxPthq1fr+0HwSNIl3btYPbw2m2lbM=
9090
github.com/jackc/pgtype v1.4.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
91-
github.com/jackc/pgtype v1.4.1 h1:8PRKqCS9Nt2FQbNegoEAIlY6r/DTP2aaXyh5bAEn89g=
92-
github.com/jackc/pgtype v1.4.1/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
91+
github.com/jackc/pgtype v1.4.2 h1:t+6LWm5eWPLX1H5Se702JSBcirq6uWa4jiG4wV1rAWY=
92+
github.com/jackc/pgtype v1.4.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
9393
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
9494
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
9595
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
@@ -98,14 +98,16 @@ github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6
9898
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
9999
github.com/jackc/pgx/v4 v4.7.1 h1:aqUSOcStk6fik+lSE+tqfFhvt/EwT8q/oMtJbP9CjXI=
100100
github.com/jackc/pgx/v4 v4.7.1/go.mod h1:nu42q3aPjuC1M0Nak4bnoprKlXPINqopEKqbq5AZSC4=
101-
github.com/jackc/pgx/v4 v4.7.2 h1:0DJC1AiqH0Lba79JHFQkcoxi0sOAn75Zr+QCRCAXvBc=
102-
github.com/jackc/pgx/v4 v4.7.2/go.mod h1:IaoCMFiHwe2J7SjRZ97Qc7zr8QGNwnlAU4J0f3S1UYk=
101+
github.com/jackc/pgx/v4 v4.8.0 h1:xO3bPvwr0MJSoDfb4yeeWZIxSZ2VFBm5axPnaNEnGUQ=
102+
github.com/jackc/pgx/v4 v4.8.0/go.mod h1:AjqYcDmEyst6GF8jJi/RF73Gla9d7/HLZzJEZj2uwpM=
103103
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
104104
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
105105
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
106106
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
107107
github.com/jinzhu/gorm v1.9.14 h1:Kg3ShyTPcM6nzVo148fRrcMO6MNKuqtOUwnzqMgVniM=
108108
github.com/jinzhu/gorm v1.9.14/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
109+
github.com/jinzhu/gorm v1.9.15 h1:OdR1qFvtXktlxk73XFYMiYn9ywzTwytqe4QkuMRqc38=
110+
github.com/jinzhu/gorm v1.9.15/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
109111
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
110112
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
111113
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
@@ -225,8 +227,8 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
225227
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
226228
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
227229
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
228-
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
229-
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
230+
golang.org/x/sys v0.0.0-20200727154430-2d971f7391a4 h1:gtF+PUC1CD1a9ocwQHbVNXuTp6RQsAYt6tpi6zjT81Y=
231+
golang.org/x/sys v0.0.0-20200727154430-2d971f7391a4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
230232
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
231233
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
232234
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
@@ -254,9 +256,9 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
254256
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
255257
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
256258
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
257-
gorm.io/driver/postgres v0.2.5 h1:HAzk6g9BhPtaJOcdf7WFaR7VJStENs8Ksi6WvIWyj/c=
258-
gorm.io/driver/postgres v0.2.5/go.mod h1:AsPyuhKFOplSmQwOPsycVKbe0dRxF8v18KZ7p9i8dIs=
259+
gorm.io/driver/postgres v0.2.6 h1:hoE6SzA5wKOo6AYxz2V7ooxnzD6S6ToLAHHDDawt+b0=
260+
gorm.io/driver/postgres v0.2.6/go.mod h1:AsPyuhKFOplSmQwOPsycVKbe0dRxF8v18KZ7p9i8dIs=
259261
gorm.io/gorm v0.2.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
260-
gorm.io/gorm v0.2.22 h1:kktbaUjQf4aA6L9o/qCghKRNuCvaWJycSToqvhQAB8c=
261-
gorm.io/gorm v0.2.22/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
262+
gorm.io/gorm v0.2.24 h1:NKjfopoXim5xAHYkt/uN0n7ZNmyoXZ9FEZUX4ijzXlI=
263+
gorm.io/gorm v0.2.24/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
262264
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

main.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ import (
2121
const version = "v3.12.0"
2222

2323
var (
24-
app = kingpin.New("dmserver", "The data manager server")
25-
appLogLevel = app.Flag("log-level", "Enable debug mode").HintOptions(constants.LogLevels...).Envar(getEnVar(EnVarLogLevel)).Short('l').Default(constants.LogLevels[2]).String()
26-
appNoColor = app.Flag("no-color", "Disable colors").Envar(getEnVar(EnVarNoColor)).Bool()
27-
appCfgFile = app.
24+
app = kingpin.New("dmserver", "The data manager server")
25+
appLogLevel = app.Flag("log-level", "Enable debug mode").HintOptions(constants.LogLevels...).Envar(getEnVar(EnVarLogLevel)).Short('l').Default(constants.LogLevels[2]).String()
26+
appNoColor = app.Flag("no-color", "Disable colors").Envar(getEnVar(EnVarNoColor)).Bool()
27+
appNoConfirm = app.Flag("no-confirm", "Disable confirmations. Make it headless").Bool()
28+
appDryRun = app.Flag("dry-run", "Don't perform any action").Short('d').Bool()
29+
appCfgFile = app.
2830
Flag("config", "the configuration file for the server").
2931
Envar(getEnVar(EnVarConfigFile)).
3032
Short('c').String()
@@ -39,6 +41,8 @@ var (
3941
configCmd = app.Command("config", "Commands for the config file")
4042
configCmdCreate = configCmd.Command("create", "Create config file")
4143
configCmdCreateName = configCmdCreate.Arg("name", "Config filename").Default(models.GetDefaultConfig()).String()
44+
45+
syncFilesCmd = app.Command("sync-files", "Delete untracked files from the database and the filesystem")
4246
)
4347

4448
var (
@@ -134,6 +138,15 @@ func main() {
134138
{
135139
startAPI()
136140
}
141+
142+
// Tools
143+
case syncFilesCmd.FullCommand():
144+
{
145+
if err := syncFiles(*appDryRun, *appNoConfirm); err != nil {
146+
log.Error(err)
147+
}
148+
}
149+
137150
// Config --------------------
138151
case configCmdCreate.FullCommand():
139152
{

storage/Database.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func ConnectToDatabase(config *models.Config) (*gorm.DB, error) {
2222
}
2323

2424
//Automigration
25-
db.AutoMigrate(
25+
err = db.AutoMigrate(
2626
&models.Role{},
2727
&models.Namespace{},
2828
&models.Tag{},

0 commit comments

Comments
 (0)