velocity-python 0.0.67__tar.gz → 0.0.68__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.
Files changed (64) hide show
  1. {velocity_python-0.0.67 → velocity_python-0.0.68}/PKG-INFO +1 -1
  2. {velocity_python-0.0.67 → velocity_python-0.0.68}/pyproject.toml +1 -1
  3. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/__init__.py +1 -1
  4. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/tablehelper.py +35 -26
  5. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity_python.egg-info/PKG-INFO +1 -1
  6. {velocity_python-0.0.67 → velocity_python-0.0.68}/LICENSE +0 -0
  7. {velocity_python-0.0.67 → velocity_python-0.0.68}/README.md +0 -0
  8. {velocity_python-0.0.67 → velocity_python-0.0.68}/setup.cfg +0 -0
  9. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/aws/__init__.py +0 -0
  10. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/aws/handlers/__init__.py +0 -0
  11. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/aws/handlers/context.py +0 -0
  12. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/aws/handlers/lambda_handler.py +0 -0
  13. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/aws/handlers/response.py +0 -0
  14. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/aws/handlers/sqs_handler.py +0 -0
  15. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/__init__.py +0 -0
  16. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/__init__.py +0 -0
  17. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/column.py +0 -0
  18. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/database.py +0 -0
  19. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/decorators.py +0 -0
  20. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/engine.py +0 -0
  21. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/exceptions.py +0 -0
  22. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/result.py +0 -0
  23. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/row.py +0 -0
  24. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/sequence.py +0 -0
  25. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/table.py +0 -0
  26. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/core/transaction.py +0 -0
  27. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/__init__.py +0 -0
  28. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/mysql.py +0 -0
  29. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/mysql_reserved.py +0 -0
  30. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/postgres/__init__.py +0 -0
  31. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/postgres/operators.py +0 -0
  32. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/postgres/reserved.py +0 -0
  33. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/postgres/sql.py +0 -0
  34. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/postgres/types.py +0 -0
  35. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/sqlite.py +0 -0
  36. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/sqlite_reserved.py +0 -0
  37. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/sqlserver.py +0 -0
  38. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/db/servers/sqlserver_reserved.py +0 -0
  39. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/__init__.py +0 -0
  40. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/conv/__init__.py +0 -0
  41. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/conv/iconv.py +0 -0
  42. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/conv/oconv.py +0 -0
  43. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/db.py +0 -0
  44. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/export.py +0 -0
  45. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/format.py +0 -0
  46. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/mail.py +0 -0
  47. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/merge.py +0 -0
  48. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/timer.py +0 -0
  49. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity/misc/tools.py +0 -0
  50. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity_python.egg-info/SOURCES.txt +0 -0
  51. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity_python.egg-info/dependency_links.txt +0 -0
  52. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity_python.egg-info/requires.txt +0 -0
  53. {velocity_python-0.0.67 → velocity_python-0.0.68}/src/velocity_python.egg-info/top_level.txt +0 -0
  54. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_db.py +0 -0
  55. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_email_processing.py +0 -0
  56. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_format.py +0 -0
  57. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_iconv.py +0 -0
  58. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_merge.py +0 -0
  59. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_oconv.py +0 -0
  60. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_postgres.py +0 -0
  61. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_response.py +0 -0
  62. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_spreadsheet_functions.py +0 -0
  63. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_sql_builder.py +0 -0
  64. {velocity_python-0.0.67 → velocity_python-0.0.68}/tests/test_timer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.67
3
+ Version: 0.0.68
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Paul Perez <pperez@codeclubs.org>
6
6
  Project-URL: Homepage, https://codeclubs.org/projects/velocity
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "velocity-python"
3
- version = "0.0.67"
3
+ version = "0.0.68"
4
4
  authors = [
5
5
  { name="Paul Perez", email="pperez@codeclubs.org" },
6
6
  ]
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.0.67"
1
+ __version__ = version = "0.0.68"
2
2
 
3
3
  from . import aws
4
4
  from . import db
@@ -143,47 +143,56 @@ class TableHelper:
143
143
  """
144
144
  Extracts the 'bare' column name from a SQL expression.
145
145
 
146
- This version intelligently detects window functions like ROW_NUMBER() OVER(ORDER BY x)
147
- and returns the actual column used inside ORDER BY.
146
+ Supports:
147
+ - Aliases (AS ...)
148
+ - Window functions (OVER(... ORDER BY ...))
149
+ - CAST(... AS ...)
150
+ - CASE WHEN ... THEN ... ELSE ... END
151
+ - Nested function calls
152
+ - Grabs column from inside expressions (e.g. PLAID_ERROR from SUM(CASE...))
148
153
 
149
154
  Args:
150
- sql_expression (str): Complex SQL expression (may include OVER, CAST, CASE, etc.)
155
+ sql_expression (str): SQL expression (SELECT column) string.
151
156
 
152
157
  Returns:
153
- str or None: Inferred base column name, like "amount", "a.email", or "*"
158
+ str or None: Extracted column name or None if undetectable.
154
159
  """
155
- import re
156
-
157
160
  expr = sql_expression.replace('"', "").strip()
158
161
 
159
- # Step 1: Remove alias
162
+ # Remove trailing alias
160
163
  expr = re.sub(r"(?i)\s+as\s+\w+$", "", expr).strip()
161
164
 
162
- # Step 2: Pull column from ORDER BY inside OVER()
163
- over_match = re.search(r"(?i)OVER\s*\(\s*ORDER\s+BY\s+([^)\s]+)", expr)
165
+ # If OVER clause: extract column inside ORDER BY
166
+ over_match = re.search(r"(?i)OVER\s*\(\s*ORDER\s+BY\s+([^\s,)]+)", expr)
164
167
  if over_match:
165
- column = over_match.group(1).strip(",")
166
- return column
167
-
168
- # Step 3: Strip CAST(x AS type)
169
- expr = re.sub(r"(?i)CAST\s*\((.*?)\s+AS\s+[^\)]+\)", r"\1", expr)
170
-
171
- # Step 4: Strip CASE WHEN ... THEN ... ELSE ... END
172
- expr = re.sub(
173
- r"(?i)CASE\s+WHEN\s+(.*?)\s+THEN\s+.*?\s+(ELSE\s+.*?)?END", r"\1", expr
174
- )
168
+ return over_match.group(1)
169
+
170
+ # Remove CAST(... AS ...)
171
+ while re.search(r"(?i)CAST\s*\(([^()]+?)\s+AS\s+[^\)]+\)", expr):
172
+ expr = re.sub(r"(?i)CAST\s*\(([^()]+?)\s+AS\s+[^\)]+\)", r"\1", expr)
173
+
174
+ # Remove CASE WHEN ... THEN ... ELSE ... END, keep just the WHEN part
175
+ while re.search(
176
+ r"(?i)CASE\s+WHEN\s+(.+?)\s+THEN\s+.+?(?:\s+ELSE\s+.+?)?\s+END", expr
177
+ ):
178
+ expr = re.sub(
179
+ r"(?i)CASE\s+WHEN\s+(.+?)\s+THEN\s+.+?(?:\s+ELSE\s+.+?)?\s+END",
180
+ r"\1",
181
+ expr,
182
+ )
175
183
 
176
- # Step 5: Remove nested function calls
177
- while re.search(r"\b\w+\s*\([^()]*\)", expr):
178
- expr = re.sub(r"\b\w+\s*\(([^()]*)\)", r"\1", expr)
184
+ # Unwrap function calls (SUM(...), MAX(...), etc.)
185
+ while re.search(r"\b\w+\s*\(([^()]+)\)", expr):
186
+ expr = re.sub(r"\b\w+\s*\(([^()]+)\)", r"\1", expr)
179
187
 
180
- # Step 6: Keep only first expression if comma-separated
188
+ # If multiple columns, take the first
181
189
  if "," in expr:
182
190
  expr = expr.split(",")[0].strip()
183
191
 
184
- # Step 7: Match column-like patterns
185
- pattern = r"^([a-zA-Z_][\w]*\.\*|\*|[a-zA-Z_][\w]*(?:\.[a-zA-Z_][\w]*)?)$"
186
- match = re.search(pattern, expr)
192
+ # Extract column name (basic or dotted like table.col or *)
193
+ match = re.search(
194
+ r"\b([a-zA-Z_][\w]*\.\*|\*|[a-zA-Z_][\w]*(?:\.[a-zA-Z_][\w]*)?)\b", expr
195
+ )
187
196
  return match.group(1) if match else None
188
197
 
189
198
  def are_parentheses_balanced(self, expression):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.67
3
+ Version: 0.0.68
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Paul Perez <pperez@codeclubs.org>
6
6
  Project-URL: Homepage, https://codeclubs.org/projects/velocity