func dropUnusedDBFiles(olderThan time.Time) {
	prefetchDB.Model(&MirrorDB{}).Unscoped().Where("mirror_dbs.last_time_downloaded < ?", olderThan).Delete(&MirrorDB{})
}
Returns unused db files and removes them from the db
package main
import (
	"fmt"
	"log"
	"os"
	"path"
	"time"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)
type Package struct {
	PackageName         string     `gorm:"primaryKey;not null"`
	Version             string     `gorm:"not null"`
	Arch                string     `gorm:"primaryKey;not null"`
	RepoName            string     `gorm:"primaryKey;not null"`
	LastTimeDownloaded  *time.Time `gorm:"not null"`
	LastTimeRepoUpdated *time.Time `gorm:"not null"`
}
func getPackagePaths(pkg Package) []string {
	baseString := path.Join("pkgs", pkg.RepoName, pkg.PackageName+"-"+pkg.Version+"-"+pkg.Arch)
	var pkgPaths []string
	for _, ext := range allowedPackagesExtensions {
		pkgPaths = append(pkgPaths, baseString+ext)
		pkgPaths = append(pkgPaths, baseString+ext+".sig")
	}
	return pkgPaths
}
type MirrorDB struct {
	URL                string     `gorm:"primaryKey;not null"`
	RepoName           string     `gorm:"primaryKey;not null"`
	LastTimeDownloaded *time.Time `gorm:"not null"`
}
type RepoPackage struct {
	PackageName string `gorm:"primaryKey;not null"`
	Version     string `gorm:"not null"`
	Arch        string `gorm:"primaryKey;not null"`
	RepoName    string `gorm:"primaryKey;not null"`
	DownloadURL string `gorm:"not null"`
}
func createRepoTable() error {
	_ = prefetchDB.Migrator().DropTable(&RepoPackage{})
	return prefetchDB.Migrator().CreateTable(&RepoPackage{})
}
func deleteRepoTable() error {
	return prefetchDB.Migrator().DropTable(&RepoPackage{})
}
func createPrefetchDB() {
	if config == nil {
		log.Fatalf("Config have not been parsed yet")
	}
	dbPath := path.Join(config.CacheDir, DefaultDBName)
	exists, err := fileExists(dbPath)
	if err != nil {
		log.Fatal(err)
	}
	if !exists {
		log.Printf("Creating %v", dbPath)
		file, err := os.Create(dbPath)  
		if err != nil {
			log.Fatal(err)
		}
		file.Close()
		db, err := getDBConnection()
		if err != nil {
			log.Fatal(err)
		}
		db.Migrator().CreateTable(&Package{})
		db.Migrator().CreateTable(&MirrorDB{})
		db.Migrator().CreateTable(&RepoPackage{})
	}
}
func getDBConnection() (*gorm.DB, error) {
	dbPath := path.Join(config.CacheDir, DefaultDBName)
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags),  
		logger.Config{
			SlowThreshold:             time.Second,  
			IgnoreRecordNotFoundError: true,         
		},
	)
	return gorm.Open(sqlite.Open(dbPath), &gorm.Config{Logger: newLogger})
}
func getPackage(pkgName string, arch string, reponame string) Package {
	var pkg Package
	if prefetchDB == nil {
		log.Fatalf("Called getPackage with no initialized db!")
	}
	prefetchDB.Model(&Package{}).Where("packages.package_name=? AND packages.arch=? AND packages.repo_name = ?", pkgName, arch, reponame).First(&pkg)
	return pkg
}
func getAndDropUnusedPackages(period time.Duration) []Package {
	var possiblyUnusedPkgs []Package
	prefetchDB.Model(&Package{}).Where("packages.last_time_repo_updated > packages.last_time_downloaded").Find(&possiblyUnusedPkgs)
	var unusedPkgs []Package
	for _, pkg := range possiblyUnusedPkgs {
		if pkg.LastTimeRepoUpdated.Sub(*pkg.LastTimeDownloaded) > period {
			unusedPkgs = append(unusedPkgs, pkg)
			var tmp []Package
			prefetchDB.Model(&Package{}).Unscoped().Where("packages.package_name = ? and packages.arch = ? and packages.repo_name = ?", pkg.PackageName, pkg.Arch, pkg.RepoName).Delete(&tmp)
		}
	}
	return unusedPkgs
}