kaqing 2.0.98__py3-none-any.whl → 2.0.203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) 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 +11 -25
  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/alter_tables.py +37 -63
  15. adam/commands/app/app.py +38 -0
  16. adam/commands/{app_ping.py → app/app_ping.py} +8 -14
  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 +8 -14
  20. adam/commands/app/utils_app.py +106 -0
  21. adam/commands/audit/audit.py +31 -35
  22. adam/commands/audit/audit_repair_tables.py +26 -48
  23. adam/commands/audit/audit_run.py +50 -0
  24. adam/commands/audit/completions_l.py +15 -0
  25. adam/commands/audit/show_last10.py +36 -0
  26. adam/commands/audit/show_slow10.py +36 -0
  27. adam/commands/audit/show_top10.py +36 -0
  28. adam/commands/audit/utils_show_top10.py +71 -0
  29. adam/commands/bash/__init__.py +5 -0
  30. adam/commands/bash/bash.py +36 -0
  31. adam/commands/bash/bash_completer.py +93 -0
  32. adam/commands/bash/utils_bash.py +16 -0
  33. adam/commands/cassandra/__init__.py +0 -0
  34. adam/commands/cassandra/download_cassandra_log.py +45 -0
  35. adam/commands/cassandra/nodetool.py +64 -0
  36. adam/commands/cassandra/nodetool_commands.py +120 -0
  37. adam/commands/{restart.py → cassandra/restart_cluster.py} +12 -26
  38. adam/commands/cassandra/restart_node.py +51 -0
  39. adam/commands/cassandra/restart_nodes.py +47 -0
  40. adam/commands/cassandra/rollout.py +88 -0
  41. adam/commands/cat.py +36 -0
  42. adam/commands/cd.py +14 -92
  43. adam/commands/check.py +18 -21
  44. adam/commands/cli_commands.py +8 -4
  45. adam/commands/clipboard_copy.py +87 -0
  46. adam/commands/code.py +57 -0
  47. adam/commands/command.py +212 -39
  48. adam/commands/commands_utils.py +20 -28
  49. adam/commands/cql/alter_tables.py +66 -0
  50. adam/commands/cql/completions_c.py +29 -0
  51. adam/commands/cql/cqlsh.py +10 -29
  52. adam/commands/cql/utils_cql.py +305 -0
  53. adam/commands/debug/__init__.py +0 -0
  54. adam/commands/debug/debug.py +22 -0
  55. adam/commands/debug/debug_completes.py +35 -0
  56. adam/commands/debug/debug_timings.py +35 -0
  57. adam/commands/deploy/code_start.py +7 -10
  58. adam/commands/deploy/code_stop.py +4 -21
  59. adam/commands/deploy/code_utils.py +3 -3
  60. adam/commands/deploy/deploy.py +4 -21
  61. adam/commands/deploy/deploy_frontend.py +14 -17
  62. adam/commands/deploy/deploy_pg_agent.py +3 -6
  63. adam/commands/deploy/deploy_pod.py +65 -73
  64. adam/commands/deploy/deploy_utils.py +14 -24
  65. adam/commands/deploy/undeploy.py +4 -21
  66. adam/commands/deploy/undeploy_frontend.py +4 -7
  67. adam/commands/deploy/undeploy_pg_agent.py +6 -8
  68. adam/commands/deploy/undeploy_pod.py +11 -12
  69. adam/commands/devices/__init__.py +0 -0
  70. adam/commands/devices/device.py +149 -0
  71. adam/commands/devices/device_app.py +163 -0
  72. adam/commands/devices/device_auit_log.py +49 -0
  73. adam/commands/devices/device_cass.py +179 -0
  74. adam/commands/devices/device_export.py +87 -0
  75. adam/commands/devices/device_postgres.py +160 -0
  76. adam/commands/devices/devices.py +25 -0
  77. adam/commands/download_cassandra_log.py +45 -0
  78. adam/commands/download_file.py +47 -0
  79. adam/commands/exit.py +1 -4
  80. adam/commands/export/__init__.py +0 -0
  81. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  82. adam/commands/export/clean_up_export_sessions.py +39 -0
  83. adam/commands/export/completions_x.py +11 -0
  84. adam/commands/export/download_export_session.py +40 -0
  85. adam/commands/export/drop_export_database.py +39 -0
  86. adam/commands/export/drop_export_databases.py +37 -0
  87. adam/commands/export/export.py +37 -0
  88. adam/commands/export/export_databases.py +247 -0
  89. adam/commands/export/export_select.py +34 -0
  90. adam/commands/export/export_sessions.py +211 -0
  91. adam/commands/export/export_use.py +49 -0
  92. adam/commands/export/export_x_select.py +48 -0
  93. adam/commands/export/exporter.py +361 -0
  94. adam/commands/export/import_files.py +44 -0
  95. adam/commands/export/import_session.py +44 -0
  96. adam/commands/export/importer.py +82 -0
  97. adam/commands/export/importer_athena.py +150 -0
  98. adam/commands/export/importer_sqlite.py +69 -0
  99. adam/commands/export/show_column_counts.py +45 -0
  100. adam/commands/export/show_export_databases.py +39 -0
  101. adam/commands/export/show_export_session.py +39 -0
  102. adam/commands/export/show_export_sessions.py +37 -0
  103. adam/commands/export/utils_export.py +366 -0
  104. adam/commands/find_files.py +51 -0
  105. adam/commands/find_processes.py +76 -0
  106. adam/commands/generate_report.py +52 -0
  107. adam/commands/head.py +36 -0
  108. adam/commands/help.py +12 -8
  109. adam/commands/intermediate_command.py +52 -0
  110. adam/commands/issues.py +14 -40
  111. adam/commands/kubectl.py +38 -0
  112. adam/commands/login.py +26 -25
  113. adam/commands/ls.py +11 -116
  114. adam/commands/medusa/medusa.py +4 -22
  115. adam/commands/medusa/medusa_backup.py +20 -27
  116. adam/commands/medusa/medusa_restore.py +35 -48
  117. adam/commands/medusa/medusa_show_backupjobs.py +17 -18
  118. adam/commands/medusa/medusa_show_restorejobs.py +13 -18
  119. adam/commands/medusa/utils_medusa.py +15 -0
  120. adam/commands/nodetool.py +8 -19
  121. adam/commands/os/__init__.py +0 -0
  122. adam/commands/os/cat.py +36 -0
  123. adam/commands/os/download_file.py +47 -0
  124. adam/commands/os/find_files.py +51 -0
  125. adam/commands/os/find_processes.py +76 -0
  126. adam/commands/os/head.py +36 -0
  127. adam/commands/os/shell.py +41 -0
  128. adam/commands/param_get.py +11 -14
  129. adam/commands/param_set.py +8 -12
  130. adam/commands/postgres/completions_p.py +22 -0
  131. adam/commands/postgres/postgres.py +47 -55
  132. adam/commands/postgres/postgres_databases.py +269 -0
  133. adam/commands/postgres/postgres_ls.py +4 -8
  134. adam/commands/postgres/postgres_preview.py +5 -9
  135. adam/commands/postgres/utils_postgres.py +79 -0
  136. adam/commands/preview_table.py +10 -61
  137. adam/commands/pwd.py +14 -46
  138. adam/commands/reaper/reaper.py +4 -24
  139. adam/commands/reaper/reaper_forward.py +49 -56
  140. adam/commands/reaper/reaper_forward_session.py +6 -0
  141. adam/commands/reaper/reaper_forward_stop.py +10 -16
  142. adam/commands/reaper/reaper_restart.py +7 -14
  143. adam/commands/reaper/reaper_run_abort.py +8 -33
  144. adam/commands/reaper/reaper_runs.py +43 -58
  145. adam/commands/reaper/reaper_runs_abort.py +29 -49
  146. adam/commands/reaper/reaper_schedule_activate.py +14 -33
  147. adam/commands/reaper/reaper_schedule_start.py +9 -33
  148. adam/commands/reaper/reaper_schedule_stop.py +9 -33
  149. adam/commands/reaper/reaper_schedules.py +4 -14
  150. adam/commands/reaper/reaper_status.py +8 -16
  151. adam/commands/reaper/utils_reaper.py +203 -0
  152. adam/commands/repair/repair.py +4 -22
  153. adam/commands/repair/repair_log.py +5 -11
  154. adam/commands/repair/repair_run.py +27 -34
  155. adam/commands/repair/repair_scan.py +32 -40
  156. adam/commands/repair/repair_stop.py +5 -12
  157. adam/commands/restart_cluster.py +47 -0
  158. adam/commands/restart_node.py +51 -0
  159. adam/commands/restart_nodes.py +47 -0
  160. adam/commands/rollout.py +19 -24
  161. adam/commands/shell.py +12 -4
  162. adam/commands/show/show.py +10 -23
  163. adam/commands/show/show_adam.py +3 -3
  164. adam/commands/show/show_cassandra_repairs.py +37 -0
  165. adam/commands/show/show_cassandra_status.py +47 -51
  166. adam/commands/show/show_cassandra_version.py +5 -18
  167. adam/commands/show/show_cli_commands.py +56 -0
  168. adam/commands/show/show_host.py +1 -1
  169. adam/commands/show/show_login.py +23 -27
  170. adam/commands/show/show_params.py +2 -5
  171. adam/commands/show/show_processes.py +18 -21
  172. adam/commands/show/show_storage.py +11 -20
  173. adam/commands/watch.py +26 -29
  174. adam/config.py +5 -15
  175. adam/embedded_params.py +1 -1
  176. adam/log.py +4 -4
  177. adam/repl.py +105 -133
  178. adam/repl_commands.py +68 -28
  179. adam/repl_session.py +9 -1
  180. adam/repl_state.py +300 -62
  181. adam/sql/async_executor.py +44 -0
  182. adam/sql/lark_completer.py +286 -0
  183. adam/sql/lark_parser.py +604 -0
  184. adam/sql/qingl.lark +1076 -0
  185. adam/sql/sql_completer.py +104 -64
  186. adam/sql/sql_state_machine.py +630 -0
  187. adam/sql/term_completer.py +3 -0
  188. adam/sso/authn_ad.py +6 -8
  189. adam/sso/authn_okta.py +4 -6
  190. adam/sso/cred_cache.py +3 -5
  191. adam/sso/idp.py +9 -12
  192. adam/utils.py +640 -10
  193. adam/utils_athena.py +140 -87
  194. adam/utils_audits.py +102 -0
  195. adam/utils_issues.py +32 -0
  196. adam/utils_k8s/app_clusters.py +28 -0
  197. adam/utils_k8s/app_pods.py +35 -0
  198. adam/utils_k8s/cassandra_clusters.py +34 -21
  199. adam/utils_k8s/cassandra_nodes.py +9 -6
  200. adam/utils_k8s/custom_resources.py +16 -17
  201. adam/utils_k8s/ingresses.py +2 -2
  202. adam/utils_k8s/jobs.py +7 -11
  203. adam/utils_k8s/k8s.py +96 -0
  204. adam/utils_k8s/kube_context.py +3 -6
  205. adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +11 -5
  206. adam/utils_k8s/pods.py +146 -75
  207. adam/utils_k8s/secrets.py +4 -4
  208. adam/utils_k8s/service_accounts.py +5 -4
  209. adam/utils_k8s/services.py +2 -2
  210. adam/utils_k8s/statefulsets.py +6 -14
  211. adam/utils_local.py +42 -0
  212. adam/utils_net.py +4 -4
  213. adam/utils_repl/__init__.py +0 -0
  214. adam/utils_repl/appendable_completer.py +6 -0
  215. adam/utils_repl/automata_completer.py +48 -0
  216. adam/utils_repl/repl_completer.py +89 -0
  217. adam/utils_repl/state_machine.py +173 -0
  218. adam/utils_sqlite.py +137 -0
  219. adam/version.py +1 -1
  220. {kaqing-2.0.98.dist-info → kaqing-2.0.203.dist-info}/METADATA +1 -1
  221. kaqing-2.0.203.dist-info/RECORD +277 -0
  222. kaqing-2.0.203.dist-info/top_level.txt +2 -0
  223. teddy/__init__.py +0 -0
  224. teddy/lark_parser.py +436 -0
  225. teddy/lark_parser2.py +618 -0
  226. adam/commands/app.py +0 -67
  227. adam/commands/bash.py +0 -92
  228. adam/commands/cp.py +0 -95
  229. adam/commands/cql/cql_completions.py +0 -11
  230. adam/commands/cql/cql_table_completer.py +0 -8
  231. adam/commands/cql/cql_utils.py +0 -115
  232. adam/commands/describe/describe.py +0 -47
  233. adam/commands/describe/describe_keyspace.py +0 -60
  234. adam/commands/describe/describe_keyspaces.py +0 -49
  235. adam/commands/describe/describe_schema.py +0 -49
  236. adam/commands/describe/describe_table.py +0 -60
  237. adam/commands/describe/describe_tables.py +0 -49
  238. adam/commands/devices.py +0 -118
  239. adam/commands/logs.py +0 -39
  240. adam/commands/postgres/postgres_session.py +0 -240
  241. adam/commands/postgres/postgres_utils.py +0 -31
  242. adam/commands/postgres/psql_completions.py +0 -10
  243. adam/commands/postgres/psql_table_completer.py +0 -11
  244. adam/commands/reaper/reaper_session.py +0 -159
  245. adam/commands/report.py +0 -57
  246. adam/commands/show/show_app_actions.py +0 -53
  247. adam/commands/show/show_commands.py +0 -61
  248. adam/commands/show/show_repairs.py +0 -47
  249. adam/sql/state_machine.py +0 -460
  250. kaqing-2.0.98.dist-info/RECORD +0 -191
  251. kaqing-2.0.98.dist-info/top_level.txt +0 -1
  252. /adam/commands/{describe → app}/__init__.py +0 -0
  253. {kaqing-2.0.98.dist-info → kaqing-2.0.203.dist-info}/WHEEL +0 -0
  254. {kaqing-2.0.98.dist-info → kaqing-2.0.203.dist-info}/entry_points.txt +0 -0
@@ -1,53 +0,0 @@
1
- from adam.app_session import AppSession
2
- from adam.apps import AppAction, Apps
3
- from adam.commands.command import Command
4
- from adam.config import Config
5
- from adam.repl_state import ReplState
6
- from adam.utils import lines_to_tabular, log
7
-
8
- class ShowAppActions(Command):
9
- COMMAND = 'show app actions'
10
-
11
- # the singleton pattern
12
- def __new__(cls, *args, **kwargs):
13
- if not hasattr(cls, 'instance'): cls.instance = super(ShowAppActions, cls).__new__(cls)
14
-
15
- return cls.instance
16
-
17
- def __init__(self, successor: Command=None):
18
- super().__init__(successor)
19
-
20
- def command(self):
21
- return ShowAppActions.COMMAND
22
-
23
- def run(self, cmd: str, state: ReplState):
24
- if not self.args(cmd):
25
- return super().run(cmd, state)
26
-
27
- lines = []
28
- for typ in Apps().app_types():
29
- for action in typ.actions:
30
- a: AppAction = action
31
- args = ','.join(a.arguments())
32
- if args:
33
- line = f'{typ.name}.{a.name},{args}'
34
- else:
35
- line = f'{typ.name}.{a.name},'
36
- if a.help:
37
- line = f'{line},{a.help}'
38
- lines.append(line)
39
- log(lines_to_tabular(lines, 'ACTION,ARGS,DESCRIPTION', separator=','))
40
- log()
41
-
42
- app_session: AppSession = AppSession.create(state.app_env or 'c3', state.app_app or 'c3')
43
- endpoint = Config().get('app.console-endpoint', 'https://{host}/{env}/{app}/static/console/index.html')
44
- endpoint = endpoint.replace('{host}', app_session.host).replace('{env}', app_session.env).replace('{app}', state.app_app or 'c3')
45
- log(lines_to_tabular([f'CONSOLE:,{endpoint}'], separator=','))
46
-
47
- return lines
48
-
49
- def completion(self, state: ReplState):
50
- return super().completion(state)
51
-
52
- def help(self, _: ReplState):
53
- return f"{ShowAppActions.COMMAND}\t show app actions"
@@ -1,61 +0,0 @@
1
- from adam.commands.command import Command
2
- from adam.commands.cli_commands import CliCommands
3
- from adam.repl_state import ReplState, RequiredState
4
- from adam.utils import lines_to_tabular, log
5
-
6
- class ShowKubectlCommands(Command):
7
- COMMAND = 'show cli-commands'
8
-
9
- # the singleton pattern
10
- def __new__(cls, *args, **kwargs):
11
- if not hasattr(cls, 'instance'): cls.instance = super(ShowKubectlCommands, cls).__new__(cls)
12
-
13
- return cls.instance
14
-
15
- def __init__(self, successor: Command=None):
16
- super().__init__(successor)
17
-
18
- def command(self):
19
- return ShowKubectlCommands.COMMAND
20
-
21
- def required(self):
22
- return RequiredState.CLUSTER_OR_POD
23
-
24
- def run(self, cmd: str, state: ReplState):
25
- if not self.args(cmd):
26
- return super().run(cmd, state)
27
-
28
- if not self.validate_state(state):
29
- return state
30
-
31
- v = CliCommands.values(state, collapse=True)
32
- # node-exec-?, nodetool-?, cql-?, reaper-exec, reaper-forward, reaper-ui, reaper-username, reaper-password
33
- cmds = [
34
- f'bash,{v["node-exec-?"]}',
35
- f'nodetool,{v["nodetool-?"]}',
36
- f'cql,{v["cql-?"]}',
37
- ]
38
-
39
- if 'reaper-exec' in v:
40
- cmds += [
41
- f'reaper,{v["reaper-exec"]}',
42
- f',{v["reaper-forward"]} * should be run from your laptop',
43
- f',{v["reaper-ui"]}',
44
- f',{v["reaper-username"]}',
45
- f',{v["reaper-password"]}',
46
- ]
47
-
48
- cmds += [f'{k},{v0}' for k, v0 in v.items() if k.startswith('pg-')]
49
-
50
- log(lines_to_tabular(cmds, separator=','))
51
-
52
- return cmds
53
-
54
- def completion(self, state: ReplState):
55
- if not state.sts:
56
- return {}
57
-
58
- return super().completion(state)
59
-
60
- def help(self, _: ReplState):
61
- return f"{ShowKubectlCommands.COMMAND}\t show kubectl commands"
@@ -1,47 +0,0 @@
1
- from adam.commands.command import Command
2
- from adam.utils_k8s.cassandra_clusters import CassandraClusters
3
- from adam.utils_k8s.cassandra_nodes import CassandraNodes
4
- from adam.repl_state import ReplState, RequiredState
5
-
6
- class ShowRepairs(Command):
7
- COMMAND = 'show cassandra repairs'
8
-
9
- # the singleton pattern
10
- def __new__(cls, *args, **kwargs):
11
- if not hasattr(cls, 'instance'): cls.instance = super(ShowRepairs, cls).__new__(cls)
12
-
13
- return cls.instance
14
-
15
- def __init__(self, successor: Command=None):
16
- super().__init__(successor)
17
-
18
- def command(self):
19
- return ShowRepairs.COMMAND
20
-
21
- def required(self):
22
- return RequiredState.CLUSTER_OR_POD
23
-
24
- def run(self, cmd: str, state: ReplState):
25
- if not(args := self.args(cmd)):
26
- return super().run(cmd, state)
27
-
28
- state, _ = state.apply_args(args)
29
- if not self.validate_state(state):
30
- return state
31
-
32
- user, pw = state.user_pass()
33
- command = f"nodetool -u {user} -pw {pw} repair_admin list"
34
-
35
- if state.pod:
36
- return CassandraNodes.exec(state.pod, state.namespace, command)
37
- else:
38
- return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool')
39
-
40
- def completion(self, state: ReplState):
41
- if state.sts:
42
- return super().completion(state)
43
-
44
- return {}
45
-
46
- def help(self, _: ReplState):
47
- return f'{ShowRepairs.COMMAND}\t show Cassandra repairs'
adam/sql/state_machine.py DELETED
@@ -1,460 +0,0 @@
1
- # <select_statement> ::= SELECT <select_list>
2
- # FROM <table_expression>
3
- # [WHERE <search_condition>]
4
- # [<group_by_clause>]
5
- # [<having_clause>]
6
- # [<order_by_clause>]
7
- # [<limit_clause>]
8
-
9
- # <search_condition> ::= <boolean_term>
10
- # | <search_condition> OR <boolean_term>
11
-
12
- # <boolean_term> ::= <boolean_factor>
13
- # | <boolean_term> AND <boolean_factor>
14
-
15
- # <boolean_factor> ::= [NOT] <predicate>
16
- # | ([NOT] <search_condition>)
17
-
18
- # <predicate> ::= <comparison_predicate>
19
- # | <between_predicate>
20
- # | <in_predicate>
21
- # | <like_predicate>
22
- # | <null_predicate>
23
- # | <exists_predicate>
24
- # | <quantified_predicate>
25
- # | <unique_predicate>
26
- # | <match_predicate>
27
- # | <overlaps_predicate>
28
- # | <distinct_predicate>
29
- # | <member_predicate>
30
- # | <submultiset_predicate>
31
- # | <set_predicate>
32
-
33
- # <comparison_predicate> ::= <row_value_expression> <comparison_operator> <row_value_expression>
34
- # <comparison_operator> ::= '=' | '<>' | '<' | '<=' | '>' | '>='
35
-
36
- # <row_value_expression> ::= <value_expression>
37
- # | (<value_expression> [ { <comma> <value_expression> }... ])
38
-
39
- # <value_expression> ::= <numeric_value_expression>
40
- # | <string_value_expression>
41
- # | <datetime_value_expression>
42
- # | <interval_value_expression>
43
- # | <boolean_value_expression>
44
- # | <user_defined_type_value_expression>
45
- # | <reference_value_expression>
46
- # | <collection_value_expression>
47
- # | <row_value_constructor>
48
- # | <case_expression>
49
- # | <cast_expression>
50
- # | <subquery>
51
- # | NULL
52
- # | DEFAULT
53
- # | <identifier>
54
- # | <literal>
55
-
56
- # <insert_statement> ::= INSERT INTO <table_name> [ ( <column_list> ) ]
57
- # VALUES ( <value_list> )
58
- # | INSERT INTO <table_name> [ ( <column_list> ) ]
59
- # <query_expression>
60
-
61
- # <table_name> ::= <identifier>
62
-
63
- # <column_list> ::= <column_name> [ , <column_list> ]
64
-
65
- # <column_name> ::= <identifier>
66
-
67
- # <value_list> ::= <expression> [ , <value_list> ]
68
-
69
- # <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> ]
70
-
71
- # <update_statement> ::= UPDATE <table_name>
72
- # SET <set_clause_list>
73
- # [WHERE <search_condition>]
74
-
75
- # <set_clause_list> ::= <set_clause> { , <set_clause> }
76
-
77
- # <set_clause> ::= <column_name> = <update_value>
78
-
79
- # <update_value> ::= <expression> | NULL | DEFAULT
80
-
81
- # <search_condition> ::= <boolean_expression>
82
-
83
- # <delete_statement> ::= DELETE FROM <table_name> [ WHERE <search_condition> ]
84
-
85
- # <table_name> ::= <identifier>
86
-
87
- # <search_condition> ::= <boolean_expression>
88
-
89
- # <boolean_expression> ::= <predicate>
90
- # | <boolean_expression> AND <predicate>
91
- # | <boolean_expression> OR <predicate>
92
- # | NOT <predicate>
93
- # | ( <boolean_expression> )
94
-
95
- # <predicate> ::= <expression> <comparison_operator> <expression>
96
- # | <expression> IS NULL
97
- # | <expression> IS NOT NULL
98
- # | <expression> LIKE <pattern> [ ESCAPE <escape_character> ]
99
- # | <expression> IN ( <expression_list> )
100
- # | EXISTS ( <select_statement> )
101
- # | ... (other predicates)
102
-
103
- # <comparison_operator> ::= = | <> | != | > | < | >= | <=
104
-
105
- # <expression> ::= <literal>
106
- # | <column_name>
107
- # | <function_call>
108
- # | ( <expression> )
109
- # | <expression> <arithmetic_operator> <expression>
110
- # | ... (other expressions)
111
-
112
- # <literal> ::= <numeric_literal> | <string_literal> | <boolean_literal> | <date_literal> | ...
113
-
114
- # <column_name> ::= <identifier>
115
-
116
- # <identifier> ::= <letter> { <letter> | <digit> | _ }...
117
-
118
- # <pattern> ::= <string_literal>
119
-
120
- # <escape_character> ::= <string_literal> (single character)
121
-
122
- # <expression_list> ::= <expression> { , <expression> }...
123
-
124
- from sqlparse.sql import Token
125
- from sqlparse import tokens as T
126
-
127
- __all__ = [
128
- "StateMachine",
129
- ]
130
-
131
- SPEC = [
132
- ' > select > select',
133
- 'select_ > name|* > select_a ^ *',
134
- 'select_a > , > select_a_comma_',
135
- 'select_a_comma_ > name|* > select_a ^ *',
136
- 'select_a_ > from > select_from ^ from',
137
- 'select_from_ > name|audit > select_from_x ^ (select,tables',
138
- '- > ( > select_from_lp_',
139
- '- < ) > select_from_sq',
140
- 'select_from_lp_ > select > select',
141
- 'select_from_x > , > select_from_x_comma_ ^ (select,tables',
142
- 'select_from_sq_ > as > select_from_x_as ^ as',
143
- 'select_from_x_comma_ > name > select_from_x ^ tables',
144
- 'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
145
- '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',
146
- '- > as > select_from_x_as',
147
- '- > where > select_where',
148
- '- > order > select_order',
149
- '- > order by > select_order_by',
150
- '- > limit > select_where_sc_limit',
151
- '- > group > select_group',
152
- '- > group by > select_group_by',
153
- '- > inner > select_from_x_inner',
154
- '- > inner join > select_join',
155
- '- > left > select_from_x_left',
156
- '- > left join > select_join',
157
- '- > left outer join > select_join',
158
- '- > right > select_from_x_right',
159
- '- > right join > select_join',
160
- '- > right outer join > select_join',
161
- '- > full > select_from_x_full',
162
- '- > full outer join > select_join',
163
- 'select_from_x_as_ > name > select_from_x_as_x ^ x,y,z',
164
- 'select_from_x_as_x > , > select_from_x_as_x_comma_',
165
- 'select_from_x_as_x_comma_ > name > select_from_x ^ tables',
166
- 'select_where_ > name > select_where_a ^ columns',
167
- 'select_where_a > name > select_where_a ^ columns,=,<,<=,>,>=,<>',
168
- '- > comparison > select_where_a_op',
169
- 'select_where_a_ > comparison > select_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
170
- '- > not > select_where_a_not',
171
- '- > in > select_where_a_in',
172
- 'select_where_a_not_ > comparison > select_where_a_not_op ^ like,in',
173
- '- > in > select_where_a_in',
174
- 'select_where_a_in > ( > select_where_a_in_lp_ ^ (',
175
- '- < ) > select_where_sc',
176
- 'select_where_a_in_lp_ > name|single|num > select_where_a_in_lp_a ^ single,select',
177
- '- > select > select_where_a_in_lp_select',
178
- 'select_where_a_in_lp_select_ > name > select_a ^ id',
179
- 'select_where_a_in_lp_a > , > select_where_a_in_lp_a_comma_ ^ comma,)',
180
- 'select_where_a_in_lp_a_comma_ > name|single|num > select_where_a_in_lp_a ^ single',
181
- 'select_where_a_not_op > name|single|num > select_where_sc ^ single',
182
- 'select_where_a_op > name|single|num > select_where_sc ^ single',
183
- 'select_where_sc_ > and|or > select_where ^ and,or,order by,group by,limit',
184
- '- > group > select_group',
185
- '- > group by > select_group_by',
186
- '- > order > select_order',
187
- '- > order by > select_order_by',
188
- '- > limit > select_where_sc_limit',
189
- 'select_group_ > by > select_group_by ^ by',
190
- 'select_group_by_ > name > select_group_by_a ^ columns',
191
- 'select_group_by_a > name > select_group_by_a ^ columns',
192
- '- > , > select_group_by_a_comma_ ^ columns',
193
- 'select_group_by_a_comma_ > name > select_group_by_a ^ columns',
194
- 'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by',
195
- '- > order > select_order',
196
- '- > order by > select_order_by',
197
- 'select_order_ > by > select_order_by ^ by',
198
- 'select_order_by_ > name > select_order_by_a ^ columns',
199
- 'select_order_by_a > name > select_order_by_a ^ columns',
200
- '- > , > select_order_by_a_comma_',
201
- 'select_order_by_a_comma_ > name > select_order_by_a ^ columns',
202
- 'select_order_by_a_ > desc|asc > select_order_by_a_desc ^ desc,asc,limit',
203
- '- > limit > select_where_sc_limit',
204
- 'select_order_by_a_desc > , > select_order_by_a_comma_',
205
- 'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit',
206
- 'select_where_sc_limit_ > num > select_where_sc_limit_num ^ 1',
207
- 'select_where_sc_limit_num_rp__ > as > select_from_x_as ^ as',
208
- 'select_where_x_inner_ > join > select_join',
209
- 'select_join_ > name > select_x_join_y ^ tables',
210
- 'select_from_x_left_ > join > select_join ^ outer join',
211
- '- > outer > select_from_x_left_outer',
212
- 'select_from_x_left_outer_ > join > select_join ^ join',
213
- 'select_from_x_right_ > join > select_join ^ outer join',
214
- '- > outer > select_from_x_right_outer',
215
- 'select_from_x_right_outer_ > join > select_join ^ join',
216
- 'select_from_x_full_ > join > select_join ^ outer join',
217
- '- > outer > select_from_x_full_outer',
218
- 'select_from_x_full_outer_ > join > select_join ^ join',
219
- 'select_x_join_y > name > select_x_join_y ^ tables',
220
- 'select_x_join_y_ > as > select_x_join_y_as ^ as,on',
221
- '- > on > select_x_join_y_on ^ as,on',
222
- 'select_x_join_y_as_ > name > select_x_join_y_as_y ^ x,y,z',
223
- 'select_x_join_y_as_y_ > on > select_x_join_y_on ^ on',
224
- 'select_x_join_y_on_ > name > select_x_join_y_on_a ^ columns',
225
- 'select_x_join_y_on_a > name > select_x_join_y_on_a ^ columns,=',
226
- '- > comparison > select_x_join_y_on_a_op',
227
- 'select_x_join_y_on_a_ > comparison > select_x_join_y_on_a_op ^ =',
228
- 'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ columns',
229
- 'select_x_join_y_on_a_op_b > name > select_x_join_y_on_a_op_b ^ columns',
230
- '- > _ > select_from_x_as_x_',
231
-
232
-
233
- ' > insert > insert',
234
- 'insert_ > into > insert_into ^ into',
235
- 'insert_into_ > name > insert_into_x ^ tables',
236
- 'insert_into_x > name > insert_into_x ^ tables',
237
- '- > ( > insert_into_x_lp_',
238
- 'insert_into_x_ > ( > insert_into_x_lp_ ^ (,values(',
239
- '- > values > insert_values',
240
- 'insert_into_x_lp_ > name > insert_into_x_lp_a ^ id',
241
- 'insert_into_x_lp_a > , > insert_into_x_lp_a_comma_',
242
- '- > ) > insert_into_x_lp_a_rp_',
243
- 'insert_into_x_lp_a_comma_ > name > insert_into_x_lp_a ^ id',
244
- 'insert_into_x_lp_a_rp__ > values > insert_values ^ values(,select',
245
- '- > select > select',
246
- 'insert_values > ( > insert_values_lp_',
247
- 'insert_values_lp_ > name|single|num > insert_values_lp_v ^ single',
248
- 'insert_values_lp_v > , > insert_values_lp_v_comma_',
249
- 'insert_values_lp_v_comma_ > name|single|num > insert_values_lp_v',
250
-
251
-
252
- ' > update > update',
253
- 'update_ > name > update_x ^ tables',
254
- 'update_x > name > update_x ^ tables',
255
- 'update_x_ > set > update_set ^ set',
256
- 'update_set_ > name > update_set_a ^ id',
257
- 'update_set_a > comparison > update_set_a_op',
258
- 'update_set_a_op > name|single|num > update_set_sc ^ single',
259
- 'update_set_sc > , > update_set_sc_comma_',
260
- 'update_set_sc_comma_ > name > update_set_a ^ id',
261
- 'update_set_sc_ > , > update_set_sc_comma_ ^ where',
262
- '- > where > update_where',
263
- 'update_where_ > name > update_where_a ^ id',
264
- 'update_where_a > comparison > update_where_a_op',
265
- 'update_where_a_ > comparison > update_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
266
- '- > not > update_where_a_not',
267
- '- > in > update_where_a_in',
268
- 'update_where_a_not_ > comparison > update_where_a_not_op ^ like,in',
269
- '- > in > update_where_a_in',
270
- 'update_where_a_in > ( > update_where_a_in_lp_ ^ (',
271
- '- < ) > update_where_sc',
272
- 'update_where_a_in_lp_ > name|single|num > update_where_a_in_lp_a ^ single,select',
273
- '- > select > update_where_a_in_lp_select',
274
- 'update_where_a_in_lp_select_ > name > select_a ^ id',
275
- 'update_where_a_in_lp_a > , > update_where_a_in_lp_a_comma_ ^ comma,)',
276
- 'update_where_a_in_lp_a_comma_ > name|single|num > update_where_a_in_lp_a ^ single',
277
- 'update_where_a_not_op > name|single|num > update_where_sc ^ single',
278
- 'update_where_a_op > name|single|num > update_where_sc ^ single',
279
- 'update_where_sc_ > and|or > update_where ^ and,or',
280
-
281
-
282
- ' > delete > delete',
283
- 'delete_ > from > delete_from ^ from',
284
- 'delete_from_ > name > delete_from_x ^ tables',
285
- 'delete_from_x > name > delete_from_x ^ tables',
286
- 'delete_from_x_ > where > update_where ^ where',
287
- ]
288
-
289
- KEYWORDS = [
290
- 'select', 'from', 'as', 'not', 'in', 'where',
291
- 'and', 'or', 'group', 'by', 'group by', 'order', 'order by', 'limit', 'asc', 'desc',
292
- 'inner join', 'on', 'left', 'right', 'full', 'outer', 'left outer join',
293
- 'left join', 'right outer join', 'right join', 'full join', 'full outer join',
294
- 'insert', 'into', 'values',
295
- 'update', 'where', 'set',
296
- 'delete',
297
- 'audit'
298
- ]
299
-
300
- class StateTo:
301
- def __init__(self, to_s: str, comeback_token: str = None, comeback_state: str = None):
302
- self.to_s = to_s
303
- self.comeback_token = comeback_token
304
- self.comeback_state = comeback_state
305
-
306
- def __str__(self):
307
- return f'{self.to_s} comeback[{self.comeback_token} {self.comeback_state}]'
308
-
309
- class StateMachine:
310
- def __init__(self, indent=0, lp_level = 0, debug = False):
311
- self.states: dict[str, StateTo] = {}
312
- self.suggestions: dict[str, str] = {}
313
-
314
- self.indent = indent
315
- self.lp_level = lp_level
316
- self.comebacks: dict[int, str] = {}
317
- self.debug = debug
318
-
319
- from_ss_to_add = []
320
- from_ss = ['']
321
- words: str = None
322
- for l in SPEC:
323
- t_and_w = l.split('^')
324
- if len(t_and_w) > 1:
325
- words = t_and_w[1]
326
- else:
327
- words = None
328
-
329
- tks = t_and_w[0].strip(' ').split('>')
330
- if not l.startswith('-'):
331
- if words:
332
- self.suggestions[tks[0].strip(' ')] = words
333
-
334
- if len(tks) == 1:
335
- from_ss_to_add.append(tks[0].strip(' '))
336
- continue
337
-
338
- from_ss = []
339
- from_ss.extend(from_ss_to_add)
340
- from_ss_to_add = []
341
- from_ss.append(tks[0].strip(' '))
342
-
343
- self.add_transitions(from_ss, tks)
344
-
345
- def add_transitions(self, from_ss: list[str], tks: list[str]):
346
- token = tks[1].strip(' ')
347
- if len(tks) > 2:
348
- to_s = tks[2].strip(' ')
349
- for from_s in from_ss:
350
- self.add_whitespace_transition(from_s, to_s)
351
- self.add_transition(from_s, token, to_s)
352
- elif '<' in tks[0]:
353
- from_and_token = tks[0].split('<')
354
- if len(from_and_token) > 1:
355
- for from_s in from_ss:
356
- self.add_comeback_transition(from_s, from_and_token[1], tks[1].strip(' '))
357
-
358
- def add_whitespace_transition(self, from_s: str, to_s: str):
359
- # add whitespace transition if a state with trailing whitespace is found from from states, for example, select > _ > select_
360
- if from_s.endswith('_') and not from_s.endswith('_comma_') and not from_s.endswith('_lp_') and not from_s.endswith('_rp_'):
361
- if self.debug:
362
- print(f'{from_s[:-1]} > _ = {to_s}')
363
- self.states[f'{from_s[:-1]} > _'] = StateTo(from_s)
364
-
365
- def add_transition(self, from_s: str, token: str, to_s: str):
366
- tokens = [token]
367
- if '|' in token:
368
- tokens = token.split('|')
369
-
370
- for t in tokens:
371
- if self.debug:
372
- print(f'{from_s} > {t} = {to_s}')
373
- self.states[f'{from_s} > {t}'] = StateTo(to_s)
374
-
375
- def add_comeback_transition(self, from_s: str, token: str, to_s: str):
376
- key = f'{from_s} > ('
377
- orig = self.states[key]
378
- if not orig:
379
- raise Exception(f'from state not found for {key}')
380
-
381
- orig.comeback_token = token
382
- orig.comeback_state = to_s
383
- if self.debug:
384
- print(f'{from_s} > ) = {to_s}')
385
- self.states[key] = orig
386
-
387
- def traverse_tokens(self, tokens: list[Token], state: StateTo = StateTo('')):
388
- def handle_opening_parenthesis():
389
- if f'{state.to_s} > {it}' in self.states:
390
- state_test = self.states[f'{state.to_s} > {it}']
391
- if state_test.comeback_token:
392
- self.comebacks[self.lp_level] = state_test.comeback_state
393
-
394
- def handle_closing_parenthesis():
395
- if self.lp_level in self.comebacks:
396
- try:
397
- return StateTo(self.comebacks[self.lp_level])
398
- finally:
399
- del self.comebacks[self.lp_level]
400
-
401
- return None
402
-
403
- for token in tokens:
404
- if self.debug:
405
- if token.ttype == T.Whitespace:
406
- print('_ ', end='')
407
- elif token.ttype in [T.DML, T.Wildcard, T.Punctuation]:
408
- print(f'{token.value} ', end='')
409
- elif token.ttype:
410
- tks = str(token.ttype).split('.')
411
- typ = tks[len(tks) - 1]
412
- if ' ' in token.value:
413
- print(f'"{token.value}:{typ}" ', end='')
414
- else:
415
- print(f'{token.value}:{typ} ', end='')
416
- # print(" " * self.indent + f"Token: {token.value}, Type: {token.ttype}@{token.ttype.__class__}")
417
-
418
- if token.is_group:
419
- state = self.traverse_tokens(token.tokens, state)
420
- else:
421
- comeback_state = None
422
-
423
- it = ''
424
- if (t := token.value.lower()) in KEYWORDS:
425
- it = t
426
- elif token.ttype == T.Text.Whitespace:
427
- it = '_'
428
- elif token.ttype == T.Name:
429
- it = 'name'
430
- elif token.ttype == T.Literal.String.Single:
431
- it = 'single'
432
- elif token.ttype in [T.Literal.Number.Integer, T.Literal.Number.Float]:
433
- it = 'num'
434
- elif token.ttype == T.Wildcard:
435
- it = '*'
436
- elif token.ttype == T.Punctuation:
437
- it = token.value
438
-
439
- if it == '(':
440
- handle_opening_parenthesis()
441
- self.lp_level += 1
442
- elif it == ')':
443
- self.lp_level -= 1
444
- comeback_state = handle_closing_parenthesis()
445
-
446
- elif token.ttype == T.Operator.Comparison:
447
- it = 'comparison'
448
-
449
- try:
450
- # print(f'\n{state.to_s} > {it} > ', end='')
451
- if comeback_state:
452
- state = comeback_state
453
- else:
454
- state = self.states[f'{state.to_s} > {it}']
455
- # print(state)
456
- except:
457
- pass
458
- # print('error')
459
-
460
- return state