schema.go 2.77 KB
package models

import (
	"pro2d/common/components"
	"pro2d/common/db/mongoproxy"
	"pro2d/common/logger"
	"reflect"
	"strings"
)

type SchemaOption func(schema *Schema)

func WithSchemaDB(idb components.IDB) SchemaOption {
	return func(schema *Schema) {
		schema.db = idb
	}
}

type SchemaMap map[string]components.ISchema

type Schema struct {
	db           components.IDB
	reflectValue *reflect.Value
	reflectType  reflect.Type

	cacheFields map[string]interface{}

	pri    interface{}
	schema interface{}
}

func NewSchema(key string, schema interface{}) *Schema {
	s := reflect.ValueOf(schema)
	if s.Kind() == reflect.Ptr {
		s = reflect.ValueOf(schema).Elem()
	}
	sch := &Schema{
		reflectValue: &s,
		reflectType:  s.Type(),
		cacheFields:  make(map[string]interface{}),
		schema:       schema,
	}

	sch.db = mongoproxy.NewMongoColl(sch.GetSchemaName(), sch)
	sch.pri = mongoproxy.GetBsonD(sch.getPriTag(), key)
	return sch
}

func (s *Schema) FindIndex() (string, []string) {
	var index []string
	for i := 0; i < s.reflectType.NumField(); i++ {
		if s.reflectType.Field(i).Tag.Get("index") != "" {
			js := strings.Split(s.reflectType.Field(i).Tag.Get("json"), ",")
			if len(js) == 0 {
				continue
			}
			index = append(index, js[0])
		}
	}
	return strings.ToLower(s.reflectType.Name()), index
}

func (s *Schema) Init() {
	coll, keys := s.FindIndex()
	for _, index := range keys {
		s.db.CreateTable()

		logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index)
		res, err := s.db.SetUnique(index)
		if err != nil {
			logger.Error("InitDoc unique: %s, err: %v", res, err)
			continue
		}
	}
}

func (s *Schema) GetDB() components.IDB {
	return s.db
}

func (s *Schema) GetPri() interface{} {
	return s.pri
}

func (s *Schema) GetSchema() interface{} {
	return s.schema
}

func (s *Schema) GetSchemaName() string {
	return strings.ToLower(s.reflectType.Name())
}

func (s *Schema) Load() error {
	return s.db.Load()
}

func (s *Schema) Create() error {
	_, err := s.db.Create()
	return err
}

func (s *Schema) Save() error {
	return s.db.Save()
}

func (s *Schema) Update() {
	if s.cacheFields != nil {
		s.db.UpdateProperties(s.cacheFields)
		s.cacheFields = make(map[string]interface{})
	}
}

func (s *Schema) SetProperty(key string, val interface{}) {
	s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val))
	s.cacheFields[strings.ToLower(key)] = val
}

func (s *Schema) SetProperties(properties map[string]interface{}) {
	for key, val := range properties {
		s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val))
		s.cacheFields[strings.ToLower(key)] = val
	}
}

func (s *Schema) getPriTag() string {
	var pri string
	for i := 0; i < s.reflectType.NumField(); i++ {
		if s.reflectType.Field(i).Tag.Get("pri") == "1" {
			pri = strings.ToLower(s.reflectType.Field(i).Name)
			break
		}
	}
	return pri
}