Skip to content

Commit 8115d07

Browse files
committed
refactor: remove collectors from ParsedQuery
1 parent a0ca52d commit 8115d07

File tree

7 files changed

+182
-105
lines changed

7 files changed

+182
-105
lines changed

documentation/components/libs/pg-query.md

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,27 @@ composer require flow-php/pg-query:~--FLOW_PHP_VERSION--
2121
```php
2222
<?php
2323

24-
use function Flow\PgQuery\DSL\pg_parse;
24+
use function Flow\PgQuery\DSL\{pg_parse, pg_query_tables, pg_query_columns, pg_query_functions};
2525

2626
$query = pg_parse('SELECT u.id, u.name FROM users u JOIN orders o ON u.id = o.user_id');
2727

2828
// Get all tables
29-
foreach ($query->tables() as $table) {
29+
foreach (pg_query_tables($query)->all() as $table) {
3030
echo $table->name(); // 'users', 'orders'
3131
echo $table->alias(); // 'u', 'o'
3232
}
3333

3434
// Get all columns
35-
foreach ($query->columns() as $column) {
35+
foreach (pg_query_columns($query)->all() as $column) {
3636
echo $column->name(); // 'id', 'name', 'id', 'user_id'
3737
echo $column->table(); // 'u', 'u', 'u', 'o'
3838
}
3939

4040
// Get columns for specific table
41-
$userColumns = $query->columns('u');
41+
$userColumns = pg_query_columns($query)->forTable('u');
4242

4343
// Get all function calls
44-
foreach ($query->functions() as $func) {
44+
foreach (pg_query_functions($query)->all() as $func) {
4545
echo $func->name(); // function name
4646
echo $func->schema(); // schema if qualified (e.g., 'pg_catalog')
4747
}
@@ -97,6 +97,9 @@ use function Flow\PgQuery\DSL\{
9797
pg_deparse_options,
9898
pg_format,
9999
pg_summary,
100+
pg_query_columns,
101+
pg_query_tables,
102+
pg_query_functions,
100103
pg_to_paginated_query,
101104
pg_to_count_query,
102105
pg_to_keyset_query,
@@ -111,6 +114,11 @@ $normalizedDdl = pg_normalize_utility('CREATE TABLE users (id INT)');
111114
$statements = pg_split('SELECT 1; SELECT 2;');
112115
$summary = pg_summary('SELECT * FROM users');
113116

117+
// Extract columns, tables, and functions
118+
$columns = pg_query_columns($query)->all();
119+
$tables = pg_query_tables($query)->all();
120+
$functions = pg_query_functions(pg_parse('SELECT COUNT(*) FROM users'))->all();
121+
114122
// Deparse (convert AST back to SQL)
115123
$sql = pg_deparse($query); // Simple output
116124
$sql = pg_deparse($query, pg_deparse_options()->indentSize(2)); // Pretty printed
@@ -127,13 +135,30 @@ $formatted = pg_format('SELECT id,name FROM users WHERE active=true');
127135

128136
| Method | Description | Returns |
129137
|--------|-------------|---------|
130-
| `tables()` | Get all tables referenced in the query | `array<Table>` |
131-
| `columns(?string $tableName)` | Get columns, optionally filtered by table/alias | `array<Column>` |
132-
| `functions()` | Get all function calls | `array<FunctionCall>` |
133138
| `deparse(?DeparseOptions $options)` | Convert AST back to SQL string | `string` |
134139
| `traverse(NodeVisitor|NodeModifier ...)` | Traverse AST with visitors/modifiers | `$this` |
135140
| `raw()` | Access underlying protobuf ParseResult | `ParseResult` |
136141

142+
## Extractor Functions
143+
144+
| Function | Description | Returns |
145+
|----------|-------------|---------|
146+
| `pg_query_tables($query)` | Extract tables from the query | `Tables` |
147+
| `pg_query_columns($query)` | Extract columns from the query | `Columns` |
148+
| `pg_query_functions($query)` | Extract function calls from the query | `Functions` |
149+
150+
### Extractor Methods
151+
152+
**Columns** extractor:
153+
- `all()` - Get all columns
154+
- `forTable(string $tableName)` - Get columns filtered by table/alias
155+
156+
**Tables** extractor:
157+
- `all()` - Get all tables
158+
159+
**Functions** extractor:
160+
- `all()` - Get all function calls
161+
137162
## Deparsing (AST to SQL)
138163

139164
Convert a parsed query back to SQL, optionally with pretty-printing:

src/lib/pg-query/src/Flow/PgQuery/DSL/functions.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Flow\ETL\Attribute\{DocumentationDSL, Module, Type as DSLType};
88
use Flow\PgQuery\AST\Transformers\{CountModifier, KeysetColumn, KeysetPaginationConfig, KeysetPaginationModifier, PaginationConfig, PaginationModifier, SortOrder};
99
use Flow\PgQuery\{DeparseOptions, ParsedQuery, Parser};
10+
use Flow\PgQuery\Extractors\{Columns, Functions, Tables};
1011

1112
#[DocumentationDSL(module: Module::PG_QUERY, type: DSLType::HELPER)]
1213
function pg_parser() : Parser
@@ -247,3 +248,30 @@ function pg_keyset_pagination(int $limit, array $columns, ?array $cursor = null)
247248
{
248249
return new KeysetPaginationModifier(new KeysetPaginationConfig($limit, $columns, $cursor));
249250
}
251+
252+
/**
253+
* Extract columns from a parsed SQL query.
254+
*/
255+
#[DocumentationDSL(module: Module::PG_QUERY, type: DSLType::HELPER)]
256+
function pg_query_columns(ParsedQuery $query) : Columns
257+
{
258+
return new Columns($query);
259+
}
260+
261+
/**
262+
* Extract tables from a parsed SQL query.
263+
*/
264+
#[DocumentationDSL(module: Module::PG_QUERY, type: DSLType::HELPER)]
265+
function pg_query_tables(ParsedQuery $query) : Tables
266+
{
267+
return new Tables($query);
268+
}
269+
270+
/**
271+
* Extract functions from a parsed SQL query.
272+
*/
273+
#[DocumentationDSL(module: Module::PG_QUERY, type: DSLType::HELPER)]
274+
function pg_query_functions(ParsedQuery $query) : Functions
275+
{
276+
return new Functions($query);
277+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\PgQuery\Extractors;
6+
7+
use Flow\PgQuery\AST\Nodes\Column;
8+
use Flow\PgQuery\AST\Visitors\ColumnRefCollector;
9+
use Flow\PgQuery\ParsedQuery;
10+
11+
final readonly class Columns
12+
{
13+
public function __construct(private ParsedQuery $query)
14+
{
15+
}
16+
17+
/**
18+
* @return array<Column>
19+
*/
20+
public function all() : array
21+
{
22+
$collector = new ColumnRefCollector();
23+
$this->query->traverse($collector);
24+
25+
return \array_values(\array_filter(
26+
\array_map(static fn ($ref) => new Column($ref), $collector->getColumnRefs()),
27+
static fn ($col) => $col->name() !== null
28+
));
29+
}
30+
31+
/**
32+
* @return array<Column>
33+
*/
34+
public function forTable(string $tableName) : array
35+
{
36+
return \array_values(\array_filter(
37+
$this->all(),
38+
static fn ($col) => $col->table() === $tableName
39+
));
40+
}
41+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\PgQuery\Extractors;
6+
7+
use Flow\PgQuery\AST\Nodes\FunctionCall;
8+
use Flow\PgQuery\AST\Visitors\FuncCallCollector;
9+
use Flow\PgQuery\ParsedQuery;
10+
11+
final readonly class Functions
12+
{
13+
public function __construct(private ParsedQuery $query)
14+
{
15+
}
16+
17+
/**
18+
* @return array<FunctionCall>
19+
*/
20+
public function all() : array
21+
{
22+
$collector = new FuncCallCollector();
23+
$this->query->traverse($collector);
24+
25+
return \array_values(\array_filter(
26+
\array_map(static fn ($ref) => new FunctionCall($ref), $collector->getFuncCalls()),
27+
static fn ($func) => $func->name() !== null
28+
));
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\PgQuery\Extractors;
6+
7+
use Flow\PgQuery\AST\Nodes\Table;
8+
use Flow\PgQuery\AST\Visitors\RangeVarCollector;
9+
use Flow\PgQuery\ParsedQuery;
10+
11+
final readonly class Tables
12+
{
13+
public function __construct(private ParsedQuery $query)
14+
{
15+
}
16+
17+
/**
18+
* @return array<Table>
19+
*/
20+
public function all() : array
21+
{
22+
$collector = new RangeVarCollector();
23+
$this->query->traverse($collector);
24+
25+
return \array_values(\array_filter(
26+
\array_map(static fn ($ref) => new Table($ref), $collector->getRangeVars()),
27+
static fn ($table) => $table->name() !== ''
28+
));
29+
}
30+
}

src/lib/pg-query/src/Flow/PgQuery/ParsedQuery.php

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
namespace Flow\PgQuery;
66

77
use Flow\PgQuery\AST\{NodeModifier, NodeVisitor, Traverser};
8-
use Flow\PgQuery\AST\Nodes\{Column, FunctionCall, Table};
9-
use Flow\PgQuery\AST\Visitors\{ColumnRefCollector, FuncCallCollector, RangeVarCollector};
108
use Flow\PgQuery\Protobuf\AST\ParseResult;
119

1210
final readonly class ParsedQuery
@@ -16,34 +14,6 @@ public function __construct(
1614
) {
1715
}
1816

19-
/**
20-
* @return array<Column>
21-
*/
22-
public function columns(?string $tableName = null) : array
23-
{
24-
$collector = new ColumnRefCollector();
25-
$traverser = new Traverser($collector);
26-
$traverser->traverse($this->parseResult);
27-
28-
$columns = [];
29-
30-
foreach ($collector->getColumnRefs() as $columnRef) {
31-
$column = new Column($columnRef);
32-
33-
if ($column->name() === null) {
34-
continue;
35-
}
36-
37-
if ($tableName !== null && $column->table() !== $tableName) {
38-
continue;
39-
}
40-
41-
$columns[] = $column;
42-
}
43-
44-
return $columns;
45-
}
46-
4717
/**
4818
* Convert the parsed AST back to SQL string.
4919
*
@@ -68,59 +38,11 @@ public function deparse(?DeparseOptions $options = null) : string
6838
);
6939
}
7040

71-
/**
72-
* @return array<FunctionCall>
73-
*/
74-
public function functions() : array
75-
{
76-
$collector = new FuncCallCollector();
77-
$traverser = new Traverser($collector);
78-
$traverser->traverse($this->parseResult);
79-
80-
$functions = [];
81-
82-
foreach ($collector->getFuncCalls() as $funcCall) {
83-
$function = new FunctionCall($funcCall);
84-
85-
if ($function->name() === null) {
86-
continue;
87-
}
88-
89-
$functions[] = $function;
90-
}
91-
92-
return $functions;
93-
}
94-
9541
public function raw() : ParseResult
9642
{
9743
return $this->parseResult;
9844
}
9945

100-
/**
101-
* @return array<Table>
102-
*/
103-
public function tables() : array
104-
{
105-
$collector = new RangeVarCollector();
106-
$traverser = new Traverser($collector);
107-
$traverser->traverse($this->parseResult);
108-
109-
$tables = [];
110-
111-
foreach ($collector->getRangeVars() as $rangeVar) {
112-
$table = new Table($rangeVar);
113-
114-
if ($table->name() === '') {
115-
continue;
116-
}
117-
118-
$tables[] = $table;
119-
}
120-
121-
return $tables;
122-
}
123-
12446
/**
12547
* Traverse the AST with visitors and/or modifiers.
12648
*

0 commit comments

Comments
 (0)