repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
3a18c6d
parent
4a34fa3
author
Eric Bower
date
2023-08-13 20:33:59 +0000 UTC
feat: more pgs commands
3 files changed,  +172, -7
M db/db.go
+2, -0
 1@@ -210,7 +210,9 @@ type DB interface {
 2 	LinkToProject(userID, projectID, projectDir string) error
 3 	RemoveProject(projectID string) error
 4 	FindProjectByName(userID, name string) (*Project, error)
 5+	FindProjectLinks(userID, name string) ([]*Project, error)
 6 	FindProjectsByUser(userID string) ([]*Project, error)
 7+	FindProjectsByPrefix(userID, name string) ([]*Project, error)
 8 
 9 	Close() error
10 }
M db/postgres/storage.go
+63, -5
 1@@ -243,11 +243,13 @@ const (
 2 	sqlRemoveKeys          = `DELETE FROM public_keys WHERE id = ANY($1::uuid[])`
 3 	sqlRemoveUsers         = `DELETE FROM app_users WHERE id = ANY($1::uuid[])`
 4 
 5-	sqlInsertProject      = `INSERT INTO projects (user_id, name, project_dir) VALUES ($1, $2, $3) RETURNING id;`
 6-	sqlFindProjectByName  = `SELECT id, user_id, name, project_dir FROM projects WHERE user_id = $1 AND name = $2;`
 7-	sqlFindProjectsByUser = `SELECT id, user_id, name, project_dir FROM projects WHERE user_id = $1;`
 8-	sqlLinkToProject      = `UPDATE projects SET project_dir = $1, updated_at = $2 WHERE id = $3;`
 9-	sqlRemoveProject      = `DELETE FROM projects WHERE id = $1;`
10+	sqlInsertProject        = `INSERT INTO projects (user_id, name, project_dir) VALUES ($1, $2, $3) RETURNING id;`
11+	sqlFindProjectByName    = `SELECT id, user_id, name, project_dir FROM projects WHERE user_id = $1 AND name = $2;`
12+	sqlFindProjectsByUser   = `SELECT id, user_id, name, project_dir FROM projects WHERE user_id = $1;`
13+	sqlFindProjectsByPrefix = `SELECT id, user_id, name, project_dir FROM projects WHERE user_id = $1 AND name = project_dir AND name ILIKE $2;`
14+	sqlFindProjectLinks     = `SELECT id, user_id, name, project_dir FROM projects WHERE user_id = $1 AND name != project_dir AND project_dir = $2;`
15+	sqlLinkToProject        = `UPDATE projects SET project_dir = $1, updated_at = $2 WHERE id = $3;`
16+	sqlRemoveProject        = `DELETE FROM projects WHERE id = $1;`
17 )
18 
19 type PsqlDB struct {
20@@ -1249,6 +1251,62 @@ func (me *PsqlDB) FindProjectByName(userID, name string) (*db.Project, error) {
21 	return project, nil
22 }
23 
24+func (me *PsqlDB) FindProjectLinks(userID, name string) ([]*db.Project, error) {
25+	var projects []*db.Project
26+	rs, err := me.Db.Query(sqlFindProjectLinks, userID, name)
27+	if err != nil {
28+		return nil, err
29+	}
30+	for rs.Next() {
31+		project := &db.Project{}
32+		err := rs.Scan(
33+			&project.ID,
34+			&project.UserID,
35+			&project.Name,
36+			&project.ProjectDir,
37+		)
38+		if err != nil {
39+			return nil, err
40+		}
41+
42+		projects = append(projects, project)
43+	}
44+
45+	if rs.Err() != nil {
46+		return nil, rs.Err()
47+	}
48+
49+	return projects, nil
50+}
51+
52+func (me *PsqlDB) FindProjectsByPrefix(userID, prefix string) ([]*db.Project, error) {
53+	var projects []*db.Project
54+	rs, err := me.Db.Query(sqlFindProjectsByPrefix, userID, prefix+"%")
55+	if err != nil {
56+		return nil, err
57+	}
58+	for rs.Next() {
59+		project := &db.Project{}
60+		err := rs.Scan(
61+			&project.ID,
62+			&project.UserID,
63+			&project.Name,
64+			&project.ProjectDir,
65+		)
66+		if err != nil {
67+			return nil, err
68+		}
69+
70+		projects = append(projects, project)
71+	}
72+
73+	if rs.Err() != nil {
74+		return nil, rs.Err()
75+	}
76+
77+	return projects, nil
78+}
79+
80 func (me *PsqlDB) FindProjectsByUser(userID string) ([]*db.Project, error) {
81 	var projects []*db.Project
82 	rs, err := me.Db.Query(sqlFindProjectsByUser, userID)
M pgs/wish.go
+107, -2
  1@@ -39,6 +39,8 @@ func getHelpText(userName, projectName string) string {
  2 	helpStr += fmt.Sprintf("`%s stats`: prints stats for user\n", sshCmdStr)
  3 	helpStr += fmt.Sprintf("`%s ls`: lists projects\n", sshCmdStr)
  4 	helpStr += fmt.Sprintf("`%s %s rm`: deletes `%s`\n", sshCmdStr, projectName, projectName)
  5+	helpStr += fmt.Sprintf("`%s %s clean`: removes all projects that matches `%s` which is not linked\n", sshCmdStr, projectName, projectName)
  6+	helpStr += fmt.Sprintf("`%s %s links`: lists all projects linked to `%s`\n", sshCmdStr, projectName, projectName)
  7 	helpStr += fmt.Sprintf("`%s %s link projectB`: symbolic link from `%s` to `projectB`\n", sshCmdStr, projectName, projectName)
  8 	helpStr += fmt.Sprintf("`%s %s unlink`: removes symbolic link for `%s`\n", sshCmdStr, projectName, projectName)
  9 	return helpStr
 10@@ -183,7 +185,15 @@ func WishMiddleware(handler *uploadassets.UploadAssetHandler) wish.Middleware {
 11 					}
 12 				} else {
 13 					log.Infof("user (%s) has no project record (%s), creating ...", user.Name, projectName)
 14-					_, err := dbpool.InsertProject(user.ID, projectName, projectDir)
 15+					id, err := dbpool.InsertProject(user.ID, projectName, projectName)
 16+					if err != nil {
 17+						log.Error(err)
 18+						utils.ErrorHandler(session, err)
 19+						return
 20+					}
 21+
 22+					log.Infof("user (%s) linking (%s) to (%s) ...", user.Name, projectName, projectDir)
 23+					err = dbpool.LinkToProject(user.ID, id, projectDir)
 24 					if err != nil {
 25 						log.Error(err)
 26 						utils.ErrorHandler(session, err)
 27@@ -193,11 +203,106 @@ func WishMiddleware(handler *uploadassets.UploadAssetHandler) wish.Middleware {
 28 				out := fmt.Sprintf("(%s) now points to (%s)\n", projectName, linkTo)
 29 				_, _ = session.Write([]byte(out))
 30 				return
 31+			} else if cmd == "links" {
 32+				projects, err := dbpool.FindProjectLinks(user.ID, projectName)
 33+				if err != nil {
 34+					log.Error(err)
 35+					utils.ErrorHandler(session, err)
 36+					return
 37+				}
 38+
 39+				if len(projects) == 0 {
 40+					out := fmt.Sprintf("no projects linked to this project (%s) found\n", projectName)
 41+					_, _ = session.Write([]byte(out))
 42+					return
 43+				}
 44+
 45+				for _, project := range projects {
 46+					out := fmt.Sprintf("%s (links to: %s)\n", project.Name, project.ProjectDir)
 47+					if project.Name == project.ProjectDir {
 48+						out = fmt.Sprintf("%s\n", project.Name)
 49+					}
 50+					_, _ = session.Write([]byte(out))
 51+				}
 52+			} else if cmd == "clean" {
 53+				log.Infof("user (%s) running `clean` command for (%s)", user.Name, projectName)
 54+				if projectName == "" || projectName == "*" {
 55+					e := fmt.Errorf("must provide valid prefix")
 56+					log.Error(e)
 57+					utils.ErrorHandler(session, e)
 58+					return
 59+				}
 60+
 61+				projects, err := dbpool.FindProjectsByPrefix(user.ID, projectName)
 62+				if err != nil {
 63+					log.Error(err)
 64+					utils.ErrorHandler(session, err)
 65+				}
 66+
 67+				bucketName := shared.GetAssetBucketName(user.ID)
 68+				bucket, err := store.GetBucket(bucketName)
 69+				if err != nil {
 70+					log.Error(err)
 71+					utils.ErrorHandler(session, err)
 72+					return
 73+				}
 74+
 75+				rmProjects := []*db.Project{}
 76+				for _, project := range projects {
 77+					links, err := dbpool.FindProjectLinks(user.ID, project.Name)
 78+					if err != nil {
 79+						log.Error(err)
 80+						utils.ErrorHandler(session, err)
 81+					}
 82+
 83+					if len(links) == 0 {
 84+						out := fmt.Sprintf("project (%s) is available to delete", project.Name)
 85+						_, _ = session.Write([]byte(out))
 86+						rmProjects = append(rmProjects, project)
 87+					}
 88+				}
 89+
 90+				for _, project := range rmProjects {
 91+					fileList, err := store.ListFiles(bucket, project.Name, true)
 92+					if err != nil {
 93+						log.Error(err)
 94+						return
 95+					}
 96+
 97+					for _, file := range fileList {
 98+						err = store.DeleteFile(bucket, file.Name())
 99+						if err == nil {
100+							// _, _ = session.Write([]byte(fmt.Sprintf("deleted (%s)\n", file.Name())))
101+						} else {
102+							log.Error(err)
103+							utils.ErrorHandler(session, err)
104+						}
105+					}
106+
107+					err = dbpool.RemoveProject(project.ID)
108+					if err != nil {
109+						log.Error(err)
110+						utils.ErrorHandler(session, err)
111+					}
112+				}
113 			} else if cmd == "rm" {
114 				log.Infof("user (%s) running `rm` command for (%s)", user.Name, projectName)
115 				project, err := dbpool.FindProjectByName(user.ID, projectName)
116 				if err == nil {
117-					log.Infof("found project (%s) (%s), removing ...", projectName, project.ID)
118+					log.Infof("found project (%s) (%s), checking dependencies ...", projectName, project.ID)
119+
120+					links, err := dbpool.FindProjectLinks(user.ID, projectName)
121+					if err != nil {
122+						log.Error(err)
123+						utils.ErrorHandler(session, err)
124+					}
125+
126+					if len(links) > 0 {
127+						e := fmt.Errorf("project (%s) has (%d) other projects linking to it, can't delete project until they have been unlinked or removed, aborting ...", projectName, len(links))
128+						log.Error(e)
129+						return
130+					}
131+
132 					err = dbpool.RemoveProject(project.ID)
133 					if err != nil {
134 						log.Error(err)