github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/dbutil/string-value-list.go (about)

     1  package dbutil
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"fmt"
     7  )
     8  
     9  // StringValueList is just a string slice but has SQL marshaling to/from JSON.
    10  // JSON values are always an empty array ("[]") and never "null".  Inputs
    11  // which are nil will be converted to an emtpy array automatically.
    12  type StringValueList []string
    13  
    14  func (l StringValueList) Value() (driver.Value, error) {
    15  	if l == nil {
    16  		l = StringValueList{}
    17  	}
    18  	b, err := json.Marshal(l)
    19  	return driver.Value(b), err
    20  }
    21  
    22  func (l *StringValueList) Scan(value interface{}) error {
    23  
    24  	var ret StringValueList
    25  	var b []byte
    26  
    27  	if value != nil {
    28  
    29  		switch v := value.(type) {
    30  		case []byte:
    31  			b = v
    32  		case string:
    33  			b = []byte(v)
    34  		default:
    35  			return fmt.Errorf("cannot convert from StringValueList to sql driver type %T", value)
    36  		}
    37  
    38  		err := json.Unmarshal(b, &ret)
    39  		if err != nil {
    40  			return err
    41  		}
    42  
    43  	} else {
    44  		ret = StringValueList{}
    45  	}
    46  
    47  	*l = ret
    48  
    49  	return nil
    50  }
    51  
    52  func (l StringValueList) String() string {
    53  	dv, err := l.Value()
    54  	if err != nil {
    55  		return fmt.Sprintf("(string conversion resulted in error: %v)", err)
    56  	}
    57  	return fmt.Sprintf("%s", dv)
    58  }
    59  
    60  func (l StringValueList) Contains(v string) bool {
    61  	for _, sv := range l {
    62  		if sv == v {
    63  			return true
    64  		}
    65  	}
    66  	return false
    67  }
    68  
    69  func (l StringValueList) IndexOf(v string) int {
    70  	for i, sv := range l {
    71  		if sv == v {
    72  			return i
    73  		}
    74  	}
    75  	return -1
    76  }
    77  
    78  // RemoveFast deletes the value at the specified position
    79  // without preserving sequence and returns the new slice.
    80  // Note that the array backing the original slice is modified.
    81  func (l StringValueList) RemoveFast(i int) StringValueList {
    82  	// swap value we're removing to end of array
    83  	l[len(l)-1], l[i] = l[i], l[len(l)-1]
    84  	// return with last element omitted
    85  	return l[:len(l)-1]
    86  }