11import 'package:ht_data_client/ht_data_client.dart' ;
22import 'package:ht_shared/ht_shared.dart' hide ServerException;
3+ import 'package:logging/logging.dart' ;
34import 'package:postgres/postgres.dart' ;
45
56/// {@template ht_data_postgres}
@@ -19,6 +20,8 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
1920 required this .toJson,
2021 }) : _queryBuilder = _QueryBuilder (tableName: tableName);
2122
23+ final _log = Logger ('HtDataPostgresClient<$T >' );
24+
2225 /// The active PostgreSQL database connection.
2326 final Connection connection;
2427
@@ -40,6 +43,7 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
4043 required T item,
4144 String ? userId,
4245 }) async {
46+ _log.fine ('Creating item in "$tableName "...' );
4347 try {
4448 final data = toJson (item);
4549 if (userId != null ) {
@@ -62,15 +66,20 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
6266 final createdItem = fromJson (
6367 result.first.toColumnMap (),
6468 );
69+ _log.finer (
70+ 'Successfully created item with id "${(createdItem as dynamic ).id }" in "$tableName ".' ,
71+ );
6572 return SuccessApiResponse (data: createdItem);
66- } on Object catch (e) {
73+ } on Object catch (e, st) {
74+ _log.severe ('Failed to create item in "$tableName ".' , e, st);
6775 throw _handlePgException (e);
6876 }
6977 }
7078
7179 @override
7280 Future <void > delete ({required String id, String ? userId}) async {
7381 try {
82+ _log.fine ('Deleting item with id "$id " from "$tableName "...' );
7483 var sql = 'DELETE FROM $tableName WHERE id = @id' ;
7584 final parameters = < String , dynamic > {'id' : id};
7685
@@ -89,7 +98,9 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
8998 'Item with ID "$id " not found${userId != null ? ' for this user' : '' }.' ,
9099 );
91100 }
92- } on Object catch (e) {
101+ _log.finer ('Successfully deleted item with id "$id " from "$tableName ".' );
102+ } on Object catch (e, st) {
103+ _log.severe ('Failed to delete item with id "$id " from "$tableName ".' , e, st);
93104 throw _handlePgException (e);
94105 }
95106 }
@@ -99,6 +110,7 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
99110 required String id,
100111 String ? userId,
101112 }) async {
113+ _log.fine ('Reading item with id "$id " from "$tableName "...' );
102114 try {
103115 var sql = 'SELECT * FROM $tableName WHERE id = @id' ;
104116 final parameters = < String , dynamic > {'id' : id};
@@ -120,8 +132,10 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
120132 );
121133 }
122134 final readItem = fromJson (result.first.toColumnMap ());
135+ _log.finer ('Successfully read item with id "$id " from "$tableName ".' );
123136 return SuccessApiResponse (data: readItem);
124- } on Object catch (e) {
137+ } on Object catch (e, st) {
138+ _log.severe ('Failed to read item with id "$id " from "$tableName ".' , e, st);
125139 throw _handlePgException (e);
126140 }
127141 }
@@ -154,6 +168,9 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
154168 String ? sortBy,
155169 SortOrder ? sortOrder,
156170 }) async {
171+ _log.fine (
172+ 'Querying "$tableName " with query: $query , limit: $limit , sortBy: $sortBy ' ,
173+ );
157174 try {
158175 // Note: startAfterId is not yet implemented for PostgreSQL client.
159176 // Keyset pagination would be required for a robust implementation.
@@ -183,14 +200,18 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
183200 ? (items.last as dynamic ).id as String ?
184201 : null ;
185202
203+ _log.finer (
204+ 'Successfully queried "$tableName ". Found ${items .length } items.' ,
205+ );
186206 return SuccessApiResponse (
187207 data: PaginatedResponse (
188208 items: items,
189209 hasMore: hasMore,
190210 cursor: cursor,
191211 ),
192212 );
193- } on Object catch (e) {
213+ } on Object catch (e, st) {
214+ _log.severe ('Failed to query "$tableName ".' , e, st);
194215 throw _handlePgException (e);
195216 }
196217 }
@@ -201,6 +222,7 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
201222 required T item,
202223 String ? userId,
203224 }) async {
225+ _log.fine ('Updating item with id "$id " in "$tableName "...' );
204226 try {
205227 final data = toJson (item)
206228 // Remove 'id' from the data to be updated in SET clause, as it's used
@@ -235,15 +257,21 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
235257 );
236258 }
237259 final updatedItem = fromJson (result.first.toColumnMap ());
260+ _log.finer ('Successfully updated item with id "$id " in "$tableName ".' );
238261 return SuccessApiResponse (data: updatedItem);
239- } on Object catch (e) {
262+ } on Object catch (e, st) {
263+ _log.severe ('Failed to update item with id "$id " in "$tableName ".' , e, st);
240264 throw _handlePgException (e);
241265 }
242266 }
243267
244268 /// Maps a [PgException] to a corresponding [HtHttpException] .
245269 Exception _handlePgException (Object e) {
246270 if (e is ServerException ) {
271+ _log.warning (
272+ 'Mapping ServerException with code: ${e .code } to HtHttpException.' ,
273+ e,
274+ );
247275 // See PostgreSQL error codes: https://www.postgresql.org/docs/current/errcodes-appendix.html
248276 final code = e.code;
249277 if (code != null ) {
@@ -262,10 +290,12 @@ class HtDataPostgresClient<T> implements HtDataClient<T> {
262290 'A database error occurred: ${e .message }' ,
263291 );
264292 } else if (e is PgException ) {
293+ _log.warning ('Mapping generic PgException to HtHttpException.' , e);
265294 return OperationFailedException (
266295 'A database connection error occurred: ${e .message }' ,
267296 );
268297 }
298+ _log.severe ('Encountered an unknown exception type.' , e);
269299 return Exception ('An unknown error occurred: $e ' );
270300 }
271301}
0 commit comments