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

     1  package query
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/mithrandie/csvq/lib/option"
     7  	"github.com/mithrandie/csvq/lib/parser"
     8  )
     9  
    10  type PreparedStatementMap struct {
    11  	*SyncMap
    12  }
    13  
    14  func NewPreparedStatementMap() PreparedStatementMap {
    15  	return PreparedStatementMap{
    16  		NewSyncMap(),
    17  	}
    18  }
    19  
    20  func (m PreparedStatementMap) Store(name string, statement *PreparedStatement) {
    21  	m.store(strings.ToUpper(name), statement)
    22  }
    23  
    24  func (m PreparedStatementMap) LoadDirect(name string) (interface{}, bool) {
    25  	return m.load(strings.ToUpper(name))
    26  }
    27  
    28  func (m PreparedStatementMap) Load(name string) (*PreparedStatement, bool) {
    29  	if v, ok := m.load(strings.ToUpper(name)); ok {
    30  		return v.(*PreparedStatement), true
    31  	}
    32  	return nil, false
    33  }
    34  
    35  func (m PreparedStatementMap) Delete(name string) {
    36  	m.delete(strings.ToUpper(name))
    37  }
    38  
    39  func (m PreparedStatementMap) Exists(name string) bool {
    40  	return m.exists(strings.ToUpper(name))
    41  }
    42  
    43  func (m PreparedStatementMap) Prepare(flags *option.Flags, expr parser.StatementPreparation) error {
    44  	stmt, err := NewPreparedStatement(flags, expr)
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	if m.Exists(expr.Name.Literal) {
    50  		return NewDuplicateStatementNameError(expr.Name)
    51  	}
    52  	m.Store(expr.Name.Literal, stmt)
    53  	return nil
    54  }
    55  
    56  func (m PreparedStatementMap) Get(name parser.Identifier) (*PreparedStatement, error) {
    57  	if stmt, ok := m.Load(name.Literal); ok {
    58  		return stmt, nil
    59  	}
    60  	return nil, NewStatementNotExistError(name)
    61  }
    62  
    63  func (m PreparedStatementMap) Dispose(expr parser.DisposeStatement) error {
    64  	if !m.Exists(expr.Name.Literal) {
    65  		return NewStatementNotExistError(expr.Name)
    66  	}
    67  	m.Delete(expr.Name.Literal)
    68  	return nil
    69  }
    70  
    71  type PreparedStatement struct {
    72  	Name            string
    73  	StatementString string
    74  	Statements      []parser.Statement
    75  	HolderNumber    int
    76  }
    77  
    78  func NewPreparedStatement(flags *option.Flags, expr parser.StatementPreparation) (*PreparedStatement, error) {
    79  	statements, holderNum, err := parser.Parse(expr.Statement.Raw(), expr.Name.Literal, true, flags.AnsiQuotes)
    80  	if err != nil {
    81  		return nil, NewPreparedStatementSyntaxError(err.(*parser.SyntaxError))
    82  	}
    83  
    84  	return &PreparedStatement{
    85  		Name:            expr.Name.Literal,
    86  		StatementString: expr.Statement.Raw(),
    87  		Statements:      statements,
    88  		HolderNumber:    holderNum,
    89  	}, nil
    90  }
    91  
    92  type ReplaceValues struct {
    93  	Values []parser.QueryExpression
    94  	Names  map[string]int
    95  }
    96  
    97  func NewReplaceValues(replace []parser.ReplaceValue) *ReplaceValues {
    98  	values := make([]parser.QueryExpression, 0, len(replace))
    99  	names := make(map[string]int, len(replace))
   100  
   101  	for i := range replace {
   102  		if 0 < len(replace[i].Name.Literal) {
   103  			names[replace[i].Name.Literal] = i
   104  		}
   105  		values = append(values, replace[i].Value)
   106  	}
   107  
   108  	return &ReplaceValues{
   109  		Values: values,
   110  		Names:  names,
   111  	}
   112  }