maleo-foundation 0.0.20__py3-none-any.whl → 0.0.22__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,6 +51,7 @@ class BaseResponses:
51
51
  class PaginatedMultipleData(BaseResultSchemas.PaginatedMultipleData):
52
52
  page:int = Field(1, ge=1, description="Page number, must be >= 1.", exclude=True)
53
53
  limit:int = Field(10, ge=1, le=100, description="Page size, must be 1 <= limit <= 100.", exclude=True)
54
+ total_data:int = Field(..., ge=0, description="Total data count", exclude=True)
54
55
 
55
56
  @model_validator(mode="before")
56
57
  @classmethod
@@ -37,5 +37,5 @@ class BaseResultSchemas:
37
37
  UnpaginatedMultipleData,
38
38
  BaseGeneralSchemas.SimplePagination
39
39
  ):
40
- total_data:int = Field(..., description="Total data count")
40
+ total_data:int = Field(..., ge=0, description="Total data count")
41
41
  pagination:BaseGeneralSchemas.ExtendedPagination = Field(..., description="Pagination metadata")
@@ -0,0 +1,81 @@
1
+ from sqlalchemy import Column, Table
2
+ from sqlalchemy.orm import Query
3
+ from sqlalchemy.orm.attributes import InstrumentedAttribute
4
+ from sqlalchemy.sql.expression import or_, asc, cast, desc
5
+ from sqlalchemy.types import DATE, String, TEXT, TIMESTAMP
6
+ from typing import Optional, Type
7
+ from maleo_foundation.db import DatabaseManager
8
+ from maleo_foundation.models.enums import BaseEnums
9
+ from maleo_foundation.models.schemas.general import BaseGeneralSchemas
10
+
11
+ class BaseQuery:
12
+ @staticmethod
13
+ def filter_ids(query:Query, table:Type[DatabaseManager.Base], column:str, ids:Optional[list[int]]) -> Query:
14
+ if ids is not None:
15
+ column_attr = getattr(table, column, None)
16
+ if column_attr:
17
+ id_filters = [column_attr == id for id in ids]
18
+ query = query.filter(or_(*id_filters))
19
+ return query
20
+
21
+ @staticmethod
22
+ def filter_timestamps(query:Query, table:Type[DatabaseManager.Base], date_filters:list[BaseGeneralSchemas.DateFilter]) -> Query:
23
+ if date_filters and len(date_filters) > 0:
24
+ for date_filter in date_filters:
25
+ try:
26
+ table:Table = table.__table__
27
+ column:Column = table.columns[date_filter.name]
28
+ column_attr:InstrumentedAttribute = getattr(table, date_filter.name)
29
+ if isinstance(column.type, (TIMESTAMP, DATE)):
30
+ if date_filter.from_date and date_filter.to_date:
31
+ query = query.filter(column_attr.between(date_filter.from_date, date_filter.to_date))
32
+ elif date_filter.from_date:
33
+ query = query.filter(column_attr >= date_filter.from_date)
34
+ elif date_filter.to_date:
35
+ query = query.filter(column_attr <= date_filter.to_date)
36
+ except KeyError:
37
+ continue
38
+ return query
39
+
40
+ @staticmethod
41
+ def filter_statuses(query:Query, table:Type[DatabaseManager.Base], statuses:Optional[list[BaseEnums.StatusType]]) -> Query:
42
+ if statuses is not None:
43
+ status_filters = [table.status == status for status in statuses]
44
+ query = query.filter(or_(*status_filters))
45
+ return query
46
+
47
+ @staticmethod
48
+ def filter_search(query:Query, table:Type[DatabaseManager.Base], search:Optional[str]) -> Query:
49
+ if search:
50
+ search_term = f"%{search}%" #* Use wildcard for partial matching
51
+ search_filters = []
52
+ sqla_table:Table = table.__table__
53
+ for name, attr in vars(table).items():
54
+ try:
55
+ column: Column = sqla_table.columns[name]
56
+ if not isinstance(attr, InstrumentedAttribute):
57
+ continue
58
+ if isinstance(column.type, (String, TEXT)):
59
+ search_filters.append(cast(attr, TEXT).ilike(search_term))
60
+ except KeyError:
61
+ continue
62
+ if search_filters:
63
+ query = query.filter(or_(*search_filters))
64
+ return query
65
+
66
+ @staticmethod
67
+ def sort(query:Query, table:Type[DatabaseManager.Base], sort_columns:list[BaseGeneralSchemas.SortColumn]) -> Query:
68
+ for sort_column in sort_columns:
69
+ try:
70
+ sort_col = getattr(table, sort_column.name)
71
+ sort_col = asc(sort_col) if sort_column.order.value.lower() == "asc" else desc(sort_col)
72
+ query = query.order_by(sort_col)
73
+ except AttributeError:
74
+ continue
75
+ return query
76
+
77
+ @staticmethod
78
+ def paginate(query:Query, page:int, limit:int) -> Query:
79
+ offset:int = (page - 1) * limit #* Calculate offset based on page
80
+ query = query.limit(limit=limit).offset(offset=offset)
81
+ return query
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.0.20
3
+ Version: 0.0.22
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -1,6 +1,7 @@
1
1
  maleo_foundation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  maleo_foundation/constants.py,sha256=l6WQp0nu2y4Ucs8bFcEdzVUJfR1dRM_nveuHGMhe3rY,424
3
3
  maleo_foundation/controller.py,sha256=91OK1W4MnO85m0GUOQv1F8m50nlTZpZJ2HJcScH7OGA,2980
4
+ maleo_foundation/query.py,sha256=Wv9smUNuAa8ZMvb9KiG_sUqyNFG9KXFo3JX6kpxjWQ4,3868
4
5
  maleo_foundation/clients/__init__.py,sha256=W8vydJYeDEi6gdmOZSBFSSDsfZJtb8C05CHErZgsZ30,188
5
6
  maleo_foundation/clients/general/__init__.py,sha256=l9eQrBeLW4aXtGU5aK3i6fD-msVR4526W7D9V8WCXIg,91
6
7
  maleo_foundation/clients/general/http.py,sha256=Awvs470hgdhZSZW_uoIFJGcJ5hcfDEIX0A2yUaP9UCA,1353
@@ -18,11 +19,11 @@ maleo_foundation/middlewares/base.py,sha256=KcpODNs0DQXX8Cwc6T9dC6aiZIqxTLtuJjVA
18
19
  maleo_foundation/middlewares/cors.py,sha256=9uvBvY2N6Vxa9RP_YtESxcWo6Doi6uS0lzAG9iLY7Uc,2288
19
20
  maleo_foundation/models/__init__.py,sha256=Wh92XAduE1Sg9qi2GMhptyXig0fKcTS5AbGo3tE3tLs,348
20
21
  maleo_foundation/models/enums.py,sha256=Ob2v312JxypHEq7hTKZKOV462FEeLkIjIhpx-YF6Jdw,2203
21
- maleo_foundation/models/responses.py,sha256=qvgiq17tF2gHXKhF2l8-segCRYAjSS40MjP3cKX_XlI,4127
22
+ maleo_foundation/models/responses.py,sha256=1Rs3EflBJdsTC8PSbaOFbbTyxwRwK031eU3qLEj21sU,4215
22
23
  maleo_foundation/models/schemas/__init__.py,sha256=Xj8Ahsqyra-fmEaVcGPok5GOOsPQlKcknHYMvbjvENA,277
23
24
  maleo_foundation/models/schemas/general.py,sha256=ZRppkwkrEUo3UXVXRdYIvobYaW6kkr8SWjy47mg3inA,6526
24
25
  maleo_foundation/models/schemas/parameter.py,sha256=1og_crWds6YLS-8Ha5EbAi3ZaNMzNFiIZ06v_HO3b9k,875
25
- maleo_foundation/models/schemas/result.py,sha256=fzzq5mbJSwTXt6r-m9Yz9XNx36gGtroaj7dCCySKSFo,1870
26
+ maleo_foundation/models/schemas/result.py,sha256=xGpGxYcK_HEzAU2yaySHGR9cnsCGfMloVoK8vF-4QZA,1876
26
27
  maleo_foundation/models/transfers/__init__.py,sha256=B8oCZHE3NTsrJ_rviSXaDsuc-gc25jpjuhJO40lpQiE,222
27
28
  maleo_foundation/models/transfers/parameters/__init__.py,sha256=oKW4RPIEISISRjsJzD8lsCGY1HhZRTzshPpWHcJu86k,353
28
29
  maleo_foundation/models/transfers/parameters/client.py,sha256=Q43A-Z7JPXcxb_v7iUKoA1_WV8AMdEaeSl9Z39WSF_8,2287
@@ -47,7 +48,7 @@ maleo_foundation/utils/exceptions.py,sha256=mcvBwHm6uWpVQkPtO1T2j-GaTYEiyPOeGxiD
47
48
  maleo_foundation/utils/logger.py,sha256=ICrFi0MxuAjDy8KTRL7pex1miwzZqZX-HHArgN3niJM,2453
48
49
  maleo_foundation/utils/formatter/__init__.py,sha256=iKf5YCbEdg1qKnFHyKqqcQbqAqEeRUf8mhI3v3dQoj8,78
49
50
  maleo_foundation/utils/formatter/case.py,sha256=TmvvlfzGdC_omMTB5vAa40TZBxQ3hnr-SYeo0M52Rlg,1352
50
- maleo_foundation-0.0.20.dist-info/METADATA,sha256=yx8TRW94I6B8vFpw5DZWsryR4tqE6bcRDJELvo7gwUw,3160
51
- maleo_foundation-0.0.20.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
52
- maleo_foundation-0.0.20.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
53
- maleo_foundation-0.0.20.dist-info/RECORD,,
51
+ maleo_foundation-0.0.22.dist-info/METADATA,sha256=YarudNggd1mhQLpPGEINhjIg8EeDjR2eS9msU_wBipg,3160
52
+ maleo_foundation-0.0.22.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
53
+ maleo_foundation-0.0.22.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
54
+ maleo_foundation-0.0.22.dist-info/RECORD,,