• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stephenafamo / bob / 14939098091

09 May 2025 10:59PM UTC coverage: 36.868% (-4.6%) from 41.506%
14939098091

push

github

stephenafamo
Move reusable sqlite parser components to antlrhelpers package

0 of 758 new or added lines in 12 files covered. (0.0%)

547 existing lines in 8 files now uncovered.

6533 of 17720 relevant lines covered (36.87%)

212.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/gen/bobgen-sqlite/driver/parser/visitor_helpers.go
1
package parser
2

3
import (
4
        "fmt"
5
        "slices"
6
        "strings"
7

8
        "github.com/antlr4-go/antlr/v4"
9
        "github.com/stephenafamo/bob/gen/bobgen-helpers/parser"
10
        antlrhelpers "github.com/stephenafamo/bob/gen/bobgen-helpers/parser/antlrhelpers"
11
        "github.com/stephenafamo/bob/internal"
12
        sqliteparser "github.com/stephenafamo/sqlparser/sqlite"
13
)
14

15
// ---------------------------------------------------------------------------
16
// Comment getter
17
// ---------------------------------------------------------------------------
18

NEW
19
func (v *visitor) getCommentToLeft(ctx Node) string {
×
UNCOV
20
        stream, isCommon := ctx.GetParser().GetTokenStream().(*antlr.CommonTokenStream)
×
UNCOV
21
        if !isCommon {
×
22
                return ""
×
23
        }
×
24

UNCOV
25
        tokenIndex := ctx.GetStart().GetTokenIndex()
×
UNCOV
26
        hiddenTokens := stream.GetHiddenTokensToLeft(tokenIndex, 1)
×
UNCOV
27
        for _, token := range slices.Backward(hiddenTokens) {
×
UNCOV
28
                if token.GetTokenType() == sqliteparser.SQLiteParserSINGLE_LINE_COMMENT {
×
UNCOV
29
                        return strings.TrimSpace(token.GetText()[2:])
×
UNCOV
30
                }
×
31
        }
32

33
        return ""
×
34
}
35

NEW
36
func (v *visitor) getCommentToRight(ctx Node) string {
×
UNCOV
37
        stream, isCommon := ctx.GetParser().GetTokenStream().(*antlr.CommonTokenStream)
×
UNCOV
38
        if !isCommon {
×
39
                return ""
×
40
        }
×
41

UNCOV
42
        tokenIndex := ctx.GetStop().GetTokenIndex()
×
UNCOV
43
        hiddenTokens := stream.GetHiddenTokensToRight(tokenIndex, 1)
×
UNCOV
44
        for _, token := range hiddenTokens {
×
UNCOV
45
                if token.GetTokenType() == sqliteparser.SQLiteParserMULTILINE_COMMENT {
×
46
                        txt := token.GetText()
×
47
                        return strings.TrimSpace(txt[2 : len(txt)-2])
×
48
                }
×
49
        }
50

UNCOV
51
        return ""
×
52
}
53

54
// ---------------------------------------------------------------------------
55
// Edit Rule helpers
56
// ---------------------------------------------------------------------------
57
func (v *visitor) quoteIdentifiable(ctx interface {
58
        Identifier() sqliteparser.IIdentifierContext
59
},
UNCOV
60
) {
×
UNCOV
61
        if ctx == nil {
×
UNCOV
62
                return
×
UNCOV
63
        }
×
64

UNCOV
65
        v.quoteIdentifier(ctx.Identifier())
×
66
}
67

UNCOV
68
func (v *visitor) quoteIdentifier(ctx sqliteparser.IIdentifierContext) {
×
UNCOV
69
        if ctx == nil {
×
70
                return
×
71
        }
×
72

UNCOV
73
        switch ctx.GetParent().(type) {
×
74
        case sqliteparser.ISimple_funcContext,
75
                sqliteparser.IAggregate_funcContext,
76
                sqliteparser.IWindow_funcContext,
77
                sqliteparser.ITable_function_nameContext:
×
78
                return
×
79
        }
80

UNCOV
81
        idContext := ctx
×
UNCOV
82

×
UNCOV
83
        for idContext.OPEN_PAR() != nil {
×
84
                idContext = idContext.Identifier()
×
85
        }
×
86

UNCOV
87
        txt := ctx.GetText()
×
UNCOV
88
        if strings.ContainsAny(string(txt[0]), "\"`[") {
×
89
                txt = txt[1 : len(txt)-1]
×
90
        }
×
91

NEW
92
        v.StmtRules = append(v.StmtRules, internal.Replace(ctx.GetStart().GetStart(), ctx.GetStop().GetStop(), fmt.Sprintf("%q", txt)))
×
93
}
94

95
func (v *visitor) getSourceFromTable(ctx interface {
96
        Schema_name() sqliteparser.ISchema_nameContext
97
        Table_name() sqliteparser.ITable_nameContext
98
        Table_alias() sqliteparser.ITable_aliasContext
99
},
NEW
100
) QuerySource {
×
UNCOV
101
        schema := getName(ctx.Schema_name())
×
UNCOV
102
        v.quoteIdentifiable(ctx.Schema_name())
×
UNCOV
103

×
UNCOV
104
        tableName := getName(ctx.Table_name())
×
UNCOV
105
        v.quoteIdentifiable(ctx.Table_name())
×
UNCOV
106

×
UNCOV
107
        alias := getName(ctx.Table_alias())
×
UNCOV
108
        v.quoteIdentifiable(ctx.Table_alias())
×
UNCOV
109

×
UNCOV
110
        hasAlias := alias != ""
×
UNCOV
111
        if alias == "" {
×
UNCOV
112
                alias = tableName
×
UNCOV
113
        }
×
114

115
        // First check the sources to see if the table exists
116
        // do this ONLY if no schema is provided
UNCOV
117
        if schema == "" {
×
NEW
118
                for _, source := range v.Sources {
×
NEW
119
                        if source.Name == tableName {
×
NEW
120
                                return QuerySource{
×
NEW
121
                                        Name:    alias,
×
NEW
122
                                        Columns: source.Columns,
×
UNCOV
123
                                }
×
UNCOV
124
                        }
×
125
                }
126
        }
127

NEW
128
        for _, table := range v.DB {
×
UNCOV
129
                if table.Name != tableName {
×
UNCOV
130
                        continue
×
131
                }
132

UNCOV
133
                switch {
×
UNCOV
134
                case table.Schema == schema: // schema matches
×
135
                case table.Schema == "" && schema == "main": // schema is shared
×
136
                default:
×
137
                        continue
×
138
                }
139

NEW
140
                source := QuerySource{
×
NEW
141
                        Name:    alias,
×
NEW
142
                        Columns: make([]ReturnColumn, len(table.Columns)),
×
UNCOV
143
                }
×
UNCOV
144
                if !hasAlias {
×
NEW
145
                        source.Schema = schema
×
UNCOV
146
                }
×
UNCOV
147
                for i, col := range table.Columns {
×
NEW
148
                        source.Columns[i] = ReturnColumn{
×
NEW
149
                                Name: col.Name,
×
NEW
150
                                Type: NodeTypes{getColumnType(v.DB, table.Schema, table.Name, col.Name)},
×
UNCOV
151
                        }
×
UNCOV
152
                }
×
UNCOV
153
                return source
×
154
        }
155

NEW
156
        v.Err = fmt.Errorf("table not found: %s", tableName)
×
NEW
157
        return QuerySource{}
×
158
}
159

NEW
160
func (v *visitor) sourceFromColumns(columns []sqliteparser.IResult_columnContext) QuerySource {
×
UNCOV
161
        // Get the return columns
×
NEW
162
        var returnSource QuerySource
×
UNCOV
163

×
UNCOV
164
        for _, resultColumn := range columns {
×
UNCOV
165
                switch {
×
UNCOV
166
                case resultColumn.STAR() != nil: // Has a STAR: * OR table_name.*
×
UNCOV
167
                        table := getName(resultColumn.Table_name())
×
UNCOV
168
                        hasTable := table != "" // the result column is table_name.*
×
UNCOV
169

×
UNCOV
170
                        start := resultColumn.GetStart().GetStart()
×
UNCOV
171
                        stop := resultColumn.GetStop().GetStop()
×
NEW
172
                        v.StmtRules = append(v.StmtRules, internal.Delete(start, stop))
×
UNCOV
173

×
UNCOV
174
                        buf := &strings.Builder{}
×
UNCOV
175
                        var i int
×
NEW
176
                        for _, source := range v.Sources {
×
NEW
177
                                if source.CTE {
×
UNCOV
178
                                        continue
×
179
                                }
NEW
180
                                if hasTable && source.Name != table {
×
181
                                        continue
×
182
                                }
183

NEW
184
                                returnSource.Columns = append(returnSource.Columns, source.Columns...)
×
UNCOV
185

×
UNCOV
186
                                if i > 0 {
×
UNCOV
187
                                        buf.WriteString(", ")
×
UNCOV
188
                                }
×
NEW
189
                                antlrhelpers.ExpandQuotedSource(buf, source)
×
UNCOV
190
                                i++
×
191
                        }
NEW
192
                        v.StmtRules = append(v.StmtRules, internal.Insert(start, buf.String()))
×
193

UNCOV
194
                case resultColumn.Expr() != nil: // expr (AS_? alias)?
×
UNCOV
195
                        expr := resultColumn.Expr()
×
UNCOV
196
                        alias := getName(resultColumn.Alias())
×
UNCOV
197
                        if alias == "" {
×
UNCOV
198
                                if expr, ok := expr.(*sqliteparser.Expr_qualified_column_nameContext); ok {
×
UNCOV
199
                                        alias = getName(expr.Column_name())
×
UNCOV
200
                                }
×
201
                        }
202

NEW
203
                        returnSource.Columns = append(returnSource.Columns, ReturnColumn{
×
NEW
204
                                Name:   alias,
×
NEW
205
                                Config: parser.ParseQueryColumnConfig(v.getCommentToRight(expr)),
×
NEW
206
                                Type:   v.Infos[antlrhelpers.Key(resultColumn.Expr())].Type,
×
UNCOV
207
                        })
×
208
                }
209
        }
210

UNCOV
211
        return returnSource
×
212
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc