kaqing 2.0.52__py3-none-any.whl → 2.0.110__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 kaqing might be problematic. Click here for more details.

Files changed (121) hide show
  1. adam/apps.py +2 -2
  2. adam/batch.py +11 -15
  3. adam/checks/check_utils.py +4 -4
  4. adam/checks/compactionstats.py +1 -1
  5. adam/checks/cpu.py +2 -2
  6. adam/checks/disk.py +1 -1
  7. adam/checks/gossip.py +1 -1
  8. adam/checks/memory.py +3 -3
  9. adam/checks/status.py +1 -1
  10. adam/commands/alter_tables.py +3 -14
  11. adam/commands/app.py +2 -2
  12. adam/commands/app_ping.py +2 -2
  13. adam/commands/audit/audit.py +85 -0
  14. adam/commands/audit/audit_repair_tables.py +76 -0
  15. adam/commands/audit/audit_run.py +57 -0
  16. adam/commands/audit/show_last10.py +50 -0
  17. adam/commands/audit/show_slow10.py +49 -0
  18. adam/commands/audit/show_top10.py +48 -0
  19. adam/commands/audit/utils_show_top10.py +59 -0
  20. adam/commands/bash.py +76 -13
  21. adam/commands/cd.py +22 -13
  22. adam/commands/check.py +6 -0
  23. adam/commands/cli_commands.py +3 -3
  24. adam/commands/command.py +15 -11
  25. adam/commands/commands_utils.py +4 -5
  26. adam/commands/cql/cql_completions.py +7 -3
  27. adam/commands/cql/cql_utils.py +13 -10
  28. adam/commands/cql/cqlsh.py +6 -3
  29. adam/commands/deploy/code_utils.py +2 -2
  30. adam/commands/deploy/deploy.py +7 -1
  31. adam/commands/deploy/deploy_pg_agent.py +2 -2
  32. adam/commands/deploy/deploy_pod.py +6 -6
  33. adam/commands/deploy/deploy_utils.py +2 -2
  34. adam/commands/deploy/undeploy.py +7 -1
  35. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  36. adam/commands/deploy/undeploy_pod.py +4 -4
  37. adam/commands/devices.py +29 -0
  38. adam/commands/help.py +10 -7
  39. adam/commands/issues.py +6 -0
  40. adam/commands/login.py +6 -3
  41. adam/commands/logs.py +2 -1
  42. adam/commands/ls.py +30 -24
  43. adam/commands/medusa/medusa_backup.py +2 -2
  44. adam/commands/medusa/medusa_restore.py +2 -2
  45. adam/commands/medusa/medusa_show_backupjobs.py +3 -2
  46. adam/commands/medusa/medusa_show_restorejobs.py +2 -2
  47. adam/commands/nodetool.py +5 -3
  48. adam/commands/postgres/postgres.py +3 -3
  49. adam/commands/postgres/{postgres_session.py → postgres_context.py} +29 -30
  50. adam/commands/postgres/postgres_utils.py +5 -5
  51. adam/commands/postgres/psql_completions.py +1 -1
  52. adam/commands/preview_table.py +17 -32
  53. adam/commands/pwd.py +5 -2
  54. adam/commands/reaper/reaper.py +3 -0
  55. adam/commands/reaper/reaper_restart.py +1 -1
  56. adam/commands/reaper/reaper_session.py +1 -1
  57. adam/commands/repair/repair.py +3 -3
  58. adam/commands/repair/repair_log.py +1 -1
  59. adam/commands/repair/repair_run.py +2 -2
  60. adam/commands/repair/repair_scan.py +1 -1
  61. adam/commands/repair/repair_stop.py +1 -1
  62. adam/commands/report.py +6 -0
  63. adam/commands/restart.py +2 -2
  64. adam/commands/rollout.py +1 -1
  65. adam/commands/show/show.py +5 -2
  66. adam/commands/show/show_app_actions.py +3 -0
  67. adam/commands/show/show_app_id.py +1 -1
  68. adam/commands/show/show_app_queues.py +3 -2
  69. adam/commands/show/show_cassandra_status.py +3 -3
  70. adam/commands/show/show_cassandra_version.py +3 -3
  71. adam/commands/show/show_host.py +33 -0
  72. adam/commands/show/show_login.py +3 -0
  73. adam/commands/show/show_processes.py +1 -1
  74. adam/commands/show/show_repairs.py +2 -2
  75. adam/commands/show/show_storage.py +1 -1
  76. adam/commands/watch.py +1 -1
  77. adam/config.py +2 -1
  78. adam/embedded_params.py +1 -1
  79. adam/pod_exec_result.py +7 -2
  80. adam/repl.py +141 -88
  81. adam/repl_commands.py +21 -20
  82. adam/repl_state.py +167 -39
  83. adam/sql/sql_completer.py +76 -386
  84. adam/sql/sql_state_machine.py +518 -0
  85. adam/sql/term_completer.py +14 -4
  86. adam/sso/cred_cache.py +1 -1
  87. adam/sso/idp.py +1 -1
  88. adam/utils.py +0 -1
  89. adam/utils_audits.py +193 -0
  90. adam/{k8s_utils → utils_k8s}/cassandra_clusters.py +6 -8
  91. adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +11 -4
  92. adam/{k8s_utils → utils_k8s}/deployment.py +2 -2
  93. adam/{k8s_utils → utils_k8s}/pods.py +33 -9
  94. adam/{k8s_utils → utils_k8s}/secrets.py +4 -0
  95. adam/{k8s_utils → utils_k8s}/statefulsets.py +4 -4
  96. adam/utils_net.py +24 -0
  97. adam/version.py +1 -1
  98. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/METADATA +1 -1
  99. kaqing-2.0.110.dist-info/RECORD +187 -0
  100. adam/commands/cql/cql_table_completer.py +0 -8
  101. adam/commands/describe/describe.py +0 -46
  102. adam/commands/describe/describe_keyspace.py +0 -60
  103. adam/commands/describe/describe_keyspaces.py +0 -50
  104. adam/commands/describe/describe_table.py +0 -60
  105. adam/commands/describe/describe_tables.py +0 -50
  106. adam/commands/postgres/psql_table_completer.py +0 -11
  107. adam/sql/sql_utils.py +0 -5
  108. kaqing-2.0.52.dist-info/RECORD +0 -184
  109. /adam/commands/{describe → audit}/__init__.py +0 -0
  110. /adam/{k8s_utils → utils_k8s}/__init__.py +0 -0
  111. /adam/{k8s_utils → utils_k8s}/config_maps.py +0 -0
  112. /adam/{k8s_utils → utils_k8s}/custom_resources.py +0 -0
  113. /adam/{k8s_utils → utils_k8s}/ingresses.py +0 -0
  114. /adam/{k8s_utils → utils_k8s}/jobs.py +0 -0
  115. /adam/{k8s_utils → utils_k8s}/kube_context.py +0 -0
  116. /adam/{k8s_utils → utils_k8s}/service_accounts.py +0 -0
  117. /adam/{k8s_utils → utils_k8s}/services.py +0 -0
  118. /adam/{k8s_utils → utils_k8s}/volumes.py +0 -0
  119. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/WHEEL +0 -0
  120. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/entry_points.txt +0 -0
  121. {kaqing-2.0.52.dist-info → kaqing-2.0.110.dist-info}/top_level.txt +0 -0
adam/sql/sql_completer.py CHANGED
@@ -1,403 +1,93 @@
1
- from typing import Callable, Iterable
2
- from prompt_toolkit.completion import CompleteEvent, Completer, Completion
3
- from prompt_toolkit.document import Document
1
+ from typing import Callable
2
+
4
3
  import sqlparse
5
4
  from sqlparse.sql import Statement, Token
6
- from sqlparse import tokens as T
7
5
 
8
6
  from adam.sql.term_completer import TermCompleter
7
+ from adam.utils_repl.automata_completer import AutomataCompleter
8
+ from adam.sql.sql_state_machine import AthenaStateMachine, CqlStateMachine, SqlStateMachine
9
+ from adam.utils_repl.state_machine import State
9
10
 
10
- class SqlCompleter(Completer):
11
- def __init__(self, tables: Callable[[], list[str]], dml: str = None, debug = False):
12
- super().__init__()
13
- self.dml = dml
14
- self.tables = tables
15
- self.debug = debug
11
+ __all__ = [
12
+ "SqlCompleter",
13
+ ]
14
+
15
+ def default_columns(_: list[str]):
16
+ return 'id,x.,y.,z.'.split(',')
16
17
 
17
- def get_completions(
18
- self, document: Document, complete_event: CompleteEvent
19
- ) -> Iterable[Completion]:
20
- text = document.text_before_cursor.lstrip()
21
- if self.dml:
22
- state = f'{self.dml}_'
23
- text = f'{self.dml} {text}'
18
+ class SqlCompleter(AutomataCompleter[Token]):
19
+ def tokens(self, text: str) -> list[Token]:
20
+ tokens = []
24
21
 
25
- completer = None
26
22
  stmts = sqlparse.parse(text)
27
23
  if not stmts:
28
- completer = TermCompleter(['select', 'insert', 'delete', 'update'])
24
+ tokens = []
29
25
  else:
30
26
  statement: Statement = stmts[0]
31
- state = self.traverse_tokens(text, statement.tokens)
32
- if self.debug:
33
- print('\n =>', state)
34
- if state == 'dml_incomplete':
35
- completer = TermCompleter(['select', 'insert', 'delete', 'update'])
36
-
37
- elif state == 'select_':
38
- completer = TermCompleter(['*'])
39
- elif state == 'select_a':
40
- completer = TermCompleter(['from'])
41
- elif state == 'select_a,':
42
- completer = TermCompleter(['*'])
43
- elif state == 'select_a_':
44
- completer = TermCompleter(['from'])
45
- elif state == "select_a_from_":
46
- completer = TermCompleter(self.tables())
47
- elif state == "select_a_from_x_":
48
- completer = TermCompleter(['where', 'group', 'limit'])
49
- elif state == "select_a_from_x,":
50
- completer = TermCompleter(self.tables())
51
- elif state == "select_a_from_x_where_":
52
- completer = TermCompleter(['id'])
53
- elif state == "select_a_from_x_where_id":
54
- completer = TermCompleter(['=', '<', '<=', '>', '>=', '<>', 'like'])
55
- elif state == "select_a_from_x_where_id=":
56
- completer = TermCompleter(["'"])
57
- elif state == "select_a_from_x_where_id=v_":
58
- completer = TermCompleter(['and', 'or', 'group', 'limit'])
59
- elif state == "select_a_from_x_where_id=v_limit_":
60
- completer = TermCompleter(['1'])
61
- elif state == "select_a_from_x_group_":
62
- completer = TermCompleter(['by'])
63
- elif state == "select_a_from_x_group_by_":
64
- completer = TermCompleter(['id'])
65
- elif state == "select_a_from_x_group_by_a,":
66
- completer = TermCompleter(['id'])
67
- elif state == "select_a_from_x_group_by_a_":
68
- completer = TermCompleter(['limit'])
69
- elif state == "select_a_from_x_group_by_a_limit_":
70
- completer = TermCompleter(['1'])
71
-
72
- elif state == "insert_":
73
- completer = TermCompleter(['into'])
74
- elif state == "insert_into_":
75
- completer = TermCompleter(self.tables())
76
- elif state == "insert_into_x_":
77
- completer = TermCompleter(['values'])
78
- elif state == "insert_into_x(":
79
- completer = TermCompleter(['id'])
80
- elif state == "insert_into_x(a,":
81
- completer = TermCompleter(['id'])
82
- elif state == "insert_into_x(a)_":
83
- completer = TermCompleter(['values('])
84
- elif state == "insert_into_x_values":
85
- completer = TermCompleter(['('])
86
- elif state == "insert_into_x_values(":
87
- completer = TermCompleter(["'"])
88
-
89
- elif state == "update_":
90
- completer = TermCompleter(self.tables())
91
- elif state == "update_x_":
92
- completer = TermCompleter(['set'])
93
- elif state in ["update_x_set_", "update_x_set_a=v,"]:
94
- completer = TermCompleter(['id'])
95
- elif state == "update_x_set_a":
96
- completer = TermCompleter(['='])
97
- elif state == "update_x_set_a=":
98
- completer = TermCompleter(["'"])
99
- elif state == "update_x_set_a=v_":
100
- completer = TermCompleter(['where'])
101
- elif state == "update_x_set_a=v_where_":
102
- completer = TermCompleter(['id'])
103
- elif state == "update_x_set_a=v_where_id":
104
- completer = TermCompleter(['='])
105
- elif state == "update_x_set_a=v_where_id=v_":
106
- completer = TermCompleter(['and', 'or'])
107
-
108
- elif state == "delete_":
109
- completer = TermCompleter(['from'])
110
- elif state == "delete_from_":
111
- completer = TermCompleter(self.tables())
112
- elif state == "delete_from_x_":
113
- completer = TermCompleter(['where'])
114
- elif state == "delete_from_x_where_":
115
- completer = TermCompleter(['id'])
116
- elif state == "delete_from_x_where_id":
117
- completer = TermCompleter(['='])
118
- elif state == "delete_from_x_where_id=":
119
- completer = TermCompleter(["'"])
120
- elif state == "delete_from_x_where_id=v_":
121
- completer = TermCompleter(['and', 'or'])
27
+ tokens = statement.tokens
28
+
29
+ return tokens
30
+
31
+ def __init__(self,
32
+ tables: Callable[[], list[str]],
33
+ dml: str = None,
34
+ columns: Callable[[list[str]], list[str]] = default_columns,
35
+ partition_columns: Callable[[list[str]], list[str]] = lambda x: [],
36
+ table_props: Callable[[], dict[str,list[str]]] = lambda: [],
37
+ variant = 'sql',
38
+ debug = False):
39
+ machine = SqlStateMachine(debug=debug)
40
+ if variant == 'cql':
41
+ machine = CqlStateMachine(debug=debug)
42
+ elif variant == 'athena':
43
+ machine = AthenaStateMachine(debug=debug)
44
+ super().__init__(machine, dml, debug)
122
45
 
123
- if completer:
124
- for c in completer.get_completions(document, complete_event):
125
- yield c
126
-
127
- def traverse_tokens(self, text: str, tokens: list[Token], state: str = None, indent=0):
128
- # state: str = None
129
- for token in tokens:
130
- if self.debug:
131
- if token.ttype == T.Whitespace:
132
- print('_ ', end='')
133
- elif token.ttype in [T.DML, T.Wildcard, T.Punctuation]:
134
- print(f'{token.value} ', end='')
135
- elif token.ttype:
136
- tks = str(token.ttype).split('.')
137
- typ = tks[len(tks) - 1]
138
- if ' ' in token.value:
139
- print(f'"{token.value}:{typ}" ', end='')
140
- else:
141
- print(f'{token.value}:{typ} ', end='')
142
- # print(" " * indent + f"Token: {token.value}, Type: {token.ttype}@{token.ttype.__class__}")
143
- node: str = None
144
- if token.is_group:
145
- state = self.traverse_tokens(text, token.tokens, state, indent + 1)
146
- else:
147
- if not state:
148
- if token.ttype == T.Keyword.DML and token.value.lower() == 'select':
149
- state = 'select'
150
- if token.ttype == T.Keyword.DML and token.value.lower() == 'insert':
151
- state = 'insert'
152
- if token.ttype == T.Keyword.DML and token.value.lower() == 'update':
153
- state = 'update'
154
- if token.ttype == T.Keyword.DML and token.value.lower() == 'delete':
155
- state = 'delete'
156
- elif token.ttype == T.Name:
157
- state = 'dml_incomplete'
158
-
159
- elif state == 'select':
160
- if token.ttype == T.Text.Whitespace:
161
- state = 'select_'
162
- elif state == 'select_':
163
- if token.ttype == T.Name or token.ttype == T.Wildcard:
164
- state = 'select_a'
165
- elif state == 'select_a':
166
- if token.ttype == T.Text.Whitespace:
167
- state = 'select_a_'
168
- elif token.ttype == T.Punctuation and token.value == ',':
169
- state = 'select_a,'
170
- elif state == 'select_a,':
171
- if token.ttype == T.Name or token.ttype == T.Wildcard:
172
- state = 'select_a'
173
- elif state == 'select_a_':
174
- if token.ttype == T.Keyword and token.value.lower() == 'from':
175
- state = 'select_a_from'
176
- elif state == 'select_a_from':
177
- if token.ttype == T.Text.Whitespace:
178
- state = 'select_a_from_'
179
- elif state == 'select_a_from_':
180
- if token.ttype == T.Name:
181
- state = 'select_a_from_x'
182
- elif state == 'select_a_from_x':
183
- if token.ttype == T.Text.Whitespace:
184
- state = 'select_a_from_x_'
185
- elif token.ttype == T.Punctuation and token.value == ',':
186
- state = 'select_a_from_x,'
187
- elif state == 'select_a_from_x,':
188
- if token.ttype == T.Name:
189
- state = 'select_a_from_x'
190
- elif state == 'select_a_from_x_':
191
- if token.ttype == T.Keyword and token.value.lower() == 'where':
192
- state = 'select_a_from_x_where'
193
- elif token.ttype == T.Keyword and token.value.lower() == 'limit':
194
- state = 'select_a_from_x_where_id=v_limit'
195
- elif token.ttype == T.Keyword and token.value.lower() == 'group':
196
- state = 'select_a_from_x_group'
197
- elif token.ttype == T.Keyword and token.value.lower() == 'group by':
198
- state = 'select_a_from_x_group_by'
199
- elif state == 'select_a_from_x_where':
200
- if token.ttype == T.Text.Whitespace:
201
- state = 'select_a_from_x_where_'
202
- elif state == 'select_a_from_x_where_':
203
- if token.ttype == T.Name:
204
- state = 'select_a_from_x_where_id'
205
- elif state == 'select_a_from_x_where_id':
206
- if token.ttype == T.Operator.Comparison:
207
- state = 'select_a_from_x_where_id='
208
- elif state == 'select_a_from_x_where_id=':
209
- if token.ttype in [T.Literal.String.Single, T.Name]:
210
- state = 'select_a_from_x_where_id=v'
211
- elif state == 'select_a_from_x_where_id=v':
212
- if token.ttype == T.Text.Whitespace:
213
- state = 'select_a_from_x_where_id=v_'
214
- elif state == 'select_a_from_x_where_id=v_':
215
- if token.ttype == T.Keyword and token.value.lower() in ['and', 'or']:
216
- state = 'select_a_from_x_where'
217
- elif token.ttype == T.Keyword and token.value.lower() == 'group':
218
- state = 'select_a_from_x_group'
219
- elif token.ttype == T.Keyword and token.value.lower() == 'limit':
220
- state = 'select_a_from_x_where_id=v_limit'
221
- elif state == 'select_a_from_x_group':
222
- if token.ttype == T.Text.Whitespace:
223
- state = 'select_a_from_x_group_'
224
- elif state == 'select_a_from_x_group_':
225
- if token.ttype == T.Keyword and token.value.lower() == 'by':
226
- state = 'select_a_from_x_group_by'
227
- elif state == 'select_a_from_x_group_by':
228
- if token.ttype == T.Text.Whitespace:
229
- state = 'select_a_from_x_group_by_'
230
- elif state == 'select_a_from_x_group_by_':
231
- if token.ttype == T.Name:
232
- state = 'select_a_from_x_group_by_a'
233
- elif state == 'select_a_from_x_group_by_a':
234
- if token.ttype == T.Text.Whitespace:
235
- state = 'select_a_from_x_group_by_a_'
236
- elif token.ttype == T.Punctuation and token.value == ',':
237
- state = 'select_a_from_x_group_by_a,'
238
- elif state == 'select_a_from_x_group_by_a,':
239
- if token.ttype == T.Name:
240
- state = 'select_a_from_x_group_by_a'
241
- elif state == 'select_a_from_x_group_by_a_':
242
- if token.ttype == T.Keyword and token.value.lower() == 'limit':
243
- state = 'select_a_from_x_where_id=v_limit'
244
- elif state == 'select_a_from_x_where_id=v_limit':
245
- if token.ttype == T.Text.Whitespace:
246
- state = 'select_a_from_x_where_id=v_limit_'
247
-
248
- elif state == 'insert':
249
- if token.ttype == T.Text.Whitespace:
250
- state = 'insert_'
251
- elif state == 'insert_':
252
- if token.ttype == T.Keyword and token.value.lower() == 'into':
253
- state = 'insert_into'
254
- elif state == 'insert_into':
255
- if token.ttype == T.Text.Whitespace:
256
- state = 'insert_into_'
257
- elif state == 'insert_into_':
258
- if token.ttype == T.Name:
259
- state = 'insert_into_x'
260
- elif state == 'insert_into_x':
261
- if token.ttype == T.Text.Whitespace:
262
- state = 'insert_into_x_'
263
- elif token.ttype == T.Punctuation and token.value == '(':
264
- state = 'insert_into_x('
265
- elif state == 'insert_into_x_':
266
- if token.ttype == T.Punctuation and token.value == '(':
267
- state = 'insert_into_x('
268
- elif token.ttype == T.Keyword and token.value.lower() == 'values':
269
- state = 'insert_into_x_values'
270
- elif state == 'insert_into_x(':
271
- if token.ttype == T.Name:
272
- state = 'insert_into_x(a'
273
- elif state == 'insert_into_x(a':
274
- if token.ttype == T.Punctuation and token.value == ',':
275
- state = 'insert_into_x(a,'
276
- elif token.ttype == T.Punctuation and token.value == ')':
277
- state = 'insert_into_x(a)'
278
- elif state == 'insert_into_x(a,':
279
- if token.ttype == T.Name:
280
- state = 'insert_into_x(a'
281
- elif state == 'insert_into_x(a)':
282
- if token.ttype == T.Text.Whitespace:
283
- state = 'insert_into_x(a)_'
284
- elif state == 'insert_into_x(a)_':
285
- if token.ttype == T.Keyword and token.value.lower() == 'values':
286
- state = 'insert_into_x_values'
287
- elif state == 'insert_into_x_values':
288
- if token.ttype == T.Punctuation and token.value == '(':
289
- state = 'insert_into_x_values('
290
- elif state == 'insert_into_x_values(':
291
- if token.ttype in [T.Literal.String.Single, T.Name]:
292
- state = 'insert_into_x_values(v'
293
- elif state == 'insert_into_x_values(v':
294
- if token.ttype == T.Punctuation and token.value == ',':
295
- state = 'insert_into_x_values(v,'
296
- elif token.ttype == T.Punctuation and token.value == ')':
297
- state = 'insert_into_x_values(v)'
298
- elif state == 'insert_into_x_values(v,':
299
- if token.ttype in [T.Literal.String.Single, T.Name]:
300
- state = 'insert_into_x_values(v'
301
-
302
- elif state == 'update':
303
- if token.ttype == T.Text.Whitespace:
304
- state = 'update_'
305
- elif state == 'update_':
306
- if token.ttype == T.Name:
307
- state = 'update_x'
308
- elif state == 'update_x':
309
- if token.ttype == T.Text.Whitespace:
310
- state = 'update_x_'
311
- elif state == 'update_x_':
312
- if token.ttype == T.Keyword and token.value.lower() == 'set':
313
- state = 'update_x_set'
314
- elif state == 'update_x_set':
315
- if token.ttype == T.Text.Whitespace:
316
- state = 'update_x_set_'
317
- elif state == 'update_x_set_':
318
- if token.ttype == T.Name:
319
- state = 'update_x_set_a'
320
- elif state == 'update_x_set_a':
321
- if token.ttype == T.Operator.Comparison:
322
- state = 'update_x_set_a='
323
- elif state == 'update_x_set_a=':
324
- if token.ttype in [T.Literal.String.Single, T.Name]:
325
- state = 'update_x_set_a=v'
326
- elif state == 'update_x_set_a=v':
327
- if token.ttype == T.Punctuation and token.value == ',':
328
- state = 'update_x_set_a=v,'
329
- elif token.ttype == T.Text.Whitespace:
330
- state = 'update_x_set_a=v_'
331
- elif state == 'update_x_set_a=v,':
332
- if token.ttype == T.Name:
333
- state = 'update_x_set_a'
334
- elif state == 'update_x_set_a=v_':
335
- if token.ttype == T.Punctuation and token.value == ',':
336
- state = 'update_x_set_a=v,'
337
- elif token.ttype == T.Keyword and token.value.lower() == 'where':
338
- state = 'update_x_set_a=v_where'
339
- elif state == 'update_x_set_a=v_where':
340
- if token.ttype == T.Text.Whitespace:
341
- state = 'update_x_set_a=v_where_'
342
- elif state == 'update_x_set_a=v_where_':
343
- if token.ttype == T.Name:
344
- state = 'update_x_set_a=v_where_id'
345
- elif state == 'update_x_set_a=v_where_id':
346
- if token.ttype == T.Operator.Comparison:
347
- state = 'update_x_set_a=v_where_id='
348
- elif state == 'update_x_set_a=v_where_id=':
349
- if token.ttype in [T.Literal.String.Single, T.Name]:
350
- state = 'update_x_set_a=v_where_id=v'
351
- elif state == 'update_x_set_a=v_where_id=v':
352
- if token.ttype == T.Text.Whitespace:
353
- state = 'update_x_set_a=v_where_id=v_'
354
- elif state == 'update_x_set_a=v_where_id=v_':
355
- if token.ttype == T.Keyword and token.value.lower() in ['and', 'or']:
356
- state = 'update_x_set_a=v_where'
46
+ self.tables = tables
47
+ self.columns = columns
48
+ self.partition_columns = partition_columns
49
+ self.table_props = table_props
50
+ self.variant = variant
51
+ self.debug = debug
357
52
 
358
- elif state == 'delete':
359
- if token.ttype == T.Text.Whitespace:
360
- state = 'delete_'
361
- elif state == 'delete_':
362
- if token.ttype == T.Keyword and token.value.lower() == 'from':
363
- state = 'delete_from'
364
- elif state == 'delete_from':
365
- if token.ttype == T.Text.Whitespace:
366
- state = 'delete_from_'
367
- elif state == 'delete_from_':
368
- if token.ttype == T.Name:
369
- state = 'delete_from_x'
370
- elif state == 'delete_from_x':
371
- if token.ttype == T.Text.Whitespace:
372
- state = 'delete_from_x_'
373
- elif state == 'delete_from_x_':
374
- if token.ttype == T.Keyword and token.value.lower() == 'where':
375
- state = 'delete_from_x_where'
376
- elif state == 'delete_from_x_where':
377
- if token.ttype == T.Text.Whitespace:
378
- state = 'delete_from_x_where_'
379
- elif state == 'delete_from_x_where_':
380
- if token.ttype == T.Name:
381
- state = 'delete_from_x_where_id'
382
- elif state == 'delete_from_x_where_id':
383
- if token.ttype == T.Operator.Comparison:
384
- state = 'delete_from_x_where_id='
385
- elif state == 'delete_from_x_where_id=':
386
- if token.ttype in [T.Literal.String.Single, T.Name]:
387
- state = 'delete_from_x_where_id=v'
388
- elif state == 'delete_from_x_where_id=v':
389
- if token.ttype == T.Text.Whitespace:
390
- state = 'delete_from_x_where_id=v_'
391
- elif state == 'delete_from_x_where_id=v_':
392
- if token.ttype == T.Keyword and token.value.lower() in ['and', 'or']:
393
- state = 'delete_from_x_where'
53
+ def suggestions_completer(self, state: State, suggestions: str) -> list[str]:
54
+ if not suggestions:
55
+ return None
56
+
57
+ terms = []
58
+ for suggestion in suggestions.split(','):
59
+ terms.extend(self._terms(state, suggestion))
60
+
61
+ return TermCompleter(terms)
62
+
63
+ def _terms(self, state: State, word: str) -> list[str]:
64
+ terms = []
65
+
66
+ if word == 'tables':
67
+ terms.extend(self.tables())
68
+ elif word == '`tables`':
69
+ terms.append('tables')
70
+ elif word == 'columns':
71
+ terms.extend(self.columns([]))
72
+ elif word == 'partition-columns':
73
+ terms.extend(self.partition_columns([]))
74
+ elif word == 'table-props':
75
+ terms.extend(self.table_props().keys())
76
+ elif word == 'table-prop-values':
77
+ if 'last_name' in state.context and state.context['last_name']:
78
+ terms.extend(self.table_props()[state.context['last_name']])
79
+ elif word == 'single':
80
+ terms.append("'")
81
+ elif word == 'comma':
82
+ terms.append(",")
83
+ else:
84
+ terms.append(word)
394
85
 
395
- return state
86
+ return terms
396
87
 
397
- def completions(table_names: Callable[[], list[str]]):
88
+ def completions_for_nesting(self):
398
89
  return {
399
- 'delete': SqlCompleter(table_names, 'delete'),
400
- 'insert': SqlCompleter(table_names, 'insert'),
401
- 'select': SqlCompleter(table_names, 'select'),
402
- 'update': SqlCompleter(table_names, 'update'),
90
+ word : SqlCompleter(self.tables, word, columns=self.columns, partition_columns=self.partition_columns,
91
+ table_props=self.table_props, variant=self.variant)
92
+ for word in self.machine.suggestions[''].strip(' ').split(',')
403
93
  }