-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathref-graph.go
More file actions
171 lines (145 loc) · 4.44 KB
/
ref-graph.go
File metadata and controls
171 lines (145 loc) · 4.44 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package syncbox
import "strconv"
// RefGraph is the graph representation structure of file tree nodes and files,
// it should handles CRUD to refs in database
type RefGraph struct {
*Logger
Usernmae string
User *UserTable
FileRecords []*FileTable
FileRefRecords []*FileRefTable
DB *DB
}
// NewRefGraph instantiates a RefGraph
func NewRefGraph(username string, password string, db *DB) (*RefGraph, error) {
rg := &RefGraph{
Usernmae: username,
DB: db,
Logger: NewDefaultLogger(),
}
userQuery := NewQuery(db)
userTableSlice := &[]*UserTable{}
if err := userQuery.Select("*").From("user").Where("username='" + username + "'").Populate(userTableSlice); err != nil {
return nil, err
}
if len(*(userTableSlice)) == 0 {
_, err := db.Exec("INSERT INTO user (username, password) VALUES (?, ?)", username, password)
if err != nil {
return nil, err
}
if err := userQuery.Select("*").From("user").Where("username='" + username + "'").Populate(userTableSlice); err != nil {
return nil, err
}
}
rg.User = (*userTableSlice)[0]
if err := rg.UpdateRecords(); err != nil {
return nil, err
}
return rg, nil
}
// UpdateRecords updates the file and file_ref table records
func (rg *RefGraph) UpdateRecords() error {
if err := rg.GetFileRecords(); err != nil {
return err
}
if err := rg.GetFileRefRecords(); err != nil {
return err
}
return nil
}
// GetFileRecords gets all file records in database
func (rg *RefGraph) GetFileRecords() error {
fileQuery := NewQuery(rg.DB)
if err := fileQuery.Select("*").From("file").Where("user_id='" + strconv.Itoa(rg.User.ID) + "'").Populate(&rg.FileRecords); err != nil {
return err
}
return nil
}
// GetFileRefRecords gets all file_ref records in database
func (rg *RefGraph) GetFileRefRecords() error {
fileRefQuery := NewQuery(rg.DB)
if err := fileRefQuery.Select("*").From("file_ref").Where("user_id='" + strconv.Itoa(rg.User.ID) + "'").Populate(&rg.FileRefRecords); err != nil {
return err
}
return nil
}
// GetRefCount returns the file_ref count
func (rg *RefGraph) GetRefCount() (int, error) {
return len(rg.FileRefRecords), nil
}
// AddFileRecord add a record to file table
func (rg *RefGraph) AddFileRecord(file *File) error {
_, err := rg.DB.Exec("INSERT INTO file (checksum, user_id) VALUES (?, ?)", ChecksumToNumString(file.ContentChecksum), rg.User.ID)
if err != nil {
return err
}
if err := rg.UpdateRecords(); err != nil {
return err
}
return nil
}
// AddFileRefRecord add a record to file_ref table
func (rg *RefGraph) AddFileRefRecord(file *File, path string, device string) error {
query := NewQuery(rg.DB)
fileRecords := &[]*FileTable{}
err := query.Select("*").From("file").Where("checksum='" + ChecksumToNumString(file.ContentChecksum) + "'").Populate(fileRecords)
if err != nil {
return err
}
fileRecord := (*fileRecords)[0]
_, err = rg.DB.Exec("INSERT INTO file_ref (user_id, file_id, path, device) VALUES (?, ?, ?, ?)", rg.User.ID, fileRecord.ID, path, device)
if err != nil {
return err
}
if err := rg.UpdateRecords(); err != nil {
return err
}
return nil
}
// DeleteFileRecord deletes a record in file table
func (rg *RefGraph) DeleteFileRecord(fileRecord *FileTable) error {
_, err := rg.DB.Exec("DELETE FROM file WHERE id=?", fileRecord.ID)
if err != nil {
return err
}
if err := rg.UpdateRecords(); err != nil {
return err
}
return nil
}
// DeleteFileRefRecord deletes a record in file_ref table
func (rg *RefGraph) DeleteFileRefRecord(file *File) error {
query := NewQuery(rg.DB)
fileRecords := &[]*FileTable{}
err := query.Select("*").From("file").Where("checksum='" + ChecksumToNumString(file.ContentChecksum) + "'").Populate(fileRecords)
if err != nil {
return err
}
if len(*fileRecords) == 0 {
return ErrorNoFileRecords
}
fileRecord := (*fileRecords)[0]
_, err = rg.DB.Exec("DELETE FROM file_ref WHERE file_id=?", fileRecord.ID)
if err != nil {
return err
}
if err := rg.UpdateRecords(); err != nil {
return err
}
return nil
}
// GetNoRefFiles returns file records that has no references on them
func (rg *RefGraph) GetNoRefFiles() ([]*FileTable, error) {
noRefFiles := make([]*FileTable, 0, 0)
for _, fileRecord := range rg.FileRecords {
count := 0
err := rg.DB.QueryRow("SELECT COUNT(*) as cnt FROM file_ref WHERE file_id=?;", fileRecord.ID).Scan(&count)
if err != nil {
return nil, err
}
if count == 0 {
noRefFiles = append(noRefFiles, fileRecord)
}
}
return noRefFiles, nil
}