Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
k1LoW committed Aug 11, 2024
1 parent f59852a commit ed003a9
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 88 deletions.
2 changes: 1 addition & 1 deletion cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion cmd/out.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package cmd

import (
"fmt"
"io"
"os"

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
59 changes: 35 additions & 24 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -373,23 +376,25 @@ 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)

return c.LoadConfig(buf)
}

// 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
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
}
Expand Down
62 changes: 39 additions & 23 deletions datasource/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package datasource
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
Expand All @@ -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)
Expand All @@ -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{}
Expand Down Expand Up @@ -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 {
Expand All @@ -139,76 +143,85 @@ 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)
}
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
}
Expand All @@ -220,22 +233,25 @@ 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, "{") {
buf = bytes.NewBufferString(strOrPath)
} 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
}
7 changes: 5 additions & 2 deletions drivers/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -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], `"`)
Expand Down
Loading

0 comments on commit ed003a9

Please sign in to comment.