github.com/fraugster/parquet-go@v0.12.0/type_int96.go (about)

     1  package goparquet
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/fraugster/parquet-go/parquet"
     9  )
    10  
    11  type int96PlainDecoder struct {
    12  	r io.Reader
    13  }
    14  
    15  func (i *int96PlainDecoder) init(r io.Reader) error {
    16  	i.r = r
    17  
    18  	return nil
    19  }
    20  
    21  func (i *int96PlainDecoder) decodeValues(dst []interface{}) (int, error) {
    22  	idx := 0
    23  	for range dst {
    24  		var data [12]byte
    25  		// this one is a little tricky do not use ReadFull here
    26  		n, err := i.r.Read(data[:])
    27  		// make sure we handle the read data first then handle the error
    28  		if n == 12 {
    29  			dst[idx] = data
    30  			idx++
    31  		}
    32  
    33  		if err != nil && (n == 0 || n == 12) {
    34  			return idx, err
    35  		}
    36  
    37  		if err != nil {
    38  			return idx, fmt.Errorf("not enough byte to read Int96: %w", err)
    39  		}
    40  	}
    41  	return len(dst), nil
    42  }
    43  
    44  type int96PlainEncoder struct {
    45  	w io.Writer
    46  }
    47  
    48  func (i *int96PlainEncoder) Close() error {
    49  	return nil
    50  }
    51  
    52  func (i *int96PlainEncoder) init(w io.Writer) error {
    53  	i.w = w
    54  
    55  	return nil
    56  }
    57  
    58  func (i *int96PlainEncoder) encodeValues(values []interface{}) error {
    59  	data := make([]byte, len(values)*12)
    60  	for j := range values {
    61  		i96 := values[j].([12]byte)
    62  		copy(data[j*12:], i96[:])
    63  	}
    64  
    65  	return writeFull(i.w, data)
    66  }
    67  
    68  type int96Store struct {
    69  	byteArrayStore
    70  }
    71  
    72  func (*int96Store) sizeOf(v interface{}) int {
    73  	if vv, ok := v.([][12]byte); ok {
    74  		return 12 * len(vv)
    75  	}
    76  	return 12
    77  }
    78  
    79  func (is *int96Store) parquetType() parquet.Type {
    80  	return parquet.Type_INT96
    81  }
    82  
    83  func (is *int96Store) repetitionType() parquet.FieldRepetitionType {
    84  	return is.repTyp
    85  }
    86  
    87  func (is *int96Store) getValues(v interface{}) ([]interface{}, error) {
    88  	var vals []interface{}
    89  	switch typed := v.(type) {
    90  	case [12]byte:
    91  		if err := is.setMinMax(typed[:]); err != nil {
    92  			return nil, err
    93  		}
    94  		vals = []interface{}{typed}
    95  	case [][12]byte:
    96  		if is.repTyp != parquet.FieldRepetitionType_REPEATED {
    97  			return nil, errors.New("the value is not repeated but it is an array")
    98  		}
    99  		vals = make([]interface{}, len(typed))
   100  		for j := range typed {
   101  			if err := is.setMinMax(typed[j][:]); err != nil {
   102  				return nil, err
   103  			}
   104  			vals[j] = typed[j]
   105  		}
   106  	default:
   107  		return nil, fmt.Errorf("unsupported type for storing in Int96 column: %T => %+v", v, v)
   108  	}
   109  
   110  	return vals, nil
   111  }
   112  
   113  func (*int96Store) append(arrayIn interface{}, value interface{}) interface{} {
   114  	if arrayIn == nil {
   115  		arrayIn = make([][12]byte, 0, 1)
   116  	}
   117  	return append(arrayIn.([][12]byte), value.([12]byte))
   118  }