sqlshell 0.2.2__py3-none-any.whl → 0.3.0__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.
Potentially problematic release.
This version of sqlshell might be problematic. Click here for more details.
- sqlshell/README.md +5 -1
- sqlshell/__init__.py +35 -5
- sqlshell/create_test_data.py +29 -0
- sqlshell/db/__init__.py +2 -1
- sqlshell/db/database_manager.py +336 -23
- sqlshell/db/export_manager.py +188 -0
- sqlshell/editor_integration.py +127 -0
- sqlshell/execution_handler.py +421 -0
- sqlshell/main.py +784 -143
- sqlshell/query_tab.py +592 -7
- sqlshell/table_list.py +90 -1
- sqlshell/ui/filter_header.py +36 -1
- sqlshell/utils/profile_column.py +2515 -0
- sqlshell/utils/profile_distributions.py +613 -0
- sqlshell/utils/profile_foreign_keys.py +547 -0
- sqlshell/utils/profile_ohe.py +631 -0
- sqlshell-0.3.0.dist-info/METADATA +400 -0
- {sqlshell-0.2.2.dist-info → sqlshell-0.3.0.dist-info}/RECORD +21 -14
- {sqlshell-0.2.2.dist-info → sqlshell-0.3.0.dist-info}/WHEEL +1 -1
- sqlshell-0.2.2.dist-info/METADATA +0 -198
- {sqlshell-0.2.2.dist-info → sqlshell-0.3.0.dist-info}/entry_points.txt +0 -0
- {sqlshell-0.2.2.dist-info → sqlshell-0.3.0.dist-info}/top_level.txt +0 -0
sqlshell/table_list.py
CHANGED
|
@@ -37,7 +37,7 @@ class DraggableTablesList(QTreeWidget):
|
|
|
37
37
|
self.setHeaderHidden(True)
|
|
38
38
|
self.setColumnCount(1)
|
|
39
39
|
self.setIndentation(15) # Smaller indentation for a cleaner look
|
|
40
|
-
self.setSelectionMode(QTreeWidget.SelectionMode.
|
|
40
|
+
self.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
|
|
41
41
|
self.setExpandsOnDoubleClick(False) # Handle double-clicks manually
|
|
42
42
|
|
|
43
43
|
# Apply custom styling
|
|
@@ -120,6 +120,95 @@ class DraggableTablesList(QTreeWidget):
|
|
|
120
120
|
|
|
121
121
|
def startDrag(self, supportedActions):
|
|
122
122
|
"""Override startDrag to customize the drag data."""
|
|
123
|
+
# Check for multiple selected items
|
|
124
|
+
selected_items = self.selectedItems()
|
|
125
|
+
if len(selected_items) > 1:
|
|
126
|
+
# Only support dragging multiple items to the editor (not for folder management)
|
|
127
|
+
# Filter out folder items
|
|
128
|
+
table_items = [item for item in selected_items if not self.is_folder_item(item)]
|
|
129
|
+
|
|
130
|
+
if not table_items:
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
# Extract table names
|
|
134
|
+
table_names = [self.get_table_name_from_item(item) for item in table_items]
|
|
135
|
+
table_names = [name for name in table_names if name] # Remove None values
|
|
136
|
+
|
|
137
|
+
if not table_names:
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
# Create mime data with comma-separated table names
|
|
141
|
+
mime_data = QMimeData()
|
|
142
|
+
mime_data.setText(", ".join(table_names))
|
|
143
|
+
|
|
144
|
+
# Create drag object
|
|
145
|
+
drag = QDrag(self)
|
|
146
|
+
drag.setMimeData(mime_data)
|
|
147
|
+
|
|
148
|
+
# Create a visually appealing drag pixmap
|
|
149
|
+
font = self.font()
|
|
150
|
+
font.setBold(True)
|
|
151
|
+
metrics = self.fontMetrics()
|
|
152
|
+
|
|
153
|
+
# Build a preview label with limited number of tables
|
|
154
|
+
display_names = table_names[:3]
|
|
155
|
+
if len(table_names) > 3:
|
|
156
|
+
display_text = f"{', '.join(display_names)} (+{len(table_names) - 3} more)"
|
|
157
|
+
else:
|
|
158
|
+
display_text = ", ".join(display_names)
|
|
159
|
+
|
|
160
|
+
text_width = metrics.horizontalAdvance(display_text)
|
|
161
|
+
text_height = metrics.height()
|
|
162
|
+
|
|
163
|
+
# Make the pixmap large enough for the text plus padding and a small icon
|
|
164
|
+
padding = 10
|
|
165
|
+
pixmap = QPixmap(text_width + padding * 2 + 16, text_height + padding)
|
|
166
|
+
pixmap.fill(Qt.GlobalColor.transparent)
|
|
167
|
+
|
|
168
|
+
# Begin painting
|
|
169
|
+
painter = QPainter(pixmap)
|
|
170
|
+
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
|
171
|
+
|
|
172
|
+
# Draw a nice rounded rectangle background
|
|
173
|
+
bg_color = QColor(44, 62, 80, 220) # Dark blue with transparency
|
|
174
|
+
painter.setBrush(QBrush(bg_color))
|
|
175
|
+
painter.setPen(Qt.PenStyle.NoPen)
|
|
176
|
+
painter.drawRoundedRect(0, 0, pixmap.width(), pixmap.height(), 5, 5)
|
|
177
|
+
|
|
178
|
+
# Draw text
|
|
179
|
+
painter.setPen(Qt.GlobalColor.white)
|
|
180
|
+
painter.setFont(font)
|
|
181
|
+
painter.drawText(int(padding + 16), int(text_height + (padding / 2) - 2), display_text)
|
|
182
|
+
|
|
183
|
+
# Draw a small database icon (simulated)
|
|
184
|
+
icon_x = padding / 2
|
|
185
|
+
icon_y = (pixmap.height() - 12) / 2
|
|
186
|
+
|
|
187
|
+
# Draw a simple database icon as a blue circle with lines
|
|
188
|
+
table_icon_color = QColor("#3498DB")
|
|
189
|
+
painter.setBrush(QBrush(table_icon_color))
|
|
190
|
+
painter.setPen(Qt.GlobalColor.white)
|
|
191
|
+
painter.drawEllipse(int(icon_x), int(icon_y), 12, 12)
|
|
192
|
+
|
|
193
|
+
# Draw "table" lines inside the circle
|
|
194
|
+
painter.setPen(Qt.GlobalColor.white)
|
|
195
|
+
painter.drawLine(int(icon_x + 3), int(icon_y + 4), int(icon_x + 9), int(icon_y + 4))
|
|
196
|
+
painter.drawLine(int(icon_x + 3), int(icon_y + 6), int(icon_x + 9), int(icon_y + 6))
|
|
197
|
+
painter.drawLine(int(icon_x + 3), int(icon_y + 8), int(icon_x + 9), int(icon_y + 8))
|
|
198
|
+
|
|
199
|
+
painter.end()
|
|
200
|
+
|
|
201
|
+
# Set the drag pixmap
|
|
202
|
+
drag.setPixmap(pixmap)
|
|
203
|
+
|
|
204
|
+
# Set hotspot to be at the top-left corner of the text
|
|
205
|
+
drag.setHotSpot(QPoint(padding, pixmap.height() // 2))
|
|
206
|
+
|
|
207
|
+
# Execute drag operation - only allow copy action for multiple tables
|
|
208
|
+
drag.exec(Qt.DropAction.CopyAction)
|
|
209
|
+
return
|
|
210
|
+
|
|
211
|
+
# Single item drag (original functionality)
|
|
123
212
|
item = self.currentItem()
|
|
124
213
|
if not item:
|
|
125
214
|
return
|
sqlshell/ui/filter_header.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from PyQt6.QtWidgets import (QHeaderView, QMenu, QCheckBox, QWidgetAction,
|
|
2
|
-
QWidget, QVBoxLayout, QLineEdit, QHBoxLayout, QPushButton, QTableWidget)
|
|
2
|
+
QWidget, QVBoxLayout, QLineEdit, QHBoxLayout, QPushButton, QTableWidget, QMessageBox)
|
|
3
3
|
from PyQt6.QtCore import Qt, QRect, QPoint
|
|
4
4
|
from PyQt6.QtGui import QColor, QFont, QPolygon, QPainterPath, QBrush
|
|
5
5
|
|
|
@@ -88,6 +88,17 @@ class FilterHeader(QHeaderView):
|
|
|
88
88
|
# Add sort actions
|
|
89
89
|
sort_asc_action = context_menu.addAction("Sort Ascending")
|
|
90
90
|
sort_desc_action = context_menu.addAction("Sort Descending")
|
|
91
|
+
context_menu.addSeparator()
|
|
92
|
+
|
|
93
|
+
# Add count rows action
|
|
94
|
+
count_rows_action = context_menu.addAction("Count Rows")
|
|
95
|
+
|
|
96
|
+
# Add explain column action
|
|
97
|
+
explain_action = context_menu.addAction("Explain Column")
|
|
98
|
+
|
|
99
|
+
# Add encode text action
|
|
100
|
+
encode_action = context_menu.addAction("Encode Text")
|
|
101
|
+
|
|
91
102
|
context_menu.addSeparator()
|
|
92
103
|
filter_action = context_menu.addAction("Filter...")
|
|
93
104
|
|
|
@@ -127,6 +138,30 @@ class FilterHeader(QHeaderView):
|
|
|
127
138
|
self.show_filter_menu(logical_index)
|
|
128
139
|
elif action == toggle_bar_action:
|
|
129
140
|
self.toggle_bar_chart(logical_index)
|
|
141
|
+
elif action == explain_action:
|
|
142
|
+
# Call the explain_column method on the main window
|
|
143
|
+
if self.main_window and hasattr(self.main_window, "explain_column"):
|
|
144
|
+
# Get the column name from the table (if it has a current dataframe)
|
|
145
|
+
current_tab = self.main_window.get_current_tab()
|
|
146
|
+
if current_tab and hasattr(current_tab, "current_df") and current_tab.current_df is not None:
|
|
147
|
+
if logical_index < len(current_tab.current_df.columns):
|
|
148
|
+
column_name = current_tab.current_df.columns[logical_index]
|
|
149
|
+
self.main_window.explain_column(column_name)
|
|
150
|
+
elif action == encode_action:
|
|
151
|
+
# Call the encode_text method on the main window
|
|
152
|
+
if self.main_window and hasattr(self.main_window, "encode_text"):
|
|
153
|
+
# Get the column name from the table (if it has a current dataframe)
|
|
154
|
+
current_tab = self.main_window.get_current_tab()
|
|
155
|
+
if current_tab and hasattr(current_tab, "current_df") and current_tab.current_df is not None:
|
|
156
|
+
if logical_index < len(current_tab.current_df.columns):
|
|
157
|
+
column_name = current_tab.current_df.columns[logical_index]
|
|
158
|
+
self.main_window.encode_text(column_name)
|
|
159
|
+
elif action == count_rows_action:
|
|
160
|
+
# Get the current tab and show row count
|
|
161
|
+
current_tab = self.main_window.get_current_tab()
|
|
162
|
+
if current_tab and hasattr(current_tab, "current_df") and current_tab.current_df is not None:
|
|
163
|
+
row_count = len(current_tab.current_df)
|
|
164
|
+
QMessageBox.information(self, "Row Count", f"Total rows: {row_count:,}")
|
|
130
165
|
|
|
131
166
|
def set_main_window(self, window):
|
|
132
167
|
"""Set the reference to the main window"""
|