mirror of
https://github.com/asdine/storm.git
synced 2025-10-06 23:32:51 +08:00
Extracing increment tag
This commit is contained in:
4
all.go
4
all.go
@@ -53,12 +53,12 @@ func (n *node) allByIndex(tx *bolt.Tx, fieldName string, cfg *structConfig, ref
|
|||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
idxInfo, ok := cfg.Fields[fieldName]
|
fieldCfg, ok := cfg.Fields[fieldName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
idx, err := getIndex(bucket, idxInfo.Type, fieldName)
|
idx, err := getIndex(bucket, fieldCfg.Index, fieldName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -36,8 +36,12 @@ func (n *node) deleteStruct(tx *bolt.Tx, cfg *structConfig, id []byte) error {
|
|||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
for fieldName, idxInfo := range cfg.Fields {
|
for fieldName, fieldCfg := range cfg.Fields {
|
||||||
idx, err := getIndex(bucket, idxInfo.Type, fieldName)
|
if fieldCfg.Index == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
idx, err := getIndex(bucket, fieldCfg.Index, fieldName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
25
extract.go
25
extract.go
@@ -14,12 +14,13 @@ const (
|
|||||||
tagIdx = "index"
|
tagIdx = "index"
|
||||||
tagUniqueIdx = "unique"
|
tagUniqueIdx = "unique"
|
||||||
tagInline = "inline"
|
tagInline = "inline"
|
||||||
|
tagIncrement = "increment"
|
||||||
indexPrefix = "__storm_index_"
|
indexPrefix = "__storm_index_"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fieldConfig struct {
|
type fieldConfig struct {
|
||||||
Name string
|
Name string
|
||||||
Type string
|
Index string
|
||||||
IsZero bool
|
IsZero bool
|
||||||
IsID bool
|
IsID bool
|
||||||
Increment bool
|
Increment bool
|
||||||
@@ -34,18 +35,6 @@ type structConfig struct {
|
|||||||
ID *fieldConfig
|
ID *fieldConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper
|
|
||||||
func (m *structConfig) AllByType(indexType string) []*fieldConfig {
|
|
||||||
var idx []*fieldConfig
|
|
||||||
for k := range m.Fields {
|
|
||||||
if m.Fields[k].Type == indexType {
|
|
||||||
idx = append(idx, m.Fields[k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
|
|
||||||
func extract(s *reflect.Value, mi ...*structConfig) (*structConfig, error) {
|
func extract(s *reflect.Value, mi ...*structConfig) (*structConfig, error) {
|
||||||
if s.Kind() == reflect.Ptr {
|
if s.Kind() == reflect.Ptr {
|
||||||
e := s.Elem()
|
e := s.Elem()
|
||||||
@@ -130,7 +119,9 @@ func extractField(value *reflect.Value, field *reflect.StructField, m *structCon
|
|||||||
case "id":
|
case "id":
|
||||||
f.IsID = true
|
f.IsID = true
|
||||||
case tagUniqueIdx, tagIdx:
|
case tagUniqueIdx, tagIdx:
|
||||||
f.Type = tag
|
f.Index = tag
|
||||||
|
case tagIncrement:
|
||||||
|
f.Increment = true
|
||||||
case tagInline:
|
case tagInline:
|
||||||
if value.Kind() == reflect.Ptr {
|
if value.Kind() == reflect.Ptr {
|
||||||
e := value.Elem()
|
e := value.Elem()
|
||||||
@@ -150,10 +141,8 @@ func extractField(value *reflect.Value, field *reflect.StructField, m *structCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Type != "" {
|
if _, ok := m.Fields[f.Name]; !ok || !isChild {
|
||||||
if _, ok := m.Fields[f.Name]; !ok || !isChild {
|
m.Fields[f.Name] = f
|
||||||
m.Fields[f.Name] = f
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,17 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func allByType(m *structConfig, indexType string) []*fieldConfig {
|
||||||
|
var idx []*fieldConfig
|
||||||
|
for k := range m.Fields {
|
||||||
|
if m.Fields[k].Index == indexType {
|
||||||
|
idx = append(idx, m.Fields[k])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
|
||||||
func TestExtractNoTags(t *testing.T) {
|
func TestExtractNoTags(t *testing.T) {
|
||||||
s := ClassicNoTags{}
|
s := ClassicNoTags{}
|
||||||
r := reflect.ValueOf(&s)
|
r := reflect.ValueOf(&s)
|
||||||
@@ -33,8 +44,8 @@ func TestExtractUniqueTags(t *testing.T) {
|
|||||||
assert.NotNil(t, infos.ID)
|
assert.NotNil(t, infos.ID)
|
||||||
assert.False(t, infos.ID.IsZero)
|
assert.False(t, infos.ID.IsZero)
|
||||||
assert.Equal(t, "ClassicUnique", infos.Name)
|
assert.Equal(t, "ClassicUnique", infos.Name)
|
||||||
assert.Len(t, infos.AllByType("index"), 0)
|
assert.Len(t, allByType(infos, "index"), 0)
|
||||||
assert.Len(t, infos.AllByType("unique"), 4)
|
assert.Len(t, allByType(infos, "unique"), 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractIndexTags(t *testing.T) {
|
func TestExtractIndexTags(t *testing.T) {
|
||||||
@@ -46,8 +57,8 @@ func TestExtractIndexTags(t *testing.T) {
|
|||||||
assert.NotNil(t, infos.ID)
|
assert.NotNil(t, infos.ID)
|
||||||
assert.False(t, infos.ID.IsZero)
|
assert.False(t, infos.ID.IsZero)
|
||||||
assert.Equal(t, "ClassicIndex", infos.Name)
|
assert.Equal(t, "ClassicIndex", infos.Name)
|
||||||
assert.Len(t, infos.AllByType("index"), 5)
|
assert.Len(t, allByType(infos, "index"), 5)
|
||||||
assert.Len(t, infos.AllByType("unique"), 0)
|
assert.Len(t, allByType(infos, "unique"), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractInlineWithIndex(t *testing.T) {
|
func TestExtractInlineWithIndex(t *testing.T) {
|
||||||
@@ -58,6 +69,6 @@ func TestExtractInlineWithIndex(t *testing.T) {
|
|||||||
assert.NotNil(t, infos)
|
assert.NotNil(t, infos)
|
||||||
assert.NotNil(t, infos.ID)
|
assert.NotNil(t, infos.ID)
|
||||||
assert.Equal(t, "ClassicInline", infos.Name)
|
assert.Equal(t, "ClassicInline", infos.Name)
|
||||||
assert.Len(t, infos.AllByType("index"), 3)
|
assert.Len(t, allByType(infos, "index"), 3)
|
||||||
assert.Len(t, infos.AllByType("unique"), 2)
|
assert.Len(t, allByType(infos, "unique"), 2)
|
||||||
}
|
}
|
||||||
|
7
init.go
7
init.go
@@ -32,8 +32,11 @@ func (n *node) init(tx *bolt.Tx, cfg *structConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for fieldName, idxInfo := range cfg.Fields {
|
for fieldName, fieldCfg := range cfg.Fields {
|
||||||
switch idxInfo.Type {
|
if fieldCfg.Index == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch fieldCfg.Index {
|
||||||
case tagUniqueIdx:
|
case tagUniqueIdx:
|
||||||
_, err = index.NewUniqueIndex(bucket, []byte(indexPrefix+fieldName))
|
_, err = index.NewUniqueIndex(bucket, []byte(indexPrefix+fieldName))
|
||||||
case tagIdx:
|
case tagIdx:
|
||||||
|
9
one.go
9
one.go
@@ -3,6 +3,7 @@ package storm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/asdine/storm/index"
|
"github.com/asdine/storm/index"
|
||||||
"github.com/asdine/storm/q"
|
"github.com/asdine/storm/q"
|
||||||
@@ -56,8 +57,14 @@ func (n *node) One(fieldName string, value interface{}, to interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isID bool
|
||||||
|
if tag != "" {
|
||||||
|
tags := strings.Split(tag, ",")
|
||||||
|
isID = tags[0] == ""
|
||||||
|
}
|
||||||
|
|
||||||
return n.readTx(func(tx *bolt.Tx) error {
|
return n.readTx(func(tx *bolt.Tx) error {
|
||||||
return n.one(tx, bucketName, fieldName, tag, to, val, fieldName == "ID" || tag == "id")
|
return n.one(tx, bucketName, fieldName, tag, to, val, fieldName == "ID" || isID)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
save.go
12
save.go
@@ -81,13 +81,17 @@ func (n *node) save(tx *bolt.Tx, cfg *structConfig, id []byte, raw []byte, data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for fieldName, idxInfo := range cfg.Fields {
|
for fieldName, fieldCfg := range cfg.Fields {
|
||||||
idx, err := getIndex(bucket, idxInfo.Type, fieldName)
|
if fieldCfg.Index == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
idx, err := getIndex(bucket, fieldCfg.Index, fieldName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if idxInfo.IsZero {
|
if fieldCfg.IsZero {
|
||||||
err = idx.RemoveID(id)
|
err = idx.RemoveID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -95,7 +99,7 @@ func (n *node) save(tx *bolt.Tx, cfg *structConfig, id []byte, raw []byte, data
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
value, err := toBytes(idxInfo.Value.Interface(), n.s.codec)
|
value, err := toBytes(fieldCfg.Value.Interface(), n.s.codec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
7
sink.go
7
sink.go
@@ -235,8 +235,11 @@ func (d *deleteSink) add(bucket *bolt.Bucket, k []byte, v []byte, elem reflect.V
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for fieldName, idxInfo := range info.Fields {
|
for fieldName, fieldCfg := range info.Fields {
|
||||||
idx, err := getIndex(bucket, idxInfo.Type, fieldName)
|
if fieldCfg.Index == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
idx, err := getIndex(bucket, fieldCfg.Index, fieldName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user