Skip to content

Commit

Permalink
adopted dblist/v3 usage
Browse files Browse the repository at this point in the history
  • Loading branch information
zavla committed Mar 31, 2020
1 parent 0c534b3 commit 52e8056
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
debug
DeleteArchivedBackups.exe
testdata/files/
104 changes: 61 additions & 43 deletions DeleteArchivedBackups.go
@@ -1,85 +1,103 @@
// package main leaves recent backups only. It doesn't delete last backup files.
package main

import (
"dblist/v2"
"flag"
"fmt"
"log"
"os"
"path/filepath"
"sort"
"syscall"

"github.com/zavla/dblist/v3"
)

func main() {
var (
printExample bool
delArchived bool
dryRun bool
configfile string
keepLastNcopies uint
)

func init() {
// register flags in init() allows me to go test the main package
flag.BoolVar(&printExample, "example", false,
"print example of config file")
flag.BoolVar(&delArchived, "withArchiveAttr", false,
"deletes files with attribute archived set")
flag.StringVar(&configfile, "config", "",
"config `file` name")
flag.BoolVar(&dryRun, "dryrun", false,
"print commands (doesn't actually delete files)")
flag.UintVar(&keepLastNcopies, "keeplastN", 2,
"keep recent N copies")

// Example of config file:
// [{"path":"g:/ShebB", "Filename":"buh_log8", "Days":1},
// {"path":"g:/ShebB", "Filename":"buh_log3", "Days":1},
// {"path":"g:/ShebB", "Filename":"buh_prom8", "Days":1},
// ]
}

delArchived := flag.Bool("withArchiveAttr", false, "deletes files with attribute archived set")
configfile := flag.String("config", "", "full config file name (lists databases files groups)")
dryRun := flag.Bool("dryrun", false, "dry run (doesn't actually delete files)")
keepLastNcopies := flag.Uint("keeplastN", 2, "keep recent N copies")
const exampleconf = `
[
{"path":"./testdata/files", "Filename":"E08", "suffix":"-FULL.bak", "Days":2},
{"path":"./testdata/files", "Filename":"A2", "suffix":"-FULL.bak", "Days":10},
{"path":"./testdata/files", "Filename":"A2", "suffix":"-differ.dif", "Days":1},
{"path":"./testdata/files/bases116", "Filename":"dbase1", "suffix":"-FULL.bak", "Days":5},
{"path":"./testdata/files/bases116", "Filename":"dbase1", "suffix":"-differ.dif", "Days":1}
]
`

func main() {
flag.Parse()
if *configfile == "" {

//println(exampleconf)

if printExample {
fmt.Println(exampleconf)
return
}
if configfile == "" {
flag.Usage()
os.Exit(1)
}
conf, err := dblist.ReadConfig(*configfile)
conf, err := dblist.ReadConfig(configfile)
if err != nil {
log.Printf("Config file read error: %s", err)
return
}

// sort conf by databases names to allow sort.Search by database name
sort.Slice(conf, func(i, j int) bool {
if conf[i].Filename < conf[j].Filename {
return true
}
return false
return conf[i].Filename < conf[j].Filename
})

// collect unique suffixes
suffixes := make(map[string]int)
for _, val := range conf {
if _, has := suffixes[val.Suffix]; !has {
suffixes[val.Suffix] = 0
}
// get map with filename to suffixes
uniquesuffixes := dblist.GetMapFilenameToSuffixes(conf)

}
// transform a map into slice
uniquesuffixes := make([]string, 0, len(suffixes))
for suf := range suffixes {
uniquesuffixes = append(uniquesuffixes, suf)
}
// gets unique folders names
unique := dblist.GetUniquePaths(conf)
uniquedirs := dblist.GetUniquePaths(conf)

// get files of each folder
files := dblist.ReadFilesFromPaths(unique)
// get existing files in each unique folder
files := dblist.ReadFilesFromPaths(uniquedirs)

lastfilesmap := make(map[string][]dblist.FileInfoWin)

// We append to dontDeleteLastbackupfiles files that should not be deleted: last files and file that have no config line for them.
// Append to dontDeleteLastbackupfiles all files that should NOT be deleted:
// the most recent files and files that have no config lines for them.
for dir, filesindir := range files {
// We get most recent files. The will not be deleted.
dontDeleteLastbackupfiles := dblist.GetLastFilesGroupedByFunc(filesindir, dblist.GroupFunc, uniquesuffixes, *keepLastNcopies)
dontDeleteLastbackupfiles := dblist.GetLastFilesGroupedByFunc(filesindir, dblist.GroupFunc, uniquesuffixes, keepLastNcopies)

// A directory may contain some extra files not covered by config file - don't delete them.
notinConfigFile := dblist.GetFilesNotCoveredByConfigFile(filesindir, conf, dblist.GroupFunc, uniquesuffixes)

// some actual files may not be in config file
dontDeleteLastbackupfiles = append(dontDeleteLastbackupfiles, notinConfigFile...)

// sort dontDeleteLastbackupfiles descending to use sort.Search later.
// We exploite descending order to find most recent backup files.
// We exploit descending order while searching on the list of last files.
sort.Slice(dontDeleteLastbackupfiles, func(i, j int) bool {
return dontDeleteLastbackupfiles[i].Name() > dontDeleteLastbackupfiles[j].Name() //DESC
})
lastfilesmap[dir] = dontDeleteLastbackupfiles
}
deleteArchivedFiles(files, lastfilesmap, *delArchived, *dryRun)
deleteArchivedFiles(files, lastfilesmap, delArchived, dryRun)

}

Expand All @@ -95,12 +113,12 @@ func deleteArchivedFiles(files, exceptfiles map[string][]dblist.FileInfoWin, del
delArchived { // or you insist on deleting files with Archive attr set

// search if current file is in the exception list
curmap := exceptfiles[dir] // exceptfiles is already sorted descending
pos := sort.Search(len(curmap), func(i int) bool { // we use bin search
return curmap[i].Name() <= finf.Name() // <= for the descending slice
exeptionsForDir := exceptfiles[dir] // exceptfiles is already sorted descending
pos := sort.Search(len(exeptionsForDir), func(i int) bool { // we use bin search
return exeptionsForDir[i].Name() <= finf.Name() // <= for the descending slice

})
if pos < len(curmap) && curmap[pos].Name() == finf.Name() {
if pos < len(exeptionsForDir) && exeptionsForDir[pos].Name() == finf.Name() {
// found
continue // file should not be deleted. this is the last file in the group of backup files
}
Expand Down
46 changes: 46 additions & 0 deletions DeleteArchivedBackups_test.go
@@ -0,0 +1,46 @@
// package main leaves recent backups only. It doesn't delete last backup files.

package main

import (
"bytes"
"io/ioutil"
"os"
"testing"
)

func Test_main(t *testing.T) {
main()
}

func TestMainParamExample(t *testing.T) {
printExample = true
oldstdout := os.Stdout
name := "./testdata/config.json"
f, err := os.OpenFile(name, os.O_CREATE, 0)
if err != nil {
t.Errorf("%s", err)
return
}
os.Stdout = f
defer func() { os.Stdout = oldstdout }()

main()

os.Stdout = oldstdout
_ = f.Close()
f, err = os.Open(name)
if err != nil {
t.Error(err)
return
}
b, err := ioutil.ReadAll(f)
if err != nil {
t.Error(err)
return
}
if !bytes.Equal(b, []byte(exampleconf+"\n")) { // \n was added with fmt.Println()
t.Errorf("not equal\n want %v\n got %v\n", []byte(exampleconf), b)
return
}
}
10 changes: 0 additions & 10 deletions deleteOldBackups-WorkSpace.code-workspace

This file was deleted.

10 changes: 10 additions & 0 deletions go.mod
@@ -0,0 +1,10 @@
module github.com/zavla/deleteArchivedBackups

go 1.13

require (
github.com/zavla/dblist/v3 v3.0.0
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d // indirect
)

// fo development only replace github.com/zavla/dblist/v3 v3.0.0-20200221165736-a44997e2237c => d:/za/zavlagopath/dblist/v3
13 changes: 13 additions & 0 deletions go.sum
@@ -0,0 +1,13 @@
github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 h1:iD+PFTQwKEmbwSdwfvP5ld2WEI/g7qbdhmHJ2ASfYGs=
github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A=
github.com/zavla/dblist v2.0.1+incompatible h1:yVQeaovcNs4SZgTtWSV535gC3uteSWKyS6k1U/hqMWE=
github.com/zavla/dblist/v2 v2.0.1 h1:uZs4IJRzXfpui3hAci5b/BPcxQuh8MYvgvNkiFBVZvc=
github.com/zavla/dblist/v2 v2.0.1/go.mod h1:IA1N3nX+DcTO2k24vQ7SFAILspeQp7e8dwY4o7Is2EA=
github.com/zavla/dblist/v3 v3.0.0-20200221165736-a44997e2237c h1:dJGpf51noguoaIS8XmlVXX6sA/+PeRgMv/94ZyYde0Y=
github.com/zavla/dblist/v3 v3.0.0-20200221165736-a44997e2237c/go.mod h1:txBAtQRvDEgwboFq/d6Fsx1zEYNfCFQEIOG0G8lrUz0=
github.com/zavla/dblist/v3 v3.0.0 h1:k+5baX8NflR9R+Yky/OYACthQHHu+xakwwUR7abb0bE=
github.com/zavla/dblist/v3 v3.0.0/go.mod h1:50zyWn745NnNN3Uj4/sBK0oMFSZ4DhSAb+0Fta1jdLY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
16 changes: 9 additions & 7 deletions testdata/config.json
@@ -1,7 +1,9 @@
[
{"path":"j:/b", "Filename":"BC_Cold", "suffix":"-differ.dif","Days":1},
{"path":"j:/b", "Filename":"нашипост", "suffix":"-FULL.bak","Days":5},
{"path":"j:/b", "Filename":"from_84_Dirs", "suffix":".rar","Days":7},
{"path":"g:/Shebb", "Filename":"buh_canvest", "suffix":"-differ.rar","Days":1},
{"path":"g:/Shebb", "Filename":"buh_canvest", "suffix":"-FULL.rar","Days":1}
]

[
{"path":"./testdata/files", "Filename":"E08", "suffix":"-FULL.bak", "Days":2},
{"path":"./testdata/files", "Filename":"A2", "suffix":"-FULL.bak", "Days":10},
{"path":"./testdata/files", "Filename":"A2", "suffix":"-differ.dif", "Days":1},
{"path":"./testdata/files/bases116", "Filename":"dbase1", "suffix":"-FULL.bak", "Days":5},
{"path":"./testdata/files/bases116", "Filename":"dbase1", "suffix":"-differ.dif", "Days":1}
]

0 comments on commit 52e8056

Please sign in to comment.