velocity-python 0.0.109__py3-none-any.whl → 0.0.161__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.
- velocity/__init__.py +3 -1
- velocity/app/orders.py +3 -4
- velocity/app/tests/__init__.py +1 -0
- velocity/app/tests/test_email_processing.py +112 -0
- velocity/app/tests/test_payment_profile_sorting.py +191 -0
- velocity/app/tests/test_spreadsheet_functions.py +124 -0
- velocity/aws/__init__.py +3 -0
- velocity/aws/amplify.py +10 -6
- velocity/aws/handlers/__init__.py +2 -0
- velocity/aws/handlers/base_handler.py +248 -0
- velocity/aws/handlers/context.py +251 -2
- velocity/aws/handlers/exceptions.py +16 -0
- velocity/aws/handlers/lambda_handler.py +24 -85
- velocity/aws/handlers/mixins/__init__.py +16 -0
- velocity/aws/handlers/mixins/activity_tracker.py +181 -0
- velocity/aws/handlers/mixins/aws_session_mixin.py +192 -0
- velocity/aws/handlers/mixins/error_handler.py +192 -0
- velocity/aws/handlers/mixins/legacy_mixin.py +53 -0
- velocity/aws/handlers/mixins/standard_mixin.py +73 -0
- velocity/aws/handlers/response.py +1 -1
- velocity/aws/handlers/sqs_handler.py +28 -143
- velocity/aws/tests/__init__.py +1 -0
- velocity/aws/tests/test_lambda_handler_json_serialization.py +120 -0
- velocity/aws/tests/test_response.py +163 -0
- velocity/db/__init__.py +16 -4
- velocity/db/core/decorators.py +48 -13
- velocity/db/core/engine.py +187 -840
- velocity/db/core/result.py +33 -25
- velocity/db/core/row.py +15 -3
- velocity/db/core/table.py +493 -50
- velocity/db/core/transaction.py +28 -15
- velocity/db/exceptions.py +42 -18
- velocity/db/servers/base/__init__.py +9 -0
- velocity/db/servers/base/initializer.py +70 -0
- velocity/db/servers/base/operators.py +98 -0
- velocity/db/servers/base/sql.py +503 -0
- velocity/db/servers/base/types.py +135 -0
- velocity/db/servers/mysql/__init__.py +73 -0
- velocity/db/servers/mysql/operators.py +54 -0
- velocity/db/servers/{mysql_reserved.py → mysql/reserved.py} +2 -14
- velocity/db/servers/mysql/sql.py +718 -0
- velocity/db/servers/mysql/types.py +107 -0
- velocity/db/servers/postgres/__init__.py +59 -11
- velocity/db/servers/postgres/operators.py +34 -0
- velocity/db/servers/postgres/sql.py +474 -120
- velocity/db/servers/postgres/types.py +88 -2
- velocity/db/servers/sqlite/__init__.py +61 -0
- velocity/db/servers/sqlite/operators.py +52 -0
- velocity/db/servers/sqlite/reserved.py +20 -0
- velocity/db/servers/sqlite/sql.py +677 -0
- velocity/db/servers/sqlite/types.py +92 -0
- velocity/db/servers/sqlserver/__init__.py +73 -0
- velocity/db/servers/sqlserver/operators.py +47 -0
- velocity/db/servers/sqlserver/reserved.py +32 -0
- velocity/db/servers/sqlserver/sql.py +805 -0
- velocity/db/servers/sqlserver/types.py +114 -0
- velocity/db/servers/tablehelper.py +117 -91
- velocity/db/tests/__init__.py +1 -0
- velocity/db/tests/common_db_test.py +0 -0
- velocity/db/tests/postgres/__init__.py +1 -0
- velocity/db/tests/postgres/common.py +49 -0
- velocity/db/tests/postgres/test_column.py +29 -0
- velocity/db/tests/postgres/test_connections.py +25 -0
- velocity/db/tests/postgres/test_database.py +21 -0
- velocity/db/tests/postgres/test_engine.py +205 -0
- velocity/db/tests/postgres/test_general_usage.py +88 -0
- velocity/db/tests/postgres/test_imports.py +8 -0
- velocity/db/tests/postgres/test_result.py +19 -0
- velocity/db/tests/postgres/test_row.py +137 -0
- velocity/db/tests/postgres/test_row_comprehensive.py +720 -0
- velocity/db/tests/postgres/test_schema_locking.py +335 -0
- velocity/db/tests/postgres/test_schema_locking_unit.py +115 -0
- velocity/db/tests/postgres/test_sequence.py +34 -0
- velocity/db/tests/postgres/test_sql_comprehensive.py +462 -0
- velocity/db/tests/postgres/test_table.py +101 -0
- velocity/db/tests/postgres/test_table_comprehensive.py +646 -0
- velocity/db/tests/postgres/test_transaction.py +106 -0
- velocity/db/tests/sql/__init__.py +1 -0
- velocity/db/tests/sql/common.py +177 -0
- velocity/db/tests/sql/test_postgres_select_advanced.py +285 -0
- velocity/db/tests/sql/test_postgres_select_variances.py +517 -0
- velocity/db/tests/test_cursor_rowcount_fix.py +150 -0
- velocity/db/tests/test_db_utils.py +270 -0
- velocity/db/tests/test_postgres.py +448 -0
- velocity/db/tests/test_postgres_unchanged.py +81 -0
- velocity/db/tests/test_process_error_robustness.py +292 -0
- velocity/db/tests/test_result_caching.py +279 -0
- velocity/db/tests/test_result_sql_aware.py +117 -0
- velocity/db/tests/test_row_get_missing_column.py +72 -0
- velocity/db/tests/test_schema_locking_initializers.py +226 -0
- velocity/db/tests/test_schema_locking_simple.py +97 -0
- velocity/db/tests/test_sql_builder.py +165 -0
- velocity/db/tests/test_tablehelper.py +486 -0
- velocity/db/utils.py +129 -51
- velocity/misc/conv/__init__.py +2 -0
- velocity/misc/conv/iconv.py +5 -4
- velocity/misc/export.py +1 -4
- velocity/misc/merge.py +1 -1
- velocity/misc/tests/__init__.py +1 -0
- velocity/misc/tests/test_db.py +90 -0
- velocity/misc/tests/test_fix.py +78 -0
- velocity/misc/tests/test_format.py +64 -0
- velocity/misc/tests/test_iconv.py +203 -0
- velocity/misc/tests/test_merge.py +82 -0
- velocity/misc/tests/test_oconv.py +144 -0
- velocity/misc/tests/test_original_error.py +52 -0
- velocity/misc/tests/test_timer.py +74 -0
- velocity/misc/tools.py +0 -1
- {velocity_python-0.0.109.dist-info → velocity_python-0.0.161.dist-info}/METADATA +2 -2
- velocity_python-0.0.161.dist-info/RECORD +129 -0
- velocity/db/core/exceptions.py +0 -70
- velocity/db/servers/mysql.py +0 -641
- velocity/db/servers/sqlite.py +0 -968
- velocity/db/servers/sqlite_reserved.py +0 -208
- velocity/db/servers/sqlserver.py +0 -921
- velocity/db/servers/sqlserver_reserved.py +0 -314
- velocity_python-0.0.109.dist-info/RECORD +0 -56
- {velocity_python-0.0.109.dist-info → velocity_python-0.0.161.dist-info}/WHEEL +0 -0
- {velocity_python-0.0.109.dist-info → velocity_python-0.0.161.dist-info}/licenses/LICENSE +0 -0
- {velocity_python-0.0.109.dist-info → velocity_python-0.0.161.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
|
-
|
|
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
|
+
]
|