loader

package module
v0.0.7 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2020 License: MIT Imports: 11 Imported by: 0

README

BSON Migrator

For example please see here

Definition

The whole idea is base on a Migrator which will auto call the registered func to complete the transformer progress for need.

package model

type User struct {
	Home                 string
	AddressButNotTHeSame string
	ANotherGender        string
	Age                  int
}

//for global usage latest version for this struct
var UserCurrentVersion = loader.NewVersionPanic("0.3")
//for global usage latest version struct for this struct
type UserCurrent = User_0_3

//v0.1 struct
type User_0_1 struct {
	Home    string
	Address string
	Gender  string
}

//v0.2 struct
type User_0_2 struct {
	Home     string
	XAddress string
	XGender  string
	Age      int
}

//v0.3 struct
type User_0_3 User

}

For auto migration from old version to new version struct with this migrator,you need to create a Registry with loader and transformer.

package model
import loader "github.com/LaysDragon/bson-migrator"

//v0.1 loader
func User_0_3_Loader(src []byte, dst loader.VersionWrapper) error {
	dst.SetData(User_0_3{})//as custom loader,you need to set your data struct into wrapper for it to Unmarshal 

	if err := bson.Unmarshal(src, dst); err != nil {
		return err
	}
	return nil
}

//
func User_0_1_to_0_2_Transformer(container loader.VersionWrapper) error {
	if user_0_1, ok := container.GetData().(User_0_1); ok {
		user_0_2 := User_0_2{
			Home:     user_0_1.Home,
			XAddress: user_0_1.Address,
			XGender:  user_0_1.Address,
			Age:      0,
		}
		container.SetData(user_0_2)
		container.SetVersion(loader.NewVersionPanic("0.2"))
		return nil
	}
	return xerrors.Errorf("Cannot cast %T to %T:%w", container, User_0_1{}, loader.TransformerSrcTypeIncorrectError)

}

func User_0_2_to_0_3_Transformer(container loader.VersionWrapper) error {
	if user_0_2, ok := container.GetData().(User_0_2); ok {
		user_0_3 := User_0_3{
			Home:                 user_0_2.Home + "03version",
			AddressButNotTHeSame: user_0_2.XAddress + "new address format",
			ANotherGender:        user_0_2.XGender + "i am dragon",
			Age:                  user_0_2.Age + 25,
		}
		container.SetData(user_0_3)
		container.SetVersion(loader.NewVersionPanic("0.3"))
		return nil
	}
	return xerrors.Errorf("Cannot cast %T to %T:%w", container, User_0_2{}, loader.TransformerSrcTypeIncorrectError)

}

var UserLoadersRegistry = loader.NewRegistry(
	loader.SLoaders{//Loaders set version with responsible loader func
		"0.1": User_0_1{},//simply give a zero value struct,it will use default loader
   	    "0.2": loader.DefaultLoader(User_0_2{}) ,//same as above
	    "0.1": User_0_3_Loader,//use custom loader
	},
	loader.STransformers{//Transformer set with source version to target version with responsible transformer func
		"0.1": loader.STargetTransformers{
			"0.2": User_0_1_to_0_2_Transformer,
			...
		},
		"0.2": loader.STargetTransformers{
			"0.3": User_0_2_to_0_3_Transformer,
		},
	},
)

Usage

package model

func (s User) MarshalBSON() ([]byte, error) {
	//use versionCapture to wrapper before Marshal can add version inline field into bson data
	return bson.Marshal(loader.VersionCapture{Version: UserCurrentVersion, Data: s})
}

func (s *User) UnmarshalBSON(src []byte) error {
    //use registry Load method,it will load src byte into VersionWrapper with the specified struct you registered
	versionUser, err := UserLoadersRegistry.Load(src, UserCurrentVersion)
	if err != nil {
		return err
	}
    //extract it and cast back to current version
	*s = User(versionUser.GetData().(UserCurrent))
	return nil
}

package main
import "go.mongodb.org/mongo-driver/bson"

func main(){
var bsonByte := ...//from mongodb go driver or something else
user:= User{}
bson.Unmarshal(bsonByte,&user)

}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DynamicVersionWrapperStructs = map[reflect.Type]dynamicstruct.DynamicStruct{}
View Source
var InvalidVersionValue = errors.New("Invalid version value")
View Source
var LoaderNotFoundError = errors.New("cannot found loader handlers for src version")

LoaderNotFoundError while can't found loader for the specified version

View Source
var NoVersionTagError = errors.New("data has no _version field or with invalid 0.0 version")

NoVersionTagError while loaded data not contain any valid _version tag

View Source
var TransformerNotFoundError = errors.New("cannot found next transformer to the target version")

TransformerNotFoundError while can't found Transformer for specified version path transformation progress

View Source
var TransformerSrcTypeIncorrectError = errors.New("src type for transformer is incorrect and failed to cast")

TransformerSrcTypeIncorrectError while Transformer trying to cast interface{} src data into desired version struct and failed

Functions

func AddVersionWrapperType

func AddVersionWrapperType(typeVal interface{}) dynamicstruct.DynamicStruct

func GetVersionWrapperStruct

func GetVersionWrapperStruct(typeVal interface{}) dynamicstruct.DynamicStruct

Types

type AVersionCapture

type AVersionCapture VersionCapture

AVersionCapture use for prevent MarshalBSON loop

type Loader

type Loader func([]byte, VersionWrapper) error

Loader func that responsible for load data for specified Version

func DefaultLoader

func DefaultLoader(typeVal interface{}) Loader

type Registry

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

func NewRegistry

func NewRegistry(loadersL SLoaders, transformersT STransformers) *Registry

NewRegistry Registry the Loaders and Transformers for migration

func (*Registry) Load

func (l *Registry) Load(src []byte, target Version) (VersionWrapper, error)

Load load the bson src bytes into target Version,it will return a Version Container with data

func (*Registry) Transform

func (l *Registry) Transform(data VersionWrapper, target Version) error

Transform transformation the src Data Struct to target Version

type SLoaders

type SLoaders map[string]interface{}

type SLoaders map[string]Loader

func (SLoaders) SrcLoaders

func (l SLoaders) SrcLoaders() SrcLoaders

type STargetTransformers

type STargetTransformers map[string]Transformer

type STransformers

type STransformers map[string]STargetTransformers

func (STransformers) SrcToTargetTransformers

func (t STransformers) SrcToTargetTransformers() SrcToTargetTransformers

type SrcLoaders

type SrcLoaders map[Version]Loader

type SrcToTargetTransformers

type SrcToTargetTransformers map[Version]TargetTransformers

type SrcToTargetVersions

type SrcToTargetVersions map[Version]Versions

type TargetTransformers

type TargetTransformers map[Version]Transformer

type Transformer

type Transformer func(VersionWrapper) error

Transformer func that responsible for transform the data between Versions

type Version

type Version struct {
	MINOR int
	PATCH int
}

func NewVersion

func NewVersion(value string) (Version, error)

func NewVersionPanic

func NewVersionPanic(value string) Version

NewVersionPanic use with no error but panic directly

func (Version) Greater

func (v Version) Greater(anotherVersion Version) bool

Greater operator to compare to another Version,return true if it is greater then another one

func (Version) Less

func (v Version) Less(anotherVersion Version) bool

Less operator to compare to another Version,return true if it is less then another one

func (Version) MarshalBSONValue

func (v Version) MarshalBSONValue() (bsontype.Type, []byte, error)

func (Version) NextMINOR

func (v Version) NextMINOR() Version

func (Version) NextPATCH

func (v Version) NextPATCH() Version

func (Version) String

func (v Version) String() string

func (*Version) UnmarshalBSONValue

func (v *Version) UnmarshalBSONValue(t bsontype.Type, src []byte) error

type VersionCapture

type VersionCapture struct {
	Version Version `bson:"_version"`
	Data    interface{}
}

VersionCapture a Capture for extract the version info from byte data and carry the corresponding version structure data though the progress

func (VersionCapture) GetData

func (v VersionCapture) GetData() interface{}

GetData get Data

func (VersionCapture) GetVersion

func (v VersionCapture) GetVersion() Version

GetVersion get Version

func (VersionCapture) MarshalBSON

func (v VersionCapture) MarshalBSON() ([]byte, error)

MarshalBSON where VersionCapture deal with version and inline Data

func (*VersionCapture) SetData

func (v *VersionCapture) SetData(d interface{})

SetData set Data

func (*VersionCapture) SetVersion

func (v *VersionCapture) SetVersion(vv Version)

SetVersion set Version

func (*VersionCapture) UnmarshalBSON

func (v *VersionCapture) UnmarshalBSON(src []byte) error

UnmarshalBSON where VersionCapture deal with version and inline Data

type VersionWrapper

type VersionWrapper interface {
	GetVersion() Version
	SetVersion(Version)
	GetData() interface{}
	SetData(interface{})
}

VersionWrapper wrapper that contain data and version

type Versions

type Versions []Version

Versions array of Version

func (*Versions) Max

func (vs *Versions) Max() *Version

Max get the Max Version out of array

Directories

Path Synopsis
example
v1
v2
v3

Jump to

Keyboard shortcuts

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