mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
173 lines
4.8 KiB
Go
173 lines
4.8 KiB
Go
// Copyright 2013 Matthew Baird
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package elastigo
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
type Mapping map[string]MappingOptions
|
|
|
|
type MappingOptions struct {
|
|
Id IdOptions `json:"_id"`
|
|
Timestamp TimestampOptions `json:"_timestamp"`
|
|
Analyzer *AnalyzerOptions `json:"_analyzer,omitempty"`
|
|
Parent *ParentOptions `json:"_parent,omitempty"`
|
|
Routing *RoutingOptions `json:"_routing,omitempty"`
|
|
Size *SizeOptions `json:"_size,omitempty"`
|
|
Source *SourceOptions `json:"_source,omitempty"`
|
|
TTL *TTLOptions `json:"_ttl,omitempty"`
|
|
Type *TypeOptions `json:"_type,omitempty"`
|
|
Properties map[string]interface{} `json:"properties"`
|
|
DynamicTemplates []map[string]interface{} `json:"dynamic_templates,omitempty"`
|
|
}
|
|
|
|
type TimestampOptions struct {
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
type AnalyzerOptions struct {
|
|
Path string `json:"path,omitempty"`
|
|
Index string `json:"index,omitempty"`
|
|
}
|
|
|
|
type ParentOptions struct {
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
type RoutingOptions struct {
|
|
Required bool `json:"required,omitempty"`
|
|
Path string `json:"path,omitempty"`
|
|
}
|
|
|
|
type SizeOptions struct {
|
|
Enabled bool `json:"enabled,omitempty"`
|
|
Store bool `json:"store,omitempty"`
|
|
}
|
|
|
|
type SourceOptions struct {
|
|
Enabled bool `json:"enabled,omitempty"`
|
|
Includes []string `json:"includes,omitempty"`
|
|
Excludes []string `json:"excludes,omitempty"`
|
|
}
|
|
|
|
type TypeOptions struct {
|
|
Store bool `json:"store,omitempty"`
|
|
Index string `json:"index,omitempty"`
|
|
}
|
|
|
|
type TTLOptions struct {
|
|
Enabled bool `json:"enabled"`
|
|
Default string `json:"default,omitempty"`
|
|
}
|
|
|
|
type IdOptions struct {
|
|
Index string `json:"index,omitempty"`
|
|
Path string `json:"path,omitempty"`
|
|
}
|
|
|
|
func (m_ Mapping) Options() MappingOptions {
|
|
m := map[string]MappingOptions(m_)
|
|
for _, v := range m {
|
|
return v
|
|
}
|
|
panic(fmt.Errorf("Malformed input: %v", m_))
|
|
}
|
|
|
|
func MappingForType(typeName string, opts MappingOptions) Mapping {
|
|
return map[string]MappingOptions{typeName: opts}
|
|
}
|
|
|
|
func (c *Conn) PutMapping(index string, typeName string, instance interface{}, opt MappingOptions) error {
|
|
instanceType := reflect.TypeOf(instance)
|
|
if instanceType.Kind() != reflect.Struct {
|
|
return fmt.Errorf("instance kind was not struct")
|
|
}
|
|
|
|
if opt.Properties == nil {
|
|
opt.Properties = make(map[string]interface{})
|
|
}
|
|
getProperties(instanceType, opt.Properties)
|
|
body, err := json.Marshal(MappingForType(typeName, opt))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = c.DoCommand("PUT", fmt.Sprintf("/%s/%s/_mapping", index, typeName), nil, string(body))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//Same as PutMapping, but takes a []byte for mapping and provides no check of structure
|
|
func (c *Conn) PutMappingFromJSON(index string, typeName string, mapping []byte) error {
|
|
_, err := c.DoCommand("PUT", fmt.Sprintf("/%s/%s/_mapping", index, typeName), nil, string(mapping))
|
|
return err
|
|
}
|
|
|
|
func getProperties(t reflect.Type, prop map[string]interface{}) {
|
|
n := t.NumField()
|
|
for i := 0; i < n; i++ {
|
|
field := t.Field(i)
|
|
|
|
name := strings.Split(field.Tag.Get("json"), ",")[0]
|
|
if name == "-" {
|
|
continue
|
|
} else if name == "" {
|
|
name = field.Name
|
|
}
|
|
|
|
attrMap := make(map[string]interface{})
|
|
attrs := splitTag(field.Tag.Get("elastic"))
|
|
for _, attr := range attrs {
|
|
keyvalue := strings.Split(attr, ":")
|
|
attrMap[keyvalue[0]] = keyvalue[1]
|
|
}
|
|
|
|
if len(attrMap) == 0 || attrMap["type"] == "nested" {
|
|
|
|
// We are looking for tags on any inner struct, independently of
|
|
// whether the field is a struct, a pointer to struct, or a slice of structs
|
|
targetType := field.Type
|
|
if targetType.Kind() == reflect.Ptr ||
|
|
targetType.Kind() == reflect.Slice {
|
|
targetType = field.Type.Elem()
|
|
}
|
|
if targetType.Kind() == reflect.Struct {
|
|
if field.Anonymous {
|
|
getProperties(targetType, prop)
|
|
} else {
|
|
innerStructProp := make(map[string]interface{})
|
|
getProperties(targetType, innerStructProp)
|
|
attrMap["properties"] = innerStructProp
|
|
}
|
|
}
|
|
}
|
|
if len(attrMap) != 0 {
|
|
prop[name] = attrMap
|
|
}
|
|
}
|
|
}
|
|
|
|
func splitTag(tag string) []string {
|
|
tag = strings.Trim(tag, " ")
|
|
if tag == "" {
|
|
return []string{}
|
|
} else {
|
|
return strings.Split(tag, ",")
|
|
}
|
|
}
|