vortex-cli 4.13.1__tar.gz → 4.14.0__tar.gz

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 (41) hide show
  1. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/PKG-INFO +1 -2
  2. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/setup.cfg +2 -2
  3. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/cli.py +31 -14
  4. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/clone.py +8 -1
  5. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/db.py +53 -21
  6. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/list.py +9 -2
  7. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/main.py +4 -3
  8. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/models.py +5 -0
  9. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex_cli.egg-info/PKG-INFO +1 -2
  10. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/LICENSE +0 -0
  11. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/README.md +0 -0
  12. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/setup.py +0 -0
  13. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/__init__.py +0 -0
  14. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/__main__.py +0 -0
  15. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/colour.py +0 -0
  16. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/__init__.py +0 -0
  17. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/clean.py +0 -0
  18. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/code.py +0 -0
  19. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/config.py +0 -0
  20. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/copy.py +0 -0
  21. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/delete.py +0 -0
  22. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/docs.py +0 -0
  23. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/execute.py +0 -0
  24. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/find.py +0 -0
  25. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/grep.py +0 -0
  26. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/log.py +0 -0
  27. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/new.py +0 -0
  28. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/commands/watch.py +0 -0
  29. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/constants.py +0 -0
  30. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/docs/Blackbook.pdf +0 -0
  31. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/lib/puakma.jar +0 -0
  32. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/logging.py +0 -0
  33. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/soap.py +0 -0
  34. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/spinner.py +0 -0
  35. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/util.py +0 -0
  36. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex/workspace.py +0 -0
  37. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex_cli.egg-info/SOURCES.txt +0 -0
  38. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex_cli.egg-info/dependency_links.txt +0 -0
  39. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex_cli.egg-info/entry_points.txt +0 -0
  40. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex_cli.egg-info/requires.txt +0 -0
  41. {vortex_cli-4.13.1 → vortex_cli-4.14.0}/vortex_cli.egg-info/top_level.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vortex_cli
3
- Version: 4.13.1
4
- Summary: Vortex CLI
3
+ Version: 4.14.0
5
4
  Home-page: https://github.com/jordanamos/vortex-cli
6
5
  Author: Jordan Amos
7
6
  Author-email: jordan.amos@gmail.com
@@ -1,7 +1,6 @@
1
1
  [metadata]
2
2
  name = vortex_cli
3
- version = 4.13.1
4
- description = Vortex CLI
3
+ version = 4.14.0
5
4
  long_description = file: README.md
6
5
  long_description_content_type = text/markdown
7
6
  url = https://github.com/jordanamos/vortex-cli
@@ -18,6 +17,7 @@ classifiers =
18
17
  Programming Language :: Python :: 3
19
18
  Programming Language :: Python :: 3 :: Only
20
19
  keywords = vortex cli
20
+ vdescription = Vortex CLI
21
21
 
22
22
  [options]
23
23
  packages = find:
@@ -71,6 +71,7 @@ def validate_args(
71
71
  args: Namespace,
72
72
  new_parser: ArgumentParser,
73
73
  clone_parser: ArgumentParser,
74
+ db_parser: ArgumentParser,
74
75
  ) -> None:
75
76
  if args.command == "new" and args.subcommand == "object":
76
77
  missing_required_fields = not args.update_id and not (
@@ -103,13 +104,18 @@ def validate_args(
103
104
  elif update_arg_contains_app_id:
104
105
  msg = "Can't use --app-id with --update"
105
106
  elif update_is_missing_args:
106
- msg = "Please spectify an option to update"
107
+ msg = "Please specify an option to update"
107
108
 
108
109
  if msg:
109
110
  new_parser.error(msg)
110
111
 
111
112
  elif args.command == "clone" and not (args.app_ids or args.reclone):
112
- clone_parser.error("Please specifiy the APP_ID[s] to clone or use --reclone")
113
+ clone_parser.error("Please specifiy the APP_ID[s] to clone or use '--reclone'")
114
+ elif args.command == "db":
115
+ if args.sql and not args.conn_id:
116
+ db_parser.error("The '--sql' option requires '--connection-id'")
117
+ if (args.schema or args.list) and not args.db_name:
118
+ db_parser.error("Options '--schema' and '--list' require '--db-name'")
113
119
 
114
120
 
115
121
  def add_code_parser(
@@ -198,9 +204,10 @@ def add_list_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
198
204
  action="store_true",
199
205
  )
200
206
  list_parser.add_argument(
201
- "--show-connections",
207
+ "--connections",
202
208
  help="List the Database Connections of locally cloned apps",
203
209
  action="store_true",
210
+ dest="show_connections",
204
211
  )
205
212
  _add_server_option(list_parser)
206
213
 
@@ -514,16 +521,9 @@ def add_delete_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None
514
521
  _add_server_option(delete_parser)
515
522
 
516
523
 
517
- def add_db_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
518
- db_parser = command_parser.add_parser(
519
- "db", help="Interact with Database Connections"
520
- )
521
- db_parser.add_argument(
522
- "connection_id",
523
- metavar="CONNECTION_ID",
524
- type=int,
525
- help="The Database Connection ID",
526
- )
524
+ def add_db_parser(command_parser: _SubParsersAction[ArgumentParser]) -> ArgumentParser:
525
+ db_parser = command_parser.add_parser("db", help="Interact with Databases")
526
+
527
527
  db_mutex = db_parser.add_mutually_exclusive_group(required=True)
528
528
  db_mutex.add_argument("--sql", help="Execute a given SQL query")
529
529
  db_mutex.add_argument(
@@ -537,7 +537,24 @@ def add_db_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
537
537
  action="store_true",
538
538
  help="List the tables in the Database",
539
539
  )
540
+ list_schema_group = db_parser.add_argument_group("List/Schema Options")
541
+ list_schema_group.add_argument(
542
+ "--db-name",
543
+ "--name",
544
+ "-n",
545
+ metavar="DB_NAME",
546
+ dest="db_name",
547
+ help="The Database Name.",
548
+ )
540
549
  sql_group = db_parser.add_argument_group("SQL Options")
550
+ sql_group.add_argument(
551
+ "--connection-id",
552
+ "--id",
553
+ metavar="INT",
554
+ dest="conn_id",
555
+ type=int,
556
+ help="The Database Connection ID to query. (Required for SQL)",
557
+ )
541
558
  sql_group.add_argument(
542
559
  "--update",
543
560
  "-u",
@@ -552,7 +569,6 @@ def add_db_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
552
569
  )
553
570
  sql_group.add_argument(
554
571
  "--limit",
555
- "-n",
556
572
  metavar="INT",
557
573
  type=_check_int_in_range,
558
574
  help=(
@@ -563,6 +579,7 @@ def add_db_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
563
579
  ),
564
580
  default=5,
565
581
  )
582
+ return db_parser
566
583
 
567
584
 
568
585
  def add_docs_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
@@ -122,8 +122,15 @@ def _parse_app_xml(
122
122
  db_connections: list[DatabaseConnection] = []
123
123
  for db_ele in app_xml.findall(".//database"):
124
124
  db_conn = DatabaseConnection(
125
- int(db_ele.attrib["id"]), db_ele.attrib["name"].lower()
125
+ int(db_ele.attrib["id"]),
126
+ db_ele.attrib["name"],
127
+ db_ele.attrib["dbName"],
128
+ db_ele.attrib["driver"],
129
+ db_ele.attrib["url"],
130
+ db_ele.attrib["userName"],
131
+ db_ele.attrib["pwd"],
126
132
  )
133
+ # print(db_ele.attrib)
127
134
  db_connections.append(db_conn)
128
135
 
129
136
  java_version_ele = app_xml.find('.//sysProp[@name="java.class.version"]')
@@ -38,9 +38,14 @@ def _output_result(
38
38
  sql: str,
39
39
  update: bool,
40
40
  truncate_cols: bool = False,
41
- ) -> None:
41
+ db_name: str | None = None,
42
+ schema_table: str | None = None,
43
+ ) -> int:
42
44
  with server:
43
45
  result = tuple(server.database_designer.execute_query(conn_id, sql, update))
46
+ if schema_table and not result:
47
+ logger.error(f"Table '{schema_table}' not found in database '{db_name}'")
48
+ return 1
44
49
  if result:
45
50
  if truncate_cols:
46
51
  result = _truncate_cols(result)
@@ -55,9 +60,10 @@ def _output_result(
55
60
  )
56
61
  else:
57
62
  logger.info("Query returned nil results.")
63
+ return 0
58
64
 
59
65
 
60
- def _check_connection_is_cloned(workspace: Workspace, conn_id: int) -> bool:
66
+ def _is_connection_cloned(workspace: Workspace, conn_id: int) -> bool:
61
67
  """Returns True if the given conn_id exists in a locally cloned Application."""
62
68
  conns: list[DatabaseConnection] = []
63
69
  for app in workspace.listapps():
@@ -69,7 +75,8 @@ def _check_connection_is_cloned(workspace: Workspace, conn_id: int) -> bool:
69
75
  def db(
70
76
  workspace: Workspace,
71
77
  server: PuakmaServer,
72
- conn_id: int,
78
+ conn_id: int | None,
79
+ db_name: str | None,
73
80
  sql: str | None,
74
81
  update: bool = False,
75
82
  limit_n_results: int = 5,
@@ -77,21 +84,45 @@ def db(
77
84
  list_tables: bool = False,
78
85
  truncate_cols: bool = False,
79
86
  ) -> int:
80
- if schema_table is not None:
87
+ do_schema = schema_table is not None
88
+ db_name = db_name or ""
89
+ conn_id = conn_id or -1
90
+ if do_schema:
81
91
  sql = f"""\
82
- SELECT attributename AS name
83
- , type
84
- , typesize AS type_size
92
+ SELECT DISTINCT
93
+ CASE
94
+ WHEN isprimarykey = '1'
95
+ THEN 'PK'
96
+ ELSE ''
97
+ END AS "PK"
98
+ , attributename AS "Attribute"
99
+ , CASE WHEN ref.tableid > 0
100
+ THEN UPPER(ref.tablename)
101
+ ELSE ''
102
+ END AS "References"
103
+ , CASE WHEN type IN ('VARCHAR', 'CHAR')
104
+ THEN CONCAT(type, ' (', typesize, ')')
105
+ ELSE type
106
+ END AS "Type"
107
+ , CASE
108
+ WHEN isunique = '1'
109
+ THEN 'Yes'
110
+ ELSE 'No'
111
+ END AS "Unique"
85
112
  , CASE
86
113
  WHEN allownull = '1'
87
- THEN 'Y'
88
- ELSE 'N'
89
- END AS nullable
114
+ THEN 'Yes'
115
+ ELSE 'No'
116
+ END AS "Allow Null"
90
117
  FROM attribute a
91
118
  INNER JOIN pmatable t
92
119
  ON t.tableid = a.tableid
93
- WHERE dbconnectionid = {conn_id}
94
- AND lower(tablename) = '{schema_table}'
120
+ INNER JOIN dbconnection db
121
+ ON db.dbconnectionid = t.dbconnectionid
122
+ LEFT JOIN pmatable ref
123
+ ON ref.tableid::VARCHAR = a.reftable
124
+ WHERE LOWER(db.dbname) = '{db_name.lower()}'
125
+ AND LOWER(t.tablename) = '{schema_table}'
95
126
  ORDER BY attributename
96
127
  """
97
128
  update = False
@@ -99,11 +130,12 @@ def db(
99
130
  conn_id = server.puakma_db_conn_id
100
131
  elif list_tables:
101
132
  sql = f"""\
102
- SELECT tablename
133
+ SELECT DISTINCT tablename
103
134
  , description
104
- FROM pmatable a
105
- WHERE dbconnectionid = {conn_id}
106
- ORDER BY tablename
135
+ FROM dbconnection db
136
+ INNER JOIN pmatable t
137
+ ON db.dbconnectionid = t.dbconnectionid
138
+ WHERE LOWER(db.dbname)='{db_name.lower()}'
107
139
  """
108
140
  update = False
109
141
  truncate_cols = False
@@ -111,8 +143,8 @@ def db(
111
143
  elif sql is not None:
112
144
  # If we're modifying a database, lets check that its locally
113
145
  # cloned to ensure intent
114
- if update and not _check_connection_is_cloned(workspace, conn_id):
115
- logger.error(f"No cloned applications with DB Connection '{conn_id}'")
146
+ if not _is_connection_cloned(workspace, conn_id):
147
+ logger.error(f"No cloned applications with DB Connection ID '{conn_id}'")
116
148
  return 1
117
149
  if not update:
118
150
  sql = sql + f" LIMIT {limit_n_results}"
@@ -120,6 +152,6 @@ def db(
120
152
  if sql is None:
121
153
  raise ValueError("No Query to execute.")
122
154
 
123
- _output_result(server, conn_id, sql, update, truncate_cols)
124
-
125
- return 0
155
+ return _output_result(
156
+ server, conn_id, sql, update, truncate_cols, db_name, schema_table
157
+ )
@@ -63,12 +63,19 @@ def list_(
63
63
 
64
64
 
65
65
  def _render_db_connections(apps: list[PuakmaApplication]) -> None:
66
- row_headers = ["ID", "Connection Name", "Application"]
66
+ row_headers = ["ID", "Name", "DB Name", "Driver", "URL", "Application"]
67
67
  row_data = []
68
68
  for app in sorted(apps, key=lambda x: (x.group.casefold(), x.name.casefold())):
69
69
  if app.db_connections:
70
70
  for conn in app.db_connections:
71
- row = (conn.id, conn.name, str(app))
71
+ row = (
72
+ conn.id,
73
+ conn.name,
74
+ conn.db_name,
75
+ conn.driver,
76
+ conn.url,
77
+ str(app),
78
+ )
72
79
  row_data.append(row)
73
80
  print(tabulate.tabulate(row_data, headers=row_headers))
74
81
 
@@ -92,11 +92,11 @@ def main(argv: Sequence[str] | None = None) -> int:
92
92
  cli.add_grep_parser(command_parser)
93
93
  cli.add_log_parser(command_parser)
94
94
  cli.add_watch_parser(command_parser)
95
- cli.add_db_parser(command_parser)
96
95
  cli.add_docs_parser(command_parser)
97
96
  cli.add_execute_parser(command_parser)
98
97
  clone_parser = cli.add_clone_parser(command_parser)
99
98
  code_parser = cli.add_code_parser(command_parser)
99
+ db_parser = cli.add_db_parser(command_parser)
100
100
  new_parser = cli.add_new_parser(command_parser)
101
101
 
102
102
  args, remaining_args = parser.parse_known_args(argv)
@@ -104,7 +104,7 @@ def main(argv: Sequence[str] | None = None) -> int:
104
104
  if args.command != "code":
105
105
  parser.parse_args(argv)
106
106
 
107
- cli.validate_args(args, new_parser, clone_parser)
107
+ cli.validate_args(args, new_parser, clone_parser, db_parser)
108
108
 
109
109
  if args.no_colour:
110
110
  Colour.disable()
@@ -230,7 +230,8 @@ def main(argv: Sequence[str] | None = None) -> int:
230
230
  return db(
231
231
  workspace,
232
232
  server,
233
- args.connection_id,
233
+ args.conn_id,
234
+ args.db_name,
234
235
  args.sql,
235
236
  update=args.update,
236
237
  limit_n_results=args.limit,
@@ -120,6 +120,11 @@ class LogItem(NamedTuple):
120
120
  class DatabaseConnection(NamedTuple):
121
121
  id: int
122
122
  name: str
123
+ db_name: str
124
+ driver: str
125
+ url: str
126
+ username: str
127
+ password: str
123
128
 
124
129
 
125
130
  class PuakmaServer:
@@ -1,7 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vortex_cli
3
- Version: 4.13.1
4
- Summary: Vortex CLI
3
+ Version: 4.14.0
5
4
  Home-page: https://github.com/jordanamos/vortex-cli
6
5
  Author: Jordan Amos
7
6
  Author-email: jordan.amos@gmail.com
File without changes
File without changes
File without changes
File without changes
File without changes