1
1
<?php
2
+
2
3
namespace App ;
3
4
4
5
use PDO ;
@@ -14,10 +15,91 @@ public function __construct(PDO $pdo)
14
15
$ this ->inspector = new SchemaInspector ($ pdo );
15
16
}
16
17
17
- public function list (string $ table ): array
18
+ /**
19
+ * Enhanced list: supports filtering, sorting, pagination.
20
+ */
21
+ public function list (string $ table , array $ opts = []): array
18
22
{
19
- $ stmt = $ this ->pdo ->query ("SELECT * FROM ` $ table` " );
20
- return $ stmt ->fetchAll (PDO ::FETCH_ASSOC );
23
+ $ columns = $ this ->inspector ->getColumns ($ table );
24
+ $ colNames = array_column ($ columns , 'Field ' );
25
+
26
+ // --- Filtering ---
27
+ $ where = [];
28
+ $ params = [];
29
+ if (!empty ($ opts ['filter ' ])) {
30
+ // Example filter: ['name:Alice', 'email:gmail.com']
31
+ $ filters = explode (', ' , $ opts ['filter ' ]);
32
+ foreach ($ filters as $ f ) {
33
+ $ parts = explode (': ' , $ f , 2 );
34
+ if (count ($ parts ) === 2 && in_array ($ parts [0 ], $ colNames , true )) {
35
+ $ col = $ parts [0 ];
36
+ $ val = $ parts [1 ];
37
+ // Use LIKE for partial match, = for exact
38
+ if (str_contains ($ val , '% ' )) {
39
+ $ where [] = "` $ col` LIKE : $ col " ;
40
+ $ params [$ col ] = $ val ;
41
+ } else {
42
+ $ where [] = "` $ col` = : $ col " ;
43
+ $ params [$ col ] = $ val ;
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ // --- Sorting ---
50
+ $ orderBy = '' ;
51
+ if (!empty ($ opts ['sort ' ])) {
52
+ $ orders = [];
53
+ $ sorts = explode (', ' , $ opts ['sort ' ]);
54
+ foreach ($ sorts as $ sort ) {
55
+ $ direction = 'ASC ' ;
56
+ $ col = $ sort ;
57
+ if (str_starts_with ($ sort , '- ' )) {
58
+ $ direction = 'DESC ' ;
59
+ $ col = substr ($ sort , 1 );
60
+ }
61
+ if (in_array ($ col , $ colNames , true )) {
62
+ $ orders [] = "` $ col` $ direction " ;
63
+ }
64
+ }
65
+ if ($ orders ) {
66
+ $ orderBy = 'ORDER BY ' . implode (', ' , $ orders );
67
+ }
68
+ }
69
+
70
+ // --- Pagination ---
71
+ $ page = max (1 , (int )($ opts ['page ' ] ?? 1 ));
72
+ $ pageSize = max (1 , min (100 , (int )($ opts ['page_size ' ] ?? 20 ))); // max 100 rows per page
73
+ $ offset = ($ page - 1 ) * $ pageSize ;
74
+ $ limit = "LIMIT $ pageSize OFFSET $ offset " ;
75
+
76
+ $ sql = "SELECT * FROM ` $ table` " ;
77
+ if ($ where ) {
78
+ $ sql .= ' WHERE ' . implode (' AND ' , $ where );
79
+ }
80
+ if ($ orderBy ) {
81
+ $ sql .= ' ' . $ orderBy ;
82
+ }
83
+ $ sql .= " $ limit " ;
84
+
85
+ $ stmt = $ this ->pdo ->prepare ($ sql );
86
+ $ stmt ->execute ($ params );
87
+ $ rows = $ stmt ->fetchAll (PDO ::FETCH_ASSOC );
88
+
89
+ // Optionally: include pagination meta info
90
+ $ countStmt = $ this ->pdo ->prepare ("SELECT COUNT(*) FROM ` $ table` " . ($ where ? ' WHERE ' . implode (' AND ' , $ where ) : '' ));
91
+ $ countStmt ->execute ($ params );
92
+ $ total = (int )$ countStmt ->fetchColumn ();
93
+
94
+ return [
95
+ 'data ' => $ rows ,
96
+ 'meta ' => [
97
+ 'total ' => $ total ,
98
+ 'page ' => $ page ,
99
+ 'page_size ' => $ pageSize ,
100
+ 'pages ' => (int )ceil ($ total / $ pageSize )
101
+ ]
102
+ ];
21
103
}
22
104
23
105
public function read (string $ table , $ id ): ?array
@@ -52,6 +134,10 @@ public function update(string $table, $id, array $data): array
52
134
foreach ($ data as $ col => $ val ) {
53
135
$ sets [] = "` $ col` = : $ col " ;
54
136
}
137
+ // Handle no fields to update
138
+ if (empty ($ sets )) {
139
+ return ["error " => "No fields to update. Send at least one column. " ];
140
+ }
55
141
$ sql = sprintf (
56
142
"UPDATE `%s` SET %s WHERE ` $ pk` = :id " ,
57
143
$ table ,
@@ -60,13 +146,32 @@ public function update(string $table, $id, array $data): array
60
146
$ stmt = $ this ->pdo ->prepare ($ sql );
61
147
$ data ['id ' ] = $ id ;
62
148
$ stmt ->execute ($ data );
63
- return $ this ->read ($ table , $ id );
149
+ // Check if any row was actually updated
150
+ if ($ stmt ->rowCount () === 0 ) {
151
+ // Check if the row exists at all
152
+ $ existing = $ this ->read ($ table , $ id );
153
+ if ($ existing === null ) {
154
+ return ["error " => "Item with id $ id not found in $ table. " ];
155
+ } else {
156
+ // The row exists but there was no change (e.g., same data)
157
+ return $ existing ;
158
+ }
159
+ }
160
+ $ updated = $ this ->read ($ table , $ id );
161
+ if ($ updated === null ) {
162
+ return ["error " => "Unexpected error: item not found after update. " ];
163
+ }
164
+ return $ updated ;
64
165
}
65
166
66
- public function delete (string $ table , $ id ): bool
167
+ public function delete (string $ table , $ id ): array
67
168
{
68
169
$ pk = $ this ->inspector ->getPrimaryKey ($ table );
69
170
$ stmt = $ this ->pdo ->prepare ("DELETE FROM ` $ table` WHERE ` $ pk` = :id " );
70
- return $ stmt ->execute (['id ' => $ id ]);
171
+ $ stmt ->execute (['id ' => $ id ]);
172
+ if ($ stmt ->rowCount () === 0 ) {
173
+ return ['error ' => "Item with id $ id not found in $ table. " ];
174
+ }
175
+ return ['success ' => true ];
71
176
}
72
- }
177
+ }
0 commit comments