2013-05-14 12:04:11 +04:00
|
|
|
package mapping
|
2013-05-13 15:58:44 +04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2013-05-14 18:15:35 +04:00
|
|
|
"goposm/element"
|
2013-05-13 15:58:44 +04:00
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Field struct {
|
2013-05-21 16:39:24 +04:00
|
|
|
Name string `json:"name"`
|
|
|
|
Key string `json:"key"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Args map[string]interface{} `json:"args"`
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
type Table struct {
|
2013-05-14 18:15:35 +04:00
|
|
|
Name string
|
2013-05-13 15:58:44 +04:00
|
|
|
Type string `json:"type"`
|
|
|
|
Mapping map[string][]string `json:"mapping"`
|
2013-05-15 10:15:33 +04:00
|
|
|
Fields []*Field `json:"fields"`
|
2013-05-17 17:07:03 +04:00
|
|
|
Filters *Filters `json:"filters"`
|
|
|
|
}
|
|
|
|
|
2013-05-22 13:48:34 +04:00
|
|
|
type GeneralizedTable struct {
|
|
|
|
Name string
|
|
|
|
SourceTableName string `json:"source"`
|
|
|
|
Tolerance float64 `json:"tolerance"`
|
|
|
|
SqlFilter string `json:"sql_filter"`
|
|
|
|
}
|
|
|
|
|
2013-05-17 17:07:03 +04:00
|
|
|
type Filters struct {
|
|
|
|
ExcludeTags *map[string]string `json:"exclude_tags"`
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
|
|
|
|
2013-05-14 18:15:35 +04:00
|
|
|
type Tables map[string]*Table
|
2013-05-13 15:58:44 +04:00
|
|
|
|
2013-05-22 13:48:34 +04:00
|
|
|
type GeneralizedTables map[string]*GeneralizedTable
|
|
|
|
|
2013-05-13 15:58:44 +04:00
|
|
|
type Mapping struct {
|
2013-05-22 13:48:34 +04:00
|
|
|
Tables Tables `json:"tables"`
|
|
|
|
GeneralizedTables GeneralizedTables `json:"generalized_tables"`
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
|
|
|
|
2013-05-23 15:09:47 +04:00
|
|
|
type ElementFilter func(tags *element.Tags) bool
|
2013-05-17 17:44:50 +04:00
|
|
|
|
|
|
|
type TagTables map[string]map[string][]string
|
|
|
|
|
|
|
|
func NewMapping(filename string) (*Mapping, error) {
|
|
|
|
f, err := os.Open(filename)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
decoder := json.NewDecoder(f)
|
|
|
|
|
|
|
|
mapping := Mapping{}
|
|
|
|
err = decoder.Decode(&mapping)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
mapping.prepare()
|
|
|
|
return &mapping, nil
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Table) ExtraTags() map[string]bool {
|
|
|
|
tags := make(map[string]bool)
|
|
|
|
for _, field := range t.Fields {
|
2013-05-15 10:15:33 +04:00
|
|
|
if field.Key != "" {
|
|
|
|
tags[field.Key] = true
|
|
|
|
}
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
|
|
|
return tags
|
|
|
|
}
|
|
|
|
|
2013-05-14 18:15:35 +04:00
|
|
|
func (m *Mapping) prepare() {
|
|
|
|
for name, t := range m.Tables {
|
|
|
|
t.Name = name
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
2013-05-22 13:48:34 +04:00
|
|
|
for name, t := range m.GeneralizedTables {
|
|
|
|
t.Name = name
|
|
|
|
}
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
|
|
|
|
2013-05-17 17:44:50 +04:00
|
|
|
func (m *Mapping) mappings(tableType string, mappings TagTables) {
|
2013-05-13 15:58:44 +04:00
|
|
|
for name, t := range m.Tables {
|
|
|
|
if t.Type != tableType {
|
|
|
|
continue
|
|
|
|
}
|
2013-05-17 17:44:50 +04:00
|
|
|
for key, vals := range t.Mapping {
|
2013-05-13 15:58:44 +04:00
|
|
|
for _, v := range vals {
|
|
|
|
vals, ok := mappings[key]
|
|
|
|
if ok {
|
|
|
|
vals[v] = append(vals[v], name)
|
|
|
|
} else {
|
|
|
|
mappings[key] = make(map[string][]string)
|
|
|
|
mappings[key][v] = append(mappings[key][v], name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-14 18:15:35 +04:00
|
|
|
func (m *Mapping) tables(tableType string) map[string]*TableFields {
|
|
|
|
result := make(map[string]*TableFields)
|
|
|
|
for name, t := range m.Tables {
|
|
|
|
if t.Type == tableType {
|
|
|
|
result[name] = t.TableFields()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2013-05-13 15:58:44 +04:00
|
|
|
func (m *Mapping) extraTags(tableType string, tags map[string]bool) {
|
|
|
|
for _, t := range m.Tables {
|
|
|
|
if t.Type != tableType {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for key, _ := range t.ExtraTags() {
|
|
|
|
tags[key] = true
|
|
|
|
}
|
2013-05-17 17:07:03 +04:00
|
|
|
if t.Filters != nil && t.Filters.ExcludeTags != nil {
|
|
|
|
for key, _ := range *t.Filters.ExcludeTags {
|
|
|
|
tags[key] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-17 17:44:50 +04:00
|
|
|
func (m *Mapping) ElementFilters() map[string][]ElementFilter {
|
|
|
|
result := make(map[string][]ElementFilter)
|
2013-05-17 17:07:03 +04:00
|
|
|
for name, t := range m.Tables {
|
|
|
|
if t.Filters == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if t.Filters.ExcludeTags != nil {
|
|
|
|
for filterKey, filterVal := range *t.Filters.ExcludeTags {
|
2013-05-23 15:09:47 +04:00
|
|
|
f := func(tags *element.Tags) bool {
|
|
|
|
if v, ok := (*tags)[filterKey]; ok {
|
2013-05-17 17:07:03 +04:00
|
|
|
if filterVal == "__any__" || v == filterVal {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
result[name] = append(result[name], f)
|
|
|
|
}
|
|
|
|
}
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|
2013-05-17 17:07:03 +04:00
|
|
|
return result
|
2013-05-13 15:58:44 +04:00
|
|
|
}
|