@ -0,0 +1,143 @@ | |||||
package Database | |||||
import ( | |||||
"database/sql" | |||||
"fmt" | |||||
"time" | |||||
) | |||||
type FilesystemHashRow struct { | |||||
Path string | |||||
Hash string | |||||
UpdatedAt time.Time | |||||
} | |||||
func FindOrCreateFileHash(rows []FilesystemHashRow) error { | |||||
var ( | |||||
stmtString string | |||||
stmt *sql.Stmt | |||||
values []interface{} = []interface{}{} | |||||
e error | |||||
) | |||||
stmtString = "INSERT OR REPLACE INTO filesystem_hash (id, path, hash, updated_at) VALUES " | |||||
for _, row := range rows { | |||||
stmtString += `( | |||||
(SELECT id FROM filesystem_hash WHERE path = ?), | |||||
?, | |||||
?, | |||||
? | |||||
),` | |||||
values = append(values, row.Path, row.Path, row.Hash, row.UpdatedAt.String()) | |||||
} | |||||
stmtString = stmtString[0 : len(stmtString)-1] | |||||
stmt, e = DB.Prepare(stmtString) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
_, e = stmt.Exec(values...) | |||||
return e | |||||
} | |||||
func FindModifiedFiles(hashes []string) ([]string, error) { | |||||
var ( | |||||
stmtString string | |||||
stmt *sql.Stmt | |||||
values []interface{} = []interface{}{} | |||||
result *sql.Rows | |||||
dirtyFiles []string = []string{} | |||||
e error | |||||
) | |||||
stmtString = "SELECT id, path FROM filesystem_hash WHERE hash NOT IN (" | |||||
for _, row := range hashes { | |||||
stmtString += "?," | |||||
values = append(values, row) | |||||
} | |||||
stmtString = stmtString[0:len(stmtString)-1] + ")" | |||||
stmt, e = DB.Prepare(stmtString) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
result, e = stmt.Query(values...) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
defer result.Close() | |||||
for result.Next() { | |||||
var id string | |||||
var hash string | |||||
e = result.Scan(&id, &hash) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
fmt.Println(id, hash) | |||||
dirtyFiles = append(dirtyFiles, hash) | |||||
} | |||||
e = result.Err() | |||||
return dirtyFiles, e | |||||
} | |||||
/* | |||||
func FindNewFiles(files []string) ([]string, error) { | |||||
var ( | |||||
stmtString string | |||||
stmt *sql.Stmt | |||||
values []interface{} = []interface{}{} | |||||
result *sql.Rows | |||||
dirtyFiles []string = []string{} | |||||
e error | |||||
) | |||||
stmtString = `select * | |||||
from ( | |||||
values (4),(5),(6) | |||||
) as v(id) | |||||
where not exists (select * | |||||
from images i | |||||
where i.id = v.id);` | |||||
for _, row := range hashes { | |||||
stmtString += "?," | |||||
values = append(values, row) | |||||
} | |||||
stmtString = stmtString[0:len(stmtString)-1] + ")" | |||||
stmt, e = DB.Prepare(stmtString) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
result, e = stmt.Query(values...) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
defer result.Close() | |||||
for result.Next() { | |||||
var id string | |||||
var hash string | |||||
e = result.Scan(&id, &hash) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
fmt.Println(id, hash) | |||||
dirtyFiles = append(dirtyFiles, hash) | |||||
} | |||||
e = result.Err() | |||||
return dirtyFiles, e | |||||
} | |||||
*/ |
@ -0,0 +1,128 @@ | |||||
package Filesystem | |||||
import ( | |||||
"PackageManager/Client/Database" | |||||
"crypto/md5" | |||||
"fmt" | |||||
"io/ioutil" | |||||
"os" | |||||
"path/filepath" | |||||
"strings" | |||||
) | |||||
func HashFile(path string) (string, error) { | |||||
var ( | |||||
Md5Hash string | |||||
hashBytes [16]byte | |||||
file *os.File | |||||
e error | |||||
) | |||||
file, e = os.Open(path) | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
defer file.Close() | |||||
body, e := ioutil.ReadAll(file) | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
//Get the 16 bytes hash | |||||
hashBytes = md5.Sum(body) | |||||
//Convert the bytes to a string | |||||
Md5Hash = fmt.Sprintf("%x", hashBytes) | |||||
return Md5Hash, nil | |||||
} | |||||
func UpdateFilesystemHash() error { | |||||
var ( | |||||
fileHash string | |||||
rows []Database.FilesystemHashRow | |||||
e error | |||||
) | |||||
e = filepath.Walk(".", func(path string, info os.FileInfo, e error) error { | |||||
if e != nil { | |||||
return e | |||||
} | |||||
// Ignore hidden files | |||||
if strings.HasPrefix(info.Name(), ".") || strings.HasPrefix(path, ".") { | |||||
return nil | |||||
} | |||||
// Ignore directories | |||||
if info.IsDir() { | |||||
return nil | |||||
} | |||||
fileHash, e = HashFile(path) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
rows = append(rows, Database.FilesystemHashRow{ | |||||
Path: path, | |||||
Hash: fileHash, | |||||
UpdatedAt: info.ModTime(), | |||||
}) | |||||
// TODO: If len(rows) > x, update the db and clear out rows, and continue | |||||
return nil | |||||
}) | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
return Database.FindOrCreateFileHash(rows) | |||||
} | |||||
func GetFilesystemDiff() error { | |||||
var ( | |||||
fileHash string | |||||
hashes []string = []string{} | |||||
e error | |||||
) | |||||
e = filepath.Walk(".", func(path string, info os.FileInfo, e error) error { | |||||
if e != nil { | |||||
return e | |||||
} | |||||
// Ignore hidden files | |||||
if strings.HasPrefix(info.Name(), ".") || strings.HasPrefix(path, ".") { | |||||
return nil | |||||
} | |||||
// Ignore directories | |||||
if info.IsDir() { | |||||
return nil | |||||
} | |||||
fileHash, e = HashFile(path) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
hashes = append(hashes, fileHash) | |||||
// TODO: If len(rows) > x, update the db and clear out rows, and continue | |||||
return nil | |||||
}) | |||||
dirty, e := Database.FindModifiedFiles(hashes) | |||||
fmt.Println(dirty) | |||||
return e | |||||
} |
@ -1,13 +1,31 @@ | |||||
package main | package main | ||||
import ( | import ( | ||||
"fmt" | |||||
"PackageManager/Archive" | |||||
"PackageManager/Client/Database" | |||||
"PackageManager/Client/Filesystem" | |||||
) | ) | ||||
func main() { | func main() { | ||||
var e error | |||||
e = Database.InitDB() | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
/* | |||||
e = Filesystem.UpdateFilesystemHash() | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
*/ | |||||
e = Filesystem.GetFilesystemDiff() | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
//e := Archive.TarGzip("/tmp/test", "/tmp/test.tar.gz") | //e := Archive.TarGzip("/tmp/test", "/tmp/test.tar.gz") | ||||
e := Archive.UntarGzip("/tmp/test.tar.gz", "/tmp/test") | |||||
fmt.Println(e) | |||||
//e := Archive.UntarGzip("/tmp/test.tar.gz", "/tmp/test") | |||||
//fmt.Println(e) | |||||
} | } |
@ -0,0 +1,5 @@ | |||||
package Variables | |||||
const ( | |||||
DatabaseName string = "package_manager.db" | |||||
) |