github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/schema/check_coll.go (about)

     1  // Copyright 2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package schema
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  )
    21  
    22  type Check interface {
    23  	Name() string
    24  	Expression() string
    25  	Enforced() bool
    26  }
    27  
    28  // CheckCollection is the set of `check` constraints on a table's schema
    29  type CheckCollection interface {
    30  	// AddCheck adds a check to this collection and returns it
    31  	AddCheck(name, expression string, enforce bool) (Check, error)
    32  	// DropCheck removes the check with the name given
    33  	DropCheck(name string) error
    34  	// AllChecks returns all the checks in the collection
    35  	AllChecks() []Check
    36  	// Equals returns whether the provided check collection is equal or not.
    37  	Equals(other CheckCollection) bool
    38  	// Count returns the size of the collection
    39  	Count() int
    40  	// Copy returns a copy of the collection safe to modify without affecting the original
    41  	Copy() CheckCollection
    42  }
    43  
    44  type check struct {
    45  	name       string
    46  	expression string
    47  	enforced   bool
    48  }
    49  
    50  func (c check) Name() string {
    51  	return c.name
    52  }
    53  
    54  func (c check) Expression() string {
    55  	return c.expression
    56  }
    57  
    58  func (c check) Enforced() bool {
    59  	return c.enforced
    60  }
    61  
    62  type checkCollection struct {
    63  	checks []check
    64  }
    65  
    66  func (c *checkCollection) AddCheck(name, expression string, enforce bool) (Check, error) {
    67  	for _, chk := range c.checks {
    68  		if strings.ToLower(name) == strings.ToLower(chk.name) {
    69  			// Engine is supposed to enforce this for us, but just in case
    70  			return nil, fmt.Errorf("name %s in use", name)
    71  		}
    72  	}
    73  
    74  	newCheck := check{
    75  		name:       name,
    76  		expression: expression,
    77  		enforced:   enforce,
    78  	}
    79  	c.checks = append(c.checks, newCheck)
    80  
    81  	return newCheck, nil
    82  }
    83  
    84  func (c *checkCollection) DropCheck(name string) error {
    85  	for i, chk := range c.checks {
    86  		if strings.ToLower(name) == strings.ToLower(chk.name) {
    87  			c.checks = append(c.checks[:i], c.checks[i+1:]...)
    88  			return nil
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  func (c *checkCollection) AllChecks() []Check {
    95  	checks := make([]Check, len(c.checks))
    96  	for i, check := range c.checks {
    97  		checks[i] = check
    98  	}
    99  	return checks
   100  }
   101  
   102  func (c *checkCollection) Equals(other CheckCollection) bool {
   103  
   104  	o := other.(*checkCollection)
   105  	if len(c.checks) != len(o.checks) {
   106  		return false
   107  	}
   108  
   109  	for i := range c.checks {
   110  		a := c.checks[i]
   111  		b := o.checks[i]
   112  		if a.name != b.name ||
   113  			a.expression != b.expression ||
   114  			a.enforced != b.enforced {
   115  			return false
   116  		}
   117  	}
   118  
   119  	return true
   120  }
   121  
   122  func (c *checkCollection) Count() int {
   123  	return len(c.checks)
   124  }
   125  
   126  func NewCheckCollection() CheckCollection {
   127  	return &checkCollection{
   128  		checks: make([]check, 0),
   129  	}
   130  }
   131  
   132  func NewCheck(name, expression string, enforced bool) check {
   133  	return check{
   134  		name:       name,
   135  		expression: expression,
   136  		enforced:   enforced,
   137  	}
   138  }
   139  
   140  func (c checkCollection) Copy() CheckCollection {
   141  	checks := make([]check, len(c.checks))
   142  	for i, check := range c.checks {
   143  		checks[i] = NewCheck(check.name, check.expression, check.enforced)
   144  	}
   145  
   146  	return &c
   147  }