| @ -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 | |||
| import ( | |||
| "fmt" | |||
| "PackageManager/Archive" | |||
| "PackageManager/Client/Database" | |||
| "PackageManager/Client/Filesystem" | |||
| ) | |||
| 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.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" | |||
| ) | |||