github.com/mithrandie/csvq@v1.18.1/lib/query/view_map.go (about)

     1  package query
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strings"
     7  
     8  	"github.com/mithrandie/csvq/lib/file"
     9  	"github.com/mithrandie/csvq/lib/option"
    10  	"github.com/mithrandie/csvq/lib/parser"
    11  	"github.com/mithrandie/csvq/lib/value"
    12  )
    13  
    14  var errTableNotLoaded = errors.New("table not loaded")
    15  
    16  type ViewMap struct {
    17  	*SyncMap
    18  }
    19  
    20  func NewViewMap() ViewMap {
    21  	return ViewMap{
    22  		NewSyncMap(),
    23  	}
    24  }
    25  
    26  func (m ViewMap) IsEmpty() bool {
    27  	return m.SyncMap == nil
    28  }
    29  
    30  func (m ViewMap) Store(identifier string, view *View) {
    31  	m.store(identifier, view)
    32  }
    33  
    34  func (m ViewMap) LoadDirect(identifier string) (interface{}, bool) {
    35  	return m.load(identifier)
    36  }
    37  
    38  func (m ViewMap) Load(identifier string) (*View, bool) {
    39  	if v, ok := m.load(identifier); ok {
    40  		return v.(*View), true
    41  	}
    42  	return nil, false
    43  }
    44  
    45  func (m ViewMap) Delete(identifier string) {
    46  	m.delete(identifier)
    47  }
    48  
    49  func (m ViewMap) Exists(identifier string) bool {
    50  	return m.exists(identifier)
    51  }
    52  
    53  func (m ViewMap) Get(identifier string) (*View, error) {
    54  	if view, ok := m.Load(identifier); ok {
    55  		return view.Copy(), nil
    56  	}
    57  	return nil, errTableNotLoaded
    58  }
    59  
    60  func (m ViewMap) GetWithInternalId(ctx context.Context, identifier string, flags *option.Flags) (*View, error) {
    61  	if view, ok := m.Load(identifier); ok {
    62  		ret := view.Copy()
    63  
    64  		ret.Header = NewHeaderWithId(ret.Header[0].View, []string{}).Merge(ret.Header)
    65  
    66  		if err := NewGoroutineTaskManager(ret.RecordLen(), -1, flags.CPU).Run(ctx, func(index int) error {
    67  			record := make(Record, len(ret.RecordSet[index])+1)
    68  			record[0] = NewCell(value.NewInteger(int64(index)))
    69  			for i := 0; i < len(ret.RecordSet[index]); i++ {
    70  				record[i+1] = ret.RecordSet[index][i]
    71  			}
    72  			ret.RecordSet[index] = record
    73  			return nil
    74  		}); err != nil {
    75  			return nil, err
    76  		}
    77  
    78  		return ret, nil
    79  	}
    80  	return nil, errTableNotLoaded
    81  }
    82  
    83  func (m ViewMap) Set(view *View) {
    84  	if view.FileInfo != nil {
    85  		m.Store(view.FileInfo.IdentifiedPath(), view)
    86  	}
    87  }
    88  
    89  func (m ViewMap) DisposeTemporaryTable(tablePath parser.QueryExpression) bool {
    90  	identifier := func() string {
    91  		if e, ok := tablePath.(parser.Stdin); ok {
    92  			return e.String()
    93  		}
    94  		return strings.ToUpper(tablePath.(parser.Identifier).Literal)
    95  	}()
    96  
    97  	if v, ok := m.Load(identifier); ok && v.FileInfo.IsInMemoryTable() {
    98  		m.Delete(identifier)
    99  		return true
   100  	}
   101  	return false
   102  }
   103  
   104  func (m ViewMap) Dispose(container *file.Container, identifier string) error {
   105  	if view, ok := m.Load(identifier); ok {
   106  		if view.FileInfo.Handler != nil {
   107  			if err := container.Close(view.FileInfo.Handler); err != nil {
   108  				return err
   109  			}
   110  		}
   111  		m.Delete(identifier)
   112  	}
   113  	return nil
   114  }
   115  
   116  func (m ViewMap) Clean(container *file.Container) error {
   117  	keys := m.Keys()
   118  	for _, k := range keys {
   119  		if err := m.Dispose(container, k); err != nil {
   120  			return err
   121  		}
   122  	}
   123  	return nil
   124  }
   125  
   126  func (m ViewMap) CleanWithErrors(container *file.Container) error {
   127  	keys := m.Keys()
   128  	var errs []error
   129  	for _, k := range keys {
   130  		if view, ok := m.Load(k); ok {
   131  			if err := container.CloseWithErrors(view.FileInfo.Handler); err != nil {
   132  				errs = append(errs, err.(*file.ForcedUnlockError).Errors...)
   133  			}
   134  			m.Delete(k)
   135  		}
   136  	}
   137  
   138  	return file.NewForcedUnlockError(errs)
   139  }