partial implementation of community profile page - next, straighten out left menus
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Amsterdam Web Communities System
|
||||
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
// The database package contains database management and storage logic.
|
||||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Category is the structure defining a category.
|
||||
type Category struct {
|
||||
CatId int32 `db:"catid"`
|
||||
Parent int32 `db:"parent"`
|
||||
SymLink int32 `db:"symlink"`
|
||||
HideDirectory int32 `db:"hide_dir"`
|
||||
HideSearch int32 `db:"hide_search"`
|
||||
Name string `db:"name"`
|
||||
}
|
||||
|
||||
// allCategories is the list of all categories loaded from the database.
|
||||
var allCategories []Category
|
||||
|
||||
// categoryIdMap maps IDs to categories.
|
||||
var categoryIdMap map[int32]*Category = make(map[int32]*Category)
|
||||
|
||||
// categoryMutex syncs the loading of the categories.
|
||||
var categoryMutex sync.Mutex
|
||||
|
||||
// loadCategories loads the categories list from the database.
|
||||
func loadCategories() error {
|
||||
categoryMutex.Lock()
|
||||
defer categoryMutex.Unlock()
|
||||
if allCategories == nil {
|
||||
rs, err := amdb.Query("SELECT COUNT(*) FROM refcategory")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !rs.Next() {
|
||||
return errors.New("internal error loading categories")
|
||||
}
|
||||
var ncats int32
|
||||
rs.Scan(&ncats)
|
||||
allCategories = make([]Category, 0, ncats)
|
||||
err = amdb.Select(&allCategories, "SELECT * FROM refcategory ORDER BY parent, name")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, c := range allCategories {
|
||||
categoryIdMap[c.CatId] = &(allCategories[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/* AmGetCategory returns the category for the given name.
|
||||
* Parameters:
|
||||
* catid - The ID of the category to get.
|
||||
* Returns:
|
||||
* Pointer to the appropriate Category, or nil.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmGetCategory(catid int32) (*Category, error) {
|
||||
err := loadCategories()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := categoryIdMap[catid]
|
||||
d := 5
|
||||
for c.SymLink != -1 {
|
||||
d--
|
||||
if d == 0 {
|
||||
return nil, errors.New("symlink resolution error")
|
||||
}
|
||||
c = categoryIdMap[c.SymLink]
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
/* AmGetCategoryHierarchy returns the category hierarchy for the given ID.
|
||||
* Parameters:
|
||||
* catid - The ID of the category to get.
|
||||
* Returns:
|
||||
* Array of pointers to the categories in hierarchical order, or nil.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmGetCategoryHierarchy(catid int32) ([]*Category, error) {
|
||||
err := loadCategories()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// walk all the way to the "root" (parent = -1)
|
||||
p := catid
|
||||
ia := make([]*Category, 0, 3)
|
||||
for p != -1 {
|
||||
c := categoryIdMap[p]
|
||||
for c.SymLink != -1 {
|
||||
c = categoryIdMap[c.SymLink]
|
||||
}
|
||||
ia = append(ia, c)
|
||||
p = c.Parent
|
||||
}
|
||||
// reverse the array for return
|
||||
rc := make([]*Category, 0, len(ia))
|
||||
for i := range ia {
|
||||
rc = append(rc, ia[len(ia)-(i+1)])
|
||||
}
|
||||
return rc, nil
|
||||
}
|
||||
Reference in New Issue
Block a user