File: filesystem.go

package info (click to toggle)
golang-github-twinj-uuid 0.10.0%2Bgit20160909.96.7bbe408-6
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 236 kB
  • sloc: makefile: 3
file content (102 lines) | stat: -rw-r--r-- 2,236 bytes parent folder | download | duplicates (3)
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
package savers

/****************
 * Date: 30/05/16
 * Time: 5:48 PM
 ***************/

import (
	"encoding/gob"
	"github.com/twinj/uuid"
	"log"
	"os"
	"path"
	"time"
)

var _ uuid.Saver = &FileSystemSaver{}

// This implements the Saver interface for UUIDs
type FileSystemSaver struct {
	// A file to save the state to
	// Used gob format on uuid.State entity
	file *os.File

	// Preferred location for the store
	Path string

	// Whether to log each save
	Report bool

	// The amount of time between each save call
	time.Duration

	// The next time to save
	uuid.Timestamp
}

func (o *FileSystemSaver) Save(pStore uuid.Store) {

	if pStore.Timestamp >= o.Timestamp {
		err := o.openAndDo(o.encode, &pStore)
		if err == nil {
			if o.Report {
				log.Printf("UUID Saved State Storage: %s", pStore)
			}
		}
		o.Timestamp = pStore.Add(o.Duration)
	}
}

func (o *FileSystemSaver) Read() (err error, store uuid.Store) {
	store = uuid.Store{}
	gob.Register(&uuid.Store{})

	if _, err = os.Stat(o.Path); os.IsNotExist(err) {
		dir, file := path.Split(o.Path)
		if dir == "" || dir == "/" {
			dir = os.TempDir()
		}
		o.Path = path.Join(dir, file)

		err = os.MkdirAll(dir, os.ModeDir|0755)
		if err == nil {
			// If new encode blank store
			err = o.openAndDo(o.encode, &store)
			if err == nil {
				log.Println("uuid.FileSystemSaver created", o.Path)
			}
		}
		log.Println("uuid.FileSystemSaver.Read: error will autogenerate", err)
		return
	}

	o.openAndDo(o.decode, &store)
	return
}

func (o *FileSystemSaver) openAndDo(fDo func(*uuid.Store), pStore *uuid.Store) (err error) {
	o.file, err = os.OpenFile(o.Path, os.O_RDWR|os.O_CREATE, os.ModeExclusive)
	defer o.file.Close()
	if err == nil {
		fDo(pStore)
	} else {
		log.Println("uuid.FileSystemSaver.openAndDo error:", err)
	}
	return
}

func (o *FileSystemSaver) encode(pStore *uuid.Store) {
	// ensure reader state is ready for use
	enc := gob.NewEncoder(o.file)
	// swallow error for encode as its only for cyclic pointers
	enc.Encode(&pStore)
}

func (o *FileSystemSaver) decode(pStore *uuid.Store) {
	// ensure reader state is ready for use
	o.file.Seek(0, 0)
	dec := gob.NewDecoder(o.file)
	// swallow error for encode as its only for cyclic pointers
	dec.Decode(&pStore)
}