transition

package module
v0.0.0-...-dcb8759 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2020 License: MIT Imports: 7 Imported by: 61

README

Transition

Transition is a Golang state machine implementation.

it can be used standalone, but it integrates nicely with GORM models. When integrated with GORM, it will also store state change logs in the database automatically.

GoDoc Build Status

Usage

Enable Transition for your struct

Embed transition.Transition into your struct, it will enable the state machine feature for the struct:

import "github.com/qor/transition"

type Order struct {
  ID uint
  transition.Transition
}
Define States and Events
var OrderStateMachine = transition.New(&Order{})

// Define initial state
OrderStateMachine.Initial("draft")

// Define a State
OrderStateMachine.State("checkout")

// Define another State and what to do when entering and exiting that state.
OrderStateMachine.State("paid").Enter(func(order interface{}, tx *gorm.DB) error {
  // To get order object use 'order.(*Order)'
  // business logic here
  return
}).Exit(func(order interface{}, tx *gorm.DB) error {
  // business logic here
  return
})

// Define more States
OrderStateMachine.State("cancelled")
OrderStateMachine.State("paid_cancelled")


// Define an Event
OrderStateMachine.Event("checkout").To("checkout").From("draft")

// Define another event and what to do before and after performing the transition.
OrderStateMachine.Event("paid").To("paid").From("checkout").Before(func(order interface{}, tx *gorm.DB) error {
  // business logic here
  return nil
}).After(func(order interface{}, tx *gorm.DB) error {
  // business logic here
  return nil
})

// Different state transitions for one event
cancellEvent := OrderStateMachine.Event("cancel")
cancellEvent.To("cancelled").From("draft", "checkout")
cancellEvent.To("paid_cancelled").From("paid").After(func(order interface{}, tx *gorm.DB) error {
  // Refund
}})
Trigger an Event
// func (*StateMachine) Trigger(name string, value Stater, tx *gorm.DB, notes ...string) error
OrderStatemachine.Trigger("paid", &order, db, "charged offline by jinzhu")
// notes will be used to generate state change logs when works with GORM

// When using without GORM, just pass nil to the db, like
OrderStatemachine.Trigger("cancel", &order, nil)

OrderStatemachine.Trigger("cancel", &order, db)
// order's state will be changed to cancelled if current state is "draft"
// order's state will be changed to paid_cancelled if current state is "paid"
Get/Set State
var order Order

// Get Current State
order.GetState()

// Set State
order.SetState("finished") // this will only update order's state, won't save it into database

State change logs

When working with GORM, Transition will store all state change logs in the database. Use GetStateChangeLogs to get those logs.

// create the table used to store logs first
db.AutoMigrate(&transition.StateChangeLog{})

// get order's state change logs
var stateChangeLogs = transition.GetStateChangeLogs(&order, db)

// type StateChangeLog struct {
//   From       string  // from state
//   To         string  // to state
//   Note       string  // notes
// }

License

Released under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateReferenceKey

func GenerateReferenceKey(model interface{}, db *gorm.DB) string

GenerateReferenceKey generate reference key used for change log

Types

type Event

type Event struct {
	Name string
	// contains filtered or unexported fields
}

Event contains Event information, including transition hooks

func (*Event) To

func (event *Event) To(name string) *EventTransition

To define EventTransition of go to a state

type EventTransition

type EventTransition struct {
	// contains filtered or unexported fields
}

EventTransition hold event's to/froms states, also including befores, afters hooks

func (*EventTransition) After

func (transition *EventTransition) After(fc func(value interface{}, tx *gorm.DB) error) *EventTransition

After register after hooks

func (*EventTransition) Before

func (transition *EventTransition) Before(fc func(value interface{}, tx *gorm.DB) error) *EventTransition

Before register before hooks

func (*EventTransition) From

func (transition *EventTransition) From(states ...string) *EventTransition

From used to define from states

type State

type State struct {
	Name string
	// contains filtered or unexported fields
}

State contains State information, including enter, exit hooks

func (*State) Enter

func (state *State) Enter(fc func(value interface{}, tx *gorm.DB) error) *State

Enter register an enter hook for State

func (*State) Exit

func (state *State) Exit(fc func(value interface{}, tx *gorm.DB) error) *State

Exit register an exit hook for State

type StateChangeLog

type StateChangeLog struct {
	gorm.Model
	ReferTable string
	ReferID    string
	From       string
	To         string
	Note       string `sql:"size:1024"`
	audited.AuditedModel
}

StateChangeLog a model that used to keep state change logs

func GetLastStateChange

func GetLastStateChange(model interface{}, db *gorm.DB) *StateChangeLog

GetLastStateChange gets last state change

func GetStateChangeLogs

func GetStateChangeLogs(model interface{}, db *gorm.DB) []StateChangeLog

GetStateChangeLogs get state change logs

func (*StateChangeLog) ConfigureQorResource

func (stageChangeLog *StateChangeLog) ConfigureQorResource(res resource.Resourcer)

ConfigureQorResource used to configure transition for qor admin

type StateMachine

type StateMachine struct {
	// contains filtered or unexported fields
}

StateMachine a struct that hold states, events definitions

func New

func New(value interface{}) *StateMachine

New initialize a new StateMachine that hold states, events definitions

func (*StateMachine) Event

func (sm *StateMachine) Event(name string) *Event

Event define an event

func (*StateMachine) Initial

func (sm *StateMachine) Initial(name string) *StateMachine

Initial define the initial state

func (*StateMachine) State

func (sm *StateMachine) State(name string) *State

State define a state

func (*StateMachine) Trigger

func (sm *StateMachine) Trigger(name string, value Stater, tx *gorm.DB, notes ...string) error

Trigger trigger an event

type Stater

type Stater interface {
	SetState(name string)
	GetState() string
}

Stater is a interface including methods `GetState`, `SetState`

type Transition

type Transition struct {
	State           string
	StateChangeLogs []StateChangeLog `sql:"-"`
}

Transition is a struct, embed it in your struct to enable state machine for the struct

func (*Transition) ConfigureQorResource

func (transition *Transition) ConfigureQorResource(res resource.Resourcer)

ConfigureQorResource used to configure transition for qor admin

func (Transition) GetState

func (transition Transition) GetState() string

GetState get current state from

func (*Transition) SetState

func (transition *Transition) SetState(name string)

SetState set state to Stater, just set, won't save it into database

Jump to

Keyboard shortcuts

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