Skip to content

Commit

Permalink
fix(api): search pagination, format SQL queries (#185)
Browse files Browse the repository at this point in the history
* fix(api): search pagination, format SQL queries

* chore(api): run gci
  • Loading branch information
bouassaba authored Jul 19, 2024
1 parent 9bcaced commit 77cb990
Show file tree
Hide file tree
Showing 20 changed files with 285 additions and 101 deletions.
8 changes: 6 additions & 2 deletions api/infra/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,12 @@ func NewSearchManager() *SearchManager {
}
}

func (mgr *SearchManager) Query(index string, query string) ([]interface{}, error) {
res, err := searchClient.Index(index).Search(query, &meilisearch.SearchRequest{})
type QueryOptions struct {
Limit int64
}

func (mgr *SearchManager) Query(index string, query string, opts QueryOptions) ([]interface{}, error) {
res, err := searchClient.Index(index).Search(query, &meilisearch.SearchRequest{Limit: opts.Limit})
if err != nil {
return nil, err
}
Expand Down
136 changes: 87 additions & 49 deletions api/repo/file_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type FileRepo interface {
FindChildren(id string) ([]model.File, error)
FindPath(id string) ([]model.File, error)
FindTree(id string) ([]model.File, error)
Count() (int64, error)
GetIDsByWorkspace(workspaceID string) ([]string, error)
GetIDsBySnapshot(snapshotID string) ([]string, error)
MoveSourceIntoTarget(targetID string, sourceID string) error
Expand Down Expand Up @@ -224,7 +225,9 @@ func (repo *fileRepo) Find(id string) (model.File, error) {

func (repo *fileRepo) find(id string) (*fileEntity, error) {
res := fileEntity{}
db := repo.db.Raw("SELECT * FROM file WHERE id = ?", id).Scan(&res)
db := repo.db.
Raw("SELECT * FROM file WHERE id = ?", id).
Scan(&res)
if db.Error != nil {
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
return nil, errorpkg.NewFileNotFoundError(db.Error)
Expand All @@ -240,7 +243,9 @@ func (repo *fileRepo) find(id string) (*fileEntity, error) {

func (repo *fileRepo) FindChildren(id string) ([]model.File, error) {
var entities []*fileEntity
db := repo.db.Raw("SELECT * FROM file WHERE parent_id = ? ORDER BY create_time ASC", id).Scan(&entities)
db := repo.db.
Raw("SELECT * FROM file WHERE parent_id = ? ORDER BY create_time ASC", id).
Scan(&entities)
if db.Error != nil {
return nil, db.Error
}
Expand All @@ -257,10 +262,11 @@ func (repo *fileRepo) FindChildren(id string) ([]model.File, error) {
func (repo *fileRepo) FindPath(id string) ([]model.File, error) {
var entities []*fileEntity
if db := repo.db.
Raw("WITH RECURSIVE rec (id, name, type, parent_id, workspace_id, create_time, update_time) AS "+
"(SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM file f WHERE f.id = ? "+
"UNION SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM rec, file f WHERE f.id = rec.parent_id) "+
"SELECT * FROM rec", id).
Raw(`WITH RECURSIVE rec (id, name, type, parent_id, workspace_id, create_time, update_time) AS
(SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM file f WHERE f.id = ?
UNION SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM rec, file f WHERE f.id = rec.parent_id)
SELECT * FROM rec`,
id).
Scan(&entities); db.Error != nil {
return nil, db.Error
}
Expand All @@ -277,10 +283,11 @@ func (repo *fileRepo) FindPath(id string) ([]model.File, error) {
func (repo *fileRepo) FindTree(id string) ([]model.File, error) {
var entities []*fileEntity
db := repo.db.
Raw("WITH RECURSIVE rec (id, name, type, parent_id, workspace_id, snapshot_id, create_time, update_time) AS "+
"(SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.snapshot_id, f.create_time, f.update_time FROM file f WHERE f.id = ? "+
"UNION SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.snapshot_id, f.create_time, f.update_time FROM rec, file f WHERE f.parent_id = rec.id) "+
"SELECT rec.* FROM rec ORDER BY create_time ASC", id).
Raw(`WITH RECURSIVE rec (id, name, type, parent_id, workspace_id, snapshot_id, create_time, update_time) AS
(SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.snapshot_id, f.create_time, f.update_time FROM file f WHERE f.id = ?
UNION SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.snapshot_id, f.create_time, f.update_time FROM rec, file f WHERE f.parent_id = rec.id)
SELECT rec.* FROM rec ORDER BY create_time ASC`,
id).
Scan(&entities)
if db.Error != nil {
return nil, db.Error
Expand All @@ -295,12 +302,28 @@ func (repo *fileRepo) FindTree(id string) ([]model.File, error) {
return res, nil
}

func (repo *fileRepo) Count() (int64, error) {
type Result struct {
Result int64
}
var res Result
db := repo.db.
Raw("SELECT count(*) as result FROM file").
Scan(&res)
if db.Error != nil {
return 0, db.Error
}
return res.Result, nil
}

func (repo *fileRepo) GetIDsByWorkspace(workspaceID string) ([]string, error) {
type IDResult struct {
Result string
}
var ids []IDResult
db := repo.db.Raw("SELECT id result FROM file WHERE workspace_id = ? ORDER BY create_time ASC", workspaceID).Scan(&ids)
db := repo.db.
Raw("SELECT id result FROM file WHERE workspace_id = ? ORDER BY create_time ASC", workspaceID).
Scan(&ids)
if db.Error != nil {
return nil, db.Error
}
Expand Down Expand Up @@ -386,7 +409,9 @@ func (repo *fileRepo) GetChildrenIDs(id string) ([]string, error) {
Result string
}
var values []Value
db := repo.db.Raw("SELECT id result FROM file WHERE parent_id = ? ORDER BY create_time ASC", id).Scan(&values)
db := repo.db.
Raw("SELECT id result FROM file WHERE parent_id = ? ORDER BY create_time ASC", id).
Scan(&values)
if db.Error != nil {
return []string{}, db.Error
}
Expand All @@ -403,10 +428,11 @@ func (repo *fileRepo) GetItemCount(id string) (int64, error) {
}
var res Result
db := repo.db.
Raw("WITH RECURSIVE rec (id, parent_id) AS "+
"(SELECT f.id, f.parent_id FROM file f WHERE f.id = ? "+
"UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id) "+
"SELECT count(rec.id) as result FROM rec", id).
Raw(`WITH RECURSIVE rec (id, parent_id) AS
(SELECT f.id, f.parent_id FROM file f WHERE f.id = ?
UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id)
SELECT count(rec.id) as result FROM rec`,
id).
Scan(&res)
if db.Error != nil {
return 0, db.Error
Expand All @@ -420,10 +446,11 @@ func (repo *fileRepo) IsGrandChildOf(id string, ancestorID string) (bool, error)
}
var res Result
if db := repo.db.
Raw("WITH RECURSIVE rec (id, parent_id) AS "+
"(SELECT f.id, f.parent_id FROM file f WHERE f.id = ? "+
"UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id) "+
"SELECT count(rec.id) > 0 as result FROM rec WHERE rec.id = ?", ancestorID, id).
Raw(`WITH RECURSIVE rec (id, parent_id) AS
(SELECT f.id, f.parent_id FROM file f WHERE f.id = ?
UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id)
SELECT count(rec.id) > 0 as result FROM rec WHERE rec.id = ?`,
ancestorID, id).
Scan(&res); db.Error != nil {
return false, db.Error
}
Expand All @@ -436,11 +463,12 @@ func (repo *fileRepo) GetSize(id string) (int64, error) {
}
var res Result
db := repo.db.
Raw("WITH RECURSIVE rec (id, parent_id) AS "+
"(SELECT f.id, f.parent_id FROM file f WHERE f.id = ? "+
"UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id) "+
"SELECT coalesce(sum((s.original->>'size')::int), 0) as result FROM snapshot s, rec "+
"LEFT JOIN snapshot_file map ON rec.id = map.file_id WHERE map.snapshot_id = s.id", id).
Raw(`WITH RECURSIVE rec (id, parent_id) AS
(SELECT f.id, f.parent_id FROM file f WHERE f.id = ?
UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id)
SELECT coalesce(sum((s.original->>'size')::int), 0) as result FROM snapshot s, rec
LEFT JOIN snapshot_file map ON rec.id = map.file_id WHERE map.snapshot_id = s.id`,
id).
Scan(&res)
if db.Error != nil {
return res.Result, db.Error
Expand All @@ -450,11 +478,12 @@ func (repo *fileRepo) GetSize(id string) (int64, error) {

func (repo *fileRepo) GrantUserPermission(id string, userID string, permission string) error {
/* Grant permission to workspace */
db := repo.db.Exec("INSERT INTO userpermission (id, user_id, resource_id, permission) "+
"(SELECT ?, ?, w.id, 'viewer' FROM file f "+
"INNER JOIN workspace w ON w.id = f.workspace_id AND f.id = ?) "+
"ON CONFLICT DO NOTHING",
helper.NewID(), userID, id)
db := repo.db.
Exec(`INSERT INTO userpermission (id, user_id, resource_id, permission)
(SELECT ?, ?, w.id, 'viewer' FROM file f
INNER JOIN workspace w ON w.id = f.workspace_id AND f.id = ?)
ON CONFLICT DO NOTHING`,
helper.NewID(), userID, id)
if db.Error != nil {
return db.Error
}
Expand All @@ -465,9 +494,10 @@ func (repo *fileRepo) GrantUserPermission(id string, userID string, permission s
return err
}
for _, f := range path {
db := repo.db.Exec("INSERT INTO userpermission (id, user_id, resource_id, permission) "+
"VALUES (?, ?, ?, 'viewer') ON CONFLICT DO NOTHING",
helper.NewID(), userID, f.GetID())
db := repo.db.
Exec(`INSERT INTO userpermission (id, user_id, resource_id, permission)
VALUES (?, ?, ?, 'viewer') ON CONFLICT DO NOTHING`,
helper.NewID(), userID, f.GetID())
if db.Error != nil {
return db.Error
}
Expand All @@ -479,9 +509,10 @@ func (repo *fileRepo) GrantUserPermission(id string, userID string, permission s
return err
}
for _, f := range tree {
db := repo.db.Exec("INSERT INTO userpermission (id, user_id, resource_id, permission) "+
"VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?",
helper.NewID(), userID, f.GetID(), permission, permission)
db := repo.db.
Exec(`INSERT INTO userpermission (id, user_id, resource_id, permission)
VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?`,
helper.NewID(), userID, f.GetID(), permission, permission)
if db.Error != nil {
return db.Error
}
Expand All @@ -492,7 +523,9 @@ func (repo *fileRepo) GrantUserPermission(id string, userID string, permission s

func (repo *fileRepo) RevokeUserPermission(tree []model.File, userID string) error {
for _, f := range tree {
db := repo.db.Exec("DELETE FROM userpermission WHERE user_id = ? AND resource_id = ?", userID, f.GetID())
db := repo.db.
Exec("DELETE FROM userpermission WHERE user_id = ? AND resource_id = ?",
userID, f.GetID())
if db.Error != nil {
return db.Error
}
Expand All @@ -502,11 +535,12 @@ func (repo *fileRepo) RevokeUserPermission(tree []model.File, userID string) err

func (repo *fileRepo) GrantGroupPermission(id string, groupID string, permission string) error {
/* Grant permission to workspace */
db := repo.db.Exec("INSERT INTO grouppermission (id, group_id, resource_id, permission) "+
"(SELECT ?, ?, w.id, 'viewer' FROM file f "+
"INNER JOIN workspace w ON w.id = f.workspace_id AND f.id = ?) "+
"ON CONFLICT DO NOTHING",
helper.NewID(), groupID, id)
db := repo.db.
Exec(`INSERT INTO grouppermission (id, group_id, resource_id, permission)
(SELECT ?, ?, w.id, 'viewer' FROM file f
INNER JOIN workspace w ON w.id = f.workspace_id AND f.id = ?)
ON CONFLICT DO NOTHING`,
helper.NewID(), groupID, id)
if db.Error != nil {
return db.Error
}
Expand All @@ -517,9 +551,10 @@ func (repo *fileRepo) GrantGroupPermission(id string, groupID string, permission
return err
}
for _, f := range path {
db := repo.db.Exec("INSERT INTO grouppermission (id, group_id, resource_id, permission) "+
"VALUES (?, ?, ?, 'viewer') ON CONFLICT DO NOTHING",
helper.NewID(), groupID, f.GetID())
db := repo.db.
Exec(`INSERT INTO grouppermission (id, group_id, resource_id, permission)
VALUES (?, ?, ?, 'viewer') ON CONFLICT DO NOTHING`,
helper.NewID(), groupID, f.GetID())
if db.Error != nil {
return db.Error
}
Expand All @@ -531,9 +566,10 @@ func (repo *fileRepo) GrantGroupPermission(id string, groupID string, permission
return err
}
for _, f := range tree {
db := repo.db.Exec("INSERT INTO grouppermission (id, group_id, resource_id, permission) "+
"VALUES (?, ?, ?, ?) ON CONFLICT (group_id, resource_id) DO UPDATE SET permission = ?",
helper.NewID(), groupID, f.GetID(), permission, permission)
db := repo.db.
Exec(`INSERT INTO grouppermission (id, group_id, resource_id, permission)
VALUES (?, ?, ?, ?) ON CONFLICT (group_id, resource_id) DO UPDATE SET permission = ?`,
helper.NewID(), groupID, f.GetID(), permission, permission)
if db.Error != nil {
return db.Error
}
Expand All @@ -544,7 +580,9 @@ func (repo *fileRepo) GrantGroupPermission(id string, groupID string, permission

func (repo *fileRepo) RevokeGroupPermission(tree []model.File, groupID string) error {
for _, f := range tree {
db := repo.db.Exec("DELETE FROM grouppermission WHERE group_id = ? AND resource_id = ?", groupID, f.GetID())
db := repo.db.
Exec("DELETE FROM grouppermission WHERE group_id = ? AND resource_id = ?",
groupID, f.GetID())
if db.Error != nil {
return db.Error
}
Expand Down
27 changes: 23 additions & 4 deletions api/repo/group_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
type GroupRepo interface {
Insert(opts GroupInsertOptions) (model.Group, error)
Find(id string) (model.Group, error)
Count() (int64, error)
GetIDsForFile(fileID string) ([]string, error)
GetIDsForUser(userID string) ([]string, error)
GetIDsForOrganization(id string) ([]string, error)
Expand Down Expand Up @@ -179,13 +180,30 @@ func (repo *groupRepo) Find(id string) (model.Group, error) {
return group, nil
}

func (repo *groupRepo) Count() (int64, error) {
type Result struct {
Result int64
}
var res Result
db := repo.db.
Raw("SELECT count(*) as result FROM group").
Scan(&res)
if db.Error != nil {
return 0, db.Error
}
return res.Result, nil
}

func (repo *groupRepo) GetIDsForFile(fileID string) ([]string, error) {
type Value struct {
Result string
}
var values []Value
db := repo.db.
Raw(`SELECT DISTINCT g.id as result FROM "group" g INNER JOIN grouppermission p ON p.resource_id = ? WHERE p.group_id = g.id`, fileID).
Raw(`SELECT DISTINCT g.id as result FROM "group" g
INNER JOIN grouppermission p ON p.resource_id = ?
WHERE p.group_id = g.id`,
fileID).
Scan(&values)
if db.Error != nil {
return []string{}, db.Error
Expand Down Expand Up @@ -301,9 +319,10 @@ func (repo *groupRepo) GetMembers(id string) ([]model.User, error) {
}

func (repo *groupRepo) GrantUserPermission(id string, userID string, permission string) error {
db := repo.db.Exec(
"INSERT INTO userpermission (id, user_id, resource_id, permission) VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?",
helper.NewID(), userID, id, permission, permission)
db := repo.db.
Exec(`INSERT INTO userpermission (id, user_id, resource_id, permission)
VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?`,
helper.NewID(), userID, id, permission, permission)
if db.Error != nil {
return db.Error
}
Expand Down
Loading

0 comments on commit 77cb990

Please sign in to comment.