func (d *model) Update(v interface{}) error {
	return d.Create(v)
}
TODO: implement the full functionality. Currently offloads to create.
package model
import (
	"context"
	"encoding/base32"
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"reflect"
	"strings"
	"unicode/utf8"
	"github.com/micro/micro/v3/service/auth"
	"github.com/micro/micro/v3/service/store"
	"github.com/stoewer/go-strcase"
)
type model struct {
	database string
	table string
	idIndex Index
	namespace string
	indexes []Index
	options *Options
	instance interface{}
}
func NewModel(opts ...Option) Model {
	var options Options
	for _, o := range opts {
		o(&options)
	}
	if options.Store == nil {
		options.Store = store.DefaultStore
	}
	if len(options.Indexes) == 0 {
		options.Indexes = append(options.Indexes, DefaultIndex)
	}
	return New(nil, &options)
}
func New(instance interface{}, options *Options) Model {
	if options == nil {
		options = new(Options)
	}
	if reflect.ValueOf(instance).Kind() == reflect.Ptr {
		instance = reflect.Indirect(reflect.ValueOf(instance)).Interface()
	}
	var namespace, database, table string
	if instance != nil {
		namespace = reflect.TypeOf(instance).String()
	}
	if len(options.Namespace) > 0 {
		namespace = options.Namespace
	}
	if options.Store == nil {
		options.Store = store.DefaultStore
	}
	if options.Context == nil {
		options.Context = context.TODO()
	}
	if options.Key == "" {
		var err error
		options.Key, err = getKey(instance)
		if err != nil {
			options.Key = err.Error()
		}
	}
	idx := DefaultIndex
	if len(options.Key) > 0 {
		idx = newIndex(options.Key)
	}
	database = options.Database
	table = options.Table
	if len(database) == 0 && options.Store != nil {
		database = options.Store.Options().Database
	}
	if len(table) == 0 && options.Store != nil {
		table = options.Store.Options().Table
	}
	return &model{
		database:  database,
		table:     table,
		idIndex:   idx,
		instance:  instance,
		namespace: namespace,
		options:   options,
	}
}
func getKey(instance interface{}) (string, error) {
	if instance == nil {
		return "", nil
	}
	idFields := []string{"ID", "Id", "id"}
	switch v := instance.(type) {
	case map[string]interface{}:
		for _, idField := range idFields {
			if _, ok := v[idField]; ok {
				return idField, nil
			}
		}
		return "ID", nil
	default:
		val := reflect.ValueOf(instance)
		for _, idField := range idFields {
			if val.FieldByName(idField).IsValid() {
				return idField, nil
			}
		}
	}
	return "", errors.New("ID Field not found")
}
func (d *model) getFieldName(field string) string {
	fieldName := ""
	if strings.Contains(field, "_") {
		fieldName = strcase.UpperCamelCase(field)
	} else {
		fieldName = strings.Title(field)
	}
	if fieldName == "ID" {
		return d.options.Key
	}
	return fieldName
}
func (d *model) getFieldValue(struc interface{}, fieldName string) interface{} {
	switch v := struc.(type) {
	case map[string]interface{}:
		return v[fieldName]
	}
	fieldName = d.getFieldName(fieldName)
	r := reflect.ValueOf(struc)
	f := reflect.Indirect(r).FieldByName(fieldName)
	if !f.IsValid() {
		return nil
	}
	return f.Interface()
}
func (d *model) setFieldValue(struc interface{}, fieldName string, value interface{}) {
	switch v := struc.(type) {
	case map[string]interface{}:
		v[fieldName] = value
		return
	}
	fieldName = d.getFieldName(fieldName)
	r := reflect.ValueOf(struc)
	f := reflect.Indirect(r).FieldByName(fieldName)
	f.Set(reflect.ValueOf(value))
}
func (d *model) Context(ctx context.Context) Model {
	opts := *d.options
	opts.Context = ctx
	acc, ok := auth.AccountFromContext(ctx)
	if ok {
		if len(acc.Issuer) > 0 {
			opts.Database = acc.Issuer
		}
	}
	return &model{
		database:  opts.Database,
		table:     opts.Table,
		idIndex:   d.idIndex,
		instance:  d.instance,
		namespace: d.namespace,
		options:   &opts,
	}
}
func (d *model) Register(instance interface{}) error {
	if instance == nil {
		return ErrorNilInterface
	}
	if reflect.ValueOf(instance).Kind() == reflect.Ptr {
		instance = reflect.Indirect(reflect.ValueOf(instance)).Interface()
	}
	if d.options.Key == "" {
		var err error
		d.options.Key, err = getKey(instance)
		if err != nil {
			return err
		}
	}
	d.namespace = reflect.TypeOf(instance).String()
	d.instance = instance
	return nil
}
func (d *model) Create(instance interface{}) error {
	if reflect.ValueOf(instance).Kind() == reflect.Ptr {
		instance = reflect.Indirect(reflect.ValueOf(instance)).Interface()
	}
	js, err := json.Marshal(instance)
	if err != nil {
		return err
	}
	idQuery := d.idIndex.ToQuery(d.getFieldValue(instance, d.idIndex.FieldName))
	var oldEntry interface{}
	switch instance.(type) {
	case map[string]interface{}:
		oldEntry = map[string]interface{}{}
	default:
		oldEntry = reflect.New(reflect.ValueOf(instance).Type()).Interface()
	}
	err = d.Read(idQuery, &oldEntry)
	if err != nil && err != ErrorNotFound {
		return err
	}
	oldEntryFound := false
	switch v := oldEntry.(type) {
	case map[string]interface{}:
		if len(v) > 0 {
			oldEntryFound = true
		}
	default:
		if oldEntry != nil {
			oldEntryFound = true
		}
	}
	for _, index := range d.options.Indexes {
		if !index.Unique {
			continue
		}
		potentialClash := reflect.New(reflect.ValueOf(instance).Type()).Interface()
		err = d.Read(index.ToQuery(d.getFieldValue(instance, index.FieldName)), &potentialClash)
		if err != nil && err != ErrorNotFound {
			return err
		}
		if err == nil {
			return errors.New("Unique index violation")
		}
	}
	id := d.getFieldValue(instance, d.idIndex.FieldName)
	for _, index := range append(d.options.Indexes, d.idIndex) {
		if !indexesMatch(d.idIndex, index) &&
			oldEntryFound &&
			!reflect.DeepEqual(d.getFieldValue(oldEntry, index.FieldName), d.getFieldValue(instance, index.FieldName)) {
			k := d.indexToKey(index, id, oldEntry, true)
			err = d.options.Store.Delete(k, store.DeleteFrom(d.database, d.table))
			if err != nil {
				return err
			}
		}
		k := d.indexToKey(index, id, instance, true)
		if d.options.Debug {
			fmt.Printf("Saving key '%v', value: '%v'\n", k, string(js))
		}
		err = d.options.Store.Write(&store.Record{
			Key:   k,
			Value: js,
		}, store.WriteTo(d.database, d.table))
		if err != nil {
			return err
		}
	}
	return nil
}