sqlshell 0.4.4__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 (54) hide show
  1. sqlshell/__init__.py +84 -0
  2. sqlshell/__main__.py +4926 -0
  3. sqlshell/ai_autocomplete.py +392 -0
  4. sqlshell/ai_settings_dialog.py +337 -0
  5. sqlshell/context_suggester.py +768 -0
  6. sqlshell/create_test_data.py +152 -0
  7. sqlshell/data/create_test_data.py +137 -0
  8. sqlshell/db/__init__.py +6 -0
  9. sqlshell/db/database_manager.py +1318 -0
  10. sqlshell/db/export_manager.py +188 -0
  11. sqlshell/editor.py +1166 -0
  12. sqlshell/editor_integration.py +127 -0
  13. sqlshell/execution_handler.py +421 -0
  14. sqlshell/menus.py +262 -0
  15. sqlshell/notification_manager.py +370 -0
  16. sqlshell/query_tab.py +904 -0
  17. sqlshell/resources/__init__.py +1 -0
  18. sqlshell/resources/icon.png +0 -0
  19. sqlshell/resources/logo_large.png +0 -0
  20. sqlshell/resources/logo_medium.png +0 -0
  21. sqlshell/resources/logo_small.png +0 -0
  22. sqlshell/resources/splash_screen.gif +0 -0
  23. sqlshell/space_invaders.py +501 -0
  24. sqlshell/splash_screen.py +405 -0
  25. sqlshell/sqlshell/__init__.py +5 -0
  26. sqlshell/sqlshell/create_test_data.py +118 -0
  27. sqlshell/sqlshell/create_test_databases.py +96 -0
  28. sqlshell/sqlshell_demo.png +0 -0
  29. sqlshell/styles.py +257 -0
  30. sqlshell/suggester_integration.py +330 -0
  31. sqlshell/syntax_highlighter.py +124 -0
  32. sqlshell/table_list.py +996 -0
  33. sqlshell/ui/__init__.py +6 -0
  34. sqlshell/ui/bar_chart_delegate.py +49 -0
  35. sqlshell/ui/filter_header.py +469 -0
  36. sqlshell/utils/__init__.py +16 -0
  37. sqlshell/utils/profile_cn2.py +1661 -0
  38. sqlshell/utils/profile_column.py +2635 -0
  39. sqlshell/utils/profile_distributions.py +616 -0
  40. sqlshell/utils/profile_entropy.py +347 -0
  41. sqlshell/utils/profile_foreign_keys.py +779 -0
  42. sqlshell/utils/profile_keys.py +2834 -0
  43. sqlshell/utils/profile_ohe.py +934 -0
  44. sqlshell/utils/profile_ohe_advanced.py +754 -0
  45. sqlshell/utils/profile_ohe_comparison.py +237 -0
  46. sqlshell/utils/profile_prediction.py +926 -0
  47. sqlshell/utils/profile_similarity.py +876 -0
  48. sqlshell/utils/search_in_df.py +90 -0
  49. sqlshell/widgets.py +400 -0
  50. sqlshell-0.4.4.dist-info/METADATA +441 -0
  51. sqlshell-0.4.4.dist-info/RECORD +54 -0
  52. sqlshell-0.4.4.dist-info/WHEEL +5 -0
  53. sqlshell-0.4.4.dist-info/entry_points.txt +2 -0
  54. sqlshell-0.4.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,124 @@
1
+ from PyQt6.QtCore import Qt, QRegularExpression
2
+ from PyQt6.QtGui import QFont, QColor, QSyntaxHighlighter, QTextCharFormat
3
+
4
+ class SQLSyntaxHighlighter(QSyntaxHighlighter):
5
+ def __init__(self, document):
6
+ super().__init__(document)
7
+ self.highlighting_rules = []
8
+
9
+ # SQL Keywords - Using darker blue for better contrast (WCAG AA: 4.5:1)
10
+ keyword_format = QTextCharFormat()
11
+ keyword_format.setForeground(QColor("#0066CC")) # Darker blue, better contrast
12
+ keyword_format.setFontWeight(QFont.Weight.Bold)
13
+ keywords = [
14
+ "\\bSELECT\\b", "\\bFROM\\b", "\\bWHERE\\b", "\\bAND\\b", "\\bOR\\b",
15
+ "\\bINNER\\b", "\\bOUTER\\b", "\\bLEFT\\b", "\\bRIGHT\\b", "\\bJOIN\\b",
16
+ "\\bON\\b", "\\bGROUP\\b", "\\bBY\\b", "\\bHAVING\\b", "\\bORDER\\b",
17
+ "\\bLIMIT\\b", "\\bOFFSET\\b", "\\bUNION\\b", "\\bEXCEPT\\b", "\\bINTERSECT\\b",
18
+ "\\bCREATE\\b", "\\bTABLE\\b", "\\bINDEX\\b", "\\bVIEW\\b", "\\bINSERT\\b",
19
+ "\\bINTO\\b", "\\bVALUES\\b", "\\bUPDATE\\b", "\\bSET\\b", "\\bDELETE\\b",
20
+ "\\bTRUNCATE\\b", "\\bALTER\\b", "\\bADD\\b", "\\bDROP\\b", "\\bCOLUMN\\b",
21
+ "\\bCONSTRAINT\\b", "\\bPRIMARY\\b", "\\bKEY\\b", "\\bFOREIGN\\b", "\\bREFERENCES\\b",
22
+ "\\bUNIQUE\\b", "\\bNOT\\b", "\\bNULL\\b", "\\bIS\\b", "\\bDISTINCT\\b",
23
+ "\\bCASE\\b", "\\bWHEN\\b", "\\bTHEN\\b", "\\bELSE\\b", "\\bEND\\b",
24
+ "\\bAS\\b", "\\bWITH\\b", "\\bBETWEEN\\b", "\\bLIKE\\b", "\\bIN\\b",
25
+ "\\bEXISTS\\b", "\\bALL\\b", "\\bANY\\b", "\\bSOME\\b", "\\bDESC\\b", "\\bASC\\b"
26
+ ]
27
+ for pattern in keywords:
28
+ regex = QRegularExpression(pattern, QRegularExpression.PatternOption.CaseInsensitiveOption)
29
+ self.highlighting_rules.append((regex, keyword_format))
30
+
31
+ # Functions - Using darker purple for better contrast
32
+ function_format = QTextCharFormat()
33
+ function_format.setForeground(QColor("#8B008B")) # Darker magenta/purple
34
+ function_format.setFontWeight(QFont.Weight.Medium)
35
+ functions = [
36
+ "\\bAVG\\b", "\\bCOUNT\\b", "\\bSUM\\b", "\\bMAX\\b", "\\bMIN\\b",
37
+ "\\bCOALESCE\\b", "\\bNVL\\b", "\\bNULLIF\\b", "\\bCAST\\b", "\\bCONVERT\\b",
38
+ "\\bLOWER\\b", "\\bUPPER\\b", "\\bTRIM\\b", "\\bLTRIM\\b", "\\bRTRIM\\b",
39
+ "\\bLENGTH\\b", "\\bSUBSTRING\\b", "\\bREPLACE\\b", "\\bCONCAT\\b",
40
+ "\\bROUND\\b", "\\bFLOOR\\b", "\\bCEIL\\b", "\\bABS\\b", "\\bMOD\\b",
41
+ "\\bCURRENT_DATE\\b", "\\bCURRENT_TIME\\b", "\\bCURRENT_TIMESTAMP\\b",
42
+ "\\bEXTRACT\\b", "\\bDATE_PART\\b", "\\bTO_CHAR\\b", "\\bTO_DATE\\b"
43
+ ]
44
+ for pattern in functions:
45
+ regex = QRegularExpression(pattern, QRegularExpression.PatternOption.CaseInsensitiveOption)
46
+ self.highlighting_rules.append((regex, function_format))
47
+
48
+ # Numbers - Darker green for better readability
49
+ number_format = QTextCharFormat()
50
+ number_format.setForeground(QColor("#007700")) # Darker green with better contrast
51
+ self.highlighting_rules.append((
52
+ QRegularExpression("\\b[0-9]+\\b"),
53
+ number_format
54
+ ))
55
+
56
+ # Single-line string literals - Warmer brown/orange
57
+ string_format = QTextCharFormat()
58
+ string_format.setForeground(QColor("#A04000")) # Darker orange/brown for better contrast
59
+ self.highlighting_rules.append((
60
+ QRegularExpression("'[^']*'"),
61
+ string_format
62
+ ))
63
+ self.highlighting_rules.append((
64
+ QRegularExpression("\"[^\"]*\""),
65
+ string_format
66
+ ))
67
+
68
+ # Comments - Medium gray with better contrast
69
+ comment_format = QTextCharFormat()
70
+ comment_format.setForeground(QColor("#6A737D")) # GitHub's comment color - well tested
71
+ comment_format.setFontItalic(True)
72
+ self.highlighting_rules.append((
73
+ QRegularExpression("--[^\n]*"),
74
+ comment_format
75
+ ))
76
+
77
+ # Multi-line comments
78
+ self.comment_start_expression = QRegularExpression("/\\*")
79
+ self.comment_end_expression = QRegularExpression("\\*/")
80
+ self.multi_line_comment_format = comment_format
81
+
82
+ def highlightBlock(self, text):
83
+ # Apply regular expression highlighting rules
84
+ for pattern, format in self.highlighting_rules:
85
+ match_iterator = pattern.globalMatch(text)
86
+ while match_iterator.hasNext():
87
+ match = match_iterator.next()
88
+ self.setFormat(match.capturedStart(), match.capturedLength(), format)
89
+
90
+ # Handle multi-line comments
91
+ self.setCurrentBlockState(0)
92
+
93
+ # If previous block was inside a comment, check if this block continues it
94
+ start_index = 0
95
+ if self.previousBlockState() != 1:
96
+ # Find the start of a comment
97
+ start_match = self.comment_start_expression.match(text)
98
+ if start_match.hasMatch():
99
+ start_index = start_match.capturedStart()
100
+ else:
101
+ return
102
+
103
+ while start_index >= 0:
104
+ # Find the end of the comment
105
+ end_match = self.comment_end_expression.match(text, start_index)
106
+
107
+ # If end match found
108
+ if end_match.hasMatch():
109
+ end_index = end_match.capturedStart()
110
+ comment_length = end_index - start_index + end_match.capturedLength()
111
+ self.setFormat(start_index, comment_length, self.multi_line_comment_format)
112
+
113
+ # Look for next comment
114
+ start_match = self.comment_start_expression.match(text, start_index + comment_length)
115
+ if start_match.hasMatch():
116
+ start_index = start_match.capturedStart()
117
+ else:
118
+ start_index = -1
119
+ else:
120
+ # No end found, comment continues to next block
121
+ self.setCurrentBlockState(1) # Still inside comment
122
+ comment_length = len(text) - start_index
123
+ self.setFormat(start_index, comment_length, self.multi_line_comment_format)
124
+ start_index = -1