nestedset

package module
v1.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 10, 2023 License: MIT Imports: 10 Imported by: 2

README

Nested Set for Go

build

Nested Set is an implementation of the Nested set model for Gorm.

This project is the Go version of awesome_nested_set, which uses the same data structure design, so it uses the same data together with awesome_nested_set.

Actually the original design is for this, the content managed by awesome_nested_set in our Rails application, the front-end Go API also needs to be maintained.

This is a Go version of the awesome_nested_set, and it built for compatible with awesome_nested_set.

What Go Nested Set can do?

For manage a nested tree node like this:

Showcase

Video taken from BlueDoc, used by awesome_nested_set + react-dnd.

Installation

go get github.com/longbridgeapp/nested-set

Usage

Define the model

You must use nestedset Stuct tag to define your Gorm model like this:

Support struct tags:

  • id - int64 - Primary key of the node
  • parent_id - sql.NullInt64 - ParentID column, null is root
  • lft - int
  • rgt - int
  • depth - int - Depth of the node
  • children_count - Number of children

Optional:

  • scope - restricts what is to be considered a list. You can also setup scope by multiple attributes.

Example:

import (
	"database/sql"
	"github.com/longbridgeapp/nested-set"
)

// Category
type Category struct {
	ID            int64         `gorm:"PRIMARY_KEY;AUTO_INCREMENT" nestedset:"id"`
	ParentID      sql.NullInt64 `nestedset:"parent_id"`
	UserType      string        `nestedset:"scope"`
	UserID        int64         `nestedset:"scope"`
	Rgt           int           `nestedset:"rgt"`
	Lft           int           `nestedset:"lft"`
	Depth         int           `nestedset:"depth"`
	ChildrenCount int           `nestedset:"children_count"`
	Title         string
}
Move Node
import nestedset "github.com/longbridgeapp/nested-set"

// create a new node root level last child
nestedset.Create(tx, &node, nil)

// create a new node as parent first child
nestedset.Create(tx, &node, &parent)

// nestedset.MoveDirectionLeft
// nestedset.MoveDirectionRight
// nestedset.MoveDirectionInner
nestedset.MoveTo(tx, node, to, nestedset.MoveDirectionLeft)
Get Nodes with tree order
// With scope, limit tree in a scope
tx := db.Model(&Category{}).Where("user_type = ? AND user_id = ?", "User", 100)

// Get all nodes
categories, _ := tx.Order("lft asc").Error

// Get root nodes
categories, _ := tx.Where("parent_id IS NULL").Order("lft asc").Error

// Get childrens
categories, _ := tx.Where("parent_id = ?", parentCategory.ID).Order("lft asc").Error

Testing

$ createdb nested-set-test
$ go test ./...
-- some useful sql to check status
SELECT n.id,
CONCAT(REPEAT('. . ', (COUNT(p.id) - 1)::int), n.title) AS t,
n.title, n.lft, n.rgt, n.depth, n.children_count
FROM categories AS n, categories AS p
WHERE (n.lft BETWEEN p.lft AND p.rgt)
GROUP BY n.id ORDER BY n.lft;

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Create

func Create(db *gorm.DB, source, parent interface{}) error

Create a new node within its parent by Gorm original Create() method ```nestedset.Create(db, &Category{...}, nil)``` will create a new category in root level ```nestedset.Create(db, &Category{...}, &parent)``` will create a new category under parent node as its last child

func Delete

func Delete(db *gorm.DB, source interface{}) error

Delete a node from scoped list and its all descendent ```nestedset.Delete(db, &Category{...})```

func MoveTo

func MoveTo(db *gorm.DB, node, to interface{}, direction MoveDirection) error

MoveTo move node to a position which is related a target node ```nestedset.MoveTo(db, &node, &to, nestedset.MoveDirectionInner)``` will move [&node] to [&to] node's child_list as its first child

func Rebuild added in v1.4.0

func Rebuild(db *gorm.DB, source interface{}, doUpdate bool) (affectedCount int, err error)

Rebuild rebuild nodes as any nestedset which in the scope ```nestedset.Rebuild(db, &node, true)``` will rebuild [&node] as nestedset

Types

type MoveDirection

type MoveDirection int

MoveDirection means where the node is going to be located

const (
	// MoveDirectionLeft : MoveTo(db, a, n, MoveDirectionLeft) => a|n|...
	MoveDirectionLeft MoveDirection = -1

	// MoveDirectionRight : MoveTo(db, a, n, MoveDirectionRight) => ...|n|a|
	MoveDirectionRight MoveDirection = 1

	// MoveDirectionInner : MoveTo(db, a, n, MoveDirectionInner) => [n [...|a]]
	MoveDirectionInner MoveDirection = 0
)

MoveDirections ...

type Tree added in v1.4.0

type Tree struct {
	Children []*TreeNode
	// contains filtered or unexported fields
}

type TreeNode added in v1.4.0

type TreeNode struct {
	Children []*TreeNode
	// contains filtered or unexported fields
}

func (TreeNode) IsPositionSame added in v1.5.0

func (item TreeNode) IsPositionSame(original *nestedItem) bool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL