diff --git a/cmd/completion.go b/cmd/completion.go index edf59d14..e9a0bc42 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -51,7 +51,7 @@ tbls completion fish ~/.config/fish/completions/tbls.fish ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - return errors.Errorf("accepts 1 arg, received %d", len(args)) + return fmt.Errorf("accepts 1 arg, received %d", len(args)) } if err := cobra.OnlyValidArgs(cmd, args); err != nil { return err diff --git a/cmd/out.go b/cmd/out.go index 4fdfa521..224bcec0 100644 --- a/cmd/out.go +++ b/cmd/out.go @@ -21,6 +21,7 @@ package cmd import ( + "fmt" "io" "os" @@ -102,7 +103,7 @@ var outCmd = &cobra.Command{ case "config": o = tbls_config.New(c) default: - return errors.Errorf("unsupported format '%s'", format) + return fmt.Errorf("unsupported format '%s'", format) } var wr io.Writer diff --git a/cmd/root.go b/cmd/root.go index b472d299..a6374174 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -272,7 +272,7 @@ func printError(err error) { env := os.Getenv("DEBUG") debug, _ := strconv.ParseBool(env) if env != "" && debug { - fmt.Println(errors.StackTraces(err)) + fmt.Println(err, errors.StackTraces(err)) } else { fmt.Println(err) } diff --git a/config/config.go b/config/config.go index 2b1cdf48..e935559e 100644 --- a/config/config.go +++ b/config/config.go @@ -356,12 +356,15 @@ func (c *Config) LoadEnviron() error { } // LoadConfigFile load config file -func (c *Config) LoadConfigFile(path string) error { +func (c *Config) LoadConfigFile(path string) (err error) { + defer func() { + err = errors.WithStack(err) + }() if path == "" && os.Getenv("TBLS_DSN") == "" { for _, p := range DefaultConfigFilePaths { if f, err := os.Stat(filepath.Join(c.root, p)); err == nil && !f.IsDir() { if path != "" { - return errors.Errorf("duplicate config file [%s, %s]", path, p) + return fmt.Errorf("duplicate config file [%s, %s]", path, p) } path = p } @@ -373,12 +376,12 @@ func (c *Config) LoadConfigFile(path string) error { fullPath, err := filepath.Abs(path) if err != nil { - return errors.Wrap(errors.WithStack(err), "failed to load config file") + return fmt.Errorf("failed to load config file: %w", err) } buf, err := os.ReadFile(filepath.Clean(fullPath)) if err != nil { - return errors.Wrap(errors.WithStack(err), "failed to load config file") + return fmt.Errorf("failed to load config file: %w", err) } c.Path = filepath.Clean(fullPath) @@ -386,10 +389,12 @@ func (c *Config) LoadConfigFile(path string) error { } // LoadConfig load config from []byte -func (c *Config) LoadConfig(in []byte) error { - err := yaml.Unmarshal(expand.ExpandenvYAMLBytes(in), c) - if err != nil { - return errors.Wrap(errors.WithStack(err), "failed to load config file") +func (c *Config) LoadConfig(in []byte) (err error) { + defer func() { + err = errors.WithStack(err) + }() + if err := yaml.Unmarshal(expand.ExpandenvYAMLBytes(in), c); err != nil { + return fmt.Errorf("failed to load config file: %w", err) } c.MergedDict.Merge(c.Dict.Dump()) return nil @@ -611,15 +616,18 @@ func (c *Config) detectShowColumnsForER(s *schema.Schema) error { return nil } -func mergeAdditionalRelations(s *schema.Schema, relations []AdditionalRelation) error { +func mergeAdditionalRelations(s *schema.Schema, relations []AdditionalRelation) (err error) { + defer func() { + err = errors.WithStack(err) + }() for _, r := range relations { c, err := schema.ToCardinality(r.Cardinality) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } pc, err := schema.ToCardinality(r.ParentCardinality) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } relation := &schema.Relation{ Cardinality: c, @@ -633,24 +641,24 @@ func mergeAdditionalRelations(s *schema.Schema, relations []AdditionalRelation) } relation.Table, err = s.FindTableByName(r.Table) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } for _, c := range r.Columns { column, err := relation.Table.FindColumnByName(c) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } relation.Columns = append(relation.Columns, column) column.ParentRelations = append(column.ParentRelations, relation) } relation.ParentTable, err = s.FindTableByName(r.ParentTable) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } for _, c := range r.ParentColumns { column, err := relation.ParentTable.FindColumnByName(c) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } relation.ParentColumns = append(relation.ParentColumns, column) column.ChildRelations = append(column.ChildRelations, relation) @@ -665,11 +673,11 @@ func mergeAdditionalRelations(s *schema.Schema, relations []AdditionalRelation) cr.Def = r.Def cr.Cardinality, err = schema.ToCardinality(r.Cardinality) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } cr.ParentCardinality, err = schema.ToCardinality(r.ParentCardinality) if err != nil { - return errors.Wrap(err, "failed to add relation") + return fmt.Errorf("failed to add relation: %w", err) } } } else { @@ -679,11 +687,14 @@ func mergeAdditionalRelations(s *schema.Schema, relations []AdditionalRelation) return nil } -func mergeAdditionalComments(s *schema.Schema, comments []AdditionalComment) error { +func mergeAdditionalComments(s *schema.Schema, comments []AdditionalComment) (err error) { + defer func() { + err = errors.WithStack(err) + }() for _, c := range comments { table, err := s.FindTableByName(c.Table) if err != nil { - return errors.Wrap(err, "failed to add table comment") + return fmt.Errorf("failed to add table comment: %w", err) } if c.TableComment != "" { table.Comment = c.TableComment @@ -696,14 +707,14 @@ func mergeAdditionalComments(s *schema.Schema, comments []AdditionalComment) err for c, comment := range c.ColumnComments { column, err := table.FindColumnByName(c) if err != nil { - return errors.Wrap(err, "failed to add column comment") + return fmt.Errorf("failed to add column comment: %w", err) } column.Comment = comment } for c, labels := range c.ColumnLabels { column, err := table.FindColumnByName(c) if err != nil { - return errors.Wrap(err, "failed to add column comment") + return fmt.Errorf("failed to add column comment: %w", err) } for _, l := range labels { column.Labels = column.Labels.Merge(l) @@ -712,21 +723,21 @@ func mergeAdditionalComments(s *schema.Schema, comments []AdditionalComment) err for i, comment := range c.IndexComments { index, err := table.FindIndexByName(i) if err != nil { - return errors.Wrap(err, "failed to add index comment") + return fmt.Errorf("failed to add index comment: %w", err) } index.Comment = comment } for c, comment := range c.ConstraintComments { constraint, err := table.FindConstraintByName(c) if err != nil { - return errors.Wrap(err, "failed to add constraint comment") + return fmt.Errorf("failed to add constraint comment: %w", err) } constraint.Comment = comment } for t, comment := range c.TriggerComments { trigger, err := table.FindTriggerByName(t) if err != nil { - return errors.Wrap(err, "failed to add trigger comment") + return fmt.Errorf("failed to add trigger comment: %w", err) } trigger.Comment = comment } diff --git a/datasource/datasource.go b/datasource/datasource.go index b953ca16..6342fdee 100644 --- a/datasource/datasource.go +++ b/datasource/datasource.go @@ -3,6 +3,7 @@ package datasource import ( "bytes" "encoding/json" + "fmt" "io" "net/http" "os" @@ -28,7 +29,10 @@ import ( ) // Analyze database -func Analyze(dsn config.DSN) (*schema.Schema, error) { +func Analyze(dsn config.DSN) (_ *schema.Schema, err error) { + defer func() { + err = errors.WithStack(err) + }() urlstr := dsn.URL if strings.HasPrefix(urlstr, "https://") || strings.HasPrefix(urlstr, "http://") { return AnalyzeHTTPResource(dsn) @@ -54,11 +58,11 @@ func Analyze(dsn config.DSN) (*schema.Schema, error) { s := &schema.Schema{} u, err := dburl.Parse(urlstr) if err != nil { - return s, errors.WithStack(err) + return s, err } splitted := strings.Split(u.Short(), "/") if len(splitted) < 2 { - return s, errors.Errorf("invalid DSN: parse %s -> %#v", urlstr, u) + return s, fmt.Errorf("invalid DSN: parse %s -> %#v", urlstr, u) } opts := []drivers.Option{} @@ -129,7 +133,7 @@ func Analyze(dsn config.DSN) (*schema.Schema, error) { s.Name = splitted[1] driver = clickhouse.New(db) default: - return s, errors.Errorf("unsupported driver '%s'", u.Driver) + return s, fmt.Errorf("unsupported driver '%s'", u.Driver) } err = driver.Analyze(s) if err != nil { @@ -139,11 +143,14 @@ func Analyze(dsn config.DSN) (*schema.Schema, error) { } // AnalyzeHTTPResource analyze `https://` or `http://` -func AnalyzeHTTPResource(dsn config.DSN) (*schema.Schema, error) { +func AnalyzeHTTPResource(dsn config.DSN) (_ *schema.Schema, err error) { + defer func() { + err = errors.WithStack(err) + }() s := &schema.Schema{} req, err := http.NewRequest("GET", dsn.URL, nil) if err != nil { - return s, errors.WithStack(err) + return s, err } for k, v := range dsn.Headers { req.Header.Add(k, v) @@ -151,64 +158,70 @@ func AnalyzeHTTPResource(dsn config.DSN) (*schema.Schema, error) { client := &http.Client{Timeout: time.Duration(10) * time.Second} resp, err := client.Do(req) if err != nil { - return s, errors.WithStack(err) + return s, err } defer resp.Body.Close() dec := json.NewDecoder(resp.Body) if err := dec.Decode(s); err != nil { - return s, errors.WithStack(err) + return s, err } if err := s.Repair(); err != nil { - return s, errors.WithStack(err) + return s, err } return s, nil } // AnalyzeGitHubContent analyze `github://` -func AnalyzeGitHubContent(dsn config.DSN) (*schema.Schema, error) { +func AnalyzeGitHubContent(dsn config.DSN) (_ *schema.Schema, err error) { + defer func() { + err = errors.WithStack(err) + }() splitted := strings.SplitN(strings.TrimPrefix(dsn.URL, "github://"), "/", 3) if len(splitted) != 3 { - return nil, errors.Errorf("invalid dsn: %s", dsn) + return nil, fmt.Errorf("invalid dsn: %s", dsn) } s := &schema.Schema{} options := []factory.Option{factory.OwnerRepo(splitted[0] + "/" + splitted[1])} c, err := factory.NewGithubClient(options...) if err != nil { - return nil, errors.WithStack(err) + return nil, err } o := ghfs.Client(c) fsys, err := ghfs.New(splitted[0], splitted[1], o) if err != nil { - return nil, errors.WithStack(err) + return nil, err } b, err := fsys.ReadFile(splitted[2]) if err != nil { - return nil, errors.WithStack(err) + return nil, err } dec := json.NewDecoder(bytes.NewReader(b)) if err := dec.Decode(s); err != nil { - return s, errors.WithStack(err) + return s, err } if err := s.Repair(); err != nil { - return s, errors.WithStack(err) + return s, err } return s, nil } // AnalyzeJSON analyze `json://` -func AnalyzeJSON(urlstr string) (*schema.Schema, error) { +func AnalyzeJSON(urlstr string) (_ *schema.Schema, err error) { + defer func() { + err = errors.WithStack(err) + }() s := &schema.Schema{} splitted := strings.Split(urlstr, "json://") file, err := os.Open(splitted[1]) if err != nil { - return s, errors.WithStack(err) + return s, err } dec := json.NewDecoder(file) if err := dec.Decode(s); err != nil { - return s, errors.WithStack(err) + return s, err } if err := s.Repair(); err != nil { - return s, errors.WithStack(err) + return s, err } return s, nil } @@ -220,6 +233,9 @@ func AnalyzeJSONString(str string) (*schema.Schema, error) { // AnalyzeJSONStringOrFile analyze JSON string or JSON file func AnalyzeJSONStringOrFile(strOrPath string) (s *schema.Schema, err error) { + defer func() { + err = errors.WithStack(err) + }() s = &schema.Schema{} var buf io.Reader if strings.HasPrefix(strOrPath, "{") { @@ -227,15 +243,15 @@ func AnalyzeJSONStringOrFile(strOrPath string) (s *schema.Schema, err error) { } else { buf, err = os.Open(filepath.Clean(strOrPath)) if err != nil { - return s, errors.WithStack(err) + return s, err } } dec := json.NewDecoder(buf) if err := dec.Decode(s); err != nil { - return s, errors.WithStack(err) + return s, err } if err := s.Repair(); err != nil { - return s, errors.WithStack(err) + return s, err } return s, nil } diff --git a/drivers/mysql/mysql.go b/drivers/mysql/mysql.go index 10a04490..9cdc123f 100644 --- a/drivers/mysql/mysql.go +++ b/drivers/mysql/mysql.go @@ -637,10 +637,13 @@ func convertColumnNullable(str string) bool { return str != "NO" } -func parseFK(def string) ([]string, string, []string, error) { +func parseFK(def string) (_ []string, _ string, _ []string, err error) { + defer func() { + err = errors.WithStack(err) + }() result := reFK.FindAllStringSubmatch(def, -1) if len(result) < 1 || len(result[0]) < 4 { - return nil, "", nil, errors.Errorf("can not parse foreign key: %s", def) + return nil, "", nil, fmt.Errorf("can not parse foreign key: %s", def) } strColumns := strings.Split(result[0][1], ", ") strParentTable := strings.Trim(result[0][2], `"`) diff --git a/drivers/postgres/postgres.go b/drivers/postgres/postgres.go index 404c949c..b6ab4f35 100644 --- a/drivers/postgres/postgres.go +++ b/drivers/postgres/postgres.go @@ -32,7 +32,10 @@ func New(db *sql.DB) *Postgres { } // Analyze PostgreSQL database schema -func (p *Postgres) Analyze(s *schema.Schema) error { +func (p *Postgres) Analyze(s *schema.Schema) (err error) { + defer func() { + err = errors.WithStack(err) + }() d, err := p.Info() if err != nil { return errors.WithStack(err) @@ -280,7 +283,7 @@ ORDER BY tgrelid case "s": column.ExtraDef = fmt.Sprintf("GENERATED ALWAYS AS %s STORED", columnDefaultOrGenerated.String) default: - return errors.Errorf("unsupported pg_attribute.attrgenerated '%s'", attrgenerated.String) + return fmt.Errorf("unsupported pg_attribute.attrgenerated '%s'", attrgenerated.String) } columns = append(columns, column) } @@ -525,7 +528,10 @@ func (p *Postgres) EnableRsMode() { p.rsMode = true } -func (p *Postgres) queryForColumns(v string) (string, error) { +func (p *Postgres) queryForColumns(v string) (_ string, err error) { + defer func() { + err = errors.WithStack(err) + }() verGeneratedColumn, err := version.Parse("12") if err != nil { return "", err @@ -533,7 +539,7 @@ func (p *Postgres) queryForColumns(v string) (string, error) { // v => PostgreSQL 9.5.24 on x86_64-pc-linux-gnu (Debian 9.5.24-1.pgdg90+1), compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit matches := reVersion.FindStringSubmatch(v) if matches == nil || len(matches) < 2 { - return "", errors.Errorf("malformed version: %s", v) + return "", fmt.Errorf("malformed version: %s", v) } vv, err := version.Parse(matches[1]) if err != nil { @@ -661,7 +667,10 @@ GROUP BY cls.relname, idx.indexrelid, descr.description ORDER BY idx.indexrelid` } -func detectFullTableName(name string, searchPaths, fullTableNames []string) (string, error) { +func detectFullTableName(name string, searchPaths, fullTableNames []string) (_ string, err error) { + defer func() { + err = errors.WithStack(err) + }() if strings.Contains(name, ".") { return name, nil } @@ -676,7 +685,7 @@ func detectFullTableName(name string, searchPaths, fullTableNames []string) (str } } if len(fns) != 1 { - return "", errors.Errorf("can not detect table name: %s", name) + return "", fmt.Errorf("can not detect table name: %s", name) } return fns[0], nil } @@ -698,10 +707,13 @@ func convertConstraintType(t string) string { } } -func parseFK(def string) ([]string, string, []string, error) { +func parseFK(def string) (_ []string, _ string, _ []string, err error) { + defer func() { + err = errors.WithStack(err) + }() result := reFK.FindAllStringSubmatch(def, -1) if len(result) < 1 || len(result[0]) < 4 { - return nil, "", nil, errors.Errorf("can not parse foreign key: %s", def) + return nil, "", nil, fmt.Errorf("can not parse foreign key: %s", def) } strColumns := []string{} for _, c := range strings.Split(result[0][1], ", ") { diff --git a/drivers/sqlite/sqlite.go b/drivers/sqlite/sqlite.go index 43fe7c97..673b828b 100644 --- a/drivers/sqlite/sqlite.go +++ b/drivers/sqlite/sqlite.go @@ -42,7 +42,10 @@ type fk struct { } // Analyze SQLite database schema -func (l *Sqlite) Analyze(s *schema.Schema) error { +func (l *Sqlite) Analyze(s *schema.Schema) (err error) { + defer func() { + err = errors.WithStack(err) + }() d, err := l.Info() if err != nil { return errors.WithStack(err) @@ -77,7 +80,7 @@ WHERE name != 'sqlite_sequence' AND (type = 'table' OR type = 'view');`) tableType = "virtual table" matches := reFTS.FindStringSubmatch(tableDef) if len(matches) < 1 { - return errors.Errorf("can not parse table definition: %s", tableDef) + return fmt.Errorf("can not parse table definition: %s", tableDef) } shadowTables = append(shadowTables, fmt.Sprintf("%s_content", tableName)) shadowTables = append(shadowTables, fmt.Sprintf("%s_segdir", tableName)) @@ -491,10 +494,13 @@ func parseCheckConstraints(table *schema.Table, sql string) []*schema.Constraint return constraints } -func parseFK(def string) ([]string, string, []string, error) { +func parseFK(def string) (_ []string, _ string, _ []string, err error) { + defer func() { + err = errors.WithStack(err) + }() result := reFK.FindAllStringSubmatch(def, -1) if len(result) < 1 || len(result[0]) < 4 { - return nil, "", nil, errors.Errorf("can not parse foreign key: %s", def) + return nil, "", nil, fmt.Errorf("can not parse foreign key: %s", def) } strColumns := strings.Split(result[0][1], ", ") strParentTable := strings.Trim(result[0][2], `"`) diff --git a/schema/filter.go b/schema/filter.go index f08dd136..32d87747 100644 --- a/schema/filter.go +++ b/schema/filter.go @@ -16,7 +16,10 @@ type FilterOption struct { Distance int } -func (s *Schema) Filter(opt *FilterOption) error { +func (s *Schema) Filter(opt *FilterOption) (err error) { + defer func() { + err = errors.WithStack(err) + }() _, excludes, err := s.SepareteTablesThatAreIncludedOrNot(opt) if err != nil { return err @@ -24,14 +27,17 @@ func (s *Schema) Filter(opt *FilterOption) error { for _, t := range excludes { err := excludeTableFromSchema(t.Name, s) if err != nil { - return errors.Wrap(errors.WithStack(err), fmt.Sprintf("failed to filter table '%s'", t.Name)) + return fmt.Errorf("failed to filter table '%s': %w", t.Name, err) } } return nil } -func (s *Schema) SepareteTablesThatAreIncludedOrNot(opt *FilterOption) ([]*Table, []*Table, error) { +func (s *Schema) SepareteTablesThatAreIncludedOrNot(opt *FilterOption) (_ []*Table, _ []*Table, err error) { + defer func() { + err = errors.WithStack(err) + }() i := append(opt.Include, s.NormalizeTableNames(opt.Include)...) e := append(opt.Exclude, s.NormalizeTableNames(opt.Exclude)...) @@ -93,7 +99,7 @@ func (s *Schema) SepareteTablesThatAreIncludedOrNot(opt *FilterOption) ([]*Table // assert if len(s.Tables) != len(includes2)+len(excludes2) { - return nil, nil, errors.Errorf("failed to separate tables. expected: %d, actual: %d", len(s.Tables), len(includes2)+len(excludes2)) + return nil, nil, fmt.Errorf("failed to separate tables. expected: %d, actual: %d", len(s.Tables), len(includes2)+len(excludes2)) } return includes2, excludes2, nil diff --git a/schema/schema.go b/schema/schema.go index 0bf8dd5b..38b7b0d1 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -214,17 +214,23 @@ func (s *Schema) NormalizeTableNames(names []string) []string { } // FindTableByName find table by table name -func (s *Schema) FindTableByName(name string) (*Table, error) { +func (s *Schema) FindTableByName(name string) (_ *Table, err error) { + defer func() { + err = errors.WithStack(err) + }() for _, t := range s.Tables { if s.NormalizeTableName(t.Name) == s.NormalizeTableName(name) { return t, nil } } - return nil, errors.Errorf("not found table '%s'", name) + return nil, fmt.Errorf("not found table '%s'", name) } // FindRelation find relation by columns and parent columns -func (s *Schema) FindRelation(cs, pcs []*Column) (*Relation, error) { +func (s *Schema) FindRelation(cs, pcs []*Column) (_ *Relation, err error) { + defer func() { + err = errors.WithStack(err) + }() L: for _, r := range s.Relations { if len(r.Columns) != len(cs) || len(r.ParentColumns) != len(pcs) { @@ -254,7 +260,7 @@ L: } return r, nil } - return nil, errors.Errorf("not found relation '%v, %v'", cs, pcs) + return nil, fmt.Errorf("not found relation '%v, %v'", cs, pcs) } func (s *Schema) HasTableWithLabels() bool { @@ -309,7 +315,10 @@ func (s *Schema) Sort() error { } // Repair column relations -func (s *Schema) Repair() error { +func (s *Schema) Repair() (err error) { + defer func() { + err = errors.WithStack(err) + }() if err := s.repairWithoutViewpoints(); err != nil { return err } @@ -317,14 +326,14 @@ func (s *Schema) Repair() error { for _, v := range s.Viewpoints { cs, err := s.CloneWithoutViewpoints() if err != nil { - return errors.Wrap(err, "failed to repair viewpoint") + return fmt.Errorf("failed to repair viewpoint: %w", err) } if err := cs.Filter(&FilterOption{ Include: v.Tables, IncludeLabels: v.Labels, Distance: v.Distance, }); err != nil { - return errors.Wrap(err, "failed to repair viewpoint") + return fmt.Errorf("failed to repair viewpoint: %w", err) } v.Schema = cs } @@ -367,7 +376,10 @@ func (s *Schema) CloneWithoutViewpoints() (c *Schema, err error) { return c, nil } -func (s *Schema) repairWithoutViewpoints() error { +func (s *Schema) repairWithoutViewpoints() (err error) { + defer func() { + err = errors.WithStack(err) + }() for _, t := range s.Tables { if len(t.Columns) == 0 { t.Columns = nil @@ -402,12 +414,12 @@ func (s *Schema) repairWithoutViewpoints() error { for _, r := range s.Relations { t, err := s.FindTableByName(r.Table.Name) if err != nil { - return errors.Wrap(err, "failed to repair relation") + return fmt.Errorf("failed to repair relation: %w", err) } for i, rc := range r.Columns { c, err := t.FindColumnByName(rc.Name) if err != nil { - return errors.Wrap(err, "failed to repair relation") + return fmt.Errorf("failed to repair relation: %w", err) } c.ParentRelations = append(c.ParentRelations, r) r.Columns[i] = c @@ -415,12 +427,12 @@ func (s *Schema) repairWithoutViewpoints() error { r.Table = t pt, err := s.FindTableByName(r.ParentTable.Name) if err != nil { - return errors.Wrap(err, "failed to repair relation") + return fmt.Errorf("failed to repair relation: %w", err) } for i, rc := range r.ParentColumns { pc, err := pt.FindColumnByName(rc.Name) if err != nil { - return errors.Wrap(err, "failed to repair relation") + return fmt.Errorf("failed to repair relation: %w", err) } pc.ChildRelations = append(pc.ChildRelations, r) r.ParentColumns[i] = pc @@ -435,43 +447,55 @@ func (s *Schema) repairWithoutViewpoints() error { } // FindColumnByName find column by column name -func (t *Table) FindColumnByName(name string) (*Column, error) { +func (t *Table) FindColumnByName(name string) (_ *Column, err error) { + defer func() { + err = errors.WithStack(err) + }() for _, c := range t.Columns { if c.Name == name { return c, nil } } - return nil, errors.Errorf("not found column '%s' on table '%s'", name, t.Name) + return nil, errors.New(fmt.Sprintf("not found column '%s' on table '%s'", name, t.Name)) } // FindIndexByName find index by index name -func (t *Table) FindIndexByName(name string) (*Index, error) { +func (t *Table) FindIndexByName(name string) (_ *Index, err error) { + defer func() { + err = errors.WithStack(err) + }() for _, i := range t.Indexes { if i.Name == name { return i, nil } } - return nil, errors.Errorf("not found index '%s' on table '%s'", name, t.Name) + return nil, errors.New(fmt.Sprintf("not found index '%s' on table '%s'", name, t.Name)) } // FindConstraintByName find constraint by constraint name -func (t *Table) FindConstraintByName(name string) (*Constraint, error) { +func (t *Table) FindConstraintByName(name string) (_ *Constraint, err error) { + defer func() { + err = errors.WithStack(err) + }() for _, c := range t.Constraints { if c.Name == name { return c, nil } } - return nil, errors.Errorf("not found constraint '%s' on table '%s'", name, t.Name) + return nil, errors.New(fmt.Sprintf("not found constraint '%s' on table '%s'", name, t.Name)) } // FindTriggerByName find trigger by trigger name -func (t *Table) FindTriggerByName(name string) (*Trigger, error) { +func (t *Table) FindTriggerByName(name string) (_ *Trigger, err error) { + defer func() { + err = errors.WithStack(err) + }() for _, trig := range t.Triggers { if trig.Name == name { return trig, nil } } - return nil, errors.Errorf("not found trigger '%s' on table '%s'", name, t.Name) + return nil, errors.New(fmt.Sprintf("not found trigger '%s' on table '%s'", name, t.Name)) } // FindConstrainsByColumnName find constraint by column name