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 }