2015-05-12 05:06:28 +00:00
package categories
import (
2015-09-13 21:57:22 +00:00
"database/sql"
"errors"
2015-05-12 05:06:28 +00:00
"fmt"
2015-09-13 21:57:22 +00:00
_ "github.com/lib/pq"
2015-05-12 15:32:47 +00:00
"strings"
2015-05-12 05:06:28 +00:00
)
type Category struct {
2015-09-13 21:57:22 +00:00
Id int
Name string
Parent sql . NullInt64
Children [ ] * Category
2015-05-12 05:06:28 +00:00
}
var CategoriesTree [ ] * Category
var CategoriesFlat map [ int ] * Category
2015-09-13 21:57:22 +00:00
// Cavet: slight cheat. All parents must have Category_id < their children.
2015-05-12 05:06:28 +00:00
func LoadCategories ( db * sql . DB ) {
2015-09-13 21:57:22 +00:00
CategoriesTree = [ ] * Category { }
CategoriesFlat = make ( map [ int ] * Category )
rows , err := db . Query ( "select categories.id, categories.name, categories.parent_id from categories order by coalesce(parent_id, id), parent_id is not null" )
if err != nil {
fmt . Println ( "DB Error loading Categories:" , err )
return
}
defer rows . Close ( )
2015-05-12 05:06:28 +00:00
for rows . Next ( ) {
category := & Category { Children : [ ] * Category { } }
err = rows . Scan ( & category . Id , & category . Name , & category . Parent )
if err != nil {
fmt . Println ( "Categories DB Error: " , err )
}
2015-05-19 15:32:35 +00:00
2015-05-12 05:06:28 +00:00
CategoriesFlat [ category . Id ] = category
2015-09-13 21:57:22 +00:00
2015-05-12 05:06:28 +00:00
if category . Parent . Valid {
2015-09-13 21:57:22 +00:00
pid := int ( category . Parent . Int64 )
CategoriesFlat [ pid ] . Children = append ( CategoriesFlat [ pid ] . Children , category )
2015-05-12 05:06:28 +00:00
} else {
2015-09-13 21:57:22 +00:00
CategoriesTree = append ( CategoriesTree , category )
}
2015-05-12 05:06:28 +00:00
}
2015-05-12 15:32:47 +00:00
}
2015-07-08 05:49:11 +00:00
func Add ( db * sql . DB , name string , parent int ) error {
var err error
if parent < 0 {
2015-07-09 03:30:47 +00:00
_ , err = db . Exec ( "INSERT INTO categories (name) VALUES ($1)" , name )
2015-07-08 05:49:11 +00:00
} else {
2015-07-09 03:30:47 +00:00
_ , err = db . Exec ( "INSERT INTO categories (name, parent_id) VALUES ($1, $2)" , name , parent )
2015-07-08 05:49:11 +00:00
}
if err != nil {
2015-09-13 21:57:22 +00:00
fmt . Println ( "Categories DB Error Add(): " , err )
2015-07-08 05:49:11 +00:00
}
return err
}
2015-07-09 14:31:54 +00:00
// Get parent id
// Set parent of children to parent
// set category of news to parent
// finallly delete
2015-07-09 04:44:55 +00:00
func Delete ( db * sql . DB , id int ) error {
2015-09-13 21:57:22 +00:00
rows , err := db . Query ( "SELECT parent_id FROM categories WHERE id=$1" , id )
if err != nil {
fmt . Println ( "Categories DB Error loading category parent id: " , err )
return err
}
if ! rows . Next ( ) {
fmt . Println ( "Categories DB Error loading category parent id: no category" )
return errors . New ( "No category" )
}
2015-07-09 14:31:54 +00:00
var parent_id sql . NullInt64
err = rows . Scan ( & parent_id )
2015-09-13 21:57:22 +00:00
_ , err = db . Exec ( "UPDATE categories SET parent_id =$2 WHERE parent_id=$1" , id , parent_id )
if err != nil {
fmt . Println ( "Categories DB error changing child parent: " , err )
return err
}
_ , err = db . Exec ( "UPDATE news SET category_id =$2 WHERE category_id=$1" , id , parent_id )
if err != nil {
fmt . Println ( "Categories DB error changing category of news: " , err )
return err
}
_ , err = db . Exec ( "DELETE FROM categories WHERE id=$1" , id )
if err != nil {
fmt . Println ( "Categories DB Error Delete(): " , err )
}
return err
2015-07-09 04:44:55 +00:00
}
2015-06-21 18:42:05 +00:00
func ( category * Category ) ChangeParent ( db * sql . DB , parent * Category ) error {
2015-09-13 21:57:22 +00:00
var err error
if parent == nil {
_ , err = db . Exec ( "UPDATE categories SET parent_id = NULL WHERE id = $1" , category . Id )
} else {
_ , err = db . Exec ( "UPDATE categories SET parent_id = $2 WHERE id = $1" , category . Id , parent . Id )
}
if err != nil {
fmt . Println ( "Categories DB Error: " , err )
}
return err
2015-06-21 18:42:05 +00:00
}
2015-05-12 15:32:47 +00:00
// get the number of parents a category has
func ( category * Category ) Depth ( ) int {
2015-09-13 21:57:22 +00:00
depth := 0
current := category
for current . Parent . Valid {
current = CategoriesFlat [ int ( current . Parent . Int64 ) ]
depth ++
}
return depth
2015-05-12 15:32:47 +00:00
}
2015-05-22 01:34:14 +00:00
// Helper function for templates (add form select list)
2015-05-12 15:32:47 +00:00
func ( category * Category ) ToString ( ) string {
2015-09-13 21:57:22 +00:00
return strings . Repeat ( "- " , category . Depth ( ) ) + category . Name
}