github.com/mithrandie/csvq@v1.18.1/lib/file/container.go (about)

     1  package file
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"strings"
     8  	"time"
     9  )
    10  
    11  type Container struct {
    12  	m map[string]*Handler
    13  }
    14  
    15  func NewContainer() *Container {
    16  	return &Container{
    17  		m: make(map[string]*Handler),
    18  	}
    19  }
    20  
    21  func (c *Container) Keys() []string {
    22  	l := make([]string, 0, len(c.m))
    23  	for k := range c.m {
    24  		l = append(l, k)
    25  	}
    26  	return l
    27  }
    28  
    29  func (c *Container) Add(path string, handler *Handler) error {
    30  	key := strings.ToUpper(path)
    31  	if _, ok := c.m[key]; ok {
    32  		return errors.New(fmt.Sprintf("file %s already opened", path))
    33  	}
    34  	c.m[key] = handler
    35  	return nil
    36  }
    37  
    38  func (c *Container) Remove(path string) {
    39  	key := strings.ToUpper(path)
    40  	if _, ok := c.m[key]; ok {
    41  		delete(c.m, key)
    42  	}
    43  }
    44  
    45  func (c *Container) CreateHandlerWithoutLock(ctx context.Context, path string, defaultWaitTimeout time.Duration, retryDelay time.Duration) (*Handler, error) {
    46  	return c.createHandler(ctx, path, defaultWaitTimeout, retryDelay, NewHandlerWithoutLock)
    47  }
    48  
    49  func (c *Container) CreateHandlerForRead(ctx context.Context, path string, defaultWaitTimeout time.Duration, retryDelay time.Duration) (*Handler, error) {
    50  	return c.createHandler(ctx, path, defaultWaitTimeout, retryDelay, NewHandlerForRead)
    51  }
    52  
    53  func (c *Container) CreateHandlerForCreate(path string) (*Handler, error) {
    54  	return c.createHandler(nil, path, DefaultWaitTimeout, DefaultRetryDelay, newHandlerForCreate)
    55  }
    56  
    57  func (c *Container) CreateHandlerForUpdate(ctx context.Context, path string, defaultWaitTimeout time.Duration, retryDelay time.Duration) (*Handler, error) {
    58  	return c.createHandler(ctx, path, defaultWaitTimeout, retryDelay, NewHandlerForUpdate)
    59  }
    60  
    61  func (c *Container) createHandler(ctx context.Context, path string, defaultWaitTimeout time.Duration, retryDelay time.Duration, fn func(context.Context, string, time.Duration, time.Duration) (*Handler, error)) (*Handler, error) {
    62  	h, err := fn(ctx, path, defaultWaitTimeout, retryDelay)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	if err := c.Add(h.path, h); err != nil {
    68  		return h, closeIsolatedHandler(h, err)
    69  	}
    70  	return h, nil
    71  }
    72  
    73  func (c *Container) Close(h *Handler) error {
    74  	if h == nil {
    75  		return nil
    76  	}
    77  
    78  	key := strings.ToUpper(h.Path())
    79  	if _, ok := c.m[key]; ok {
    80  		if err := c.m[key].close(); err != nil {
    81  			return err
    82  		}
    83  		c.Remove(h.Path())
    84  	}
    85  	return nil
    86  }
    87  
    88  func (c *Container) Commit(h *Handler) error {
    89  	if h == nil {
    90  		return nil
    91  	}
    92  
    93  	key := strings.ToUpper(h.Path())
    94  	if _, ok := c.m[key]; ok {
    95  		if err := c.m[key].commit(); err != nil {
    96  			return err
    97  		}
    98  		c.Remove(h.Path())
    99  	}
   100  	return nil
   101  }
   102  
   103  func (c *Container) CloseWithErrors(h *Handler) (err error) {
   104  	if h == nil {
   105  		return nil
   106  	}
   107  
   108  	key := strings.ToUpper(h.Path())
   109  	if _, ok := c.m[key]; ok {
   110  		err = c.m[key].closeWithErrors()
   111  		c.Remove(h.Path())
   112  	}
   113  	return
   114  }
   115  
   116  func (c *Container) CloseAll() error {
   117  	for k := range c.m {
   118  		if err := c.Close(c.m[k]); err != nil {
   119  			return err
   120  		}
   121  	}
   122  	return nil
   123  }
   124  
   125  func (c *Container) CloseAllWithErrors() error {
   126  	var errs []error
   127  	for k := range c.m {
   128  		if err := c.CloseWithErrors(c.m[k]); err != nil {
   129  			errs = append(errs, err.(*ForcedUnlockError).Errors...)
   130  		}
   131  	}
   132  
   133  	return NewForcedUnlockError(errs)
   134  }