...

Source file src/github.com/lib/pq/rows.go

Documentation: github.com/lib/pq

     1  package pq
     2  
     3  import (
     4  	"math"
     5  	"reflect"
     6  	"time"
     7  
     8  	"github.com/lib/pq/oid"
     9  )
    10  
    11  const headerSize = 4
    12  
    13  type fieldDesc struct {
    14  	// The object ID of the data type.
    15  	OID oid.Oid
    16  	// The data type size (see pg_type.typlen).
    17  	// Note that negative values denote variable-width types.
    18  	Len int
    19  	// The type modifier (see pg_attribute.atttypmod).
    20  	// The meaning of the modifier is type-specific.
    21  	Mod int
    22  }
    23  
    24  func (fd fieldDesc) Type() reflect.Type {
    25  	switch fd.OID {
    26  	case oid.T_int8:
    27  		return reflect.TypeOf(int64(0))
    28  	case oid.T_int4:
    29  		return reflect.TypeOf(int32(0))
    30  	case oid.T_int2:
    31  		return reflect.TypeOf(int16(0))
    32  	case oid.T_varchar, oid.T_text:
    33  		return reflect.TypeOf("")
    34  	case oid.T_bool:
    35  		return reflect.TypeOf(false)
    36  	case oid.T_date, oid.T_time, oid.T_timetz, oid.T_timestamp, oid.T_timestamptz:
    37  		return reflect.TypeOf(time.Time{})
    38  	case oid.T_bytea:
    39  		return reflect.TypeOf([]byte(nil))
    40  	default:
    41  		return reflect.TypeOf(new(interface{})).Elem()
    42  	}
    43  }
    44  
    45  func (fd fieldDesc) Name() string {
    46  	return oid.TypeName[fd.OID]
    47  }
    48  
    49  func (fd fieldDesc) Length() (length int64, ok bool) {
    50  	switch fd.OID {
    51  	case oid.T_text, oid.T_bytea:
    52  		return math.MaxInt64, true
    53  	case oid.T_varchar, oid.T_bpchar:
    54  		return int64(fd.Mod - headerSize), true
    55  	default:
    56  		return 0, false
    57  	}
    58  }
    59  
    60  func (fd fieldDesc) PrecisionScale() (precision, scale int64, ok bool) {
    61  	switch fd.OID {
    62  	case oid.T_numeric, oid.T__numeric:
    63  		mod := fd.Mod - headerSize
    64  		precision = int64((mod >> 16) & 0xffff)
    65  		scale = int64(mod & 0xffff)
    66  		return precision, scale, true
    67  	default:
    68  		return 0, 0, false
    69  	}
    70  }
    71  
    72  // ColumnTypeScanType returns the value type that can be used to scan types into.
    73  func (rs *rows) ColumnTypeScanType(index int) reflect.Type {
    74  	return rs.colTyps[index].Type()
    75  }
    76  
    77  // ColumnTypeDatabaseTypeName return the database system type name.
    78  func (rs *rows) ColumnTypeDatabaseTypeName(index int) string {
    79  	return rs.colTyps[index].Name()
    80  }
    81  
    82  // ColumnTypeLength returns the length of the column type if the column is a
    83  // variable length type. If the column is not a variable length type ok
    84  // should return false.
    85  func (rs *rows) ColumnTypeLength(index int) (length int64, ok bool) {
    86  	return rs.colTyps[index].Length()
    87  }
    88  
    89  // ColumnTypePrecisionScale should return the precision and scale for decimal
    90  // types. If not applicable, ok should be false.
    91  func (rs *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
    92  	return rs.colTyps[index].PrecisionScale()
    93  }
    94  

View as plain text