Refactor database schema and update dependency handling in code
This commit is contained in:
		@@ -61,7 +61,9 @@ func init() {
 | 
			
		||||
				log.Fatal(db)
 | 
			
		||||
			}
 | 
			
		||||
			defer db.Close()
 | 
			
		||||
			db.Exec("CREATE TABLE IF NOT EXISTS packages (query_name      TEXT NOT NULL,id            TEXT NOT NULL UNIQUE PRIMARY KEY, version         TEXT NOT NULL, dependencies    TEXT NOT NULL DEFAULT '', description     TEXT NOT NULL, family          TEXT NOT NULL, package_d       TEXT NOT NULL, filename        TEXT NOT NULL, os              TEXT NOT NULL, arch            TEXT NOT NULL, in_cache        INTEGER NOT NULL DEFAULT 1, serial          INTEGER NOT NULL)")
 | 
			
		||||
			if _, err := db.Exec("CREATE TABLE IF NOT EXISTS packages (query_name      TEXT NOT NULL,id            TEXT NOT NULL UNIQUE PRIMARY KEY, version         TEXT NOT NULL, description     TEXT NOT NULL, family          TEXT NOT NULL, package_d       TEXT NOT NULL, filename        TEXT NOT NULL, os              TEXT NOT NULL, arch            TEXT NOT NULL, in_cache        INTEGER NOT NULL DEFAULT 1, serial          INTEGER NOT NULL);  CREATE TABLE IF NOT EXISTS package_dependencies( package_id TEXT NOT NULL, dependency_name TEXT NOT NULL, version_constraint TEXT NOT NULL, PRIMARY KEY (package_id, dependency_name)); CREATE INDEX index_dependency_name ON package_dependencies(dependency_name);"); err != nil {
 | 
			
		||||
				log.Fatal(err)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
@@ -195,7 +197,7 @@ var installCmd = &cobra.Command{
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				fmt.Printf("Checking dependencies of (%s)\n", inputName)
 | 
			
		||||
				dependencies, err := utils.GetDependencies(inputName)
 | 
			
		||||
				dependencies, err := utils.GetDependencies(db, inputName)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatal(err)
 | 
			
		||||
				}
 | 
			
		||||
@@ -283,7 +285,7 @@ var installCmd = &cobra.Command{
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				fmt.Printf("Checking dependencies of (%s)\n", pkgs[0].Name)
 | 
			
		||||
				dependencies, err := utils.GetDependencies(pkgs[0].Name)
 | 
			
		||||
				dependencies, err := utils.GetDependencies(db, pkgs[0].Name)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatal(err)
 | 
			
		||||
				}
 | 
			
		||||
@@ -367,7 +369,7 @@ var installCmd = &cobra.Command{
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				fmt.Printf("Checking dependencies of (%s)\n", pkgs[choice].Name)
 | 
			
		||||
				dependencies, err := utils.GetDependencies(pkgs[choice].Name)
 | 
			
		||||
				dependencies, err := utils.GetDependencies(db, pkgs[choice].Name)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatal(err)
 | 
			
		||||
				}
 | 
			
		||||
@@ -591,34 +593,42 @@ func AyncFullInstall(dep string, storePackages bool, installPath string, wg *syn
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Printf(" Installing %s \n", dep)
 | 
			
		||||
	if err := packets.InstallPackage(p.PackageF, installPath); err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	allDependencies, err := utils.ResolvDependencies(p.Dependencies)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for _, dep := range allDependencies {
 | 
			
		||||
 | 
			
		||||
	if storePackages {
 | 
			
		||||
		_, err := p.Write()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			return
 | 
			
		||||
		fmt.Printf(" Installing %s \n", dep)
 | 
			
		||||
		if err := packets.InstallPackage(p.PackageF, installPath); err != nil {
 | 
			
		||||
			log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
		mu.Lock()
 | 
			
		||||
		defer mu.Unlock()
 | 
			
		||||
 | 
			
		||||
		err = p.AddToInstalledDB(1, installPath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if storePackages {
 | 
			
		||||
			_, err := p.Write()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Println(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			mu.Lock()
 | 
			
		||||
			defer mu.Unlock()
 | 
			
		||||
 | 
			
		||||
		mu.Lock()
 | 
			
		||||
		defer mu.Unlock()
 | 
			
		||||
			err = p.AddToInstalledDB(1, installPath)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Println(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
		err := p.AddToInstalledDB(0, installPath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			return
 | 
			
		||||
			mu.Lock()
 | 
			
		||||
			defer mu.Unlock()
 | 
			
		||||
 | 
			
		||||
			err := p.AddToInstalledDB(0, installPath)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Println(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,13 @@ CREATE TABLE packages (
 | 
			
		||||
 | 
			
		||||
CREATE TABLE package_dependencies(
 | 
			
		||||
    package_id TEXT NOT NULL,
 | 
			
		||||
    dependency_id TEXT NOT NULL,
 | 
			
		||||
    dependency_name TEXT NOT NULL,
 | 
			
		||||
    version_constraint TEXT NOT NULL,
 | 
			
		||||
    
 | 
			
		||||
    PRIMARY KEY (package_id, dependencie_id)
 | 
			
		||||
 | 
			
		||||
    PRIMARY KEY (package_id, dependency_name)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
CREATE INDEX index_dependency_id ON package_dependencies(dependency_id);
 | 
			
		||||
CREATE INDEX index_dependency_name ON package_dependencies(dependency_name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS packages (
 | 
			
		||||
 
 | 
			
		||||
@@ -14,23 +14,6 @@ import (
 | 
			
		||||
	lua "github.com/yuin/gopher-lua"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var SandboxDir string
 | 
			
		||||
 | 
			
		||||
var AllowedCmds = map[string]string{
 | 
			
		||||
	"go":          "go",          // "Go code compiler"
 | 
			
		||||
	"gcc":         "gcc",         // "C"
 | 
			
		||||
	"g++":         "g++",         // "C++"
 | 
			
		||||
	"rustc":       "rustc",       // "Rust"
 | 
			
		||||
	"javac":       "javac",       // "Java"
 | 
			
		||||
	"luac":        "luac",        // "Lua"
 | 
			
		||||
	"pyinstaller": "pyinstaller", // "Python"
 | 
			
		||||
	"kotlinc":     "kotlinc",     // "Kotlin"
 | 
			
		||||
	"mcs":         "mcs",         // "C# compiler"
 | 
			
		||||
	"swiftc":      "swiftc",      // "Swift compiler"
 | 
			
		||||
	"tsc":         "tsc",         // "TypeScript compiler"
 | 
			
		||||
	"rubyc":       "rubyc",       // "Ruby compiler"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsSafe(str string) bool {
 | 
			
		||||
	s, err := filepath.EvalSymlinks(filepath.Clean(str))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -239,8 +239,8 @@ func (p *Package) AddToInstalledDB(inCache int, packagePath string) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for depnId, versionConstraint := range p.Dependencies {
 | 
			
		||||
		_, err = db.Exec("INSERT INTO package_dependencies (package_id, dependencie_id, version_constraint) VALUES (?, ?, ?)", p.Manifest.Info.Id, depnId, versionConstraint)
 | 
			
		||||
	for depnName, versionConstraint := range p.Dependencies {
 | 
			
		||||
		_, err = db.Exec("INSERT INTO package_dependencies (package_id, dependency_name, version_constraint) VALUES (?, ?, ?)", p.Manifest.Info.Id, depnName, versionConstraint)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	success = true
 | 
			
		||||
@@ -263,14 +263,9 @@ func CheckIfPackageInstalled(name string) (bool, error) {
 | 
			
		||||
	return exists, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetDependencies(id string) (map[string]string, error) {
 | 
			
		||||
	db, err := sql.Open("sqlite", consts.IndexDB)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return map[string]string{}, err
 | 
			
		||||
	}
 | 
			
		||||
	defer db.Close()
 | 
			
		||||
func GetDependencies(db *sql.DB, id string) (map[string]string, error) {
 | 
			
		||||
 | 
			
		||||
	rows, err := db.Query("SELECT dependency_id, version_constraint FROM package_dependencies WHERE package_id = ?", id)
 | 
			
		||||
	rows, err := db.Query("SELECT dependency_name, version_constraint FROM package_dependencies WHERE package_id = ?", id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return map[string]string{}, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -290,13 +285,60 @@ func GetDependencies(id string) (map[string]string, error) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ResolvDependencies(depnList map[string]string) ([]Package, error) {
 | 
			
		||||
func ResolvDependencies(depnList map[string]string) ([]string, error) {
 | 
			
		||||
	db, err := sql.Open("sqlite", consts.IndexDB)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return map[string]string{}, err
 | 
			
		||||
		return []string{}, err
 | 
			
		||||
	}
 | 
			
		||||
	defer db.Close()
 | 
			
		||||
 | 
			
		||||
	var resolved []string
 | 
			
		||||
	for dependencieName, constraint := range depnList {
 | 
			
		||||
 | 
			
		||||
		var filter, order string
 | 
			
		||||
		value := strings.TrimLeft(constraint, "<>=")
 | 
			
		||||
 | 
			
		||||
		switch {
 | 
			
		||||
		case strings.HasPrefix(constraint, ">"):
 | 
			
		||||
			filter = fmt.Sprintf("AND serial > %s", value)
 | 
			
		||||
			order = "ORDER BY serial ASC LIMIT 1"
 | 
			
		||||
		case strings.HasPrefix(constraint, "<="):
 | 
			
		||||
			filter = fmt.Sprintf("AND serial <= %s", value)
 | 
			
		||||
			order = "ORDER BY serial DESC LIMIT 1"
 | 
			
		||||
		case strings.HasPrefix(constraint, "<"):
 | 
			
		||||
			filter = fmt.Sprintf("AND serial < %s", value)
 | 
			
		||||
			order = "ORDER BY serial DESC LIMIT 1"
 | 
			
		||||
		case strings.HasPrefix(constraint, "="):
 | 
			
		||||
			filter = fmt.Sprintf("AND serial = %s", value)
 | 
			
		||||
			order = ""
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var packageId string
 | 
			
		||||
 | 
			
		||||
		err := db.QueryRow(fmt.Sprintf("SELECT id FROM packages WHERE query_name = ? %s %s", filter, order), dependencieName).Scan(&packageId)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err == sql.ErrNoRows {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			return []string{}, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		resolved = append(resolved, packageId)
 | 
			
		||||
 | 
			
		||||
		dp, err := GetDependencies(db, packageId)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return resolved, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		depn, err := ResolvDependencies(dp)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return resolved, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		resolved = append(resolved, depn...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return []Package{}, nil
 | 
			
		||||
	return resolved, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ManifestFileRead(file io.Reader) (configs.Manifest, error) {
 | 
			
		||||
@@ -358,7 +400,7 @@ func GetPackage(id string) (Package, error) {
 | 
			
		||||
		return Package{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rows, err := db.Query("SELECT dependency_id, version_constraint FROM package_dependencies WHERE package_id = ?", id)
 | 
			
		||||
	rows, err := db.Query("SELECT dependency_name, version_constraint FROM package_dependencies WHERE package_id = ?", id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Package{}, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user