func (c *Config) resolveRules(canal *canal.Canal) (map[string]*Rule, error) { ruleMap, wildtables, err := c.parseSource(canal) if err != nil { return nil, err } if c.Rules != nil { // then, set custom mapping rule for _, rule := range c.Rules { if len(rule.Schema) == 0 { return nil, errors.Errorf("empty schema not allowed for rule") } if regexp.QuoteMeta(rule.Table) != rule.Table { //wildcard table tables, ok := wildtables[ruleKey(rule.Schema, rule.Table)] if !ok { return nil, errors.Errorf("wildcard table for %s.%s is not defined in source", rule.Schema, rule.Table) } if len(rule.Index) == 0 { return nil, errors.Errorf("wildcard table rule %s.%s must have a index, can not empty", rule.Schema, rule.Table) } rule.Prepare() for _, table := range tables { rr := ruleMap[ruleKey(rule.Schema, table)] rr.Index = rule.Index rr.Type = rule.Type rr.Parent = rule.Parent rr.FieldMapping = rule.FieldMapping } } else { key := ruleKey(rule.Schema, rule.Table) if _, ok := ruleMap[key]; !ok { return nil, errors.Errorf("rule %s, %s not defined in source", rule.Schema, rule.Table) } rule.Prepare() ruleMap[key] = rule } } } for _, rule := range ruleMap { if rule.TableInfo, err = canal.GetTable(rule.Schema, rule.Table); err != nil { return nil, err } // table must have a PK for one column, multi columns may be supported later. if len(rule.TableInfo.PKColumns) != 1 { return nil, errors.Errorf("%s.%s must have a PK for a column", rule.Schema, rule.Table) } } return ruleMap, nil }