Skip to content

Commit

Permalink
Merge pull request #235 from noborus/refactor-json
Browse files Browse the repository at this point in the history
Improved json errors
  • Loading branch information
noborus authored Sep 24, 2023
2 parents aa8232b + b04707c commit c478dcb
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 38 deletions.
2 changes: 2 additions & 0 deletions importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ var (
ErrNoMatchFound = errors.New("no match found")
// ErrNonDefinition is returned when there is no definition.
ErrNonDefinition = errors.New("no definition")
// ErrInvalidJSON is returned when the JSON is invalid.
ErrInvalidJSON = errors.New("invalid JSON")
// ErrInvalidYAML is returned when the YAML is invalid.
ErrInvalidYAML = errors.New("invalid YAML")
)
Expand Down
79 changes: 41 additions & 38 deletions input_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ func NewJSONReader(reader io.Reader, opts *ReadOpts) (*JSONReader, error) {
for i := 0; i < opts.InPreRead; i++ {
if err := r.reader.Decode(&top); err != nil {
if !errors.Is(err, io.EOF) {
return r, err
return r, fmt.Errorf("%w: %s", ErrInvalidJSON, err)
}
debug.Printf(err.Error())
return r, nil
}

if r.query != nil {
if err := r.jquery(top); err != nil {
if err := r.jqueryRun(top); err != nil {
return nil, err
}
return r, nil
Expand All @@ -75,23 +75,6 @@ func NewJSONReader(reader io.Reader, opts *ReadOpts) (*JSONReader, error) {
return r, nil
}

func (r *JSONReader) jquery(top interface{}) error {
iter := r.query.Run(top)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
return fmt.Errorf("%w gojq:(%s) ", err, r.query)
}
if err := r.readAhead(v); err != nil {
return err
}
}
return nil
}

// Names returns column names.
func (r *JSONReader) Names() ([]string, error) {
return r.names, nil
Expand All @@ -107,6 +90,7 @@ func (r *JSONReader) Types() ([]string, error) {
return r.types, nil
}

// readAhead parses the top level of the JSON and stores it in preRead.
func (r *JSONReader) readAhead(top interface{}) error {
switch m := top.(type) {
case []interface{}:
Expand Down Expand Up @@ -161,7 +145,7 @@ func (r *JSONReader) topLevel(top interface{}) (map[string]interface{}, []string
}
}

// PreReadRow is returns only columns that store preread rows.
// PreReadRow is returns only columns that store preRead rows.
// One json (not jsonl) returns all rows with preRead.
func (r *JSONReader) PreReadRow() [][]interface{} {
rows := make([][]interface{}, len(r.preRead))
Expand Down Expand Up @@ -190,28 +174,11 @@ func (r *JSONReader) ReadRow(row []interface{}) ([]interface{}, error) {
}

if r.query != nil {
// json query.
return r.queryRun(row, data)
return r.jqueryRunJsonl(row, data)
}
return r.rowParse(row, data), nil
}

func (r *JSONReader) queryRun(row []interface{}, jsonRow interface{}) ([]interface{}, error) {
iter := r.query.Run(jsonRow)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
debug.Printf("query %s", err.Error())
continue
}
row = r.rowParse(row, v)
}
return row, nil
}

func (r *JSONReader) rowParse(row []interface{}, jsonRow interface{}) []interface{} {
switch m := jsonRow.(type) {
case map[string]interface{}:
Expand Down Expand Up @@ -254,6 +221,42 @@ func (r *JSONReader) etcRow(val interface{}) (map[string]interface{}, []string,
return row, names, nil
}

// jqueryRun is a gojq.Run for json.
func (r *JSONReader) jqueryRun(top interface{}) error {
iter := r.query.Run(top)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
return fmt.Errorf("%w gojq:(%s) ", err, r.query)
}
if err := r.readAhead(v); err != nil {
return err
}
}
return nil
}

// jqueryRunJsonl jqueryRunJsonl gojq.Run for rows of jsonl.
func (r *JSONReader) jqueryRunJsonl(row []interface{}, jsonRow interface{}) ([]interface{}, error) {
iter := r.query.Run(jsonRow)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
debug.Printf("%s gojq: %s", err.Error(), r.query)
continue
}
row = r.rowParse(row, v)
}
return row, nil
}

// jsonString returns the string of the argument.
func (r *JSONReader) jsonString(val interface{}) interface{} {
var str string
switch val.(type) {
Expand Down
1 change: 1 addition & 0 deletions trdsql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ func BenchmarkOutput_TBLN(b *testing.B) {
func BenchmarkOutput_JSON(b *testing.B) {
benchmarkFormat(b, JSON)
}

func BenchmarkOutput_YAML(b *testing.B) {
benchmarkFormat(b, YAML)
}

0 comments on commit c478dcb

Please sign in to comment.