kaqing 2.0.110__py3-none-any.whl → 2.0.214__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 (251) hide show
  1. adam/__init__.py +0 -2
  2. adam/app_session.py +9 -12
  3. adam/apps.py +18 -4
  4. adam/batch.py +19 -19
  5. adam/checks/check_utils.py +16 -46
  6. adam/checks/cpu.py +7 -1
  7. adam/checks/cpu_metrics.py +52 -0
  8. adam/checks/disk.py +2 -3
  9. adam/columns/columns.py +3 -1
  10. adam/columns/cpu.py +3 -1
  11. adam/columns/cpu_metrics.py +22 -0
  12. adam/columns/memory.py +3 -4
  13. adam/commands/__init__.py +24 -0
  14. adam/commands/app/app.py +38 -0
  15. adam/commands/{app_ping.py → app/app_ping.py} +7 -13
  16. adam/commands/{login.py → app/login.py} +22 -24
  17. adam/commands/app/show_app_actions.py +49 -0
  18. adam/commands/{show → app}/show_app_id.py +8 -11
  19. adam/commands/{show → app}/show_app_queues.py +7 -14
  20. adam/commands/app/show_login.py +56 -0
  21. adam/commands/app/utils_app.py +106 -0
  22. adam/commands/audit/audit.py +22 -40
  23. adam/commands/audit/audit_repair_tables.py +15 -19
  24. adam/commands/audit/audit_run.py +15 -22
  25. adam/commands/audit/completions_l.py +15 -0
  26. adam/commands/audit/show_last10.py +4 -18
  27. adam/commands/audit/show_slow10.py +4 -17
  28. adam/commands/audit/show_top10.py +4 -16
  29. adam/commands/audit/utils_show_top10.py +15 -3
  30. adam/commands/bash/__init__.py +5 -0
  31. adam/commands/bash/bash.py +36 -0
  32. adam/commands/bash/bash_completer.py +93 -0
  33. adam/commands/bash/utils_bash.py +16 -0
  34. adam/commands/cassandra/__init__.py +0 -0
  35. adam/commands/cassandra/download_cassandra_log.py +45 -0
  36. adam/commands/{restart.py → cassandra/restart_cluster.py} +12 -26
  37. adam/commands/cassandra/restart_node.py +51 -0
  38. adam/commands/cassandra/restart_nodes.py +47 -0
  39. adam/commands/{rollout.py → cassandra/rollout.py} +20 -25
  40. adam/commands/cassandra/show_cassandra_repairs.py +37 -0
  41. adam/commands/cassandra/show_cassandra_status.py +117 -0
  42. adam/commands/{show → cassandra}/show_cassandra_version.py +5 -18
  43. adam/commands/cassandra/show_processes.py +50 -0
  44. adam/commands/cassandra/show_storage.py +44 -0
  45. adam/commands/{watch.py → cassandra/watch.py} +26 -29
  46. adam/commands/cli/__init__.py +0 -0
  47. adam/commands/{cli_commands.py → cli/cli_commands.py} +8 -4
  48. adam/commands/cli/clipboard_copy.py +86 -0
  49. adam/commands/cli/show_cli_commands.py +56 -0
  50. adam/commands/code.py +57 -0
  51. adam/commands/command.py +211 -40
  52. adam/commands/commands_utils.py +20 -27
  53. adam/commands/config/__init__.py +0 -0
  54. adam/commands/{param_get.py → config/param_get.py} +11 -14
  55. adam/commands/{param_set.py → config/param_set.py} +8 -12
  56. adam/commands/{show → config}/show_params.py +2 -5
  57. adam/commands/cql/alter_tables.py +66 -0
  58. adam/commands/cql/completions_c.py +29 -0
  59. adam/commands/cql/cqlsh.py +10 -32
  60. adam/commands/cql/utils_cql.py +306 -0
  61. adam/commands/debug/__init__.py +0 -0
  62. adam/commands/debug/debug.py +22 -0
  63. adam/commands/debug/debug_completes.py +35 -0
  64. adam/commands/debug/debug_timings.py +35 -0
  65. adam/commands/debug/show_offloaded_completes.py +45 -0
  66. adam/commands/deploy/code_start.py +7 -10
  67. adam/commands/deploy/code_stop.py +4 -21
  68. adam/commands/deploy/code_utils.py +3 -3
  69. adam/commands/deploy/deploy.py +4 -27
  70. adam/commands/deploy/deploy_frontend.py +14 -17
  71. adam/commands/deploy/deploy_pg_agent.py +3 -6
  72. adam/commands/deploy/deploy_pod.py +65 -73
  73. adam/commands/deploy/deploy_utils.py +14 -24
  74. adam/commands/deploy/undeploy.py +4 -27
  75. adam/commands/deploy/undeploy_frontend.py +4 -7
  76. adam/commands/deploy/undeploy_pg_agent.py +6 -8
  77. adam/commands/deploy/undeploy_pod.py +11 -12
  78. adam/commands/devices/__init__.py +0 -0
  79. adam/commands/devices/device.py +149 -0
  80. adam/commands/devices/device_app.py +163 -0
  81. adam/commands/devices/device_auit_log.py +49 -0
  82. adam/commands/devices/device_cass.py +179 -0
  83. adam/commands/devices/device_export.py +87 -0
  84. adam/commands/devices/device_postgres.py +160 -0
  85. adam/commands/devices/devices.py +25 -0
  86. adam/commands/diag/__init__.py +0 -0
  87. adam/commands/{check.py → diag/check.py} +16 -25
  88. adam/commands/diag/generate_report.py +52 -0
  89. adam/commands/diag/issues.py +43 -0
  90. adam/commands/exit.py +1 -4
  91. adam/commands/export/__init__.py +0 -0
  92. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  93. adam/commands/export/clean_up_export_sessions.py +39 -0
  94. adam/commands/export/completions_x.py +11 -0
  95. adam/commands/export/download_export_session.py +40 -0
  96. adam/commands/export/drop_export_database.py +39 -0
  97. adam/commands/export/drop_export_databases.py +37 -0
  98. adam/commands/export/export.py +37 -0
  99. adam/commands/export/export_databases.py +251 -0
  100. adam/commands/export/export_select.py +34 -0
  101. adam/commands/export/export_sessions.py +210 -0
  102. adam/commands/export/export_use.py +49 -0
  103. adam/commands/export/export_x_select.py +48 -0
  104. adam/commands/export/exporter.py +419 -0
  105. adam/commands/export/import_files.py +44 -0
  106. adam/commands/export/import_session.py +40 -0
  107. adam/commands/export/importer.py +81 -0
  108. adam/commands/export/importer_athena.py +157 -0
  109. adam/commands/export/importer_sqlite.py +78 -0
  110. adam/commands/export/show_column_counts.py +45 -0
  111. adam/commands/export/show_export_databases.py +39 -0
  112. adam/commands/export/show_export_session.py +39 -0
  113. adam/commands/export/show_export_sessions.py +37 -0
  114. adam/commands/export/utils_export.py +366 -0
  115. adam/commands/fs/__init__.py +0 -0
  116. adam/commands/fs/cat.py +36 -0
  117. adam/commands/fs/cat_local.py +42 -0
  118. adam/commands/fs/cd.py +41 -0
  119. adam/commands/fs/download_file.py +47 -0
  120. adam/commands/fs/find_files.py +51 -0
  121. adam/commands/fs/find_processes.py +76 -0
  122. adam/commands/fs/head.py +36 -0
  123. adam/commands/fs/ls.py +41 -0
  124. adam/commands/fs/ls_local.py +40 -0
  125. adam/commands/fs/pwd.py +45 -0
  126. adam/commands/fs/rm.py +18 -0
  127. adam/commands/fs/rm_downloads.py +39 -0
  128. adam/commands/fs/rm_logs.py +38 -0
  129. adam/commands/{shell.py → fs/shell.py} +12 -4
  130. adam/commands/{show → fs}/show_adam.py +3 -3
  131. adam/commands/{show → fs}/show_host.py +1 -1
  132. adam/commands/help.py +5 -3
  133. adam/commands/intermediate_command.py +52 -0
  134. adam/commands/kubectl.py +38 -0
  135. adam/commands/medusa/medusa.py +4 -22
  136. adam/commands/medusa/medusa_backup.py +20 -27
  137. adam/commands/medusa/medusa_restore.py +35 -48
  138. adam/commands/medusa/medusa_show_backupjobs.py +16 -18
  139. adam/commands/medusa/medusa_show_restorejobs.py +13 -18
  140. adam/commands/medusa/utils_medusa.py +15 -0
  141. adam/commands/nodetool/__init__.py +0 -0
  142. adam/commands/{nodetool.py → nodetool/nodetool.py} +9 -20
  143. adam/commands/postgres/completions_p.py +22 -0
  144. adam/commands/postgres/postgres.py +47 -55
  145. adam/commands/postgres/postgres_databases.py +269 -0
  146. adam/commands/postgres/postgres_ls.py +5 -9
  147. adam/commands/postgres/postgres_preview.py +5 -9
  148. adam/commands/postgres/utils_postgres.py +80 -0
  149. adam/commands/preview_table.py +8 -44
  150. adam/commands/reaper/reaper.py +4 -27
  151. adam/commands/reaper/reaper_forward.py +49 -56
  152. adam/commands/reaper/reaper_forward_session.py +6 -0
  153. adam/commands/reaper/reaper_forward_stop.py +10 -16
  154. adam/commands/reaper/reaper_restart.py +7 -14
  155. adam/commands/reaper/reaper_run_abort.py +8 -33
  156. adam/commands/reaper/reaper_runs.py +43 -58
  157. adam/commands/reaper/reaper_runs_abort.py +29 -49
  158. adam/commands/reaper/reaper_schedule_activate.py +14 -33
  159. adam/commands/reaper/reaper_schedule_start.py +9 -33
  160. adam/commands/reaper/reaper_schedule_stop.py +9 -33
  161. adam/commands/reaper/reaper_schedules.py +4 -14
  162. adam/commands/reaper/reaper_status.py +8 -16
  163. adam/commands/reaper/utils_reaper.py +203 -0
  164. adam/commands/repair/repair.py +4 -22
  165. adam/commands/repair/repair_log.py +5 -11
  166. adam/commands/repair/repair_run.py +27 -34
  167. adam/commands/repair/repair_scan.py +32 -40
  168. adam/commands/repair/repair_stop.py +5 -12
  169. adam/commands/show.py +40 -0
  170. adam/config.py +5 -15
  171. adam/embedded_params.py +1 -1
  172. adam/log.py +4 -4
  173. adam/repl.py +83 -116
  174. adam/repl_commands.py +86 -45
  175. adam/repl_session.py +9 -1
  176. adam/repl_state.py +176 -40
  177. adam/sql/async_executor.py +62 -0
  178. adam/sql/lark_completer.py +286 -0
  179. adam/sql/lark_parser.py +604 -0
  180. adam/sql/qingl.lark +1076 -0
  181. adam/sql/sql_completer.py +52 -27
  182. adam/sql/sql_state_machine.py +131 -19
  183. adam/sso/authn_ad.py +6 -8
  184. adam/sso/authn_okta.py +4 -6
  185. adam/sso/cred_cache.py +4 -9
  186. adam/sso/idp.py +9 -12
  187. adam/utils.py +670 -31
  188. adam/utils_athena.py +145 -0
  189. adam/utils_audits.py +12 -103
  190. adam/utils_issues.py +32 -0
  191. adam/utils_k8s/app_clusters.py +35 -0
  192. adam/utils_k8s/app_pods.py +41 -0
  193. adam/utils_k8s/cassandra_clusters.py +35 -20
  194. adam/utils_k8s/cassandra_nodes.py +15 -6
  195. adam/utils_k8s/custom_resources.py +16 -17
  196. adam/utils_k8s/ingresses.py +2 -2
  197. adam/utils_k8s/jobs.py +7 -11
  198. adam/utils_k8s/k8s.py +96 -0
  199. adam/utils_k8s/kube_context.py +3 -6
  200. adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +13 -4
  201. adam/utils_k8s/pods.py +159 -89
  202. adam/utils_k8s/secrets.py +4 -4
  203. adam/utils_k8s/service_accounts.py +5 -4
  204. adam/utils_k8s/services.py +2 -2
  205. adam/utils_k8s/statefulsets.py +6 -14
  206. adam/utils_local.py +80 -0
  207. adam/utils_net.py +4 -4
  208. adam/utils_repl/__init__.py +0 -0
  209. adam/utils_repl/appendable_completer.py +6 -0
  210. adam/utils_repl/automata_completer.py +48 -0
  211. adam/utils_repl/repl_completer.py +93 -0
  212. adam/utils_repl/state_machine.py +173 -0
  213. adam/utils_sqlite.py +132 -0
  214. adam/version.py +1 -1
  215. {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/METADATA +1 -1
  216. kaqing-2.0.214.dist-info/RECORD +272 -0
  217. kaqing-2.0.214.dist-info/top_level.txt +2 -0
  218. teddy/__init__.py +0 -0
  219. teddy/lark_parser.py +436 -0
  220. teddy/lark_parser2.py +618 -0
  221. adam/commands/alter_tables.py +0 -81
  222. adam/commands/app.py +0 -67
  223. adam/commands/bash.py +0 -150
  224. adam/commands/cd.py +0 -125
  225. adam/commands/cp.py +0 -95
  226. adam/commands/cql/cql_completions.py +0 -15
  227. adam/commands/cql/cql_utils.py +0 -112
  228. adam/commands/devices.py +0 -118
  229. adam/commands/issues.py +0 -75
  230. adam/commands/logs.py +0 -40
  231. adam/commands/ls.py +0 -146
  232. adam/commands/postgres/postgres_context.py +0 -239
  233. adam/commands/postgres/postgres_utils.py +0 -31
  234. adam/commands/postgres/psql_completions.py +0 -10
  235. adam/commands/pwd.py +0 -77
  236. adam/commands/reaper/reaper_session.py +0 -159
  237. adam/commands/report.py +0 -63
  238. adam/commands/show/show.py +0 -54
  239. adam/commands/show/show_app_actions.py +0 -56
  240. adam/commands/show/show_cassandra_status.py +0 -128
  241. adam/commands/show/show_commands.py +0 -61
  242. adam/commands/show/show_login.py +0 -63
  243. adam/commands/show/show_processes.py +0 -53
  244. adam/commands/show/show_repairs.py +0 -47
  245. adam/commands/show/show_storage.py +0 -52
  246. kaqing-2.0.110.dist-info/RECORD +0 -187
  247. kaqing-2.0.110.dist-info/top_level.txt +0 -1
  248. /adam/commands/{show → app}/__init__.py +0 -0
  249. /adam/commands/{nodetool_commands.py → nodetool/nodetool_commands.py} +0 -0
  250. {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/WHEEL +0 -0
  251. {kaqing-2.0.110.dist-info → kaqing-2.0.214.dist-info}/entry_points.txt +0 -0
adam/sql/sql_completer.py CHANGED
@@ -1,7 +1,8 @@
1
+ from enum import Enum
1
2
  from typing import Callable
2
3
 
3
4
  import sqlparse
4
- from sqlparse.sql import Statement, Token
5
+ from sqlparse.sql import Token
5
6
 
6
7
  from adam.sql.term_completer import TermCompleter
7
8
  from adam.utils_repl.automata_completer import AutomataCompleter
@@ -12,41 +13,42 @@ __all__ = [
12
13
  "SqlCompleter",
13
14
  ]
14
15
 
15
- def default_columns(_: list[str]):
16
+ def default_columns(x: list[str]):
16
17
  return 'id,x.,y.,z.'.split(',')
17
18
 
19
+ class SqlVariant(Enum):
20
+ SQL = 'sql'
21
+ CQL = 'cql'
22
+ ATHENA = 'athena'
23
+
18
24
  class SqlCompleter(AutomataCompleter[Token]):
19
25
  def tokens(self, text: str) -> list[Token]:
20
26
  tokens = []
21
27
 
22
28
  stmts = sqlparse.parse(text)
23
- if not stmts:
24
- tokens = []
25
- else:
26
- statement: Statement = stmts[0]
27
- tokens = statement.tokens
29
+ if stmts:
30
+ for stmt in stmts:
31
+ tokens.extend(stmt.tokens)
28
32
 
29
33
  return tokens
30
34
 
31
35
  def __init__(self,
32
36
  tables: Callable[[], list[str]],
33
37
  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
+ expandables: dict = {},
39
+ variant: SqlVariant = SqlVariant.SQL,
38
40
  debug = False):
39
41
  machine = SqlStateMachine(debug=debug)
40
- if variant == 'cql':
42
+ if variant == SqlVariant.CQL:
41
43
  machine = CqlStateMachine(debug=debug)
42
- elif variant == 'athena':
44
+ elif variant == SqlVariant.ATHENA:
43
45
  machine = AthenaStateMachine(debug=debug)
44
46
  super().__init__(machine, dml, debug)
45
47
 
46
48
  self.tables = tables
47
- self.columns = columns
48
- self.partition_columns = partition_columns
49
- self.table_props = table_props
49
+ if 'columns' not in expandables:
50
+ expandables['columns'] = default_columns
51
+ self.expandables = expandables
50
52
  self.variant = variant
51
53
  self.debug = debug
52
54
 
@@ -63,31 +65,54 @@ class SqlCompleter(AutomataCompleter[Token]):
63
65
  def _terms(self, state: State, word: str) -> list[str]:
64
66
  terms = []
65
67
 
66
- if word == 'tables':
68
+ if word.startswith('`') and word.endswith('`'):
69
+ terms.append(word.strip('`'))
70
+ elif word == 'tables':
67
71
  terms.extend(self.tables())
68
- elif word == '`tables`':
69
- terms.append('tables')
70
72
  elif word == 'columns':
71
- terms.extend(self.columns([]))
73
+ if 'last_name' in state.context and (n := state.context['last_name']):
74
+ if 'last_namespace' in state.context and (ns := state.context['last_namespace']):
75
+ n = f'{ns}.{n}'
76
+ terms.extend(self._call_expandable(word, [n]))
77
+ else:
78
+ terms.extend(self._call_expandable(word, []))
72
79
  elif word == 'partition-columns':
73
- terms.extend(self.partition_columns([]))
80
+ terms.extend(self._call_expandable(word, []))
74
81
  elif word == 'table-props':
75
- terms.extend(self.table_props().keys())
82
+ terms.extend(self._call_expandable(word).keys())
76
83
  elif word == 'table-prop-values':
77
84
  if 'last_name' in state.context and state.context['last_name']:
78
- terms.extend(self.table_props()[state.context['last_name']])
85
+ table_props = self._call_expandable('table-props')
86
+ terms.extend(table_props[state.context['last_name']])
79
87
  elif word == 'single':
80
88
  terms.append("'")
81
89
  elif word == 'comma':
82
90
  terms.append(",")
91
+ elif word in self.machine.expandable_names():
92
+ terms.extend(self._call_expandable(word))
83
93
  else:
84
94
  terms.append(word)
85
95
 
86
96
  return terms
87
97
 
88
- def completions_for_nesting(self):
98
+ def _call_expandable(self, name: str, *args):
99
+ if name in self.expandables:
100
+ c = self.expandables[name]
101
+ if args:
102
+ return c(args)
103
+ else:
104
+ return c()
105
+
106
+ return []
107
+
108
+ def completions_for_nesting(self, dml: str = None):
109
+ if dml:
110
+ return {dml: SqlCompleter(self.tables, dml, expandables=self.expandables, variant=self.variant)}
111
+
89
112
  return {
90
- word : SqlCompleter(self.tables, word, columns=self.columns, partition_columns=self.partition_columns,
91
- table_props=self.table_props, variant=self.variant)
113
+ word: SqlCompleter(self.tables, word, expandables=self.expandables, variant=self.variant)
92
114
  for word in self.machine.suggestions[''].strip(' ').split(',')
93
- }
115
+ }
116
+
117
+ def __str__(self):
118
+ return f'{self.variant}, {self.first_term}'
@@ -2,6 +2,7 @@ from typing import Callable
2
2
  from sqlparse.sql import Token
3
3
  from sqlparse import tokens as TOKEN
4
4
 
5
+ from adam.utils import log_exc
5
6
  from adam.utils_repl.state_machine import StateMachine, State
6
7
 
7
8
  __all__ = [
@@ -73,10 +74,11 @@ SQL_SPEC = [
73
74
  '- < ) > select_from_sq',
74
75
  'select_from_lp_ > select > select',
75
76
  'select_from_x > , > select_from_x_comma_ ^ (select,tables',
77
+ '- > ; > ',
76
78
  'select_from_sq_ > as > select_from_x_as ^ as',
77
79
  '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
+ 'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,order by,limit,&',
81
+ '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
82
  '- > as > select_from_x_as',
81
83
  '- > where > select_where',
82
84
  '- > order > select_order',
@@ -94,8 +96,11 @@ SQL_SPEC = [
94
96
  '- > right outer join > select_join',
95
97
  '- > full > select_from_x_full',
96
98
  '- > full outer join > select_join',
99
+ '- > ; > ',
100
+ '- > & > select_from_x$',
97
101
  'select_from_x_as_ > name > select_from_x_as_x ^ x,y,z',
98
102
  'select_from_x_as_x > , > select_from_x_as_x_comma_',
103
+ '- > ; > ',
99
104
  'select_from_x_as_x_comma_ > name|audit > select_from_x ^ tables',
100
105
  'select_where_ > name > select_where_a ^ columns',
101
106
  'select_where_a > name > select_where_a ^ columns,=,<,<=,>,>=,<>',
@@ -114,28 +119,41 @@ SQL_SPEC = [
114
119
  'select_where_a_in_lp_a_comma_ > name|single|num > select_where_a_in_lp_a ^ single',
115
120
  'select_where_a_not_op > name|single|num > select_where_sc ^ single',
116
121
  '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',
122
+ 'select_where_sc > ; > ',
123
+ 'select_where_sc_ > and|or > select_where ^ and,or,order by,group by,limit,&',
118
124
  '- > group > select_group',
119
125
  '- > group by > select_group_by',
120
126
  '- > order > select_order',
121
127
  '- > order by > select_order_by',
122
128
  '- > limit > select_where_sc_limit',
129
+ '- > ; > ',
130
+ '- > & > select_from_x$',
123
131
  'select_group_ > by > select_group_by ^ by',
124
132
  'select_group_by_ > name > select_group_by_a ^ columns',
125
133
  'select_group_by_a > , > select_group_by_a_comma_ ^ columns',
134
+ '- > ; > ',
126
135
  'select_group_by_a_comma_ > name > select_group_by_a ^ columns',
127
- 'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by',
136
+ 'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by,&',
128
137
  '- > order > select_order',
129
138
  '- > order by > select_order_by',
139
+ '- > ; > ',
140
+ '- > & > select_from_x$',
130
141
  'select_order_ > by > select_order_by ^ by',
131
142
  'select_order_by_ > name > select_order_by_a ^ columns',
132
143
  'select_order_by_a > , > select_order_by_a_comma_',
144
+ '- > ; > ',
133
145
  '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',
146
+ 'select_order_by_a_ > desc|asc > select_order_by_a_desc ^ desc,asc,limit,&',
135
147
  '- > limit > select_where_sc_limit',
148
+ '- > ; > ',
149
+ '- > & > select_from_x$',
136
150
  'select_order_by_a_desc > , > select_order_by_a_comma_',
137
- 'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit',
151
+ '- > ; > ',
152
+ 'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit,&',
153
+ '- > ; > ',
154
+ '- > & > select_from_x$',
138
155
  'select_where_sc_limit_ > num > select_where_sc_limit_num ^ 1',
156
+ 'select_where_sc_limit_num > ; > ',
139
157
  'select_where_sc_limit_num_rp__ > as > select_from_x_as ^ as',
140
158
  'select_where_x_inner_ > join > select_join',
141
159
  'select_join_ > name|audit > select_x_join_y ^ tables',
@@ -158,6 +176,7 @@ SQL_SPEC = [
158
176
  'select_x_join_y_on_a_ > comparison > select_x_join_y_on_a_op ^ =',
159
177
  'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ columns',
160
178
  'select_x_join_y_on_a_op_b > _ > select_from_x_as_x_',
179
+ '- > ; > ',
161
180
 
162
181
  # <insert_statement> ::= INSERT INTO <table_name> [ ( <column_list> ) ]
163
182
  # VALUES ( <value_list> )
@@ -188,7 +207,9 @@ SQL_SPEC = [
188
207
  'insert_values > ( > insert_values_lp_',
189
208
  'insert_values_lp_ > name|single|num > insert_values_lp_v ^ single',
190
209
  'insert_values_lp_v > , > insert_values_lp_v_comma_',
210
+ '- > ) > insert_values_lp_v_rp_',
191
211
  'insert_values_lp_v_comma_ > name|single|num > insert_values_lp_v',
212
+ 'insert_values_lp_v_rp__ > & > insert_values_lp_v_rp_$ ^ &',
192
213
 
193
214
  # <update_statement> ::= UPDATE <table_name>
194
215
  # SET <set_clause_list>
@@ -209,8 +230,9 @@ SQL_SPEC = [
209
230
  'update_set_a_op > name|single|num > update_set_sc ^ single',
210
231
  'update_set_sc > , > update_set_sc_comma_',
211
232
  'update_set_sc_comma_ > name > update_set_a ^ id',
212
- 'update_set_sc_ > , > update_set_sc_comma_ ^ where',
233
+ 'update_set_sc_ > , > update_set_sc_comma_ ^ where,&',
213
234
  '- > where > update_where',
235
+ '- > & > update_set_sc$ ^ &',
214
236
  'update_where_ > name > update_where_a ^ id',
215
237
  'update_where_a > comparison > update_where_a_op',
216
238
  'update_where_a_ > comparison > update_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
@@ -227,7 +249,7 @@ SQL_SPEC = [
227
249
  'update_where_a_in_lp_a_comma_ > name|single|num > update_where_a_in_lp_a ^ single',
228
250
  'update_where_a_not_op > name|single|num > update_where_sc ^ single',
229
251
  'update_where_a_op > name|single|num > update_where_sc ^ single',
230
- 'update_where_sc_ > and|or > update_where ^ and,or',
252
+ 'update_where_sc_ > and|or > update_where ^ and,or,&',
231
253
 
232
254
  # <delete_statement> ::= DELETE FROM <table_name> [ WHERE <search_condition> ]
233
255
 
@@ -322,10 +344,10 @@ SQL_KEYWORDS = [
322
344
  'describe', 'preview'
323
345
  ]
324
346
 
325
- EXPANDABLE_NAMES = {'tables', 'columns', 'partition-columns', 'table-props', 'table-props-values'}
347
+ EXPANDABLE_NAMES = {'keyspaces', 'tables', 'columns', 'partition-columns', 'table-props', 'table-props-values'}
326
348
 
327
349
  CQL_SPEC = SQL_SPEC + [
328
- ' > select > select ^ select,insert,update,delete,alter,describe,preview',
350
+ ' > select > select ^ select,insert,update,delete,alter,describe,preview,consistency,export,import,drop,clean',
329
351
 
330
352
  # ALTER TABLE [ <keyspace_name> . ] <table_name>
331
353
  # ( ALTER <column_name> TYPE <cql_type>
@@ -344,7 +366,7 @@ CQL_SPEC = SQL_SPEC + [
344
366
  'alter_table_with_p_op_v_ > --include-reaper > alter_table_with_p_op_v_$ ^ --include-reaper',
345
367
 
346
368
  ' > describe > describe',
347
- 'describe_ > table > desc_table ^ table,`tables`,keyspace,keyspaces,schema',
369
+ 'describe_ > table > desc_table ^ table,`tables`,keyspace,`keyspaces`,schema',
348
370
  '- > tables > desc_tables',
349
371
  '- > keyspace > desc_keyspace',
350
372
  '- > keyspaces > desc_keyspaces',
@@ -352,17 +374,88 @@ CQL_SPEC = SQL_SPEC + [
352
374
  'desc_table_ > name > desc_table_t ^ tables',
353
375
  'desc_table_t_ > & > desc_table_t_$ ^ &',
354
376
  'desc_tables_ > & > desc_tables_$ ^ &',
355
- 'desc_keyspace_ > name > desc_keyspace_k',
377
+ 'desc_keyspace_ > name > desc_keyspace_k ^ keyspaces',
356
378
  'desc_keyspace_k_ > & > desc_keyspace_k_$ ^ &',
357
379
  'desc_schema_ > & > desc_schema_$ ^ &',
380
+
381
+ ' > export > export',
382
+ 'export_ > name > export_table ^ *,tables',
383
+ '- > * > export_all',
384
+ 'export_all_ > in > export_in ^ in,with',
385
+ '- > with > export_with',
386
+ 'export_table > ( > export_table_lp_ ^ (,comma,with,tables',
387
+ '- > , > export_table_comma_',
388
+ '- > . > export_table ^ tables',
389
+ 'export_table_ > ( > export_table_lp_ ^ as,(,comma,with consistency,to',
390
+ '- > , > export_table_comma_',
391
+ '- > as > export_as',
392
+ '- > with > export_with',
393
+ '- > to > export_table_to',
394
+ 'export_table_comma_ > name > export_table ^ tables',
395
+ 'export_table_lp_ > name > export_table_lp_a ^ columns',
396
+ 'export_table_lp_a > , > export_table_lp_a_comma_',
397
+ '- > ) > export_table_lp_a_comma_rp_',
398
+ 'export_table_lp_a_comma_ > name > export_table_lp_a ^ columns',
399
+ 'export_table_lp_a_comma_rp_ > as > export_as ^ as,with consistency',
400
+ '- > , > export ^ with consistency',
401
+ '- > with > export_with',
402
+ 'export_as_ > name > export_as_f',
403
+ 'export_as_f > , > export_table_comma_',
404
+ 'export_as_f_ > , > export_table_comma_ ^ with consistency,to',
405
+ '- > with > export_with',
406
+ '- > to > export_table_to',
407
+ 'export_in_ > name > export_in_k ^ keyspaces',
408
+ 'export_in_k_ > with > export_with ^ with consistency',
409
+ 'export_with_ > consistency > export_with_consistency ^ consistency',
410
+ 'export_with_consistency_ > quorum|all|serial|one|each_quorum|local_quorum|any|local_one|two|three|local_serial > export_with_quorum ^ quorum,all,serial,one,each_quorum,local_quorum,any,local_one,two,three,local_serial',
411
+ 'export_table_to_ > athena|sqlite|csv > export_table_to$ ^ athena,sqlite,csv',
412
+
413
+ ' > import > import',
414
+ 'import_ > session > import_session ^ session,files',
415
+ '- > files > import_files',
416
+ 'import_session_ > name > import_session_s ^ export-sessions-incomplete',
417
+ 'import_session_s_ > to > import_session_to ^ to',
418
+ 'import_files_ > name > import_files_f',
419
+ 'import_files_f > , > import_files',
420
+ 'import_files_f_ > as > import_files_f_as ^ as',
421
+ 'import_files_f_as_ > name > import_files_f_as_a',
422
+ 'import_files_f_as_a_ > to > import_session_to ^ to',
423
+ 'import_session_to_ > athena|sqlite > import_session_to$ ^ athena,sqlite',
424
+
425
+ ' > consistency > consistency',
426
+ 'consistency_ > quorum|all|serial|one|each_quorum|local_quorum|any|local_one|two|three|local_serial > consistency_quorum ^ quorum,all,serial,one,each_quorum,local_quorum,any,local_one,two,three,local_serial',
427
+ 'consistency_quorum > ; > ',
428
+
429
+ ' > drop > drop',
430
+ 'drop_ > all > drop_all ^ all export databases,export database',
431
+ '- > export > drop_export',
432
+ 'drop_all_ > export > drop_all_export ^ export databases',
433
+ 'drop_all_export_ > databases > drop_all_dbs ^ databases',
434
+ 'drop_export_ > database > drop_export_db ^ database',
435
+ 'drop_export_db_ > name > drop_export_db$ ^ export-dbs',
436
+
437
+ ' > clean > clean',
438
+ 'clean_ > up > clean_up ^ up all export sessions,up export session',
439
+ 'clean_up_ > all > clean_up_all ^ all export sessions,export sessions',
440
+ '- > export > clean_up_export',
441
+ 'clean_up_all_ > export > clean_up_all_export ^ export sessions',
442
+ 'clean_up_all_export_ > sessions > clean_up_all_sessions ^ sessions',
443
+ 'clean_up_export_ > sessions > clean_up_export_sessions ^ sessions',
444
+ 'clean_up_export_sessions_ > name > clean_up_export_sessions$ ^ export-sessions',
358
445
  ]
359
446
 
360
447
  CQL_KEYWORDS = SQL_KEYWORDS + [
361
- 'schema', 'keyspace', 'keyspaces', 'tables'
448
+ 'schema', 'keyspace', 'keyspaces', 'tables', 'export', 'copy', 'consistency',
449
+ 'quorum', 'all', 'serial', 'one', 'each_quorum', 'local_quorum', 'any', 'local_one', 'two', 'three', 'local_serial', 'to',
450
+ 'database', 'databases', 'session', 'sessions', 'clean', 'up', 'athena', 'sqlite', 'csv', 'import', 'files'
362
451
  ]
363
452
 
453
+ CQL_EXPANDABLE_NAMES = EXPANDABLE_NAMES | {
454
+ 'export-dbs', 'export-sessions', 'export-sessions-incomplete'
455
+ }
456
+
364
457
  ATHENA_SPEC = SQL_SPEC + [
365
- ' > select > select ^ select,insert,update,delete,alter,describe,preview',
458
+ ' > select > select ^ select,insert,update,delete,alter,describe,preview,drop',
366
459
 
367
460
  'alter_table_t_ > add > alter_table_add ^ add partition,drop partition',
368
461
  'alter_table_add_ > partition > alter_partition ^ partition',
@@ -378,13 +471,26 @@ ATHENA_SPEC = SQL_SPEC + [
378
471
  'describe_ > name > desc_t ^ tables',
379
472
  'desc_t_ > name > desc_t_',
380
473
 
381
- 'repair'
474
+ 'repair',
475
+
476
+ ' > drop > drop',
477
+ 'drop_ > all > drop_all ^ all export databases,export database',
478
+ '- > export > drop_export',
479
+ 'drop_all_ > export > drop_all_export ^ export databases',
480
+ 'drop_all_export_ > databases > drop_all_dbs ^ databases',
481
+ 'drop_export_ > database > drop_export_db ^ database',
482
+ 'drop_export_db_ > name > drop_export_db$ ^ export-dbs',
382
483
  ]
383
484
 
384
485
  ATHENA_KEYWORDS = SQL_KEYWORDS + [
385
- 'partition'
486
+ 'partition',
487
+ 'database', 'databases', 'session', 'sessions', 'clean', 'up', 'all', 'export'
386
488
  ]
387
489
 
490
+ ATHENA_EXPANDABLE_NAMES = EXPANDABLE_NAMES | {
491
+ 'export-dbs'
492
+ }
493
+
388
494
  class SqlStateMachine(StateMachine[Token]):
389
495
  def __init__(self, indent=0, push_level = 0, debug = False):
390
496
  super().__init__(indent, push_level, debug)
@@ -449,11 +555,13 @@ class SqlStateMachine(StateMachine[Token]):
449
555
  elif it == ')':
450
556
  self.push_level -= 1
451
557
  comeback_state = handle_pop()
558
+ elif it == '.' and 'last_name' in state.context and (ln := state.context['last_name']):
559
+ state.context['last_namespace'] = ln
452
560
 
453
561
  elif token.ttype == TOKEN.Operator.Comparison:
454
562
  it = 'comparison'
455
563
 
456
- try:
564
+ with log_exc(False):
457
565
  # print(f'\n{state.to_s} > {it} > ', end='')
458
566
  if comeback_state:
459
567
  state = comeback_state
@@ -464,8 +572,6 @@ class SqlStateMachine(StateMachine[Token]):
464
572
 
465
573
  if last_name:
466
574
  state.context['last_name'] = last_name
467
- except:
468
- pass
469
575
 
470
576
  return state
471
577
 
@@ -507,6 +613,9 @@ class CqlStateMachine(SqlStateMachine):
507
613
  def keywords(self):
508
614
  return CQL_KEYWORDS
509
615
 
616
+ def expandable_names(self):
617
+ return CQL_EXPANDABLE_NAMES
618
+
510
619
  class AthenaStateMachine(SqlStateMachine):
511
620
  def __init__(self, indent=0, push_level = 0, debug = False):
512
621
  super().__init__(indent, push_level, debug)
@@ -516,3 +625,6 @@ class AthenaStateMachine(SqlStateMachine):
516
625
 
517
626
  def keywords(self):
518
627
  return ATHENA_KEYWORDS
628
+
629
+ def expandable_names(self):
630
+ return ATHENA_EXPANDABLE_NAMES
adam/sso/authn_ad.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import json
2
2
  import re
3
- import traceback
4
3
  import jwt
5
4
  import requests
6
5
  from urllib.parse import urlparse, parse_qs
@@ -8,6 +7,7 @@ from urllib.parse import urlparse, parse_qs
8
7
  from adam.log import Log
9
8
  from adam.sso.authenticator import Authenticator
10
9
  from adam.sso.id_token import IdToken
10
+ from adam.utils import debug, log_exc
11
11
  from .idp_login import IdpLogin
12
12
  from adam.config import Config
13
13
 
@@ -33,7 +33,7 @@ class AdAuthenticator(Authenticator):
33
33
 
34
34
  session = requests.Session()
35
35
  r = session.get(idp_uri)
36
- Config().debug(f'{r.status_code} {idp_uri}')
36
+ debug(f'{r.status_code} {idp_uri}')
37
37
 
38
38
  config = self.validate_and_return_config(r)
39
39
 
@@ -52,7 +52,7 @@ class AdAuthenticator(Authenticator):
52
52
  r = session.post(login_uri, data=body, headers={
53
53
  'Content-Type': 'application/x-www-form-urlencoded'
54
54
  })
55
- Config().debug(f'{r.status_code} {login_uri}')
55
+ debug(f'{r.status_code} {login_uri}')
56
56
 
57
57
  config = self.validate_and_return_config(r)
58
58
 
@@ -69,7 +69,7 @@ class AdAuthenticator(Authenticator):
69
69
  r = session.post(kmsi_uri, data=body, headers={
70
70
  'Content-Type': 'application/x-www-form-urlencoded'
71
71
  })
72
- Config().debug(f'{r.status_code} {kmsi_uri}')
72
+ debug(f'{r.status_code} {kmsi_uri}')
73
73
 
74
74
  if (config := self.extract_config_object(r.text)):
75
75
  if 'sErrorCode' in config and config['sErrorCode'] == '50058':
@@ -101,7 +101,7 @@ class AdAuthenticator(Authenticator):
101
101
 
102
102
  def validate_and_return_config(self, r: requests.Response):
103
103
  if r.status_code < 200 or r.status_code >= 300:
104
- Config().debug(r.text)
104
+ debug(r.text)
105
105
 
106
106
  return None
107
107
 
@@ -138,7 +138,7 @@ class AdAuthenticator(Authenticator):
138
138
 
139
139
  def parse_id_token(self, id_token: str) -> IdToken:
140
140
  jwks_url = Config().get('idps.ad.jwks-uri', '')
141
- try:
141
+ with log_exc():
142
142
  jwks_client = jwt.PyJWKClient(jwks_url, cache_jwk_set=True, lifespan=360)
143
143
  signing_key = jwks_client.get_signing_key_from_jwt(id_token)
144
144
  data = jwt.decode(
@@ -163,7 +163,5 @@ class AdAuthenticator(Authenticator):
163
163
  nbf=data['nbf'] if 'nbf' in data else 0,
164
164
  exp=data['exp'] if 'exp' in data else 0
165
165
  )
166
- except:
167
- Config().debug(traceback.format_exc())
168
166
 
169
167
  return None
adam/sso/authn_okta.py CHANGED
@@ -8,7 +8,7 @@ from adam.sso.id_token import IdToken
8
8
 
9
9
  from .idp_login import IdpLogin
10
10
  from adam.config import Config
11
- from adam.utils import log2
11
+ from adam.utils import debug, log2, log_exc
12
12
 
13
13
  class OktaException(Exception):
14
14
  pass
@@ -49,7 +49,7 @@ class OktaAuthenticator(Authenticator):
49
49
 
50
50
  session = requests.Session()
51
51
  response = session.post(authn_uri, headers=headers, data=json.dumps(payload))
52
- Config().debug(f'{response.status_code} {authn_uri}')
52
+ debug(f'{response.status_code} {authn_uri}')
53
53
  auth_response = response.json()
54
54
 
55
55
  if 'sessionToken' not in auth_response:
@@ -59,7 +59,7 @@ class OktaAuthenticator(Authenticator):
59
59
 
60
60
  url = f'{idp_uri}&sessionToken={session_token}'
61
61
  r = session.get(url)
62
- Config().debug(f'{r.status_code} {url}')
62
+ debug(f'{r.status_code} {url}')
63
63
 
64
64
  id_token = OktaAuthenticator().extract(r.text, r'.*name=\"id_token\" value=\"(.*?)\".*')
65
65
  if not id_token:
@@ -95,7 +95,7 @@ class OktaAuthenticator(Authenticator):
95
95
  return None
96
96
 
97
97
  jwks_url = Config().get('idps.okta.jwks-uri', 'https://c3energy.okta.com/oauth2/v1/keys')
98
- try:
98
+ with log_exc():
99
99
  jwks_client = jwt.PyJWKClient(jwks_url, cache_jwk_set=True, lifespan=360)
100
100
  signing_key = jwks_client.get_signing_key_from_jwt(id_token)
101
101
  data = jwt.decode(
@@ -121,7 +121,5 @@ class OktaAuthenticator(Authenticator):
121
121
  nbf=data['nbf'] if 'nbf' in data else 0,
122
122
  exp=data['exp'] if 'exp' in data else 0
123
123
  )
124
- except:
125
- pass
126
124
 
127
125
  return None
adam/sso/cred_cache.py CHANGED
@@ -1,9 +1,8 @@
1
1
  import os
2
2
  from pathlib import Path
3
- import traceback
4
3
  from dotenv import load_dotenv
5
4
 
6
- from adam.config import Config
5
+ from adam.utils import creating_dir, debug, log_exc
7
6
  from adam.utils_k8s.kube_context import KubeContext
8
7
 
9
8
  class CredCache:
@@ -15,7 +14,7 @@ class CredCache:
15
14
 
16
15
  def __init__(self):
17
16
  if not hasattr(self, 'env_f'):
18
- self.dir = f'{Path.home()}/.kaqing'
17
+ self.dir = creating_dir(f'{Path.home()}/.kaqing')
19
18
  self.env_f = f'{self.dir}/.credentials'
20
19
  # immutable - cannot reload with different file content
21
20
  load_dotenv(dotenv_path=self.env_f)
@@ -34,10 +33,8 @@ class CredCache:
34
33
  def cache(self, username: str, password: str = None):
35
34
  if os.path.exists(self.env_f):
36
35
  with open(self.env_f, 'w') as file:
37
- try:
36
+ with log_exc():
38
37
  file.truncate()
39
- except:
40
- Config().debug(traceback.format_exc())
41
38
 
42
39
  updated = []
43
40
  updated.append(f'IDP_USERNAME={username}')
@@ -46,8 +43,6 @@ class CredCache:
46
43
  updated.append(f'IDP_PASSWORD={password}')
47
44
 
48
45
  if updated:
49
- if not os.path.exists(self.env_f):
50
- os.makedirs(self.dir, exist_ok=True)
51
46
  with open(self.env_f, 'w') as file:
52
47
  file.write('\n'.join(updated))
53
48
 
@@ -56,4 +51,4 @@ class CredCache:
56
51
  if password:
57
52
  self.overrides['IDP_PASSWORD'] = password
58
53
 
59
- Config().debug(f'Cached username: {username}, password: {password}, try load: {self.get_username()}')
54
+ debug(f'Cached username: {username}, password: {password}, try load: {self.get_username()}')