func (c *Config) parseSource(canal *canal.Canal) (map[string]*Rule, map[string][]string, error) { ruleMap := make(map[string]*Rule) wildTables := make(map[string][]string, len(c.Sources)) // first, check sources for _, s := range c.Sources { for _, table := range s.Tables { if len(s.Schema) == 0 { return nil, nil, errors.Errorf("empty schema not allowed for source") } if regexp.QuoteMeta(table) != table { if _, ok := wildTables[ruleKey(s.Schema, table)]; ok { return nil, nil, errors.Errorf("duplicate wildcard table defined for %s.%s", s.Schema, table) } tables := []string{} sql := fmt.Sprintf(`SELECT table_name FROM information_schema.tables WHERE table_name RLIKE "%s" AND table_schema = "%s";`, table, s.Schema) res, err := canal.Execute(sql) if err != nil { return nil, nil, err } for i := 0; i < res.Resultset.RowNumber(); i++ { f, _ := res.GetString(i, 0) err := c.newRule(ruleMap, s.Schema, f) if err != nil { return nil, nil, err } tables = append(tables, f) } wildTables[ruleKey(s.Schema, table)] = tables } else { err := c.newRule(ruleMap, s.Schema, table) if err != nil { return nil, nil, err } } } } if len(ruleMap) == 0 { return nil, nil, errors.Errorf("no source data defined") } return ruleMap, wildTables, nil }