diff options
Diffstat (limited to 'database/database.go')
| -rw-r--r-- | database/database.go | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/database/database.go b/database/database.go new file mode 100644 index 0000000..aad4900 --- /dev/null +++ b/database/database.go @@ -0,0 +1,195 @@ +package database + +import ( + "fmt" + "os" + // "archive/tar" + "bufio" + "context" + "net/http" + "path" + "path/filepath" + "sync" + "time" + // "net/url" + "io" + "strings" + + "qulay/config" + "codeberg.org/UzbekLinux/uzbekdb-go" + + "github.com/codeclysm/extract/v3" + // "github.com/klauspost/compress/zstd" +) + +var _name string = filepath.Base(os.Args[0]) + +func GetReposUrls() []string { + f, err := os.Open(paths.ReposUrlsFile) + if err != nil { + return []string{} + } + defer f.Close() + var urls []string + scanner := bufio.NewScanner(f) + for scanner.Scan() { + urls = append(urls, scanner.Text()) + } + return urls +} + +func DownloadRepos(urls []string, destDir string) { + var wg sync.WaitGroup + var links []string + + for _, link := range urls { + link = strings.TrimSpace(link) + if link == "" { + continue + } + links = append(links, link) + } + wg.Add(len(links)) + for _, link := range links { + go func(link string) { + defer wg.Done() + archiveName := path.Base(link) + repoName := strings.TrimSuffix(archiveName, ".tar.zst") + destArchivePath := filepath.Join(destDir, "tmp", archiveName) + destNArchivePath := filepath.Join(destDir, "tmp") + destPath := filepath.Join(destDir, paths.ReposDir) + fullDestPath := filepath.Join(destDir, paths.ReposDir, repoName) + + os.MkdirAll(destNArchivePath, 0755) + + client := &http.Client{ + Timeout: 10 * time.Second, + } + + resp, err := client.Get(link) + if err != nil { + fmt.Println("!! failed to download", link, err) + return + } + defer resp.Body.Close() + + f, err := os.Create(destArchivePath) + if err != nil { + fmt.Println("!! failed to create file", err) + return + } + defer f.Close() + + _, err = io.Copy(f, resp.Body) + if err != nil { + fmt.Println("!! failed to copy", err) + return + } + + fmt.Println(":: downloaded", archiveName, "to", destArchivePath) + + err = os.RemoveAll(fullDestPath) + fmt.Println(":: removing old repo", fullDestPath) + if err != nil { + fmt.Println("w! failed to delete old repo", fullDestPath, err) + } + + file, err := os.Open(destArchivePath) + if err != nil { + fmt.Println("!! failed to open archive file", destArchivePath, err) + return + } + err = extract.Zstd(context.TODO(), file, destPath, nil) + if err != nil { + fmt.Println("!! failed to extract", err) + return + } + }(link) + } + wg.Wait() + fmt.Println(":: repo updating ended") +} + +func ReadInstalled(destDir string) map[interface{}][]interface{} { + installedFullPath := filepath.Join(destDir, paths.InstalledFile) + file, err := os.OpenFile(installedFullPath, os.O_RDONLY, 0644) + if err != nil { + return map[interface{}][]interface{}{} + } + defer file.Close() + text, err := io.ReadAll(file) + if err != nil { + return map[interface{}][]interface{}{} + } + data := uzbekdb.Loads(string(text), "map") + if data == nil { + return map[interface{}][]interface{}{} + } + return data.(map[interface{}][]interface{}) +} + +func WriteInstalled(data map[interface{}][]interface{}, destDir string) error { + installedFullPath := filepath.Join(destDir, paths.InstalledFile) + file, err := os.OpenFile(installedFullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + defer file.Close() + _, err = file.WriteString(uzbekdb.Dumps(data)) + return err +} + +func IsInstalled(name string, destDir string) bool { + data := ReadInstalled(destDir) + if !strings.Contains(name, "/") { + return false + } + _, ok := data[name] + return ok +} + +func GetPackageVersion(name string, destDir string) string { + data := ReadInstalled(destDir) + alo, _ := data[name] + if len(alo) > 0 { + return alo[0].(string) + } else { + return "" + } +} + +func RegPackage(name string, version string, destDir string) error { + data := ReadInstalled(destDir) + _, installed := data[name] + if installed { + if data[name][0].(string) != version { + data[name][0] = version + } + } else { + data[name] = []interface{}{version} + } + return WriteInstalled(data, destDir) +} + +func UnRegPackage(name string, destDir string) error { + data := ReadInstalled(destDir) + _, ok := data[name] + if !ok { + return fmt.Errorf("!! cant unregister '%s': package", name, "is not installed") + } + delete(data, name) + return WriteInstalled(data, destDir) +} + +func PurgeRepository(name string, destDir string) error { + dirPath := filepath.Join(destDir, paths.ReposDir, name) + err := os.RemoveAll(dirPath) + if err != nil { + return err + } + return nil +} + +// func Ensure(args, destDir) error { +// +// } |