github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/boil/columns.go (about)

     1  package boil
     2  
     3  import (
     4  	"github.com/volatiletech/strmangle"
     5  )
     6  
     7  // Columns kinds
     8  // Note: These are not exported because they should only be used
     9  // internally. To hide the clutter from the public API so boil
    10  // continues to be a package aimed towards users, we add a method
    11  // to query for each kind on the column type itself, see IsInfer
    12  // as example.
    13  const (
    14  	columnsNone int = iota
    15  	columnsInfer
    16  	columnsWhitelist
    17  	columnsGreylist
    18  	columnsBlacklist
    19  )
    20  
    21  // Columns is a list of columns and a kind of list.
    22  // Each kind interacts differently with non-zero and default column
    23  // inference to produce a final list of columns for a given query.
    24  // (Typically insert/updates).
    25  type Columns struct {
    26  	Kind int
    27  	Cols []string
    28  }
    29  
    30  // None creates an empty column list.
    31  func None() Columns {
    32  	return Columns{
    33  		Kind: columnsNone,
    34  	}
    35  }
    36  
    37  // IsNone checks to see if no columns should be inferred.
    38  // This method is here simply to not have to export the columns types.
    39  func (c Columns) IsNone() bool {
    40  	return c.Kind == columnsNone
    41  }
    42  
    43  // Infer is a placeholder that means there is no other list, simply
    44  // infer the final list of columns for insert/update etc.
    45  func Infer() Columns {
    46  	return Columns{
    47  		Kind: columnsInfer,
    48  	}
    49  }
    50  
    51  // IsInfer checks to see if these columns should be inferred.
    52  // This method is here simply to not have to export the columns types.
    53  func (c Columns) IsInfer() bool {
    54  	return c.Kind == columnsInfer
    55  }
    56  
    57  // Whitelist creates a list that completely overrides column inference.
    58  // It becomes the final list for the insert/update etc.
    59  func Whitelist(columns ...string) Columns {
    60  	return Columns{
    61  		Kind: columnsWhitelist,
    62  		Cols: columns,
    63  	}
    64  }
    65  
    66  // IsWhitelist checks to see if these columns should be inferred.
    67  // This method is here simply to not have to export the columns types.
    68  func (c Columns) IsWhitelist() bool {
    69  	return c.Kind == columnsWhitelist
    70  }
    71  
    72  // Blacklist creates a list that overrides column inference choices
    73  // by excluding a column from the inferred list. In essence, inference
    74  // creates the list of columns, and blacklisted columns are removed from
    75  // that list to produce the final list.
    76  func Blacklist(columns ...string) Columns {
    77  	return Columns{
    78  		Kind: columnsBlacklist,
    79  		Cols: columns,
    80  	}
    81  }
    82  
    83  // IsBlacklist checks to see if these columns should be inferred.
    84  // This method is here simply to not have to export the columns types.
    85  func (c Columns) IsBlacklist() bool {
    86  	return c.Kind == columnsBlacklist
    87  }
    88  
    89  // Greylist creates a list that adds to the inferred column choices.
    90  // The final list is composed of both inferred columns and greylisted columns.
    91  func Greylist(columns ...string) Columns {
    92  	return Columns{
    93  		Kind: columnsGreylist,
    94  		Cols: columns,
    95  	}
    96  }
    97  
    98  // IsGreylist checks to see if these columns should be inferred.
    99  // This method is here simply to not have to export the columns types.
   100  func (c Columns) IsGreylist() bool {
   101  	return c.Kind == columnsGreylist
   102  }
   103  
   104  // InsertColumnSet generates the set of columns to insert and return for an
   105  // insert statement. The return columns are used to get values that are
   106  // assigned within the database during the insert to keep the struct in sync
   107  // with what's in the db. The various interactions with the different
   108  // types of Columns list are outlined below.
   109  //
   110  // Note that a default column's zero value is based on the Go type and does
   111  // not take into account the default value in the database.
   112  //
   113  //  None:
   114  //   insert: empty
   115  //   return: empty
   116  //
   117  //  Infer:
   118  //   insert: columns-without-default + non-zero-default-columns
   119  //   return: columns-with-defaults - insert
   120  //
   121  //  Whitelist:
   122  //   insert: whitelist
   123  //   return: columns-with-defaults - whitelist
   124  //
   125  //  Blacklist:
   126  //    insert: columns-without-default + non-zero-default-columns - blacklist
   127  //    return: columns-with-defaults - insert
   128  //
   129  //  Greylist:
   130  //    insert: columns-without-default + non-zero-default-columns + greylist
   131  //    return: columns-with-defaults - insert
   132  func (c Columns) InsertColumnSet(cols, defaults, noDefaults, nonZeroDefaults []string) ([]string, []string) {
   133  	switch c.Kind {
   134  	case columnsNone:
   135  		return nil, nil
   136  
   137  	case columnsInfer:
   138  		insert := make([]string, len(noDefaults))
   139  		copy(insert, noDefaults)
   140  		insert = append(insert, nonZeroDefaults...)
   141  		insert = strmangle.SortByKeys(cols, insert)
   142  		ret := strmangle.SetComplement(defaults, insert)
   143  		return insert, ret
   144  
   145  	case columnsWhitelist:
   146  		return c.Cols, strmangle.SetComplement(defaults, c.Cols)
   147  
   148  	case columnsBlacklist:
   149  		insert := make([]string, len(noDefaults))
   150  		copy(insert, noDefaults)
   151  		insert = append(insert, nonZeroDefaults...)
   152  		insert = strmangle.SetComplement(insert, c.Cols)
   153  		insert = strmangle.SortByKeys(cols, insert)
   154  		ret := strmangle.SetComplement(defaults, insert)
   155  		return insert, ret
   156  
   157  	case columnsGreylist:
   158  		insert := make([]string, len(noDefaults))
   159  		copy(insert, noDefaults)
   160  		insert = append(insert, nonZeroDefaults...)
   161  		insert = strmangle.SetMerge(insert, c.Cols)
   162  		insert = strmangle.SortByKeys(cols, insert)
   163  		ret := strmangle.SetComplement(defaults, insert)
   164  		return insert, ret
   165  	default:
   166  		panic("not a real column list kind")
   167  	}
   168  }
   169  
   170  // UpdateColumnSet generates the set of columns to update for an update
   171  // statement. The various interactions with the different types of Columns
   172  // list are outlined below. In the case of greylist you can only add pkeys,
   173  // which isn't useful in an update since then you can't find the original
   174  // record you were trying to update.
   175  //
   176  //  None:      empty
   177  //  Infer:     all - pkey-columns
   178  //  whitelist: whitelist
   179  //  blacklist: all - pkeys - blacklist
   180  //  greylist:  all - pkeys + greylist
   181  func (c Columns) UpdateColumnSet(allColumns, pkeyCols []string) []string {
   182  	switch c.Kind {
   183  	case columnsNone:
   184  		return nil
   185  	case columnsInfer:
   186  		return strmangle.SetComplement(allColumns, pkeyCols)
   187  	case columnsWhitelist:
   188  		return c.Cols
   189  	case columnsBlacklist:
   190  		return strmangle.SetComplement(strmangle.SetComplement(allColumns, pkeyCols), c.Cols)
   191  	case columnsGreylist:
   192  		// okay to modify return of SetComplement since it's a new slice
   193  		update := append(strmangle.SetComplement(allColumns, pkeyCols), c.Cols...)
   194  		return strmangle.SortByKeys(allColumns, update)
   195  	default:
   196  		panic("not a real column list kind")
   197  	}
   198  }