kaqing 2.0.172__py3-none-any.whl → 2.0.174__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 (54) hide show
  1. adam/commands/__init__.py +6 -2
  2. adam/commands/alter_tables.py +24 -35
  3. adam/commands/cat.py +3 -13
  4. adam/commands/cd.py +6 -8
  5. adam/commands/check.py +9 -17
  6. adam/commands/command.py +39 -5
  7. adam/commands/cp.py +24 -32
  8. adam/commands/cql/cql_completions.py +3 -4
  9. adam/commands/cql/utils_cql.py +0 -2
  10. adam/commands/devices/device_app.py +2 -2
  11. adam/commands/devices/device_cass.py +2 -2
  12. adam/commands/devices/device_export.py +7 -9
  13. adam/commands/devices/device_postgres.py +2 -2
  14. adam/commands/export/clean_up_all_export_sessions.py +3 -3
  15. adam/commands/export/clean_up_export_sessions.py +8 -15
  16. adam/commands/export/drop_export_database.py +6 -22
  17. adam/commands/export/drop_export_databases.py +3 -9
  18. adam/commands/export/export.py +1 -1
  19. adam/commands/export/export_databases.py +70 -15
  20. adam/commands/export/export_select.py +12 -23
  21. adam/commands/export/export_select_x.py +3 -3
  22. adam/commands/export/export_sessions.py +124 -0
  23. adam/commands/export/export_use.py +0 -6
  24. adam/commands/export/exporter.py +61 -120
  25. adam/commands/export/import_session.py +4 -4
  26. adam/commands/export/importer.py +12 -5
  27. adam/commands/export/importer_athena.py +17 -13
  28. adam/commands/export/importer_sqlite.py +20 -17
  29. adam/commands/export/show_column_counts.py +5 -14
  30. adam/commands/export/show_export_databases.py +2 -1
  31. adam/commands/export/show_export_session.py +5 -13
  32. adam/commands/export/show_export_sessions.py +2 -2
  33. adam/commands/export/utils_export.py +5 -3
  34. adam/commands/medusa/medusa_backup.py +1 -2
  35. adam/commands/medusa/medusa_restore.py +21 -19
  36. adam/commands/param_get.py +8 -9
  37. adam/commands/param_set.py +7 -10
  38. adam/commands/postgres/postgres.py +13 -21
  39. adam/commands/postgres/utils_postgres.py +5 -1
  40. adam/commands/preview_table.py +1 -1
  41. adam/commands/reaper/reaper_run_abort.py +4 -10
  42. adam/commands/reaper/reaper_schedule_activate.py +6 -10
  43. adam/commands/reaper/reaper_schedule_start.py +6 -10
  44. adam/commands/reaper/reaper_schedule_stop.py +6 -10
  45. adam/repl.py +5 -3
  46. adam/utils_k8s/k8s.py +5 -5
  47. adam/utils_sqlite.py +13 -13
  48. adam/version.py +1 -1
  49. {kaqing-2.0.172.dist-info → kaqing-2.0.174.dist-info}/METADATA +1 -1
  50. {kaqing-2.0.172.dist-info → kaqing-2.0.174.dist-info}/RECORD +53 -53
  51. adam/commands/export/export_handlers.py +0 -71
  52. {kaqing-2.0.172.dist-info → kaqing-2.0.174.dist-info}/WHEEL +0 -0
  53. {kaqing-2.0.172.dist-info → kaqing-2.0.174.dist-info}/entry_points.txt +0 -0
  54. {kaqing-2.0.172.dist-info → kaqing-2.0.174.dist-info}/top_level.txt +0 -0
@@ -2,12 +2,13 @@ from collections.abc import Callable
2
2
  import os
3
3
  import boto3
4
4
 
5
- from adam.commands.export.utils_export import ExportTableStatus
5
+ from adam.commands.export.export_sessions import ExportSessions
6
+ from adam.commands.export.importer import Importer
6
7
  from adam.config import Config
7
8
  from adam.repl_session import ReplSession
9
+ from adam.repl_state import ReplState
8
10
  from adam.utils import debug, lines_to_tabular, log, log2, ing, log_exc
9
11
  from adam.utils_athena import Athena
10
- from adam.utils_k8s.statefulsets import StatefulSets
11
12
  from adam.utils_sqlite import SQLite
12
13
 
13
14
  LIKE = 'e%_%'
@@ -90,7 +91,7 @@ class ExportDatabases:
90
91
  if not export_session:
91
92
  return
92
93
 
93
- Athena.clear_cache()
94
+ ExportDatabases.clear_cache()
94
95
 
95
96
  keyspaces = {}
96
97
  for table in ExportDatabases.table_names(export_session):
@@ -102,17 +103,6 @@ class ExportDatabases:
102
103
 
103
104
  log(lines_to_tabular([f'{k},{v}' for k, v in keyspaces.items()], header='SCHEMA,# of TABLES', separator=','))
104
105
 
105
- def disply_export_session(sts: str, pod: str, namespace: str, session: str):
106
- if not pod:
107
- pod = StatefulSets.pod_names(sts, namespace)[0]
108
-
109
- if not pod:
110
- return
111
-
112
- tables, _ = ExportTableStatus.from_session(sts, pod, namespace, session)
113
- log()
114
- log(lines_to_tabular([f'{table.keyspace}\t{table.table}\t{table.target_table}\t{"export_completed_pending_import" if table.status == "pending_import" else table.status}' for table in tables], header='KEYSPACE\tTABLE\tTARGET_TABLE\tSTATUS', separator='\t'))
115
-
116
106
  def database_names():
117
107
  return ExportDatabases.copy_database_names() + ExportDatabases.export_database_names()
118
108
 
@@ -171,4 +161,69 @@ class ExportDatabases:
171
161
  if db.startswith('s'):
172
162
  return SQLite.database_names(prefix=f'{eprefix}_')
173
163
  else:
174
- return Athena.database_names(like=f'{eprefix}_%')
164
+ return Athena.database_names(like=f'{eprefix}_%')
165
+
166
+ def drop_databases(sts: str, pod: str, namespace: str, database: str = None):
167
+ importer = None
168
+ if database:
169
+ importer = Importer.importer_from_session(database)
170
+
171
+ sessions_done = ExportSessions.export_session_names(sts, pod, namespace, importer=importer, export_state='done')
172
+ sessions = ExportDatabases.sessions_from_dbs(ExportDatabases.drop_export_dbs(database))
173
+ if sessions_done and sessions:
174
+ intersects = list(set(sessions_done) & set(sessions))
175
+ with ing(f'Cleaning up {len(intersects)} completed sessions'):
176
+ ExportSessions.clean_up_sessions(sts, pod, namespace, list(intersects))
177
+ ExportSessions.clear_export_session_cache()
178
+
179
+ def clear_cache(database: str = None):
180
+ if not database or database.startswith('s'):
181
+ SQLite.clear_cache()
182
+ if not database or database.startswith('e'):
183
+ Athena.clear_cache()
184
+
185
+ def show_databases(importer: str = None):
186
+ lines = [f'{k}\t{v}' for k, v in ExportDatabases.database_names_with_keyspace_cnt(importer).items()]
187
+ log(lines_to_tabular(lines, 'NAME\tKEYSPACES', separator='\t'))
188
+
189
+ class ExportDatabaseService:
190
+ def __init__(self, handler: 'ExportDatabaseHandler'):
191
+ self.handler = handler
192
+
193
+ def sql(self, query: str, database: str = None):
194
+ if not database:
195
+ database = self.handler.state.export_session
196
+
197
+ ExportDatabases.run_query(query, database, show_query = True)
198
+
199
+ def drop(self, database: str):
200
+ state = self.handler.state
201
+
202
+ ExportDatabases.drop_databases(state.sts, state.pod, state.namespace, database)
203
+ ExportDatabases.clear_cache(database)
204
+ if state.export_session == database:
205
+ state.export_session = None
206
+
207
+ def drop_all(self):
208
+ state = self.handler.state
209
+
210
+ ExportDatabases.drop_databases(state.sts, state.pod, state.namespace)
211
+ ExportDatabases.clear_cache()
212
+
213
+ state.export_session = None
214
+
215
+ def show_databases(self, importer: str = None):
216
+ ExportDatabases.show_databases(importer)
217
+
218
+ class ExportDatabaseHandler:
219
+ def __init__(self, state: ReplState = None):
220
+ self.state = state
221
+
222
+ def __enter__(self):
223
+ return ExportDatabaseService(self)
224
+
225
+ def __exit__(self, exc_type, exc_val, exc_tb):
226
+ return False
227
+
228
+ def export_db(state: ReplState = None):
229
+ return ExportDatabaseHandler(state)
@@ -1,6 +1,6 @@
1
1
  from datetime import datetime
2
- from adam.commands import extract_trailing_options
3
- from adam.commands.command import Command
2
+ from adam.commands import extract_trailing_options, validate_args
3
+ from adam.commands.command import Command, InvalidArgumentsException
4
4
  from adam.commands.export.export_databases import ExportDatabases
5
5
  from adam.config import Config
6
6
  from adam.repl_state import ReplState, RequiredState
@@ -43,32 +43,21 @@ class ExportSelect(Command):
43
43
 
44
44
  Command.display_help()
45
45
 
46
- return 'command-missing'
46
+ raise InvalidArgumentsException()
47
47
 
48
- if not args:
49
- if state.in_repl:
50
- log2('Use a SQL statement.')
51
- else:
52
- log2('* SQL statement is missing.')
53
-
54
- Command.display_help()
55
-
56
- return 'command-missing'
57
-
58
- query = ' '.join(args)
59
-
60
- def output(out: str):
61
- log_prefix = Config().get('export.log-prefix', '/tmp/qing')
62
- log_file = f'{log_prefix}-{datetime.now().strftime("%d%H%M%S")}-sqlite.log'
48
+ with validate_args(args, state, name='SQL statement') as query:
49
+ def output(out: str):
50
+ log_prefix = Config().get('export.log-prefix', '/tmp/qing')
51
+ log_file = f'{log_prefix}-{datetime.now().strftime("%d%H%M%S")}-sqlite.log'
63
52
 
64
- with open(log_file, 'w') as f:
65
- f.write(out)
53
+ with open(log_file, 'w') as f:
54
+ f.write(out)
66
55
 
67
- return log_file
56
+ return log_file
68
57
 
69
- ExportDatabases.run_query(f'select {query}', database=state.export_session, output=output if backgrounded else None)
58
+ ExportDatabases.run_query(f'select {query}', database=state.export_session, output=output if backgrounded else None)
70
59
 
71
- return state
60
+ return state
72
61
 
73
62
  def completion(self, state: ReplState):
74
63
  if not state.export_session:
@@ -38,15 +38,15 @@ class ExportSelectX(Command):
38
38
  )}
39
39
 
40
40
  if state.export_session:
41
- completions |= {'select': SqlCompleter(
41
+ completions |= {dml: SqlCompleter(
42
42
  lambda: ExportDatabases.table_names(state.export_session),
43
- dml='select',
43
+ dml=dml,
44
44
  expandables={
45
45
  'export-dbs': lambda: ExportDatabases.database_names(),
46
46
  'columns':lambda _: Athena.column_names(database=state.export_session, function='export'),
47
47
  },
48
48
  variant=SqlVariant.ATHENA
49
- )}
49
+ ) for dml in ['select', 'preview']}
50
50
 
51
51
  return completions
52
52
 
@@ -0,0 +1,124 @@
1
+ import functools
2
+ import re
3
+
4
+ from adam.commands.export.importer import Importer
5
+ from adam.commands.export.utils_export import ExportTableStatus, csv_dir, find_files
6
+ from adam.config import Config
7
+ from adam.utils import lines_to_tabular, log, parallelize
8
+ from adam.utils_k8s.cassandra_nodes import CassandraNodes
9
+ from adam.utils_k8s.pods import log_prefix
10
+ from adam.utils_k8s.statefulsets import StatefulSets
11
+
12
+ class ExportSessions:
13
+ def clear_export_session_cache():
14
+ ExportSessions.find_export_sessions.cache_clear()
15
+ ExportSessions.export_session_names.cache_clear()
16
+
17
+ @functools.lru_cache()
18
+ def export_session_names(sts: str, pod: str, namespace: str, importer: str = None, export_state = None):
19
+ if not sts or not namespace:
20
+ return []
21
+
22
+ if not pod:
23
+ pod = StatefulSets.pod_names(sts, namespace)[0]
24
+
25
+ if not pod:
26
+ return []
27
+
28
+ return [session for session, state in ExportSessions.find_export_sessions(pod, namespace, importer).items() if not export_state or state == export_state]
29
+
30
+ @functools.lru_cache()
31
+ def find_export_sessions(pod: str, namespace: str, importer: str = None, limit = 100):
32
+ sessions: dict[str, str] = {}
33
+
34
+ prefix = Importer.prefix_from_importer(importer)
35
+
36
+ log_files: list[str] = find_files(pod, namespace, f'{log_prefix()}-{prefix}*_*.log*')
37
+
38
+ if not log_files:
39
+ return {}
40
+
41
+ for log_file in log_files[:limit]:
42
+ m = re.match(f'{log_prefix()}-(.*?)_.*\.log?(.*)', log_file)
43
+ if m:
44
+ s = m.group(1)
45
+ state = m.group(2) # '', '.pending_import', '.done'
46
+ if state:
47
+ state = state.strip('.')
48
+ else:
49
+ state = 'in_export'
50
+
51
+ if s not in sessions:
52
+ sessions[s] = state
53
+ elif sessions[s] == 'done' and state != 'done':
54
+ sessions[s] = state
55
+
56
+ return sessions
57
+
58
+ def clean_up_all_sessions(sts: str, pod: str, namespace: str):
59
+ if not sts or not namespace:
60
+ return False
61
+
62
+ if not pod:
63
+ pod = StatefulSets.pod_names(sts, namespace)[0]
64
+
65
+ CassandraNodes.exec(pod, namespace, f'rm -rf {csv_dir()}/*', show_out=Config().is_debug(), shell='bash')
66
+ CassandraNodes.exec(pod, namespace, f'rm -rf {log_prefix()}-*.log*', show_out=Config().is_debug(), shell='bash')
67
+
68
+ return True
69
+
70
+ def clean_up_sessions(sts: str, pod: str, namespace: str, sessions: list[str], max_workers = 0):
71
+ if not sessions:
72
+ return []
73
+
74
+ if not max_workers:
75
+ max_workers = Config().action_workers('export', 8)
76
+
77
+ with parallelize(sessions, max_workers, msg='Cleaning|Cleaned up {size} export sessions') as exec:
78
+ cnt_tuples = exec.map(lambda session: ExportSessions.clean_up_session(sts, pod, namespace, session, True))
79
+ csv_cnt = 0
80
+ log_cnt = 0
81
+ for (csv, log) in cnt_tuples:
82
+ csv_cnt += csv
83
+ log_cnt += log
84
+
85
+ return csv_cnt, log_cnt
86
+
87
+ def clean_up_session(sts: str, pod: str, namespace: str, session: str, multi_tables = True):
88
+ if not sts or not namespace:
89
+ return 0, 0
90
+
91
+ if not pod:
92
+ pod = StatefulSets.pod_names(sts, namespace)[0]
93
+
94
+ if not pod:
95
+ return 0, 0
96
+
97
+ csv_cnt = 0
98
+ log_cnt = 0
99
+
100
+ log_files: list[str] = find_files(pod, namespace, f'{log_prefix()}-{session}_*.log*')
101
+
102
+ for log_file in log_files:
103
+ m = re.match(f'{log_prefix()}-{session}_(.*?)\.(.*?)\.log.*', log_file)
104
+ if m:
105
+ table = m.group(2)
106
+
107
+ CassandraNodes.exec(pod, namespace, f'rm -rf {csv_dir()}/{session}_{table}', show_out=not multi_tables, shell='bash')
108
+ csv_cnt += 1
109
+
110
+ CassandraNodes.exec(pod, namespace, f'rm -rf {log_file}', show_out=not multi_tables, shell='bash')
111
+ log_cnt += 1
112
+
113
+ return csv_cnt, log_cnt
114
+
115
+ def disply_export_session(sts: str, pod: str, namespace: str, session: str):
116
+ if not pod:
117
+ pod = StatefulSets.pod_names(sts, namespace)[0]
118
+
119
+ if not pod:
120
+ return
121
+
122
+ tables, _ = ExportTableStatus.from_session(sts, pod, namespace, session)
123
+ log()
124
+ log(lines_to_tabular([f'{table.keyspace}\t{table.table}\t{table.target_table}\t{"export_completed_pending_import" if table.status == "pending_import" else table.status}' for table in tables], header='KEYSPACE\tTABLE\tTARGET_TABLE\tSTATUS', separator='\t'))
@@ -2,8 +2,6 @@ from adam.commands.command import Command
2
2
  from adam.commands.export.export_databases import ExportDatabases
3
3
  from adam.repl_state import ReplState
4
4
  from adam.utils import log2
5
- from adam.utils_athena import Athena
6
- from adam.utils_sqlite import SQLite
7
5
 
8
6
  class ExportUse(Command):
9
7
  COMMAND = 'use'
@@ -36,10 +34,6 @@ class ExportUse(Command):
36
34
  return state
37
35
 
38
36
  state.export_session = args[0]
39
- if state.export_session.startswith('e'):
40
- Athena.clear_cache()
41
- else:
42
- SQLite.clear_cache()
43
37
 
44
38
  ExportDatabases.display_export_db(state.export_session)
45
39
 
@@ -1,21 +1,21 @@
1
1
  from datetime import datetime
2
- import functools
3
- import re
4
2
  import time
5
3
 
4
+ from adam.commands import validate_args
5
+ from adam.commands.command import Command
6
6
  from adam.commands.cql.utils_cql import cassandra_table_names, run_cql, table_spec
7
7
  from adam.commands.export.export_databases import ExportDatabases
8
+ from adam.commands.export.export_sessions import ExportSessions
8
9
  from adam.commands.export.importer import Importer
9
10
  from adam.commands.export.importer_athena import AthenaImporter
10
11
  from adam.commands.export.importer_sqlite import SqliteImporter
11
- from adam.commands.export.utils_export import ExportSpec, ExportTableStatus, ExportTableSpec, ImportSpec, csv_dir, find_files
12
+ from adam.commands.export.utils_export import ExportSpec, ExportTableStatus, ExportTableSpec, ImportSpec, csv_dir, find_files, state_with_pod
12
13
  from adam.config import Config
13
14
  from adam.pod_exec_result import PodExecResult
14
15
  from adam.repl_state import ReplState
15
- from adam.utils import debug, parallelize, log2, ing, log_exc
16
+ from adam.utils import debug, log, parallelize, log2, ing, log_exc
16
17
  from adam.utils_k8s.cassandra_nodes import CassandraNodes
17
18
  from adam.utils_k8s.pods import log_prefix
18
- from adam.utils_k8s.statefulsets import StatefulSets
19
19
 
20
20
  class Exporter:
21
21
  def export_tables(args: list[str], state: ReplState, export_only: bool = False, max_workers = 0) -> tuple[list[str], ExportSpec]:
@@ -211,109 +211,7 @@ class Exporter:
211
211
 
212
212
  def import_from_csv(spec: ExportTableSpec, state: ReplState, session: str, importer: str, table: str, target_table: str, columns: str, multi_tables = True, create_db = False):
213
213
  im = AthenaImporter() if importer == 'athena' else SqliteImporter()
214
- return im.import_from_csv(state.pod, state.namespace, state.export_session, session if session else state.export_session, spec.keyspace, table, target_table, columns, multi_tables, create_db)
215
-
216
- def clear_export_session_cache():
217
- Exporter.find_export_sessions.cache_clear()
218
- Exporter.export_session_names.cache_clear()
219
-
220
- @functools.lru_cache()
221
- def export_session_names(sts: str, pod: str, namespace: str, importer: str = None, export_state = None):
222
- if not sts or not namespace:
223
- return []
224
-
225
- if not pod:
226
- pod = StatefulSets.pod_names(sts, namespace)[0]
227
-
228
- if not pod:
229
- return []
230
-
231
- return [session for session, state in Exporter.find_export_sessions(pod, namespace, importer).items() if not export_state or state == export_state]
232
-
233
- @functools.lru_cache()
234
- def find_export_sessions(pod: str, namespace: str, importer: str = None, limit = 100):
235
- sessions: dict[str, str] = {}
236
-
237
- prefix = Importer.prefix_from_importer(importer)
238
-
239
- log_files: list[str] = find_files(pod, namespace, f'{log_prefix()}-{prefix}*_*.log*')
240
-
241
- if not log_files:
242
- return {}
243
-
244
- for log_file in log_files[:limit]:
245
- m = re.match(f'{log_prefix()}-(.*?)_.*\.log?(.*)', log_file)
246
- if m:
247
- s = m.group(1)
248
- state = m.group(2) # '', '.pending_import', '.done'
249
- if state:
250
- state = state.strip('.')
251
- else:
252
- state = 'in_export'
253
-
254
- if s not in sessions:
255
- sessions[s] = state
256
- elif sessions[s] == 'done' and state != 'done':
257
- sessions[s] = state
258
-
259
- return sessions
260
-
261
- def clean_up_all_sessions(sts: str, pod: str, namespace: str):
262
- if not sts or not namespace:
263
- return False
264
-
265
- if not pod:
266
- pod = StatefulSets.pod_names(sts, namespace)[0]
267
-
268
- CassandraNodes.exec(pod, namespace, f'rm -rf {csv_dir()}/*', show_out=Config().is_debug(), shell='bash')
269
- CassandraNodes.exec(pod, namespace, f'rm -rf {log_prefix()}-*.log*', show_out=Config().is_debug(), shell='bash')
270
-
271
- return True
272
-
273
- def clean_up_sessions(sts: str, pod: str, namespace: str, sessions: list[str], max_workers = 0):
274
- if not sessions:
275
- return []
276
-
277
- if not max_workers:
278
- max_workers = Config().action_workers('export', 8)
279
-
280
- with parallelize(sessions, max_workers, msg='Cleaning|Cleaned up {size} export sessions') as exec:
281
- cnt_tuples = exec.map(lambda session: Exporter.clean_up_session(sts, pod, namespace, session, True))
282
- csv_cnt = 0
283
- log_cnt = 0
284
- for (csv, log) in cnt_tuples:
285
- csv_cnt += csv
286
- log_cnt += log
287
-
288
- return csv_cnt, log_cnt
289
-
290
- def clean_up_session(sts: str, pod: str, namespace: str, session: str, multi_tables = True):
291
- if not sts or not namespace:
292
- return 0, 0
293
-
294
- if not pod:
295
- pod = StatefulSets.pod_names(sts, namespace)[0]
296
-
297
- if not pod:
298
- return 0, 0
299
-
300
- csv_cnt = 0
301
- log_cnt = 0
302
-
303
- log_files: list[str] = find_files(pod, namespace, f'{log_prefix()}-{session}_*.log*')
304
-
305
- for log_file in log_files:
306
- m = re.match(f'{log_prefix()}-{session}_(.*?)\.(.*?)\.log.*', log_file)
307
- if m:
308
- table = m.group(2)
309
-
310
- CassandraNodes.exec(pod, namespace, f'rm -rf {csv_dir()}/{session}_{table}', show_out=not multi_tables, shell='bash')
311
- csv_cnt += 1
312
-
313
- CassandraNodes.exec(pod, namespace, f'rm -rf {log_file}', show_out=not multi_tables, shell='bash')
314
- log_cnt += 1
315
-
316
- return csv_cnt, log_cnt
214
+ return im.import_from_csv(state, session if session else state.export_session, spec.keyspace, table, target_table, columns, multi_tables, create_db)
317
215
 
318
216
  def resove_table_n_columns(spec: ExportTableSpec, state: ReplState, include_ks_in_target = False, importer = 'sqlite'):
319
217
  table = spec.table
@@ -339,15 +237,58 @@ class Exporter:
339
237
 
340
238
  return table, target_table, columns
341
239
 
342
- def drop_databases(sts: str, pod: str, namespace: str, db: str = None):
343
- importer = None
344
- if db:
345
- importer = Importer.importer_from_session(db)
346
-
347
- sessions_done = Exporter.export_session_names(sts, pod, namespace, importer=importer, export_state='done')
348
- sessions = ExportDatabases.sessions_from_dbs(ExportDatabases.drop_export_dbs(db))
349
- if sessions_done and sessions:
350
- intersects = list(set(sessions_done) & set(sessions))
351
- with ing(f'Cleaning up {len(intersects)} completed sessions'):
352
- Exporter.clean_up_sessions(sts, pod, namespace, list(intersects))
353
- Exporter.clear_export_session_cache()
240
+ class ExportService:
241
+ def __init__(self, handler: 'ExporterHandler'):
242
+ self.handler = handler
243
+
244
+ def export(self, args: list[str], export_only=False):
245
+ state = self.handler.state
246
+ export_session = state.export_session
247
+ spec: ExportSpec = None
248
+ try:
249
+ with state_with_pod(state) as state:
250
+ # --export-only for testing only
251
+ statuses, spec = Exporter.export_tables(args, state, export_only=export_only)
252
+ if not statuses:
253
+ return state
254
+
255
+ ExportSessions.clear_export_session_cache()
256
+
257
+ if spec.importer == 'csv' or export_only:
258
+ ExportSessions.disply_export_session(state.sts, state.pod, state.namespace, spec.session)
259
+ else:
260
+ log()
261
+ ExportDatabases.display_export_db(state.export_session)
262
+ finally:
263
+ # if exporting to csv, do not bind the new session id to repl state
264
+ if spec and spec.importer == 'csv':
265
+ state.export_session = export_session
266
+
267
+ return state
268
+
269
+ def import_sesion(self, args: list[str]):
270
+ state = self.handler.state
271
+
272
+ with validate_args(args, state, name='export session') as args_str:
273
+ with state_with_pod(state) as state:
274
+ tables, _ = Exporter.import_session(args_str, state)
275
+ if tables:
276
+ ExportSessions.clear_export_session_cache()
277
+
278
+ log()
279
+ ExportDatabases.display_export_db(state.export_session)
280
+
281
+ return state
282
+
283
+ class ExporterHandler:
284
+ def __init__(self, state: ReplState):
285
+ self.state = state
286
+
287
+ def __enter__(self):
288
+ return ExportService(self)
289
+
290
+ def __exit__(self, exc_type, exc_val, exc_tb):
291
+ return False
292
+
293
+ def export(state: ReplState):
294
+ return ExporterHandler(state)
@@ -1,6 +1,6 @@
1
1
  from adam.commands.command import Command
2
- from adam.commands.export.export_handlers import export
3
- from adam.commands.export.exporter import Exporter
2
+ from adam.commands.export.export_sessions import ExportSessions
3
+ from adam.commands.export.exporter import export
4
4
  from adam.repl_state import ReplState, RequiredState
5
5
 
6
6
  class ImportSession(Command):
@@ -31,8 +31,8 @@ class ImportSession(Command):
31
31
 
32
32
  def completion(self, state: ReplState):
33
33
  # warm up cache
34
- Exporter.export_session_names(state.sts, state.pod, state.namespace)
35
- Exporter.export_session_names(state.sts, state.pod, state.namespace, export_state='pending_import')
34
+ ExportSessions.export_session_names(state.sts, state.pod, state.namespace)
35
+ ExportSessions.export_session_names(state.sts, state.pod, state.namespace, export_state='pending_import')
36
36
 
37
37
  return {}
38
38
 
@@ -2,6 +2,7 @@ from abc import abstractmethod
2
2
 
3
3
  from adam.commands.export.utils_export import csv_dir
4
4
  from adam.config import Config
5
+ from adam.repl_state import ReplState
5
6
  from adam.utils import ing
6
7
  from adam.utils_k8s.cassandra_nodes import CassandraNodes
7
8
  from adam.utils_k8s.pods import log_prefix
@@ -12,10 +13,13 @@ class Importer:
12
13
  pass
13
14
 
14
15
  @abstractmethod
15
- def import_from_csv(self, pod: str, namespace: str, to_session: str, from_session: str, keyspace: str, table: str, target_table: str, columns: str, multi_tables = True, create_db = False):
16
+ def import_from_csv(self, state: ReplState, from_session: str, keyspace: str, table: str, target_table: str, columns: str, multi_tables = True, create_db = False):
16
17
  pass
17
18
 
18
- def move_to_done(self, pod: str, namespace: str, to_session: str, from_session: str, keyspace: str, target_table: str):
19
+ def move_to_done(self, state: ReplState, from_session: str, keyspace: str, target_table: str):
20
+ pod = state.pod
21
+ namespace = state.namespace
22
+ to_session = state.export_session
19
23
  log_file = f'{log_prefix()}-{from_session}_{keyspace}.{target_table}.log.pending_import'
20
24
 
21
25
  to = f'{log_prefix()}-{to_session}_{keyspace}.{target_table}.log.done'
@@ -30,9 +34,12 @@ class Importer:
30
34
 
31
35
  return session
32
36
 
33
- def remove_csv(self, pod: str, namespace: str, session: str, table: str, target_table: str, multi_tables = True):
34
- with ing(f'[{session}] Cleaning up temporary files', suppress_log=multi_tables):
35
- CassandraNodes.exec(pod, namespace, f'rm -rf {self.csv_file(session, table, target_table)}', show_out=Config().is_debug(), shell='bash')
37
+ def remove_csv(self, state: ReplState, from_session: str, table: str, target_table: str, multi_tables = True):
38
+ pod = state.pod
39
+ namespace = state.namespace
40
+
41
+ with ing(f'[{from_session}] Cleaning up temporary files', suppress_log=multi_tables):
42
+ CassandraNodes.exec(pod, namespace, f'rm -rf {self.csv_file(from_session, table, target_table)}', show_out=Config().is_debug(), shell='bash')
36
43
 
37
44
  def db(self, session: str, keyspace: str):
38
45
  return f'{session}_{keyspace}'