Skip to content

Commit 3204b5b

Browse files
committed
added table selector
1 parent 379e0e2 commit 3204b5b

File tree

4 files changed

+139
-29
lines changed

4 files changed

+139
-29
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
/sqlparser.exe
1+
/*.exe

cmd/sqlparser/main.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,26 @@ func main() {
2727
}
2828

2929
filename := args[0]
30+
31+
// Scan for tables and prompt for selection
32+
tables, err := parser.ScanTables(filename)
33+
if err != nil {
34+
fmt.Printf("Error scanning tables: %v\n", err)
35+
os.Exit(1)
36+
}
37+
38+
selectedTable, err := parser.PromptTableSelection(tables)
39+
if err != nil {
40+
fmt.Printf("Error selecting table: %v\n", err)
41+
os.Exit(1)
42+
}
43+
44+
fmt.Printf("\nSelected table: %s\n", selectedTable.Name)
45+
3046
outputFormat := models.OutputFormat(*format)
3147

3248
// Create output file or use stdout
3349
var out *os.File
34-
var err error
3550
if *output != "" {
3651
out, err = os.Create(*output)
3752
if err != nil {
@@ -53,7 +68,7 @@ func main() {
5368

5469
// Process the file
5570
fmt.Printf("Processing with %d workers...\n", *workers)
56-
err = parser.ProcessSQLFileInBatches(filename, w, *workers)
71+
err = parser.ProcessSQLFileInBatches(filename, w, *workers, selectedTable)
5772
if err != nil {
5873
fmt.Printf("Error processing SQL file: %v\n", err)
5974
os.Exit(1)

pkg/parser/database.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package parser
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
"sort"
8+
"strings"
9+
)
10+
11+
type TableInfo struct {
12+
Name string
13+
LineFrom int
14+
LineTo int
15+
}
16+
17+
func ScanTables(filename string) ([]TableInfo, error) {
18+
file, err := os.Open(filename)
19+
if err != nil {
20+
return nil, fmt.Errorf("error opening file: %v", err)
21+
}
22+
defer file.Close()
23+
24+
// Use a larger buffer for scanning
25+
buf := make([]byte, 64*1024)
26+
scanner := bufio.NewScanner(file)
27+
scanner.Buffer(buf, 10*1024*1024) // 10MB max line length
28+
29+
// Use a map to track unique tables
30+
tableMap := make(map[string]*TableInfo)
31+
32+
lineNum := 0
33+
for scanner.Scan() {
34+
lineNum++
35+
line := strings.TrimSpace(scanner.Text())
36+
37+
// Skip empty lines and comments
38+
if line == "" || strings.HasPrefix(line, "--") {
39+
continue
40+
}
41+
42+
// Check for INSERT INTO statements
43+
if strings.HasPrefix(strings.ToUpper(line), "INSERT INTO") {
44+
parts := strings.Split(line, "`")
45+
if len(parts) >= 2 {
46+
tableName := parts[1]
47+
if _, exists := tableMap[tableName]; !exists {
48+
tableMap[tableName] = &TableInfo{
49+
Name: tableName,
50+
LineFrom: lineNum,
51+
}
52+
}
53+
}
54+
}
55+
}
56+
57+
if err := scanner.Err(); err != nil {
58+
return nil, fmt.Errorf("error scanning file: %v", err)
59+
}
60+
61+
// Convert map to slice
62+
var tables []TableInfo
63+
for _, table := range tableMap {
64+
tables = append(tables, *table)
65+
}
66+
67+
// Sort tables by name for consistent display
68+
sort.Slice(tables, func(i, j int) bool {
69+
return tables[i].Name < tables[j].Name
70+
})
71+
72+
return tables, nil
73+
}
74+
75+
func PromptTableSelection(tables []TableInfo) (*TableInfo, error) {
76+
if len(tables) == 0 {
77+
return nil, fmt.Errorf("no tables found in the file")
78+
}
79+
80+
fmt.Println("\nFound the following tables with INSERT statements:")
81+
for i, table := range tables {
82+
fmt.Printf("%d. %s\n", i+1, table.Name)
83+
}
84+
85+
var choice int
86+
fmt.Print("\nEnter the number of the table you want to parse (1-" + fmt.Sprint(len(tables)) + "): ")
87+
_, err := fmt.Scanf("%d", &choice)
88+
if err != nil || choice < 1 || choice > len(tables) {
89+
return nil, fmt.Errorf("invalid selection")
90+
}
91+
92+
return &tables[choice-1], nil
93+
}

pkg/parser/parser.go

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"sqlparser/pkg/writer"
1313
)
1414

15-
func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers int) error {
15+
func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers int, selectedTable *TableInfo) error {
1616
startTime := time.Now()
1717

1818
file, err := os.Open(filename)
@@ -34,6 +34,7 @@ func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers i
3434
}, numWorkers*2)
3535

3636
fmt.Printf("Starting to process file: %s at %s\n", filename, startTime.Format(time.RFC3339))
37+
fmt.Printf("Processing table: %s (lines %d-%d)\n", selectedTable.Name, selectedTable.LineFrom, selectedTable.LineTo)
3738

3839
// Start worker pool
3940
var wg sync.WaitGroup
@@ -70,27 +71,9 @@ func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers i
7071
continue
7172
}
7273

73-
if result.rows != nil {
74+
if result.rows != nil && result.tableName == selectedTable.Name {
7475
// Handle new table
7576
if result.tableName != currentTableName {
76-
if currentTableName != "" {
77-
if len(currentBatch) > 0 {
78-
if err := writer.WriteRows(currentBatch); err != nil {
79-
fmt.Printf("Error writing rows: %v\n", err)
80-
continue
81-
}
82-
batchCount++
83-
fmt.Printf("Processed batch %d for table %s (%d rows)\n", batchCount, currentTableName, len(currentBatch))
84-
currentBatch = nil // Help GC
85-
}
86-
if err := writer.WriteTableEnd(); err != nil {
87-
fmt.Printf("Error ending table: %v\n", err)
88-
continue
89-
}
90-
tableDuration := time.Since(tableStartTime)
91-
fmt.Printf("Finished processing table %s (total %d rows in %d batches) in %v\n",
92-
currentTableName, rowCount, batchCount, tableDuration)
93-
}
9477
currentTableName = result.tableName
9578
if err := writer.WriteTableStart(currentTableName); err != nil {
9679
fmt.Printf("Error starting table: %v\n", err)
@@ -100,7 +83,7 @@ func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers i
10083
rowCount = 0
10184
batchCount = 0
10285
tableStartTime = time.Now()
103-
fmt.Printf("Started processing new table: %s at %s\n", currentTableName, tableStartTime.Format(time.RFC3339))
86+
fmt.Printf("Started processing table: %s at %s\n", currentTableName, tableStartTime.Format(time.RFC3339))
10487
}
10588

10689
// Process rows immediately
@@ -132,19 +115,37 @@ func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers i
132115

133116
// Read and send statements to workers
134117
var currentStatement strings.Builder
118+
lineNum := 0
119+
inSelectedTable := false
120+
135121
for scanner.Scan() {
122+
lineNum++
136123
line := scanner.Text()
137124

125+
// Skip empty lines and comments
138126
if strings.TrimSpace(line) == "" || strings.HasPrefix(strings.TrimSpace(line), "--") {
139127
continue
140128
}
141129

142-
currentStatement.WriteString(line)
143-
currentStatement.WriteString(" ")
130+
// Check if we're in the selected table's INSERT statements
131+
if strings.HasPrefix(strings.ToUpper(strings.TrimSpace(line)), "INSERT INTO") {
132+
tableParts := strings.Split(line, "`")
133+
if len(tableParts) >= 2 && tableParts[1] == selectedTable.Name {
134+
inSelectedTable = true
135+
} else {
136+
inSelectedTable = false
137+
}
138+
}
144139

145-
if strings.HasSuffix(strings.TrimSpace(line), ";") {
146-
statementChan <- currentStatement.String()
147-
currentStatement.Reset()
140+
// Only process INSERT statements for the selected table
141+
if inSelectedTable {
142+
currentStatement.WriteString(line)
143+
currentStatement.WriteString(" ")
144+
145+
if strings.HasSuffix(strings.TrimSpace(line), ";") {
146+
statementChan <- currentStatement.String()
147+
currentStatement.Reset()
148+
}
148149
}
149150
}
150151

@@ -177,6 +178,7 @@ func ProcessSQLFileInBatches(filename string, writer writer.Writer, numWorkers i
177178
totalDuration := time.Since(startTime)
178179
fmt.Printf("\nProcessing Summary:\n")
179180
fmt.Printf("File: %s\n", filename)
181+
fmt.Printf("Table: %s\n", selectedTable.Name)
180182
fmt.Printf("Total Statements: %d\n", totalStatements)
181183
fmt.Printf("Total Duration: %v\n", totalDuration)
182184
fmt.Printf("Average Time per Statement: %v\n", totalDuration/time.Duration(totalStatements))

0 commit comments

Comments
 (0)