pyplaykit 1.7.0__tar.gz → 1.7.1__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.
- {pyplaykit-1.7.0/pyplaykit.egg-info → pyplaykit-1.7.1}/PKG-INFO +1 -1
- {pyplaykit-1.7.0 → pyplaykit-1.7.1/pyplaykit.egg-info}/PKG-INFO +1 -1
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit.egg-info/SOURCES.txt +1 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyproject.toml +1 -1
- pyplaykit-1.7.1/utils/database_clients.py +310 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/MANIFEST.in +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/README.md +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/components/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/components/base_component.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/components/data_table.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/components/form_field.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/components/modal.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/config/config.yaml +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/config/environments.yaml +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/config/projects/customs_modernization.yaml +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/config/projects/dispatcho.yaml +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/config/projects/timelyquote.yaml +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/core/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/core/base_page.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/core/base_test.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/core/browser_factory.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/core/playwright_manager.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/dist_pkg/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/dist_pkg/distribution.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/integrations/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/integrations/adapters.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/orchestration/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/orchestration/enforcer.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/orchestration/planner.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pages/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pages/dashboard_page.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pages/login_page.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pages/orangehrm_login_page.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pages/saucedemo_inventory_page.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pages/saucedemo_login_page.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/plugins/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/plugins/api_plugin.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/plugins/base.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/plugins/data_plugin.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/plugins/registry.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/plugins/security_plugin.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit/cli.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit/plugin.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit.egg-info/dependency_links.txt +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit.egg-info/entry_points.txt +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit.egg-info/requires.txt +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/pyplaykit.egg-info/top_level.txt +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/resilience/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/resilience/locator_recovery.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/setup.cfg +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/api/ecom/auth_payloads.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/api/ecom/product_payloads.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/api_test_data.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/data_validation_test_data.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/login_test_data.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/orangehrm_login_data.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/test_data/ui_test_data.json +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/api_client.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/api_test_helper.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/assertion_helper.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/auth_manager.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/data_comparison_report.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/data_comparison_utils.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/data_loader.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/data_source.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/data_validator.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_client.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/__init__.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/db2.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/mysql.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/oracle.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/snowflake.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/sqlite.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_drivers/sqlserver.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_factory.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_fixtures.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_pool.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/db_validation_helper.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/environment_validator.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/file_reader.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/graphql_client.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/logger.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/observability.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/response_validator.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/screenshot_helper.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/soap_client.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/tdm.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/transformation_validator.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/ui_db_validator.py +0 -0
- {pyplaykit-1.7.0 → pyplaykit-1.7.1}/utils/yaml_config_reader.py +0 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom database client wrappers for cross-database comparisons.
|
|
3
|
+
|
|
4
|
+
PyPlayKit's built-in db_client fixture supports PostgreSQL only.
|
|
5
|
+
Use these wrappers to compare other database types:
|
|
6
|
+
- Oracle
|
|
7
|
+
- SQL Server
|
|
8
|
+
- MySQL
|
|
9
|
+
|
|
10
|
+
Installation:
|
|
11
|
+
pip install cx_Oracle # Oracle
|
|
12
|
+
pip install pyodbc # SQL Server
|
|
13
|
+
pip install pymysql # MySQL
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
from utils.database_clients import OracleClient, SQLServerClient, MySQLClient
|
|
17
|
+
|
|
18
|
+
oracle = OracleClient(user="...", password="...", dsn="...")
|
|
19
|
+
results = oracle.fetch_all("SELECT * FROM customers")
|
|
20
|
+
oracle.close()
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from typing import Any
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DatabaseClient:
|
|
27
|
+
"""Base class for all database clients."""
|
|
28
|
+
|
|
29
|
+
def fetch_all(self, query: str, params: tuple = ()) -> list[dict[str, Any]]:
|
|
30
|
+
"""
|
|
31
|
+
Execute query and return results as list of dictionaries.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
query: SQL query to execute
|
|
35
|
+
params: Query parameters (default: ())
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
List of dictionaries where each dict represents one row
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
results = client.fetch_all("SELECT id, name FROM users WHERE id = %s", (123,))
|
|
42
|
+
# Returns: [{"id": 123, "name": "Alice"}]
|
|
43
|
+
"""
|
|
44
|
+
raise NotImplementedError("Subclasses must implement fetch_all()")
|
|
45
|
+
|
|
46
|
+
def close(self):
|
|
47
|
+
"""Close database connection."""
|
|
48
|
+
raise NotImplementedError("Subclasses must implement close()")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class OracleClient(DatabaseClient):
|
|
52
|
+
"""
|
|
53
|
+
Oracle database client wrapper.
|
|
54
|
+
|
|
55
|
+
Installation:
|
|
56
|
+
pip install cx_Oracle
|
|
57
|
+
# Also install Oracle Instant Client
|
|
58
|
+
|
|
59
|
+
Usage:
|
|
60
|
+
oracle = OracleClient(
|
|
61
|
+
user="oracle_user",
|
|
62
|
+
password="oracle_password",
|
|
63
|
+
dsn="hostname:1521/service_name"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
results = oracle.fetch_all("SELECT * FROM CUSTOMERS ORDER BY ID")
|
|
67
|
+
oracle.close()
|
|
68
|
+
|
|
69
|
+
Column Names:
|
|
70
|
+
Automatically converts Oracle's uppercase column names to lowercase
|
|
71
|
+
for consistency with PostgreSQL/MySQL.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
def __init__(self, user: str, password: str, dsn: str):
|
|
75
|
+
"""
|
|
76
|
+
Initialize Oracle connection.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
user: Oracle username
|
|
80
|
+
password: Oracle password
|
|
81
|
+
dsn: Data Source Name in format "host:port/service_name"
|
|
82
|
+
Example: "oracle.example.com:1521/PROD"
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
import cx_Oracle
|
|
86
|
+
except ImportError:
|
|
87
|
+
raise ImportError(
|
|
88
|
+
"cx_Oracle is required for Oracle connections. "
|
|
89
|
+
"Install with: pip install cx_Oracle"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
self.connection = cx_Oracle.connect(user=user, password=password, dsn=dsn)
|
|
93
|
+
|
|
94
|
+
def fetch_all(self, query: str, params: tuple = ()) -> list[dict[str, Any]]:
|
|
95
|
+
"""Execute query and return list of dictionaries."""
|
|
96
|
+
cursor = self.connection.cursor()
|
|
97
|
+
cursor.execute(query, params)
|
|
98
|
+
|
|
99
|
+
# Get column names (convert to lowercase for consistency)
|
|
100
|
+
columns = [desc[0].lower() for desc in cursor.description]
|
|
101
|
+
|
|
102
|
+
# Fetch all rows
|
|
103
|
+
rows = cursor.fetchall()
|
|
104
|
+
|
|
105
|
+
# Convert to list of dictionaries
|
|
106
|
+
result = [dict(zip(columns, row)) for row in rows]
|
|
107
|
+
|
|
108
|
+
cursor.close()
|
|
109
|
+
return result
|
|
110
|
+
|
|
111
|
+
def close(self):
|
|
112
|
+
"""Close Oracle connection."""
|
|
113
|
+
if self.connection:
|
|
114
|
+
self.connection.close()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class SQLServerClient(DatabaseClient):
|
|
118
|
+
"""
|
|
119
|
+
SQL Server database client wrapper.
|
|
120
|
+
|
|
121
|
+
Installation:
|
|
122
|
+
pip install pyodbc
|
|
123
|
+
# Also install: ODBC Driver 17 for SQL Server
|
|
124
|
+
|
|
125
|
+
Windows:
|
|
126
|
+
Download ODBC Driver from Microsoft
|
|
127
|
+
|
|
128
|
+
Linux:
|
|
129
|
+
sudo apt-get install msodbcsql17
|
|
130
|
+
|
|
131
|
+
macOS:
|
|
132
|
+
brew tap microsoft/mssql-release
|
|
133
|
+
brew install msodbcsql17
|
|
134
|
+
|
|
135
|
+
Usage:
|
|
136
|
+
sqlserver = SQLServerClient(
|
|
137
|
+
server="sqlserver.example.com",
|
|
138
|
+
database="production",
|
|
139
|
+
username="sa",
|
|
140
|
+
password="password"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
results = sqlserver.fetch_all("SELECT * FROM dbo.Customers")
|
|
144
|
+
sqlserver.close()
|
|
145
|
+
|
|
146
|
+
Column Names:
|
|
147
|
+
Automatically converts column names to lowercase for consistency.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def __init__(
|
|
151
|
+
self,
|
|
152
|
+
server: str,
|
|
153
|
+
database: str,
|
|
154
|
+
username: str,
|
|
155
|
+
password: str,
|
|
156
|
+
driver: str = "ODBC Driver 17 for SQL Server",
|
|
157
|
+
port: int = 1433
|
|
158
|
+
):
|
|
159
|
+
"""
|
|
160
|
+
Initialize SQL Server connection.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
server: SQL Server hostname
|
|
164
|
+
database: Database name
|
|
165
|
+
username: SQL Server username
|
|
166
|
+
password: SQL Server password
|
|
167
|
+
driver: ODBC driver name (default: ODBC Driver 17 for SQL Server)
|
|
168
|
+
port: SQL Server port (default: 1433)
|
|
169
|
+
"""
|
|
170
|
+
try:
|
|
171
|
+
import pyodbc
|
|
172
|
+
except ImportError:
|
|
173
|
+
raise ImportError(
|
|
174
|
+
"pyodbc is required for SQL Server connections. "
|
|
175
|
+
"Install with: pip install pyodbc"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
conn_string = (
|
|
179
|
+
f"DRIVER={{{driver}}};"
|
|
180
|
+
f"SERVER={server},{port};"
|
|
181
|
+
f"DATABASE={database};"
|
|
182
|
+
f"UID={username};"
|
|
183
|
+
f"PWD={password}"
|
|
184
|
+
)
|
|
185
|
+
self.connection = pyodbc.connect(conn_string)
|
|
186
|
+
|
|
187
|
+
def fetch_all(self, query: str, params: tuple = ()) -> list[dict[str, Any]]:
|
|
188
|
+
"""Execute query and return list of dictionaries."""
|
|
189
|
+
cursor = self.connection.cursor()
|
|
190
|
+
cursor.execute(query, params)
|
|
191
|
+
|
|
192
|
+
# Get column names (convert to lowercase)
|
|
193
|
+
columns = [column[0].lower() for column in cursor.description]
|
|
194
|
+
|
|
195
|
+
# Fetch all rows
|
|
196
|
+
rows = cursor.fetchall()
|
|
197
|
+
|
|
198
|
+
# Convert to list of dictionaries
|
|
199
|
+
result = [dict(zip(columns, row)) for row in rows]
|
|
200
|
+
|
|
201
|
+
cursor.close()
|
|
202
|
+
return result
|
|
203
|
+
|
|
204
|
+
def close(self):
|
|
205
|
+
"""Close SQL Server connection."""
|
|
206
|
+
if self.connection:
|
|
207
|
+
self.connection.close()
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class MySQLClient(DatabaseClient):
|
|
211
|
+
"""
|
|
212
|
+
MySQL database client wrapper.
|
|
213
|
+
|
|
214
|
+
Installation:
|
|
215
|
+
pip install pymysql
|
|
216
|
+
|
|
217
|
+
Usage:
|
|
218
|
+
mysql = MySQLClient(
|
|
219
|
+
host="mysql.example.com",
|
|
220
|
+
user="root",
|
|
221
|
+
password="password",
|
|
222
|
+
database="myapp"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
results = mysql.fetch_all("SELECT * FROM products")
|
|
226
|
+
mysql.close()
|
|
227
|
+
|
|
228
|
+
Column Names:
|
|
229
|
+
Returns lowercase column names by default (MySQL convention).
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
def __init__(
|
|
233
|
+
self,
|
|
234
|
+
host: str,
|
|
235
|
+
user: str,
|
|
236
|
+
password: str,
|
|
237
|
+
database: str,
|
|
238
|
+
port: int = 3306,
|
|
239
|
+
charset: str = "utf8mb4"
|
|
240
|
+
):
|
|
241
|
+
"""
|
|
242
|
+
Initialize MySQL connection.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
host: MySQL hostname
|
|
246
|
+
user: MySQL username
|
|
247
|
+
password: MySQL password
|
|
248
|
+
database: Database name
|
|
249
|
+
port: MySQL port (default: 3306)
|
|
250
|
+
charset: Character set (default: utf8mb4)
|
|
251
|
+
"""
|
|
252
|
+
try:
|
|
253
|
+
import pymysql
|
|
254
|
+
except ImportError:
|
|
255
|
+
raise ImportError(
|
|
256
|
+
"pymysql is required for MySQL connections. "
|
|
257
|
+
"Install with: pip install pymysql"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
self.connection = pymysql.connect(
|
|
261
|
+
host=host,
|
|
262
|
+
port=port,
|
|
263
|
+
user=user,
|
|
264
|
+
password=password,
|
|
265
|
+
database=database,
|
|
266
|
+
charset=charset,
|
|
267
|
+
cursorclass=pymysql.cursors.DictCursor # Returns dict automatically
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def fetch_all(self, query: str, params: tuple = ()) -> list[dict[str, Any]]:
|
|
271
|
+
"""Execute query and return list of dictionaries."""
|
|
272
|
+
cursor = self.connection.cursor()
|
|
273
|
+
cursor.execute(query, params)
|
|
274
|
+
|
|
275
|
+
# pymysql DictCursor already returns list of dicts
|
|
276
|
+
result = cursor.fetchall()
|
|
277
|
+
|
|
278
|
+
cursor.close()
|
|
279
|
+
return result
|
|
280
|
+
|
|
281
|
+
def close(self):
|
|
282
|
+
"""Close MySQL connection."""
|
|
283
|
+
if self.connection:
|
|
284
|
+
self.connection.close()
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# Context manager support for all clients
|
|
288
|
+
class DatabaseClientContextManager:
|
|
289
|
+
"""Context manager wrapper for database clients."""
|
|
290
|
+
|
|
291
|
+
def __init__(self, client: DatabaseClient):
|
|
292
|
+
self.client = client
|
|
293
|
+
|
|
294
|
+
def __enter__(self):
|
|
295
|
+
return self.client
|
|
296
|
+
|
|
297
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
298
|
+
self.client.close()
|
|
299
|
+
return False
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# Make all clients usable as context managers
|
|
303
|
+
OracleClient.__enter__ = lambda self: self
|
|
304
|
+
OracleClient.__exit__ = lambda self, *args: self.close() or False
|
|
305
|
+
|
|
306
|
+
SQLServerClient.__enter__ = lambda self: self
|
|
307
|
+
SQLServerClient.__exit__ = lambda self, *args: self.close() or False
|
|
308
|
+
|
|
309
|
+
MySQLClient.__enter__ = lambda self: self
|
|
310
|
+
MySQLClient.__exit__ = lambda self, *args: self.close() or False
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|