velocity-python 0.0.109__py3-none-any.whl → 0.0.155__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.
Files changed (120) hide show
  1. velocity/__init__.py +3 -1
  2. velocity/app/orders.py +3 -4
  3. velocity/app/tests/__init__.py +1 -0
  4. velocity/app/tests/test_email_processing.py +112 -0
  5. velocity/app/tests/test_payment_profile_sorting.py +191 -0
  6. velocity/app/tests/test_spreadsheet_functions.py +124 -0
  7. velocity/aws/__init__.py +3 -0
  8. velocity/aws/amplify.py +10 -6
  9. velocity/aws/handlers/__init__.py +2 -0
  10. velocity/aws/handlers/base_handler.py +248 -0
  11. velocity/aws/handlers/context.py +167 -2
  12. velocity/aws/handlers/exceptions.py +16 -0
  13. velocity/aws/handlers/lambda_handler.py +24 -85
  14. velocity/aws/handlers/mixins/__init__.py +16 -0
  15. velocity/aws/handlers/mixins/activity_tracker.py +181 -0
  16. velocity/aws/handlers/mixins/aws_session_mixin.py +192 -0
  17. velocity/aws/handlers/mixins/error_handler.py +192 -0
  18. velocity/aws/handlers/mixins/legacy_mixin.py +53 -0
  19. velocity/aws/handlers/mixins/standard_mixin.py +73 -0
  20. velocity/aws/handlers/response.py +1 -1
  21. velocity/aws/handlers/sqs_handler.py +28 -143
  22. velocity/aws/tests/__init__.py +1 -0
  23. velocity/aws/tests/test_lambda_handler_json_serialization.py +120 -0
  24. velocity/aws/tests/test_response.py +163 -0
  25. velocity/db/__init__.py +16 -4
  26. velocity/db/core/decorators.py +20 -4
  27. velocity/db/core/engine.py +185 -839
  28. velocity/db/core/result.py +30 -24
  29. velocity/db/core/row.py +15 -3
  30. velocity/db/core/table.py +279 -40
  31. velocity/db/core/transaction.py +19 -11
  32. velocity/db/exceptions.py +42 -18
  33. velocity/db/servers/base/__init__.py +9 -0
  34. velocity/db/servers/base/initializer.py +70 -0
  35. velocity/db/servers/base/operators.py +98 -0
  36. velocity/db/servers/base/sql.py +503 -0
  37. velocity/db/servers/base/types.py +135 -0
  38. velocity/db/servers/mysql/__init__.py +73 -0
  39. velocity/db/servers/mysql/operators.py +54 -0
  40. velocity/db/servers/{mysql_reserved.py → mysql/reserved.py} +2 -14
  41. velocity/db/servers/mysql/sql.py +718 -0
  42. velocity/db/servers/mysql/types.py +107 -0
  43. velocity/db/servers/postgres/__init__.py +59 -11
  44. velocity/db/servers/postgres/operators.py +34 -0
  45. velocity/db/servers/postgres/sql.py +474 -120
  46. velocity/db/servers/postgres/types.py +88 -2
  47. velocity/db/servers/sqlite/__init__.py +61 -0
  48. velocity/db/servers/sqlite/operators.py +52 -0
  49. velocity/db/servers/sqlite/reserved.py +20 -0
  50. velocity/db/servers/sqlite/sql.py +677 -0
  51. velocity/db/servers/sqlite/types.py +92 -0
  52. velocity/db/servers/sqlserver/__init__.py +73 -0
  53. velocity/db/servers/sqlserver/operators.py +47 -0
  54. velocity/db/servers/sqlserver/reserved.py +32 -0
  55. velocity/db/servers/sqlserver/sql.py +805 -0
  56. velocity/db/servers/sqlserver/types.py +114 -0
  57. velocity/db/servers/tablehelper.py +117 -91
  58. velocity/db/tests/__init__.py +1 -0
  59. velocity/db/tests/common_db_test.py +0 -0
  60. velocity/db/tests/postgres/__init__.py +1 -0
  61. velocity/db/tests/postgres/common.py +49 -0
  62. velocity/db/tests/postgres/test_column.py +29 -0
  63. velocity/db/tests/postgres/test_connections.py +25 -0
  64. velocity/db/tests/postgres/test_database.py +21 -0
  65. velocity/db/tests/postgres/test_engine.py +205 -0
  66. velocity/db/tests/postgres/test_general_usage.py +88 -0
  67. velocity/db/tests/postgres/test_imports.py +8 -0
  68. velocity/db/tests/postgres/test_result.py +19 -0
  69. velocity/db/tests/postgres/test_row.py +137 -0
  70. velocity/db/tests/postgres/test_row_comprehensive.py +720 -0
  71. velocity/db/tests/postgres/test_schema_locking.py +335 -0
  72. velocity/db/tests/postgres/test_schema_locking_unit.py +115 -0
  73. velocity/db/tests/postgres/test_sequence.py +34 -0
  74. velocity/db/tests/postgres/test_sql_comprehensive.py +462 -0
  75. velocity/db/tests/postgres/test_table.py +101 -0
  76. velocity/db/tests/postgres/test_table_comprehensive.py +646 -0
  77. velocity/db/tests/postgres/test_transaction.py +106 -0
  78. velocity/db/tests/sql/__init__.py +1 -0
  79. velocity/db/tests/sql/common.py +177 -0
  80. velocity/db/tests/sql/test_postgres_select_advanced.py +285 -0
  81. velocity/db/tests/sql/test_postgres_select_variances.py +517 -0
  82. velocity/db/tests/test_cursor_rowcount_fix.py +150 -0
  83. velocity/db/tests/test_db_utils.py +221 -0
  84. velocity/db/tests/test_postgres.py +448 -0
  85. velocity/db/tests/test_postgres_unchanged.py +81 -0
  86. velocity/db/tests/test_process_error_robustness.py +292 -0
  87. velocity/db/tests/test_result_caching.py +279 -0
  88. velocity/db/tests/test_result_sql_aware.py +117 -0
  89. velocity/db/tests/test_row_get_missing_column.py +72 -0
  90. velocity/db/tests/test_schema_locking_initializers.py +226 -0
  91. velocity/db/tests/test_schema_locking_simple.py +97 -0
  92. velocity/db/tests/test_sql_builder.py +165 -0
  93. velocity/db/tests/test_tablehelper.py +486 -0
  94. velocity/db/utils.py +62 -47
  95. velocity/misc/conv/__init__.py +2 -0
  96. velocity/misc/conv/iconv.py +5 -4
  97. velocity/misc/export.py +1 -4
  98. velocity/misc/merge.py +1 -1
  99. velocity/misc/tests/__init__.py +1 -0
  100. velocity/misc/tests/test_db.py +90 -0
  101. velocity/misc/tests/test_fix.py +78 -0
  102. velocity/misc/tests/test_format.py +64 -0
  103. velocity/misc/tests/test_iconv.py +203 -0
  104. velocity/misc/tests/test_merge.py +82 -0
  105. velocity/misc/tests/test_oconv.py +144 -0
  106. velocity/misc/tests/test_original_error.py +52 -0
  107. velocity/misc/tests/test_timer.py +74 -0
  108. velocity/misc/tools.py +0 -1
  109. {velocity_python-0.0.109.dist-info → velocity_python-0.0.155.dist-info}/METADATA +2 -2
  110. velocity_python-0.0.155.dist-info/RECORD +129 -0
  111. velocity/db/core/exceptions.py +0 -70
  112. velocity/db/servers/mysql.py +0 -641
  113. velocity/db/servers/sqlite.py +0 -968
  114. velocity/db/servers/sqlite_reserved.py +0 -208
  115. velocity/db/servers/sqlserver.py +0 -921
  116. velocity/db/servers/sqlserver_reserved.py +0 -314
  117. velocity_python-0.0.109.dist-info/RECORD +0 -56
  118. {velocity_python-0.0.109.dist-info → velocity_python-0.0.155.dist-info}/WHEEL +0 -0
  119. {velocity_python-0.0.109.dist-info → velocity_python-0.0.155.dist-info}/licenses/LICENSE +0 -0
  120. {velocity_python-0.0.109.dist-info → velocity_python-0.0.155.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,11 @@
1
1
  import decimal
2
2
  import datetime
3
+ from ..base.types import BaseTypes
3
4
 
4
5
 
5
- class TYPES:
6
+ class TYPES(BaseTypes):
6
7
  """
7
- A simple mapping of Python types <-> SQL types (for PostgreSQL).
8
+ PostgreSQL-specific type mapping implementation.
8
9
  """
9
10
 
10
11
  TEXT = "TEXT"
@@ -107,3 +108,88 @@ class TYPES:
107
108
  if v == cls.DATETIME_TZ or v == cls.TIMESTAMP_TZ:
108
109
  return datetime.datetime
109
110
  raise Exception(f"Unmapped type {v}")
111
+
112
+ @classmethod
113
+ def get_type(cls, v):
114
+ """
115
+ Returns a suitable SQL type string for a Python value/object.
116
+ """
117
+ if isinstance(v, str) and v.startswith("@@"):
118
+ # e.g. @@CURRENT_TIMESTAMP => special usage
119
+ return v[2:] or cls.TEXT
120
+ if isinstance(v, str) or v is str:
121
+ return cls.TEXT
122
+ if isinstance(v, bool) or v is bool:
123
+ return cls.BOOLEAN
124
+ if isinstance(v, int) or v is int:
125
+ return cls.BIGINT
126
+ if isinstance(v, float) or v is float:
127
+ return f"{cls.NUMERIC}(19, 6)"
128
+ if isinstance(v, decimal.Decimal) or v is decimal.Decimal:
129
+ return f"{cls.NUMERIC}(19, 6)"
130
+ if isinstance(v, datetime.datetime) or v is datetime.datetime:
131
+ return cls.DATETIME
132
+ if isinstance(v, datetime.date) or v is datetime.date:
133
+ return cls.DATE
134
+ if isinstance(v, datetime.time) or v is datetime.time:
135
+ return cls.TIME
136
+ if isinstance(v, datetime.timedelta) or v is datetime.timedelta:
137
+ return cls.INTERVAL
138
+ if isinstance(v, bytes) or v is bytes:
139
+ return cls.BINARY
140
+ return cls.TEXT
141
+
142
+ @classmethod
143
+ def get_conv(cls, v):
144
+ """
145
+ Returns a base SQL type for expression usage (e.g. CAST).
146
+ """
147
+ if isinstance(v, str) and v.startswith("@@"):
148
+ return v[2:] or cls.TEXT
149
+ if isinstance(v, str) or v is str:
150
+ return cls.TEXT
151
+ if isinstance(v, bool) or v is bool:
152
+ return cls.BOOLEAN
153
+ if isinstance(v, int) or v is int:
154
+ return cls.BIGINT
155
+ if isinstance(v, float) or v is float:
156
+ return cls.NUMERIC
157
+ if isinstance(v, decimal.Decimal) or v is decimal.Decimal:
158
+ return cls.NUMERIC
159
+ if isinstance(v, datetime.datetime) or v is datetime.datetime:
160
+ return cls.DATETIME
161
+ if isinstance(v, datetime.date) or v is datetime.date:
162
+ return cls.DATE
163
+ if isinstance(v, datetime.time) or v is datetime.time:
164
+ return cls.TIME
165
+ if isinstance(v, datetime.timedelta) or v is datetime.timedelta:
166
+ return cls.INTERVAL
167
+ if isinstance(v, bytes) or v is bytes:
168
+ return cls.BINARY
169
+ return cls.TEXT
170
+
171
+ @classmethod
172
+ def py_type(cls, v):
173
+ """
174
+ Returns the Python type that corresponds to an SQL type string.
175
+ """
176
+ v = str(v).upper()
177
+ if v == cls.INTEGER or v == cls.SMALLINT or v == cls.BIGINT:
178
+ return int
179
+ if v == cls.NUMERIC:
180
+ return decimal.Decimal
181
+ if v == cls.TEXT:
182
+ return str
183
+ if v == cls.BOOLEAN:
184
+ return bool
185
+ if v == cls.DATE:
186
+ return datetime.date
187
+ if v == cls.TIME or v == cls.TIME_TZ:
188
+ return datetime.time
189
+ if v == cls.DATETIME or v == cls.TIMESTAMP:
190
+ return datetime.datetime
191
+ if v == cls.INTERVAL:
192
+ return datetime.timedelta
193
+ if v == cls.DATETIME_TZ or v == cls.TIMESTAMP_TZ:
194
+ return datetime.datetime
195
+ raise Exception(f"Unmapped type {v}")
@@ -0,0 +1,61 @@
1
+ import os
2
+ import sqlite3
3
+ from ..base.initializer import BaseInitializer
4
+ from velocity.db.core import engine
5
+ from .sql import SQL
6
+
7
+
8
+ class SQLiteInitializer(BaseInitializer):
9
+ """SQLite database initializer."""
10
+
11
+ @staticmethod
12
+ def initialize(config=None, schema_locked=False, **kwargs):
13
+ """
14
+ Initialize SQLite engine with sqlite3 driver.
15
+
16
+ Args:
17
+ config: Configuration dictionary
18
+ schema_locked: Boolean to lock schema modifications
19
+ **kwargs: Additional configuration parameters
20
+
21
+ Returns:
22
+ Configured Engine instance
23
+ """
24
+ # Base configuration - SQLite is simpler
25
+ base_config = {
26
+ "database": os.environ.get("DBDatabase", ":memory:"), # Default to in-memory
27
+ }
28
+
29
+ # Remove None values
30
+ base_config = {k: v for k, v in base_config.items() if v is not None}
31
+
32
+ # Set SQLite-specific defaults
33
+ sqlite_defaults = {
34
+ "check_same_thread": False, # Allow usage from different threads
35
+ "timeout": 30.0, # Connection timeout
36
+ }
37
+
38
+ # Merge configurations: defaults < env < config < kwargs
39
+ final_config = sqlite_defaults.copy()
40
+ final_config.update(base_config)
41
+ final_config = SQLiteInitializer._merge_config(final_config, config, **kwargs)
42
+
43
+ # Validate required configuration - only database path is required
44
+ required_keys = ["database"]
45
+ SQLiteInitializer._validate_required_config(final_config, required_keys)
46
+
47
+ # Check for environment variable override for schema locking
48
+ if os.environ.get("VELOCITY_SCHEMA_LOCKED", "").lower() in ('true', '1', 'yes'):
49
+ schema_locked = True
50
+
51
+ return engine.Engine(sqlite3, final_config, SQL, schema_locked=schema_locked)
52
+
53
+
54
+ # Maintain backward compatibility
55
+ def initialize(config=None, schema_locked=False, **kwargs):
56
+ """Backward compatible initialization function."""
57
+ # Check for environment variable override for schema locking
58
+ if os.environ.get("VELOCITY_SCHEMA_LOCKED", "").lower() in ('true', '1', 'yes'):
59
+ schema_locked = True
60
+
61
+ return SQLiteInitializer.initialize(config, schema_locked, **kwargs)
@@ -0,0 +1,52 @@
1
+ from ..base.operators import BaseOperators
2
+
3
+
4
+ class SQLiteOperators(BaseOperators):
5
+ """
6
+ SQLite-specific operator mappings.
7
+ """
8
+
9
+ @classmethod
10
+ def get_operators(cls):
11
+ """Returns SQLite-specific operator mappings."""
12
+ return OPERATORS
13
+
14
+ @classmethod
15
+ def supports_case_insensitive_like(cls):
16
+ """SQLite LIKE is case-insensitive by default."""
17
+ return True # Sort of - depends on the text encoding
18
+
19
+ @classmethod
20
+ def supports_regex(cls):
21
+ """SQLite supports REGEXP if the REGEXP function is defined."""
22
+ return True # But requires the REGEXP function to be defined
23
+
24
+ @classmethod
25
+ def get_regex_operators(cls):
26
+ """Returns SQLite regex operators."""
27
+ return {
28
+ "REGEXP": "REGEXP",
29
+ "GLOB": "GLOB",
30
+ }
31
+
32
+
33
+ OPERATORS = {
34
+ "<>": "<>",
35
+ "!=": "<>",
36
+ "!><": "NOT BETWEEN",
37
+ ">!<": "NOT BETWEEN",
38
+ "><": "BETWEEN",
39
+ "%%": "LIKE", # SQLite LIKE is case-insensitive by default
40
+ "!%%": "NOT LIKE",
41
+ "==": "=",
42
+ "<=": "<=",
43
+ ">=": ">=",
44
+ "<": "<",
45
+ ">": ">",
46
+ "%": "LIKE",
47
+ "!%": "NOT LIKE",
48
+ "=": "=",
49
+ "!": "<>",
50
+ "REGEXP": "REGEXP",
51
+ "GLOB": "GLOB",
52
+ }
@@ -0,0 +1,20 @@
1
+ reserved_words = [
2
+ "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND",
3
+ "AS", "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN",
4
+ "BY", "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN",
5
+ "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
6
+ "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
7
+ "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
8
+ "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
9
+ "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING",
10
+ "IF", "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY",
11
+ "INNER", "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL",
12
+ "JOIN", "KEY", "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO",
13
+ "NOT", "NOTNULL", "NULL", "OF", "OFFSET", "ON", "OR", "ORDER",
14
+ "OUTER", "PLAN", "PRAGMA", "PRIMARY", "QUERY", "RAISE", "RECURSIVE",
15
+ "REFERENCES", "REGEXP", "REINDEX", "RELEASE", "RENAME", "REPLACE",
16
+ "RESTRICT", "RIGHT", "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET",
17
+ "TABLE", "TEMP", "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER",
18
+ "UNION", "UNIQUE", "UPDATE", "USING", "VACUUM", "VALUES", "VIEW",
19
+ "VIRTUAL", "WHEN", "WHERE", "WITH", "WITHOUT"
20
+ ]