func (s *SoPostWrap) getModifiedFields(oriTable *SoPost, curTable *SoPost) (map[string]bool, bool, error) {
	if oriTable == nil {
		return nil, false, errors.New("table info is nil, can't get modified fields")
	}
	hasWatcher := false
	fields := make(map[string]bool)
	if !reflect.DeepEqual(oriTable.Author, curTable.Author) {
		fields["Author"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasAuthorWatcher
	}
	if !reflect.DeepEqual(oriTable.Beneficiaries, curTable.Beneficiaries) {
		fields["Beneficiaries"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasBeneficiariesWatcher
	}
	if !reflect.DeepEqual(oriTable.Body, curTable.Body) {
		fields["Body"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasBodyWatcher
	}
	if !reflect.DeepEqual(oriTable.CashoutBlockNum, curTable.CashoutBlockNum) {
		fields["CashoutBlockNum"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasCashoutBlockNumWatcher
	}
	if !reflect.DeepEqual(oriTable.Category, curTable.Category) {
		fields["Category"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasCategoryWatcher
	}
	if !reflect.DeepEqual(oriTable.Children, curTable.Children) {
		fields["Children"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasChildrenWatcher
	}
	if !reflect.DeepEqual(oriTable.Copyright, curTable.Copyright) {
		fields["Copyright"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasCopyrightWatcher
	}
	if !reflect.DeepEqual(oriTable.CopyrightMemo, curTable.CopyrightMemo) {
		fields["CopyrightMemo"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasCopyrightMemoWatcher
	}
	if !reflect.DeepEqual(oriTable.Created, curTable.Created) {
		fields["Created"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasCreatedWatcher
	}
	if !reflect.DeepEqual(oriTable.DappRewards, curTable.DappRewards) {
		fields["DappRewards"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasDappRewardsWatcher
	}
	if !reflect.DeepEqual(oriTable.Depth, curTable.Depth) {
		fields["Depth"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasDepthWatcher
	}
	if !reflect.DeepEqual(oriTable.LastPayout, curTable.LastPayout) {
		fields["LastPayout"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasLastPayoutWatcher
	}
	if !reflect.DeepEqual(oriTable.ParentId, curTable.ParentId) {
		fields["ParentId"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasParentIdWatcher
	}
	if !reflect.DeepEqual(oriTable.Rewards, curTable.Rewards) {
		fields["Rewards"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasRewardsWatcher
	}
	if !reflect.DeepEqual(oriTable.RootId, curTable.RootId) {
		fields["RootId"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasRootIdWatcher
	}
	if !reflect.DeepEqual(oriTable.Tags, curTable.Tags) {
		fields["Tags"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasTagsWatcher
	}
	if !reflect.DeepEqual(oriTable.Ticket, curTable.Ticket) {
		fields["Ticket"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasTicketWatcher
	}
	if !reflect.DeepEqual(oriTable.Title, curTable.Title) {
		fields["Title"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasTitleWatcher
	}
	if !reflect.DeepEqual(oriTable.VoteCnt, curTable.VoteCnt) {
		fields["VoteCnt"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasVoteCntWatcher
	}
	if !reflect.DeepEqual(oriTable.WeightedVp, curTable.WeightedVp) {
		fields["WeightedVp"] = true
		hasWatcher = hasWatcher || s.watcherFlag.HasWeightedVpWatcher
	}
	hasWatcher = hasWatcher || s.watcherFlag.WholeWatcher
	return fields, hasWatcher, nil
}
Get all the modified fields in the table
package table
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"sync"
	"github.com/coschain/contentos-go/common/encoding/kope"
	"github.com/coschain/contentos-go/iservices"
	prototype "github.com/coschain/contentos-go/prototype"
	proto "github.com/golang/protobuf/proto"
)
var (
	PostCreatedTable         uint32 = 3346451556
	PostCashoutBlockNumTable uint32 = 1826021466
	PostRewardsTable         uint32 = 2325142906
	PostPostIdUniTable       uint32 = 157486700
	PostPostIdRow uint32 = 3809844522
)
type SoPostWrap struct {
	dba         iservices.IDatabaseRW
	mainKey     *uint64
	watcherFlag *PostWatcherFlag
	mKeyFlag    int     
	mKeyBuf     []byte  
	mBuf        []byte  
	mdFuncMap   map[string]interface{}
}
func NewSoPostWrap(dba iservices.IDatabaseRW, key *uint64) *SoPostWrap {
	if dba == nil || key == nil {
		return nil
	}
	result := &SoPostWrap{dba, key, nil, -1, nil, nil, nil}
	result.initWatcherFlag()
	return result
}
func (s *SoPostWrap) CheckExist() bool {
	if s.dba == nil {
		return false
	}
	if s.mKeyFlag != -1 {
		if s.mKeyFlag == 0 {
			return false
		}
		return true
	}
	keyBuf, err := s.encodeMainKey()
	if err != nil {
		return false
	}
	res, err := s.dba.Has(keyBuf)
	if err != nil {
		return false
	}
	if res == false {
		s.mKeyFlag = 0
	} else {
		s.mKeyFlag = 1
	}
	return res
}
func (s *SoPostWrap) MustExist(errMsgs ...interface{}) *SoPostWrap {
	if !s.CheckExist() {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.MustExist: %v not found", s.mainKey), errMsgs...))
	}
	return s
}
func (s *SoPostWrap) MustNotExist(errMsgs ...interface{}) *SoPostWrap {
	if s.CheckExist() {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.MustNotExist: %v already exists", s.mainKey), errMsgs...))
	}
	return s
}
func (s *SoPostWrap) initWatcherFlag() {
	if s.watcherFlag == nil {
		s.watcherFlag = new(PostWatcherFlag)
		*(s.watcherFlag) = PostWatcherFlagOfDb(s.dba.ServiceId())
	}
}
func (s *SoPostWrap) create(f func(tInfo *SoPost)) error {
	if s.dba == nil {
		return errors.New("the db is nil")
	}
	if s.mainKey == nil {
		return errors.New("the main key is nil")
	}
	val := &SoPost{}
	f(val)
	if s.CheckExist() {
		return errors.New("the main key is already exist")
	}
	keyBuf, err := s.encodeMainKey()
	if err != nil {
		return err
	}
	buf, err := proto.Marshal(val)
	if err != nil {
		return err
	}
	err = s.dba.Put(keyBuf, buf)
	if err != nil {
		return err
	}
	if err = s.insertAllSortKeys(val); err != nil {
		s.delAllSortKeys(false, val)
		s.dba.Delete(keyBuf)
		return err
	}
	if sucNames, err := s.insertAllUniKeys(val); err != nil {
		s.delAllSortKeys(false, val)
		s.delUniKeysWithNames(sucNames, val)
		s.dba.Delete(keyBuf)
		return err
	}
	s.mKeyFlag = 1
	s.initWatcherFlag()
	if s.watcherFlag.AnyWatcher {
		ReportTableRecordInsert(s.dba.ServiceId(), s.dba.BranchId(), s.mainKey, val)
	}
	return nil
}
func (s *SoPostWrap) Create(f func(tInfo *SoPost), errArgs ...interface{}) *SoPostWrap {
	err := s.create(f)
	if err != nil {
		panic(bindErrorInfo(fmt.Errorf("SoPostWrap.Create failed: %s", err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) getMainKeyBuf() ([]byte, error) {
	if s.mainKey == nil {
		return nil, errors.New("the main key is nil")
	}
	if s.mBuf == nil {
		var err error = nil
		s.mBuf, err = kope.Encode(s.mainKey)
		if err != nil {
			return nil, err
		}
	}
	return s.mBuf, nil
}
func (s *SoPostWrap) modify(f func(tInfo *SoPost)) error {
	if !s.CheckExist() {
		return errors.New("the SoPost table does not exist. Please create a table first")
	}
	oriTable := s.getPost()
	if oriTable == nil {
		return errors.New("fail to get origin table SoPost")
	}
	curTable := s.getPost()
	if curTable == nil {
		return errors.New("fail to create current table SoPost")
	}
	f(curTable)
	if !reflect.DeepEqual(curTable.PostId, oriTable.PostId) {
		return errors.New("primary key does not support modification")
	}
	s.initWatcherFlag()
	modifiedFields, hasWatcher, err := s.getModifiedFields(oriTable, curTable)
	if err != nil {
		return err
	}
	if modifiedFields == nil || len(modifiedFields) < 1 {
		return nil
	}
	err = s.checkSortAndUniFieldValidity(curTable, modifiedFields)
	if err != nil {
		return err
	}
	err = s.handleFieldMd(FieldMdHandleTypeCheck, curTable, modifiedFields)
	if err != nil {
		return err
	}
	err = s.handleFieldMd(FieldMdHandleTypeDel, oriTable, modifiedFields)
	if err != nil {
		return err
	}
	err = s.updatePost(curTable)
	if err != nil {
		return err
	}
	err = s.handleFieldMd(FieldMdHandleTypeInsert, curTable, modifiedFields)
	if err != nil {
		return err
	}
	if hasWatcher {
		ReportTableRecordUpdate(s.dba.ServiceId(), s.dba.BranchId(), s.mainKey, oriTable, curTable, modifiedFields)
	}
	return nil
}
func (s *SoPostWrap) Modify(f func(tInfo *SoPost), errArgs ...interface{}) *SoPostWrap {
	err := s.modify(f)
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.Modify failed: %s", err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetAuthor(p *prototype.AccountName, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Author = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetAuthor( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetBeneficiaries(p []*prototype.BeneficiaryRouteType, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Beneficiaries = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetBeneficiaries( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetBody(p string, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Body = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetBody( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetCashoutBlockNum(p uint64, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.CashoutBlockNum = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetCashoutBlockNum( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetCategory(p string, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Category = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetCategory( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetChildren(p uint32, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Children = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetChildren( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetCopyright(p uint32, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Copyright = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetCopyright( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetCopyrightMemo(p string, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.CopyrightMemo = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetCopyrightMemo( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetCreated(p *prototype.TimePointSec, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Created = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetCreated( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetDappRewards(p *prototype.Vest, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.DappRewards = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetDappRewards( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetDepth(p uint32, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Depth = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetDepth( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetLastPayout(p *prototype.TimePointSec, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.LastPayout = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetLastPayout( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetParentId(p uint64, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.ParentId = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetParentId( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetRewards(p *prototype.Vest, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Rewards = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetRewards( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetRootId(p uint64, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.RootId = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetRootId( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetTags(p []string, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Tags = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetTags( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetTicket(p uint32, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Ticket = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetTicket( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetTitle(p string, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.Title = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetTitle( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetVoteCnt(p uint64, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.VoteCnt = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetVoteCnt( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) SetWeightedVp(p string, errArgs ...interface{}) *SoPostWrap {
	err := s.modify(func(r *SoPost) {
		r.WeightedVp = p
	})
	if err != nil {
		panic(bindErrorInfo(fmt.Sprintf("SoPostWrap.SetWeightedVp( %v ) failed: %s", p, err.Error()), errArgs...))
	}
	return s
}
func (s *SoPostWrap) checkSortAndUniFieldValidity(curTable *SoPost, fields map[string]bool) error {
	if curTable != nil && fields != nil && len(fields) > 0 {
		if fields["Created"] && curTable.Created == nil {
			return errors.New("sort field Created can't be modified to nil")
		}
		if fields["Rewards"] && curTable.Rewards == nil {
			return errors.New("sort field Rewards can't be modified to nil")
		}
	}
	return nil
}