// checkDB is a wrapper around filedb.Dial that will also create the database // if it doesn't already exist func checkDB() (*filedb.DB, error) { // check that the database exists and create if it doesn't if _, err := os.Stat(Dbpath); os.IsNotExist(err) { err := os.Mkdir(Dbpath, 0777) if err != nil { return nil, err } } db, err := filedb.Dial(Dbpath) if err != nil { return nil, err } return db, nil }
func main() { var fatalErr error defer func() { if fatalErr != nil { flag.PrintDefaults() log.Fatalln(fatalErr) } }() var ( // dbというコマンドラインフラグの指定 dbpath = flag.String("db", "./backupdata", "path to database directory") ) // コマンドライン引数の解析 flag.Parse() // os.Argsではなく、flag.Argsを使用することでコマンドラインフラグ以外をスライスとして取得 args := flag.Args() // コマンドライン引数が-dbのみの場合はエラー if len(args) < 1 { fatalErr = errors.New("invalid usage; must specify command") return } // filedbの格納箇所を指定 db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() // pathsコレクションへの参照を取得 col, err := db.C("paths") if err != nil { fatalErr = err return } switch strings.ToLower(args[0]) { case "list": var path path col.ForEach(func(i int, data []byte) bool { // dataをpath型に変換 err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return false } fmt.Printf("= %s\n", path) return false }) case "add": // backup -db=./backupdata.db addの場合 if len(args[1:]) == 0 { fatalErr = errors.New("must specify path to add") return } for _, p := range args[1:] { path := &path{Path: p, Hash: "Not yet archived"} if err := col.InsertJSON(path); err != nil { fatalErr = err return } fmt.Printf("+ %s\n", path) } case "remove": var path path // return 削除するかどうか, 以降の処理を続けるかどうか col.RemoveEach(func(i int, data []byte) (bool, bool) { err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return false, true } for _, p := range args[1:] { if path.Path == p { fmt.Printf("- %s\n", path) return true, false } } return false, false }) } }
func main() { var fatalErr error defer func() { if fatalErr != nil { flag.PrintDefaults() log.Fatalln(fatalErr) } }() var ( dbpath = flag.String("db", "./backupdata", "path to database directory") ) flag.Parse() args := flag.Args() if len(args) < 1 { fatalErr = errors.New("invalid usage; must specify command") return } db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() col, err := db.C("paths") if err != nil { fatalErr = err return } switch strings.ToLower(args[0]) { case "list": var path path col.ForEach(func(i int, data []byte) bool { err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return false } fmt.Printf("= %s\n", path) return false }) case "add": if len(args[1:]) == 0 { fatalErr = errors.New("must specify path to add") return } for _, p := range args[1:] { path := &path{Path: p, Hash: "Not yet archived"} if err := col.InsertJSON(path); err != nil { fatalErr = err return } fmt.Printf("+ %s\n", path) } case "remove": var path path col.RemoveEach(func(i int, data []byte) (bool, bool) { err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return false, true } for _, p := range args[1:] { if path.Path == p { fmt.Printf("- %s\n", path) return true, false } } return false, false }) } }
func main() { var fatalErr error defer func() { if fatalErr != nil { flag.PrintDefaults() log.Fatalln(fatalErr) } }() var ( dbpath = flag.String("db", "./backupdata", "データベースのディレクトリへのパス") ) flag.Parse() args := flag.Args() if len(args) < 1 { fatalErr = errors.New("エラー; コマンドを指定してください") return } db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() col, err := db.C("paths") if err != nil { fatalErr = err return } switch strings.ToLower(args[0]) { case "list": var path path col.ForEach(func(i int, data []byte) bool { err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return true } fmt.Printf("= %s\n", path.String()) return false }) case "add": if len(args[1:]) == 0 { fatalErr = errors.New("追加するパスを指定してください") } for _, p := range args[1:] { path := &path{Path: p, Hash: "まだアーカイブされていません"} if err := col.InsertJSON(path); err != nil { fatalErr = err return } fmt.Printf("+ %s\n", path.String()) } case "remove": var path path col.RemoveEach(func(i int, data []byte) (bool, bool) { err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return false, true } for _, p := range args[1:] { if path.Path == p { fmt.Printf("- %s\n", path.String()) return true, false } } return false, false }) } }
func main() { var fatalErr error defer func() { if fatalErr != nil { log.Fatalln(fatalErr) } }() var ( interval = flag.Duration("interval", 10, "チェックの間隔") archive = flag.String("archive", "archive", "アーカイブの保存先") dbpath = flag.String("db", "./db", "データベースへのパス") ) flag.Parse() m := &backup.Monitor{ Destination: *archive, Archiver: backup.ZIP, Paths: make(map[string]string), } db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() col, err := db.C("paths") if err != nil { fatalErr = err return } var path path col.ForEach(func(_ int, data []byte) bool { if err := json.Unmarshal(data, &path); err != nil { fatalErr = err return true } m.Paths[path.Path] = path.Hash return false }) if fatalErr != nil { return } if len(m.Paths) < 1 { fatalErr = errors.New("パスがありません。backupツールを使って追加してください") return } check(m, col) signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) Loop: for { select { case <-time.After(*interval): check(m, col) case <-signalChan: fmt.Println() log.Printf("終了します...") break Loop } } }
func main() { var fatalErr error defer func() { if fatalErr != nil { log.Fatalln(fatalErr) } }() var ( interval = flag.Int("interval", 10, "interval between checks (seconds)") archive = flag.String("archive", "archive", "path to archive location") dbpath = flag.String("db", "./db", "path to filedb database") ) flag.Parse() m := &backup.Monitor{ Destination: *archive, Archiver: backup.ZIP, Paths: make(map[string]string), } db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() col, err := db.C("paths") if err != nil { fatalErr = err return } var path path col.ForEach(func(_ int, data []byte) bool { if err := json.Unmarshal(data, &path); err != nil { fatalErr = err return true } m.Paths[path.Path] = path.Hash return false // carry on }) if fatalErr != nil { return } if len(m.Paths) < 1 { fatalErr = errors.New("no paths - use backup tool to add at least one") return } check(m, col) signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) for { select { case <-time.After(time.Duration(*interval) * time.Second): check(m, col) case <-signalChan: // stop fmt.Println() log.Printf("Stopping...") goto stop } } stop: }
func main() { var fatalErr error defer func() { if fatalErr != nil { log.Fatalln(fatalErr) } }() var ( // flag.DurationはParseDurationが使える // https://golang.org/pkg/time/#ParseDuration interval = flag.Duration("interval", 10*time.Second, "interval between checks (seconds)") archive = flag.String("archive", "archive", "path to archive location") dbpath = flag.String("db", "./db", "path to filedb database") ) flag.Parse() m := &backup.Monitor{ Destination: *archive, Archiver: backup.ZIP, Paths: make(map[string]string), } db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() col, err := db.C("paths") if err != nil { fatalErr = err return } var path path col.ForEach(func(_ int, data []byte) bool { if err := json.Unmarshal(data, &path); err != nil { fatalErr = err return true } m.Paths[path.Path] = path.Hash return false // carry on }) if fatalErr != nil { return } if len(m.Paths) < 1 { fatalErr = errors.New("no paths - use backup tool to add at least one") return } check(m, col) // シグナルのチャネル作成 signalChan := make(chan os.Signal, 1) // 作成したチャネルが終了を受け取れるようにする signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) for { select { // *intervalではint型のためtime.Durationに型変換 case <-time.After(*interval): check(m, col) case <-signalChan: // stop fmt.Println() log.Printf("Stopping...") goto stop } } stop: } func check(m *backup.Monitor, col *filedb.C) { log.Println("Checking...") // ファイルの内容が変わっていた場合はバックアップを実行して、counter++ counter, err := m.Now() if err != nil { log.Fatalln("failed to backup:", err) } if counter > 0 { log.Printf(" Archived %d directories\n", counter) // update hashes var path path // selectEachで回しつつ、更新 col.SelectEach(func(_ int, data []byte) (bool, []byte, bool) { if err := json.Unmarshal(data, &path); err != nil { log.Println("failed to unmarshal data (skipping):", err) return true, data, false } path.Hash, _ = m.Paths[path.Path] newdata, err := json.Marshal(&path) if err != nil { log.Println("failed to marshal data (skipping):", err) return true, data, false } return true, newdata, false }) } else { log.Println(" No changes") } }
func main() { var fatalErr error defer func() { if fatalErr != nil { flag.PrintDefaults() log.Fatalln(fatalErr) } }() var ( dbpath = flag.String("db", "./backupdata", "数据库文件路径") ) flag.Parse() args := flag.Args() if len(args) < 1 { fatalErr = errors.New("错误 请输入参数") return } db, err := filedb.Dial(*dbpath) if err != nil { fatalErr = err return } defer db.Close() col, err := db.C("paths") if err != nil { fatalErr = err return } switch strings.ToLower(args[0]) { case "list": var path path col.ForEach(func(i int, data []byte) bool { err := json.Unmarshal(data, &path) if err != nil { fatalErr = err return true } fmt.Printf("= %s\n", path) return false }) case "add": if len(args[1:]) == 0 { fatalErr = errors.New("请输入要追加的路径") return } for _, p := range args[1:] { path := &path{Path: p, Hash: ""} if err != col.InsertJSON(path); err != nil { fatalErr = err return } fmt.Printf("+ %s\n", path) } case "remove": } }