kaqing 2.0.101__py3-none-any.whl → 2.0.104__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 (49) hide show
  1. adam/batch.py +0 -14
  2. adam/commands/audit/audit.py +4 -8
  3. adam/commands/audit/audit_repair_tables.py +13 -35
  4. adam/commands/audit/audit_run.py +49 -0
  5. adam/commands/bash.py +60 -2
  6. adam/commands/cd.py +8 -8
  7. adam/commands/commands_utils.py +1 -2
  8. adam/commands/cql/cql_completions.py +4 -4
  9. adam/commands/cql/cql_utils.py +6 -9
  10. adam/commands/cql/cqlsh.py +6 -3
  11. adam/commands/deploy/deploy_pg_agent.py +2 -2
  12. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  13. adam/commands/ls.py +12 -12
  14. adam/commands/nodetool.py +1 -1
  15. adam/commands/postgres/postgres.py +3 -3
  16. adam/commands/postgres/{postgres_session.py → postgres_context.py} +26 -27
  17. adam/commands/postgres/postgres_utils.py +5 -5
  18. adam/commands/postgres/psql_completions.py +1 -1
  19. adam/commands/preview_table.py +8 -27
  20. adam/commands/pwd.py +2 -2
  21. adam/embedded_params.py +1 -1
  22. adam/repl.py +5 -5
  23. adam/repl_commands.py +4 -5
  24. adam/repl_state.py +2 -2
  25. adam/sql/sql_completer.py +67 -76
  26. adam/sql/sql_state_machine.py +518 -0
  27. adam/sql/term_completer.py +3 -0
  28. adam/utils_athena.py +68 -1
  29. adam/utils_k8s/cassandra_clusters.py +4 -4
  30. adam/utils_k8s/cassandra_nodes.py +2 -2
  31. adam/utils_k8s/pods.py +12 -6
  32. adam/utils_k8s/statefulsets.py +2 -2
  33. adam/version.py +1 -1
  34. {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/METADATA +1 -1
  35. {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/RECORD +38 -47
  36. adam/commands/audit/audit_table_completer.py +0 -9
  37. adam/commands/cql/cql_table_completer.py +0 -8
  38. adam/commands/describe/__init__.py +0 -0
  39. adam/commands/describe/describe.py +0 -61
  40. adam/commands/describe/describe_keyspace.py +0 -58
  41. adam/commands/describe/describe_keyspaces.py +0 -46
  42. adam/commands/describe/describe_schema.py +0 -46
  43. adam/commands/describe/describe_table.py +0 -57
  44. adam/commands/describe/describe_tables.py +0 -46
  45. adam/commands/postgres/psql_table_completer.py +0 -11
  46. adam/sql/state_machine.py +0 -576
  47. {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/WHEEL +0 -0
  48. {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/entry_points.txt +0 -0
  49. {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,518 @@
1
+ from typing import Callable
2
+ from sqlparse.sql import Token
3
+ from sqlparse import tokens as TOKEN
4
+
5
+ from adam.utils_repl.state_machine import StateMachine, State
6
+
7
+ __all__ = [
8
+ 'SqlStateMachine', 'CqlStateMachine', 'AthenaStateMachine'
9
+ ]
10
+
11
+ SQL_SPEC = [
12
+ # <select_statement> ::= SELECT <select_list>
13
+ # FROM <table_expression>
14
+ # [WHERE <search_condition>]
15
+ # [<group_by_clause>]
16
+ # [<having_clause>]
17
+ # [<order_by_clause>]
18
+ # [<limit_clause>]
19
+
20
+ # <search_condition> ::= <boolean_term>
21
+ # | <search_condition> OR <boolean_term>
22
+
23
+ # <boolean_term> ::= <boolean_factor>
24
+ # | <boolean_term> AND <boolean_factor>
25
+
26
+ # <boolean_factor> ::= [NOT] <predicate>
27
+ # | ([NOT] <search_condition>)
28
+
29
+ # <predicate> ::= <comparison_predicate>
30
+ # | <between_predicate>
31
+ # | <in_predicate>
32
+ # | <like_predicate>
33
+ # | <null_predicate>
34
+ # | <exists_predicate>
35
+ # | <quantified_predicate>
36
+ # | <unique_predicate>
37
+ # | <match_predicate>
38
+ # | <overlaps_predicate>
39
+ # | <distinct_predicate>
40
+ # | <member_predicate>
41
+ # | <submultiset_predicate>
42
+ # | <set_predicate>
43
+
44
+ # <comparison_predicate> ::= <row_value_expression> <comparison_operator> <row_value_expression>
45
+ # <comparison_operator> ::= '=' | '<>' | '<' | '<=' | '>' | '>='
46
+
47
+ # <row_value_expression> ::= <value_expression>
48
+ # | (<value_expression> [ { <comma> <value_expression> }... ])
49
+
50
+ # <value_expression> ::= <numeric_value_expression>
51
+ # | <string_value_expression>
52
+ # | <datetime_value_expression>
53
+ # | <interval_value_expression>
54
+ # | <boolean_value_expression>
55
+ # | <user_defined_type_value_expression>
56
+ # | <reference_value_expression>
57
+ # | <collection_value_expression>
58
+ # | <row_value_constructor>
59
+ # | <case_expression>
60
+ # | <cast_expression>
61
+ # | <subquery>
62
+ # | NULL
63
+ # | DEFAULT
64
+ # | <identifier>
65
+ # | <literal>
66
+ ' > select > select ^ select,insert,update,delete,alter,preview',
67
+ 'select_ > name|* > select_a ^ *',
68
+ 'select_a > , > select_a_comma_',
69
+ 'select_a_comma_ > name|* > select_a ^ *',
70
+ 'select_a_ > from > select_from ^ from',
71
+ 'select_from_ > name|audit > select_from_x ^ (select,tables',
72
+ '- > ( > select_from_lp_',
73
+ '- < ) > select_from_sq',
74
+ 'select_from_lp_ > select > select',
75
+ 'select_from_x > , > select_from_x_comma_ ^ (select,tables',
76
+ 'select_from_sq_ > as > select_from_x_as ^ as',
77
+ 'select_from_x_comma_ > name|audit > select_from_x ^ tables',
78
+ 'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
79
+ 'select_from_x_as_x_ > , > select_from_x_comma_ ^ where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
80
+ '- > as > select_from_x_as',
81
+ '- > where > select_where',
82
+ '- > order > select_order',
83
+ '- > order by > select_order_by',
84
+ '- > limit > select_where_sc_limit',
85
+ '- > group > select_group',
86
+ '- > group by > select_group_by',
87
+ '- > inner > select_from_x_inner',
88
+ '- > inner join > select_join',
89
+ '- > left > select_from_x_left',
90
+ '- > left join > select_join',
91
+ '- > left outer join > select_join',
92
+ '- > right > select_from_x_right',
93
+ '- > right join > select_join',
94
+ '- > right outer join > select_join',
95
+ '- > full > select_from_x_full',
96
+ '- > full outer join > select_join',
97
+ 'select_from_x_as_ > name > select_from_x_as_x ^ x,y,z',
98
+ 'select_from_x_as_x > , > select_from_x_as_x_comma_',
99
+ 'select_from_x_as_x_comma_ > name|audit > select_from_x ^ tables',
100
+ 'select_where_ > name > select_where_a ^ columns',
101
+ 'select_where_a > name > select_where_a ^ columns,=,<,<=,>,>=,<>',
102
+ '- > comparison > select_where_a_op',
103
+ 'select_where_a_ > comparison > select_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
104
+ '- > not > select_where_a_not',
105
+ '- > in > select_where_a_in',
106
+ 'select_where_a_not_ > comparison > select_where_a_not_op ^ like,in',
107
+ '- > in > select_where_a_in',
108
+ 'select_where_a_in > ( > select_where_a_in_lp_ ^ (',
109
+ '- < ) > select_where_sc',
110
+ 'select_where_a_in_lp_ > name|single|num > select_where_a_in_lp_a ^ single,select',
111
+ '- > select > select_where_a_in_lp_select',
112
+ 'select_where_a_in_lp_select_ > name > select_a ^ id',
113
+ 'select_where_a_in_lp_a > , > select_where_a_in_lp_a_comma_ ^ comma,)',
114
+ 'select_where_a_in_lp_a_comma_ > name|single|num > select_where_a_in_lp_a ^ single',
115
+ 'select_where_a_not_op > name|single|num > select_where_sc ^ single',
116
+ 'select_where_a_op > name|single|num > select_where_sc ^ single',
117
+ 'select_where_sc_ > and|or > select_where ^ and,or,order by,group by,limit',
118
+ '- > group > select_group',
119
+ '- > group by > select_group_by',
120
+ '- > order > select_order',
121
+ '- > order by > select_order_by',
122
+ '- > limit > select_where_sc_limit',
123
+ 'select_group_ > by > select_group_by ^ by',
124
+ 'select_group_by_ > name > select_group_by_a ^ columns',
125
+ 'select_group_by_a > , > select_group_by_a_comma_ ^ columns',
126
+ 'select_group_by_a_comma_ > name > select_group_by_a ^ columns',
127
+ 'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by',
128
+ '- > order > select_order',
129
+ '- > order by > select_order_by',
130
+ 'select_order_ > by > select_order_by ^ by',
131
+ 'select_order_by_ > name > select_order_by_a ^ columns',
132
+ 'select_order_by_a > , > select_order_by_a_comma_',
133
+ 'select_order_by_a_comma_ > name > select_order_by_a ^ columns',
134
+ 'select_order_by_a_ > desc|asc > select_order_by_a_desc ^ desc,asc,limit',
135
+ '- > limit > select_where_sc_limit',
136
+ 'select_order_by_a_desc > , > select_order_by_a_comma_',
137
+ 'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit',
138
+ 'select_where_sc_limit_ > num > select_where_sc_limit_num ^ 1',
139
+ 'select_where_sc_limit_num_rp__ > as > select_from_x_as ^ as',
140
+ 'select_where_x_inner_ > join > select_join',
141
+ 'select_join_ > name|audit > select_x_join_y ^ tables',
142
+ 'select_from_x_left_ > join > select_join ^ outer join',
143
+ '- > outer > select_from_x_left_outer',
144
+ 'select_from_x_left_outer_ > join > select_join ^ join',
145
+ 'select_from_x_right_ > join > select_join ^ outer join',
146
+ '- > outer > select_from_x_right_outer',
147
+ 'select_from_x_right_outer_ > join > select_join ^ join',
148
+ 'select_from_x_full_ > join > select_join ^ outer join',
149
+ '- > outer > select_from_x_full_outer',
150
+ 'select_from_x_full_outer_ > join > select_join ^ join',
151
+ 'select_x_join_y_ > as > select_x_join_y_as ^ as,on',
152
+ '- > on > select_x_join_y_on ^ as,on',
153
+ 'select_x_join_y_as_ > name > select_x_join_y_as_y ^ x,y,z',
154
+ 'select_x_join_y_as_y_ > on > select_x_join_y_on ^ on',
155
+ 'select_x_join_y_on_ > name > select_x_join_y_on_a ^ columns',
156
+ 'select_x_join_y_on_a > name > select_x_join_y_on_a ^ columns,=',
157
+ '- > comparison > select_x_join_y_on_a_op',
158
+ 'select_x_join_y_on_a_ > comparison > select_x_join_y_on_a_op ^ =',
159
+ 'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ columns',
160
+ 'select_x_join_y_on_a_op_b > _ > select_from_x_as_x_',
161
+
162
+ # <insert_statement> ::= INSERT INTO <table_name> [ ( <column_list> ) ]
163
+ # VALUES ( <value_list> )
164
+ # | INSERT INTO <table_name> [ ( <column_list> ) ]
165
+ # <query_expression>
166
+
167
+ # <table_name> ::= <identifier>
168
+
169
+ # <column_list> ::= <column_name> [ , <column_list> ]
170
+
171
+ # <column_name> ::= <identifier>
172
+
173
+ # <value_list> ::= <expression> [ , <value_list> ]
174
+
175
+ # <query_expression> ::= SELECT <select_list> FROM <table_reference_list> [ WHERE <search_condition> ] [ GROUP BY <grouping_column_list> ] [ HAVING <search_condition> ] [ ORDER BY <sort_specification_list> ]
176
+ ' > insert > insert',
177
+ 'insert_ > into > insert_into ^ into',
178
+ 'insert_into_ > name|audit > insert_into_x ^ tables',
179
+ 'insert_into_x > ( > insert_into_x_lp_',
180
+ 'insert_into_x_ > ( > insert_into_x_lp_ ^ (,values(',
181
+ '- > values > insert_values',
182
+ 'insert_into_x_lp_ > name > insert_into_x_lp_a ^ id',
183
+ 'insert_into_x_lp_a > , > insert_into_x_lp_a_comma_',
184
+ '- > ) > insert_into_x_lp_a_rp_',
185
+ 'insert_into_x_lp_a_comma_ > name > insert_into_x_lp_a ^ id',
186
+ 'insert_into_x_lp_a_rp__ > values > insert_values ^ values(,select',
187
+ '- > select > select',
188
+ 'insert_values > ( > insert_values_lp_',
189
+ 'insert_values_lp_ > name|single|num > insert_values_lp_v ^ single',
190
+ 'insert_values_lp_v > , > insert_values_lp_v_comma_',
191
+ 'insert_values_lp_v_comma_ > name|single|num > insert_values_lp_v',
192
+
193
+ # <update_statement> ::= UPDATE <table_name>
194
+ # SET <set_clause_list>
195
+ # [WHERE <search_condition>]
196
+
197
+ # <set_clause_list> ::= <set_clause> { , <set_clause> }
198
+
199
+ # <set_clause> ::= <column_name> = <update_value>
200
+
201
+ # <update_value> ::= <expression> | NULL | DEFAULT
202
+
203
+ # <search_condition> ::= <boolean_expression>
204
+ ' > update > update',
205
+ 'update_ > name|audit > update_x ^ tables',
206
+ 'update_x_ > set > update_set ^ set',
207
+ 'update_set_ > name > update_set_a ^ id',
208
+ 'update_set_a > comparison > update_set_a_op',
209
+ 'update_set_a_op > name|single|num > update_set_sc ^ single',
210
+ 'update_set_sc > , > update_set_sc_comma_',
211
+ 'update_set_sc_comma_ > name > update_set_a ^ id',
212
+ 'update_set_sc_ > , > update_set_sc_comma_ ^ where',
213
+ '- > where > update_where',
214
+ 'update_where_ > name > update_where_a ^ id',
215
+ 'update_where_a > comparison > update_where_a_op',
216
+ 'update_where_a_ > comparison > update_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
217
+ '- > not > update_where_a_not',
218
+ '- > in > update_where_a_in',
219
+ 'update_where_a_not_ > comparison > update_where_a_not_op ^ like,in',
220
+ '- > in > update_where_a_in',
221
+ 'update_where_a_in > ( > update_where_a_in_lp_ ^ (',
222
+ '- < ) > update_where_sc',
223
+ 'update_where_a_in_lp_ > name|single|num > update_where_a_in_lp_a ^ single,select',
224
+ '- > select > update_where_a_in_lp_select',
225
+ 'update_where_a_in_lp_select_ > name > select_a ^ id',
226
+ 'update_where_a_in_lp_a > , > update_where_a_in_lp_a_comma_ ^ comma,)',
227
+ 'update_where_a_in_lp_a_comma_ > name|single|num > update_where_a_in_lp_a ^ single',
228
+ 'update_where_a_not_op > name|single|num > update_where_sc ^ single',
229
+ 'update_where_a_op > name|single|num > update_where_sc ^ single',
230
+ 'update_where_sc_ > and|or > update_where ^ and,or',
231
+
232
+ # <delete_statement> ::= DELETE FROM <table_name> [ WHERE <search_condition> ]
233
+
234
+ # <table_name> ::= <identifier>
235
+
236
+ # <search_condition> ::= <boolean_expression>
237
+
238
+ # <boolean_expression> ::= <predicate>
239
+ # | <boolean_expression> AND <predicate>
240
+ # | <boolean_expression> OR <predicate>
241
+ # | NOT <predicate>
242
+ # | ( <boolean_expression> )
243
+
244
+ # <predicate> ::= <expression> <comparison_operator> <expression>
245
+ # | <expression> IS NULL
246
+ # | <expression> IS NOT NULL
247
+ # | <expression> LIKE <pattern> [ ESCAPE <escape_character> ]
248
+ # | <expression> IN ( <expression_list> )
249
+ # | EXISTS ( <select_statement> )
250
+ # | ... (other predicates)
251
+
252
+ # <comparison_operator> ::= = | <> | != | > | < | >= | <=
253
+
254
+ # <expression> ::= <literal>
255
+ # | <column_name>
256
+ # | <function_call>
257
+ # | ( <expression> )
258
+ # | <expression> <arithmetic_operator> <expression>
259
+ # | ... (other expressions)
260
+
261
+ # <literal> ::= <numeric_literal> | <string_literal> | <boolean_literal> | <date_literal> | ...
262
+
263
+ # <column_name> ::= <identifier>
264
+
265
+ # <identifier> ::= <letter> { <letter> | <digit> | _ }...
266
+
267
+ # <pattern> ::= <string_literal>
268
+
269
+ # <escape_character> ::= <string_literal> (single character)
270
+
271
+ # <expression_list> ::= <expression> { , <expression> }...
272
+ ' > delete > delete',
273
+ 'delete_ > from > delete_from ^ from',
274
+ 'delete_from_ > name|audit > delete_from_x ^ tables',
275
+ 'delete_from_x_ > where > update_where ^ where',
276
+
277
+ # <alter table action> ::=
278
+ # ADD <column definition>
279
+ # | DROP COLUMN <column name>
280
+ # | MODIFY COLUMN <column name> <column modification>
281
+ # | RENAME TO <new table name>
282
+ # | ADD CONSTRAINT <constraint definition>
283
+ # | DROP CONSTRAINT <constraint name>
284
+ # | ... (other actions like adding/dropping indexes, partitions, etc.)
285
+
286
+ # <column definition> ::= <column name> <data type> [ <column constraint> ... ]
287
+
288
+ # <column modification> ::=
289
+ # SET DATA TYPE <data type>
290
+ # | SET DEFAULT <expression>
291
+ # | DROP DEFAULT
292
+ # | SET NOT NULL
293
+ # | DROP NOT NULL
294
+ # | ...
295
+
296
+ # <constraint definition> ::=
297
+ # PRIMARY KEY ( <column name list> )
298
+ # | UNIQUE ( <column name list> )
299
+ # | FOREIGN KEY ( <column name list> ) REFERENCES <referenced table> ( <referenced column list> )
300
+ # | CHECK ( <search condition> )
301
+
302
+ ' > alter > alter',
303
+ 'alter_ > table > alter_table ^ table',
304
+ 'alter_table_ > name|audit > alter_table_t ^ tables',
305
+ 'alter_table_t_ > add > alter_table_add ^ add,add constraint,drop column,drop constraint,rename to',
306
+ '- > drop > alter_table_drop',
307
+
308
+ ' > preview > preview',
309
+ 'preview_ > name|audit > preview_t ^ tables',
310
+ ]
311
+
312
+ SQL_KEYWORDS = [
313
+ 'select', 'from', 'as', 'not', 'in', 'where',
314
+ 'and', 'or', 'group', 'by', 'group by', 'order', 'order by', 'limit', 'asc', 'desc',
315
+ 'inner join', 'on', 'left', 'right', 'full', 'outer', 'left outer join',
316
+ 'left join', 'right outer join', 'right join', 'full join', 'full outer join',
317
+ 'insert', 'into', 'values',
318
+ 'update', 'where', 'set',
319
+ 'delete',
320
+ 'audit',
321
+ 'alter', 'table', 'tables', 'add', 'drop', 'with',
322
+ 'describe'
323
+ ]
324
+
325
+ EXPANDABLE_NAMES = {'tables', 'columns', 'partition-columns', 'table-props', 'table-props-values'}
326
+
327
+ CQL_SPEC = SQL_SPEC + [
328
+ ' > select > select ^ select,insert,update,delete,alter,describe,preview',
329
+
330
+ # ALTER TABLE [ <keyspace_name> . ] <table_name>
331
+ # ( ALTER <column_name> TYPE <cql_type>
332
+ # | ADD ( <column_definition_list> )
333
+ # | DROP ( <column_list> )
334
+ # | RENAME <column_name> TO <column_name> [ AND <column_name> TO <column_name> ... ]
335
+ # | WITH <table_properties> );
336
+
337
+ 'alter_ > table > alter_table ^ table,`tables`',
338
+ '- > tables > alter_tables',
339
+ 'alter_tables_ > with > alter_table_with ^ with',
340
+ 'alter_table_t_ > with > alter_table_with ^ with,add,drop',
341
+ 'alter_table_with_ > name > alter_table_with_p ^ table-props',
342
+ 'alter_table_with_p > comparison > alter_table_with_p_op ^ =',
343
+ 'alter_table_with_p_op > name|single|num > alter_table_with_p_op_v ^ table-prop-values',
344
+ 'alter_table_with_p_op_v_ > --include-reaper > alter_table_with_p_op_v_$ ^ --include-reaper',
345
+
346
+ ' > describe > describe',
347
+ 'describe_ > table > desc_table ^ table,`tables`,keyspace,keyspaces,schema',
348
+ '- > tables > desc_tables',
349
+ '- > keyspace > desc_keyspace',
350
+ '- > keyspaces > desc_keyspaces',
351
+ '- > schema > desc_schema',
352
+ 'desc_table_ > name > desc_table_t ^ tables',
353
+ 'desc_table_t_ > & > desc_table_t_$ ^ &',
354
+ 'desc_tables_ > & > desc_tables_$ ^ &',
355
+ 'desc_keyspace_ > name > desc_keyspace_k',
356
+ 'desc_keyspace_k_ > & > desc_keyspace_k_$ ^ &',
357
+ 'desc_schema_ > & > desc_schema_$ ^ &',
358
+ ]
359
+
360
+ CQL_KEYWORDS = SQL_KEYWORDS + [
361
+ 'schema', 'keyspace', 'keyspaces', 'tables'
362
+ ]
363
+
364
+ ATHENA_SPEC = SQL_SPEC + [
365
+ ' > select > select ^ select,insert,update,delete,alter,describe,preview',
366
+
367
+ 'alter_table_t_ > add > alter_table_add ^ add partition,drop partition',
368
+ 'alter_table_add_ > partition > alter_partition ^ partition',
369
+ 'alter_table_drop_ > partition > alter_partition ^ partition',
370
+ 'alter_partition > ( > alter_partition_lp ^ (',
371
+ 'alter_partition_lp > name > alter_partition_lp_a ^ partition-columns',
372
+ 'alter_partition_lp_a > comparison > alter_partition_lp_a_op ^ =',
373
+ 'alter_partition_lp_a_op > single > alter_partition_lp_a_op_v ^ single',
374
+ 'alter_partition_lp_a_op_v > , > alter_partition_lp_sc ^ single',
375
+ 'alter_partition_lp_sc > name|) > alter_partition_lp_a ^ partition-columns',
376
+
377
+ ' > describe > describe',
378
+ 'describe_ > name > desc_t ^ tables',
379
+ 'desc_t_ > name > desc_t_',
380
+
381
+ 'repair'
382
+ ]
383
+
384
+ ATHENA_KEYWORDS = SQL_KEYWORDS + [
385
+ 'partition'
386
+ ]
387
+
388
+ class SqlStateMachine(StateMachine[Token]):
389
+ def __init__(self, indent=0, push_level = 0, debug = False):
390
+ super().__init__(indent, push_level, debug)
391
+
392
+ def traverse_tokens(self, tokens: list[Token], state: State = State('')):
393
+ def handle_push():
394
+ if f'{state.state} > {it}' in self.states:
395
+ state_test = self.states[f'{state.state} > {it}']
396
+ if state_test.comeback_token:
397
+ self.comebacks[self.push_level] = state_test.comeback_state
398
+
399
+ def handle_pop():
400
+ if self.push_level in self.comebacks:
401
+ try:
402
+ return State(self.comebacks[self.push_level])
403
+ finally:
404
+ del self.comebacks[self.push_level]
405
+
406
+ return None
407
+
408
+ for token in tokens:
409
+ if self.debug:
410
+ if token.ttype == TOKEN.Whitespace:
411
+ print('_ ', end='')
412
+ elif token.ttype in [TOKEN.DML, TOKEN.Wildcard, TOKEN.Punctuation, TOKEN.CTE]:
413
+ print(f'{token.value} ', end='')
414
+ elif token.ttype:
415
+ tks = str(token.ttype).split('.')
416
+ typ = tks[len(tks) - 1]
417
+ if ' ' in token.value:
418
+ print(f'"{token.value}:{typ}" ', end='')
419
+ else:
420
+ print(f'{token.value}:{typ} ', end='')
421
+ # print(" " * self.indent + f"Token: {token.value}, Type: {token.ttype}@{token.ttype.__class__}")
422
+
423
+ last_name = None
424
+ if token.is_group:
425
+ state = self.traverse_tokens(token.tokens, state)
426
+ else:
427
+ comeback_state = None
428
+
429
+ it = ''
430
+ if (t := token.value.lower()) in self.keywords():
431
+ it = t
432
+ elif token.ttype == TOKEN.Text.Whitespace:
433
+ it = '_'
434
+ elif token.ttype == TOKEN.Name:
435
+ it = 'name'
436
+ last_name = token.value
437
+ elif token.ttype == TOKEN.Literal.String.Single:
438
+ it = 'single'
439
+ elif token.ttype in [TOKEN.Literal.Number.Integer, TOKEN.Literal.Number.Float]:
440
+ it = 'num'
441
+ elif token.ttype == TOKEN.Wildcard:
442
+ it = '*'
443
+ elif token.ttype == TOKEN.Punctuation:
444
+ it = token.value
445
+
446
+ if it == '(':
447
+ handle_push()
448
+ self.push_level += 1
449
+ elif it == ')':
450
+ self.push_level -= 1
451
+ comeback_state = handle_pop()
452
+
453
+ elif token.ttype == TOKEN.Operator.Comparison:
454
+ it = 'comparison'
455
+
456
+ try:
457
+ # print(f'\n{state.to_s} > {it} > ', end='')
458
+ if comeback_state:
459
+ state = comeback_state
460
+ else:
461
+ context = state.context
462
+ state = self.states[f'{state.state} > {it}']
463
+ state.context = context
464
+
465
+ if last_name:
466
+ state.context['last_name'] = last_name
467
+ except:
468
+ pass
469
+
470
+ return state
471
+
472
+ def spec(self):
473
+ return SQL_SPEC
474
+
475
+ def keywords(self):
476
+ return SQL_KEYWORDS
477
+
478
+ def expandable_names(self):
479
+ return EXPANDABLE_NAMES
480
+
481
+ def witespace_transition_condition(self, from_s: str, to_s: str):
482
+ return from_s.endswith('_') and not from_s.endswith('_comma_') and not from_s.endswith('_lp_') and not from_s.endswith('_rp_')
483
+
484
+ def incomplete_name_transition_condition(self, from_s: str, token: str, to_s: str, suggestions: str):
485
+ if not suggestions:
486
+ return None
487
+
488
+ tokens = [token]
489
+ if '|' in token:
490
+ tokens = token.split('|')
491
+
492
+ if 'name' not in tokens:
493
+ return None
494
+
495
+ if not self.expandable_names().intersection(set(suggestions.split(','))):
496
+ return None
497
+
498
+ return tokens
499
+
500
+ class CqlStateMachine(SqlStateMachine):
501
+ def __init__(self, indent=0, push_level = 0, debug = False):
502
+ super().__init__(indent, push_level, debug)
503
+
504
+ def spec(self):
505
+ return CQL_SPEC
506
+
507
+ def keywords(self):
508
+ return CQL_KEYWORDS
509
+
510
+ class AthenaStateMachine(SqlStateMachine):
511
+ def __init__(self, indent=0, push_level = 0, debug = False):
512
+ super().__init__(indent, push_level, debug)
513
+
514
+ def spec(self):
515
+ return ATHENA_SPEC
516
+
517
+ def keywords(self):
518
+ return ATHENA_KEYWORDS
@@ -22,6 +22,9 @@ class TermCompleter(WordCompleter):
22
22
  ) -> None:
23
23
  super().__init__(words, ignore_case, display_dict, meta_dict, WORD, sentence, match_middle, pattern)
24
24
 
25
+ def __str__(self):
26
+ return ','.join(self.words)
27
+
25
28
  def get_completions(
26
29
  self, document: Document, complete_event: CompleteEvent
27
30
  ) -> Iterable[Completion]:
adam/utils_athena.py CHANGED
@@ -1,10 +1,77 @@
1
+ from datetime import datetime
1
2
  import functools
2
3
  import time
3
4
  import boto3
5
+ import requests
4
6
 
5
7
  from adam.config import Config
6
8
  from adam.utils import lines_to_tabular, log, log2
7
9
 
10
+ class AuditMeta:
11
+ def __init__(self, checked_in: float, cluster_last_checked: float):
12
+ self.checked_in = checked_in
13
+ self.cluster_last_checked = cluster_last_checked
14
+
15
+ def get_meta() -> AuditMeta:
16
+ checked_in = 0.0
17
+ cluster_last_checked = 0.0
18
+
19
+ state, _, rs = audit_query(f'select partitions_last_checked, clusters_last_checked from meta')
20
+ if state == 'SUCCEEDED':
21
+ if len(rs) > 1:
22
+ try:
23
+ row = rs[1]['Data']
24
+ checked_in = float(row[0]['VarCharValue'])
25
+ cluster_last_checked = float(row[1]['VarCharValue'])
26
+ except:
27
+ pass
28
+
29
+ return AuditMeta(checked_in, cluster_last_checked)
30
+
31
+ def find_new_clusters(cluster_last_checked: float) -> list[str]:
32
+ dt_object = datetime.fromtimestamp(cluster_last_checked)
33
+
34
+ y = dt_object.strftime("%Y")
35
+ m = dt_object.strftime("%m")
36
+ d = dt_object.strftime("%d")
37
+ # select distinct c2.name from cluster as c1 right outer join
38
+ # (select distinct c as name from audit where y = '1969' and m = '12' and d >= '31' or y = '1969' and m > '12' or y > '1969') as c2
39
+ # on c1.name = c2.name where c1.name is null
40
+ where = f"y = '{y}' and m = '{m}' and d >= '{d}' or y = '{y}' and m > '{m}' or y > '{y}'"
41
+ query = '\n '.join([
42
+ 'select distinct c2.name from cluster as c1 right outer join',
43
+ f'(select distinct c as name from audit where {where}) as c2',
44
+ 'on c1.name = c2.name where c1.name is null'])
45
+ log2(query)
46
+ state, _, rs = audit_query(query)
47
+ if state == 'SUCCEEDED':
48
+ if len(rs) > 1:
49
+ try:
50
+ return [r['Data'][0]['VarCharValue'] for r in rs[1:]]
51
+ except:
52
+ pass
53
+
54
+ return []
55
+
56
+ def put_meta(action: str, meta: AuditMeta, clusters: list[str] = None):
57
+ payload = {
58
+ 'action': action,
59
+ 'partitions-last-checked': meta.checked_in,
60
+ 'clusters-last-checked': meta.cluster_last_checked
61
+ }
62
+ if clusters:
63
+ payload['clusters'] = clusters
64
+
65
+ audit_endpoint = Config().get("audit.endpoint", "https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/")
66
+ try:
67
+ response = requests.post(audit_endpoint, json=payload, timeout=Config().get("audit.timeout", 10))
68
+ if response.status_code in [200, 201]:
69
+ Config().debug(response.text)
70
+ else:
71
+ log2(f"Error: {response.status_code} {response.text}")
72
+ except requests.exceptions.Timeout as e:
73
+ log2(f"Timeout occurred: {e}")
74
+
8
75
  @functools.lru_cache()
9
76
  def audit_table_names():
10
77
  region_name = Config().get('audit.athena.region', 'us-west-2')
@@ -50,7 +117,7 @@ def run_audit_query(sql: str, database: str = None):
50
117
  columns = [col.get('VarCharValue') for col in column_info]
51
118
  lines = []
52
119
  for row in rs[1:]:
53
- row_data = [col.get('VarCharValue') for col in row['Data']]
120
+ row_data = [col.get('VarCharValue') if col else '' for col in row['Data']]
54
121
  lines.append('\t'.join(row_data))
55
122
 
56
123
  log(lines_to_tabular(lines, header='\t'.join(columns), separator='\t'))
@@ -14,12 +14,12 @@ T = TypeVar('T')
14
14
  # utility collection on cassandra clusters; methods are all static
15
15
  class CassandraClusters:
16
16
  def exec(statefulset: str, namespace: str, command: str, action: str = 'action',
17
- max_workers=0, show_out=True, on_any = False, shell = '/bin/sh') -> list[PodExecResult]:
17
+ max_workers=0, show_out=True, on_any = False, shell = '/bin/sh', background = False) -> list[PodExecResult]:
18
18
  def body(executor: ThreadPoolExecutor, pod: str, namespace: str, show_out: bool):
19
19
  if executor:
20
- return executor.submit(CassandraNodes.exec, pod, namespace, command, False, False, shell)
20
+ return executor.submit(CassandraNodes.exec, pod, namespace, command, False, False, shell, background)
21
21
 
22
- return CassandraNodes.exec(pod, namespace, command, show_out=show_out)
22
+ return CassandraNodes.exec(pod, namespace, command, show_out=show_out, background=background)
23
23
 
24
24
  def post(result, show_out: bool):
25
25
  if KubeContext.show_out(show_out):
@@ -31,4 +31,4 @@ class CassandraClusters:
31
31
 
32
32
  return result
33
33
 
34
- return StatefulSets.on_cluster(statefulset, namespace, body, post=post, action=action, max_workers=max_workers, show_out=show_out, on_any=on_any)
34
+ return StatefulSets.on_cluster(statefulset, namespace, body, post=post, action=action, max_workers=max_workers, show_out=show_out, on_any=on_any, background=background)
@@ -6,8 +6,8 @@ from adam.repl_session import ReplSession
6
6
 
7
7
  # utility collection on cassandra nodes; methods are all static
8
8
  class CassandraNodes:
9
- def exec(pod_name: str, namespace: str, command: str, show_out = True, throw_err = False, shell = '/bin/sh') -> PodExecResult:
10
- r = Pods.exec(pod_name, "cassandra", namespace, command, show_out = show_out, throw_err = throw_err, shell = shell)
9
+ def exec(pod_name: str, namespace: str, command: str, show_out = True, throw_err = False, shell = '/bin/sh', background = False) -> PodExecResult:
10
+ r = Pods.exec(pod_name, "cassandra", namespace, command, show_out = show_out, throw_err = throw_err, shell = shell, background = background)
11
11
 
12
12
  if r and Config().get('repl.history.push-cat-remote-log-file', True):
13
13
  if r.log_file: