...

Source file src/github.com/jackc/pgtype/text.go

Documentation: github.com/jackc/pgtype

     1  package pgtype
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"fmt"
     7  )
     8  
     9  type Text struct {
    10  	String string
    11  	Status Status
    12  }
    13  
    14  func (dst *Text) Set(src interface{}) error {
    15  	if src == nil {
    16  		*dst = Text{Status: Null}
    17  		return nil
    18  	}
    19  
    20  	if value, ok := src.(interface{ Get() interface{} }); ok {
    21  		value2 := value.Get()
    22  		if value2 != value {
    23  			return dst.Set(value2)
    24  		}
    25  	}
    26  
    27  	switch value := src.(type) {
    28  	case string:
    29  		*dst = Text{String: value, Status: Present}
    30  	case *string:
    31  		if value == nil {
    32  			*dst = Text{Status: Null}
    33  		} else {
    34  			*dst = Text{String: *value, Status: Present}
    35  		}
    36  	case []byte:
    37  		if value == nil {
    38  			*dst = Text{Status: Null}
    39  		} else {
    40  			*dst = Text{String: string(value), Status: Present}
    41  		}
    42  	case fmt.Stringer:
    43  		if value == fmt.Stringer(nil) {
    44  			*dst = Text{Status: Null}
    45  		} else {
    46  			*dst = Text{String: value.String(), Status: Present}
    47  		}
    48  	default:
    49  		// Cannot be part of the switch: If Value() returns nil on
    50  		// non-string, we should still try to checks the underlying type
    51  		// using reflection.
    52  		//
    53  		// For example the struct might implement driver.Valuer with
    54  		// pointer receiver and fmt.Stringer with value receiver.
    55  		if value, ok := src.(driver.Valuer); ok {
    56  			if value == driver.Valuer(nil) {
    57  				*dst = Text{Status: Null}
    58  				return nil
    59  			} else {
    60  				v, err := value.Value()
    61  				if err != nil {
    62  					return fmt.Errorf("driver.Valuer Value() method failed: %w", err)
    63  				}
    64  
    65  				// Handles also v == nil case.
    66  				if s, ok := v.(string); ok {
    67  					*dst = Text{String: s, Status: Present}
    68  					return nil
    69  				}
    70  			}
    71  		}
    72  
    73  		if originalSrc, ok := underlyingStringType(src); ok {
    74  			return dst.Set(originalSrc)
    75  		}
    76  		return fmt.Errorf("cannot convert %v to Text", value)
    77  	}
    78  
    79  	return nil
    80  }
    81  
    82  func (dst Text) Get() interface{} {
    83  	switch dst.Status {
    84  	case Present:
    85  		return dst.String
    86  	case Null:
    87  		return nil
    88  	default:
    89  		return dst.Status
    90  	}
    91  }
    92  
    93  func (src *Text) AssignTo(dst interface{}) error {
    94  	switch src.Status {
    95  	case Present:
    96  		switch v := dst.(type) {
    97  		case *string:
    98  			*v = src.String
    99  			return nil
   100  		case *[]byte:
   101  			*v = make([]byte, len(src.String))
   102  			copy(*v, src.String)
   103  			return nil
   104  		default:
   105  			if nextDst, retry := GetAssignToDstType(dst); retry {
   106  				return src.AssignTo(nextDst)
   107  			}
   108  			return fmt.Errorf("unable to assign to %T", dst)
   109  		}
   110  	case Null:
   111  		return NullAssignTo(dst)
   112  	}
   113  
   114  	return fmt.Errorf("cannot decode %#v into %T", src, dst)
   115  }
   116  
   117  func (Text) PreferredResultFormat() int16 {
   118  	return TextFormatCode
   119  }
   120  
   121  func (dst *Text) DecodeText(ci *ConnInfo, src []byte) error {
   122  	if src == nil {
   123  		*dst = Text{Status: Null}
   124  		return nil
   125  	}
   126  
   127  	*dst = Text{String: string(src), Status: Present}
   128  	return nil
   129  }
   130  
   131  func (dst *Text) DecodeBinary(ci *ConnInfo, src []byte) error {
   132  	return dst.DecodeText(ci, src)
   133  }
   134  
   135  func (Text) PreferredParamFormat() int16 {
   136  	return TextFormatCode
   137  }
   138  
   139  func (src Text) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
   140  	switch src.Status {
   141  	case Null:
   142  		return nil, nil
   143  	case Undefined:
   144  		return nil, errUndefined
   145  	}
   146  
   147  	return append(buf, src.String...), nil
   148  }
   149  
   150  func (src Text) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
   151  	return src.EncodeText(ci, buf)
   152  }
   153  
   154  // Scan implements the database/sql Scanner interface.
   155  func (dst *Text) Scan(src interface{}) error {
   156  	if src == nil {
   157  		*dst = Text{Status: Null}
   158  		return nil
   159  	}
   160  
   161  	switch src := src.(type) {
   162  	case string:
   163  		return dst.DecodeText(nil, []byte(src))
   164  	case []byte:
   165  		srcCopy := make([]byte, len(src))
   166  		copy(srcCopy, src)
   167  		return dst.DecodeText(nil, srcCopy)
   168  	}
   169  
   170  	return fmt.Errorf("cannot scan %T", src)
   171  }
   172  
   173  // Value implements the database/sql/driver Valuer interface.
   174  func (src Text) Value() (driver.Value, error) {
   175  	switch src.Status {
   176  	case Present:
   177  		return src.String, nil
   178  	case Null:
   179  		return nil, nil
   180  	default:
   181  		return nil, errUndefined
   182  	}
   183  }
   184  
   185  func (src Text) MarshalJSON() ([]byte, error) {
   186  	switch src.Status {
   187  	case Present:
   188  		return json.Marshal(src.String)
   189  	case Null:
   190  		return []byte("null"), nil
   191  	case Undefined:
   192  		return nil, errUndefined
   193  	}
   194  
   195  	return nil, errBadStatus
   196  }
   197  
   198  func (dst *Text) UnmarshalJSON(b []byte) error {
   199  	var s *string
   200  	err := json.Unmarshal(b, &s)
   201  	if err != nil {
   202  		return err
   203  	}
   204  
   205  	if s == nil {
   206  		*dst = Text{Status: Null}
   207  	} else {
   208  		*dst = Text{String: *s, Status: Present}
   209  	}
   210  
   211  	return nil
   212  }
   213  

View as plain text