partial implementation of community profile page - next, straighten out left menus

This commit is contained in:
2025-10-15 23:20:43 -06:00
parent 0a8f67c676
commit 681b30272d
12 changed files with 915 additions and 8 deletions
+115
View File
@@ -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
}