t-sql 4.1.0__tar.gz → 4.2.0__tar.gz
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.
- {t_sql-4.1.0 → t_sql-4.2.0}/PKG-INFO +1 -1
- {t_sql-4.1.0 → t_sql-4.2.0}/pyproject.toml +1 -1
- {t_sql-4.1.0 → t_sql-4.2.0}/tsql/query_builder.py +48 -18
- {t_sql-4.1.0 → t_sql-4.2.0}/.dockerignore +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/.github/workflows/publish.yml +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/.github/workflows/test.yml +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/.gitignore +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/Dockerfile +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/LICENSE +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/README.md +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/compose.yaml +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/context7.json +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/pytest.ini +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_alembic_integration.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_asyncpg_integration.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_different_object_types.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_escaped.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_escaped_binary_hex.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_helper_functions.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_injection_edge_cases.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_injection_protection_validation.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_injections_for_escaped.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_mysql_integration.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_parameter_names.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_query_builder.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_sqlalchemy_integration.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_sqlite_integration.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_styles.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tests/test_tsql.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tsql/__init__.py +0 -0
- {t_sql-4.1.0 → t_sql-4.2.0}/tsql/styles.py +0 -0
|
@@ -240,7 +240,7 @@ class Table:
|
|
|
240
240
|
continue
|
|
241
241
|
field_value = getattr(cls, field_name, None)
|
|
242
242
|
|
|
243
|
-
# Check for Ellipsis syntax: id =
|
|
243
|
+
# Check for Ellipsis syntax: id = ...~
|
|
244
244
|
if field_value is ...:
|
|
245
245
|
if field_name not in all_fields:
|
|
246
246
|
all_fields[field_name] = {
|
|
@@ -452,7 +452,7 @@ class Condition:
|
|
|
452
452
|
class Join:
|
|
453
453
|
"""Represents a JOIN clause"""
|
|
454
454
|
|
|
455
|
-
def __init__(self, table: 'Table', condition: Condition, join_type: str = 'INNER'):
|
|
455
|
+
def __init__(self, table: type['Table'], condition: Condition, join_type: str = 'INNER'):
|
|
456
456
|
self.table = table
|
|
457
457
|
self.condition = condition
|
|
458
458
|
self.join_type = join_type
|
|
@@ -495,7 +495,7 @@ class QueryBuilder(ABC):
|
|
|
495
495
|
class InsertBuilder(QueryBuilder):
|
|
496
496
|
"""Fluent interface for building INSERT queries"""
|
|
497
497
|
|
|
498
|
-
def __init__(self, base_table: 'Table', values: dict[str, Any]):
|
|
498
|
+
def __init__(self, base_table: type['Table'], values: dict[str, Any]):
|
|
499
499
|
self.base_table = base_table
|
|
500
500
|
|
|
501
501
|
# Apply defaults from SQLAlchemy columns if available
|
|
@@ -563,13 +563,23 @@ class InsertBuilder(QueryBuilder):
|
|
|
563
563
|
self._update_cols = update
|
|
564
564
|
return self
|
|
565
565
|
|
|
566
|
-
def returning(self, *columns: str) -> 'InsertBuilder':
|
|
566
|
+
def returning(self, *columns: Union[str, Column]) -> 'InsertBuilder':
|
|
567
567
|
"""Add RETURNING clause (Postgres/SQLite only)
|
|
568
568
|
|
|
569
569
|
Args:
|
|
570
|
-
columns: Column names to return, or none for RETURNING *
|
|
570
|
+
columns: Column names (strings) or Column objects to return, or none for RETURNING *
|
|
571
571
|
"""
|
|
572
|
-
|
|
572
|
+
if columns:
|
|
573
|
+
# Convert Column objects to their column names
|
|
574
|
+
col_names = []
|
|
575
|
+
for col in columns:
|
|
576
|
+
if isinstance(col, Column):
|
|
577
|
+
col_names.append(col.column_name)
|
|
578
|
+
else:
|
|
579
|
+
col_names.append(col)
|
|
580
|
+
self._returning_cols = col_names
|
|
581
|
+
else:
|
|
582
|
+
self._returning_cols = ['*']
|
|
573
583
|
return self
|
|
574
584
|
|
|
575
585
|
def to_tsql(self) -> TSQL:
|
|
@@ -677,7 +687,7 @@ class InsertBuilder(QueryBuilder):
|
|
|
677
687
|
class UpdateBuilder(QueryBuilder):
|
|
678
688
|
"""Fluent interface for building UPDATE queries"""
|
|
679
689
|
|
|
680
|
-
def __init__(self, base_table: 'Table', values: dict[str, Any]):
|
|
690
|
+
def __init__(self, base_table: type['Table'], values: dict[str, Any]):
|
|
681
691
|
self.base_table = base_table
|
|
682
692
|
|
|
683
693
|
# Apply onupdate defaults from SQLAlchemy columns if available
|
|
@@ -726,13 +736,23 @@ class UpdateBuilder(QueryBuilder):
|
|
|
726
736
|
self._requires_where = False
|
|
727
737
|
return self
|
|
728
738
|
|
|
729
|
-
def returning(self, *columns: str) -> 'UpdateBuilder':
|
|
739
|
+
def returning(self, *columns: Union[str, Column]) -> 'UpdateBuilder':
|
|
730
740
|
"""Add RETURNING clause (Postgres/SQLite only)
|
|
731
741
|
|
|
732
742
|
Args:
|
|
733
|
-
columns: Column names to return, or none for RETURNING *
|
|
743
|
+
columns: Column names (strings) or Column objects to return, or none for RETURNING *
|
|
734
744
|
"""
|
|
735
|
-
|
|
745
|
+
if columns:
|
|
746
|
+
# Convert Column objects to their column names
|
|
747
|
+
col_names = []
|
|
748
|
+
for col in columns:
|
|
749
|
+
if isinstance(col, Column):
|
|
750
|
+
col_names.append(col.column_name)
|
|
751
|
+
else:
|
|
752
|
+
col_names.append(col)
|
|
753
|
+
self._returning_cols = col_names
|
|
754
|
+
else:
|
|
755
|
+
self._returning_cols = ['*']
|
|
736
756
|
return self
|
|
737
757
|
|
|
738
758
|
def to_tsql(self) -> TSQL:
|
|
@@ -790,7 +810,7 @@ class UpdateBuilder(QueryBuilder):
|
|
|
790
810
|
class DeleteBuilder(QueryBuilder):
|
|
791
811
|
"""Fluent interface for building DELETE queries"""
|
|
792
812
|
|
|
793
|
-
def __init__(self, base_table: 'Table'):
|
|
813
|
+
def __init__(self, base_table: type['Table']):
|
|
794
814
|
self.base_table = base_table
|
|
795
815
|
self._conditions: List[Union[Condition, Template]] = []
|
|
796
816
|
self._returning_cols: Optional[List[str]] = None
|
|
@@ -817,13 +837,23 @@ class DeleteBuilder(QueryBuilder):
|
|
|
817
837
|
self._requires_where = False
|
|
818
838
|
return self
|
|
819
839
|
|
|
820
|
-
def returning(self, *columns: str) -> 'DeleteBuilder':
|
|
840
|
+
def returning(self, *columns: Union[str, Column]) -> 'DeleteBuilder':
|
|
821
841
|
"""Add RETURNING clause (Postgres/SQLite only)
|
|
822
842
|
|
|
823
843
|
Args:
|
|
824
|
-
columns: Column names to return, or none for RETURNING *
|
|
844
|
+
columns: Column names (strings) or Column objects to return, or none for RETURNING *
|
|
825
845
|
"""
|
|
826
|
-
|
|
846
|
+
if columns:
|
|
847
|
+
# Convert Column objects to their column names
|
|
848
|
+
col_names = []
|
|
849
|
+
for col in columns:
|
|
850
|
+
if isinstance(col, Column):
|
|
851
|
+
col_names.append(col.column_name)
|
|
852
|
+
else:
|
|
853
|
+
col_names.append(col)
|
|
854
|
+
self._returning_cols = col_names
|
|
855
|
+
else:
|
|
856
|
+
self._returning_cols = ['*']
|
|
827
857
|
return self
|
|
828
858
|
|
|
829
859
|
def to_tsql(self) -> TSQL:
|
|
@@ -880,7 +910,7 @@ class DeleteBuilder(QueryBuilder):
|
|
|
880
910
|
class SelectQueryBuilder(QueryBuilder):
|
|
881
911
|
"""Fluent interface for building SQL SELECT queries"""
|
|
882
912
|
|
|
883
|
-
def __init__(self, base_table: 'Table'):
|
|
913
|
+
def __init__(self, base_table: type['Table']):
|
|
884
914
|
self.base_table = base_table
|
|
885
915
|
self._columns: Optional[List[Column]] = None
|
|
886
916
|
self._conditions: List[Condition] = []
|
|
@@ -918,16 +948,16 @@ class SelectQueryBuilder(QueryBuilder):
|
|
|
918
948
|
self._conditions.append(condition)
|
|
919
949
|
return self
|
|
920
950
|
|
|
921
|
-
def join(self, table: 'Table', on: Condition, join_type: str = 'INNER') -> 'SelectQueryBuilder':
|
|
951
|
+
def join(self, table: type['Table'], on: Condition, join_type: str = 'INNER') -> 'SelectQueryBuilder':
|
|
922
952
|
"""Add a JOIN clause"""
|
|
923
953
|
self._joins.append(Join(table, on, join_type))
|
|
924
954
|
return self
|
|
925
955
|
|
|
926
|
-
def left_join(self, table: 'Table', on: Condition) -> 'SelectQueryBuilder':
|
|
956
|
+
def left_join(self, table: type['Table'], on: Condition) -> 'SelectQueryBuilder':
|
|
927
957
|
"""Add a LEFT JOIN clause"""
|
|
928
958
|
return self.join(table, on, 'LEFT')
|
|
929
959
|
|
|
930
|
-
def right_join(self, table: 'Table', on: Condition) -> 'SelectQueryBuilder':
|
|
960
|
+
def right_join(self, table: type['Table'], on: Condition) -> 'SelectQueryBuilder':
|
|
931
961
|
"""Add a RIGHT JOIN clause"""
|
|
932
962
|
return self.join(table, on, 'RIGHT')
|
|
933
963
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|