gitdata-lib 0.0.17__tar.gz → 0.0.19__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 (66) hide show
  1. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/CHANGELOG.md +13 -0
  2. gitdata_lib-0.0.19/PKG-INFO +248 -0
  3. gitdata_lib-0.0.19/README.md +201 -0
  4. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/__init__.py +1 -1
  5. gitdata_lib-0.0.19/gitdata/__version__.py +1 -0
  6. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/cli/__init__.py +54 -1
  7. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/cli/gitdata_ls.py +3 -2
  8. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/cli/gitdata_scan.py +9 -2
  9. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/common.py +4 -0
  10. gitdata_lib-0.0.19/gitdata/connectors/oracle.py +415 -0
  11. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/tabular.py +36 -2
  12. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/common.py +2 -2
  13. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/sqlite3.py +22 -2
  14. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/utils.py +5 -2
  15. gitdata_lib-0.0.19/gitdata_lib.egg-info/PKG-INFO +248 -0
  16. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata_lib.egg-info/SOURCES.txt +1 -0
  17. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata_lib.egg-info/requires.txt +2 -2
  18. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/requirements.txt +2 -2
  19. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/setup.py +4 -1
  20. gitdata_lib-0.0.17/PKG-INFO +0 -258
  21. gitdata_lib-0.0.17/README.md +0 -214
  22. gitdata_lib-0.0.17/gitdata/__version__.py +0 -1
  23. gitdata_lib-0.0.17/gitdata_lib.egg-info/PKG-INFO +0 -258
  24. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/LICENSE +0 -0
  25. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/MANIFEST.in +0 -0
  26. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/assets/README.md +0 -0
  27. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/buckets.py +0 -0
  28. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/cli/gitdata_get.py +0 -0
  29. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/cli/gitdata_init.py +0 -0
  30. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/cli/gitdata_secrets.py +0 -0
  31. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/config.py +0 -0
  32. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/__init__.py +0 -0
  33. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/fake.py +0 -0
  34. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/gitlab.py +0 -0
  35. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/http.py +0 -0
  36. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/connectors/local.py +0 -0
  37. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/__init__.py +0 -0
  38. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/mysql.py +0 -0
  39. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/mysql_setup.sql +0 -0
  40. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/mysql_setup_test_database.sql +0 -0
  41. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/oracle.py +0 -0
  42. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/postgresql.py +0 -0
  43. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/sqlite3_setup.sql +0 -0
  44. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/database/sqlite3_setup_test_data.sql +0 -0
  45. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/digester.py +0 -0
  46. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/encryption.py +0 -0
  47. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/ext/__init__.py +0 -0
  48. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/ext/connectors/__init__.py +0 -0
  49. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/graphs.py +0 -0
  50. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/inspection.py +0 -0
  51. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/json.py +0 -0
  52. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/queues.py +0 -0
  53. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/repositories.py +0 -0
  54. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/secrets.py +0 -0
  55. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/solutions.py +0 -0
  56. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/sql.py +0 -0
  57. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/stores/__init__.py +0 -0
  58. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/stores/common.py +0 -0
  59. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/stores/entities.py +0 -0
  60. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/stores/facts.py +0 -0
  61. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata/stores/tables.py +0 -0
  62. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata_lib.egg-info/dependency_links.txt +0 -0
  63. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata_lib.egg-info/entry_points.txt +0 -0
  64. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/gitdata_lib.egg-info/top_level.txt +0 -0
  65. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/setup.cfg +0 -0
  66. {gitdata_lib-0.0.17 → gitdata_lib-0.0.19}/tests/test_blob.py +0 -0
@@ -6,6 +6,19 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [v0.0.19] - 2026-09-28
10
+ - add direct `gitdata ls` and `gitdata scan` support for Oracle services and tables
11
+ - show actionable CLI errors for Oracle connection, authentication, service, table, and query failures
12
+ - redact inline URL passwords from debug output and escape terminal control characters in CLI listings
13
+ - show actionable CLI errors for MariaDB/MySQL connection, authentication, and database-selection failures instead of tracebacks
14
+
15
+ ## [v0.0.18] - 2026-09-28
16
+ - support and test Python 3.9 through 3.12
17
+ - replace removed `collections` aliases with `collections.abc`
18
+ - update PostgreSQL and CLI dependencies for Python 3.12
19
+ - register explicit SQLite date and timestamp adapters and converters
20
+ - run pytest-based CI and local test workflows across supported Python versions and database integrations
21
+
9
22
  ## [v0.0.17] - 2026-09-28
10
23
  - add direct `gitdata ls` and streaming `gitdata scan` for CSV, SQLite, and MariaDB refs without digestion or storage
11
24
  - allow `gitdata ls` on a MariaDB server ref to list databases visible to the user
@@ -0,0 +1,248 @@
1
+ Metadata-Version: 2.4
2
+ Name: gitdata-lib
3
+ Version: 0.0.19
4
+ Summary: Data extraction and analysis library
5
+ Home-page: https://github.com/gitdata/gitdata-lib
6
+ Author: DSI Labs
7
+ Author-email: support@gitdata.com
8
+ Classifier: Development Status :: 1 - Planning
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Classifier: Topic :: Database :: Front-Ends
22
+ Requires-Python: >=3.9,<3.13
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: python-decouple>=3.4
26
+ Requires-Dist: Unipath>=1.1
27
+ Requires-Dist: PyMySQL==0.10.1
28
+ Requires-Dist: psycopg2-binary==2.9.10
29
+ Requires-Dist: python-dotenv
30
+ Requires-Dist: requests
31
+ Requires-Dist: docopt-ng<1,>=0.9
32
+ Requires-Dist: faker
33
+ Requires-Dist: cryptography
34
+ Provides-Extra: oracle
35
+ Requires-Dist: oracledb<4,>=1.3; extra == "oracle"
36
+ Dynamic: author
37
+ Dynamic: author-email
38
+ Dynamic: classifier
39
+ Dynamic: description
40
+ Dynamic: description-content-type
41
+ Dynamic: home-page
42
+ Dynamic: license-file
43
+ Dynamic: provides-extra
44
+ Dynamic: requires-dist
45
+ Dynamic: requires-python
46
+ Dynamic: summary
47
+
48
+ # GitData
49
+
50
+ GitData gives you one set of commands for exploring files and databases.
51
+ List what is inside a source with `gitdata ls`, then preview its data with
52
+ `gitdata scan`.
53
+
54
+ ## Install
55
+
56
+ GitData supports Python 3.9 through 3.12.
57
+
58
+ ```bash
59
+ python3 -m pip install gitdata-lib
60
+ ```
61
+
62
+ Oracle support is optional:
63
+
64
+ ```bash
65
+ python3 -m pip install 'gitdata-lib[oracle]'
66
+ ```
67
+
68
+ ## Explore a data source
69
+
70
+ The same two commands work across CSV files, SQLite databases,
71
+ MariaDB/MySQL databases, and Oracle databases:
72
+
73
+ ```bash
74
+ gitdata ls <source>
75
+ gitdata scan <source>
76
+ ```
77
+
78
+ Use `-l` for a detailed listing, `-a` to include system objects, and `--limit`
79
+ to choose how many rows to preview.
80
+
81
+ ## CSV
82
+
83
+ List the columns in a CSV file:
84
+
85
+ ```bash
86
+ gitdata ls examples/locations-headered.csv
87
+ ```
88
+
89
+ Preview its rows:
90
+
91
+ ```bash
92
+ gitdata scan --limit 10 examples/locations-headered.csv
93
+ ```
94
+
95
+ ## SQLite
96
+
97
+ Start with the database file, then move into a table or column:
98
+
99
+ ```bash
100
+ # List tables
101
+ gitdata ls examples/inspection.sqlite
102
+
103
+ # Show table details
104
+ gitdata ls -l examples/inspection.sqlite/customers
105
+
106
+ # Preview rows
107
+ gitdata scan --limit 5 examples/inspection.sqlite/customers
108
+
109
+ # Examine one column
110
+ gitdata scan --limit 5 examples/inspection.sqlite/customers.email
111
+ ```
112
+
113
+ SQLite references follow this shape:
114
+
115
+ ```text
116
+ path/to/database.sqlite
117
+ path/to/database.sqlite/table
118
+ path/to/database.sqlite/table.column
119
+ ```
120
+
121
+ ## MariaDB and MySQL
122
+
123
+ Keep passwords in environment variables instead of putting them in database
124
+ references:
125
+
126
+ ```bash
127
+ export GITDATA_DB_PASSWORD='your-password'
128
+
129
+ SERVER='mysql://user@db.example.com?password_env=GITDATA_DB_PASSWORD'
130
+ DATABASE='mysql://user@db.example.com/sales?password_env=GITDATA_DB_PASSWORD'
131
+ TABLE='mysql://user@db.example.com/sales.orders?password_env=GITDATA_DB_PASSWORD'
132
+ ```
133
+
134
+ Explore the server, database, and table with the same commands:
135
+
136
+ ```bash
137
+ # List databases
138
+ gitdata ls "$SERVER"
139
+
140
+ # List tables
141
+ gitdata ls "$DATABASE"
142
+
143
+ # Show columns and indexes
144
+ gitdata ls -l "$TABLE"
145
+
146
+ # Preview rows
147
+ gitdata scan --limit 10 "$TABLE"
148
+ ```
149
+
150
+ MariaDB/MySQL references follow this shape:
151
+
152
+ ```text
153
+ mysql://user@host
154
+ mysql://user@host/database
155
+ mysql://user@host/database.table
156
+ ```
157
+
158
+ If the username is omitted, GitData uses the current operating-system username.
159
+ Use `gitdata ls -a` when you also want to see system databases or tables.
160
+
161
+ ### Try the included MariaDB example
162
+
163
+ The repository includes `examples/mariadb.sql`. Load it into a disposable
164
+ MariaDB container:
165
+
166
+ ```bash
167
+ docker run --name gitdata-example-mariadb \
168
+ -e MARIADB_ROOT_PASSWORD=example \
169
+ -p 3307:3306 \
170
+ -d mariadb:10.7
171
+
172
+ until docker exec gitdata-example-mariadb \
173
+ mariadb-admin ping -h 127.0.0.1 -uroot -pexample --silent
174
+ do
175
+ sleep 1
176
+ done
177
+
178
+ docker exec -i gitdata-example-mariadb \
179
+ mariadb -uroot -pexample < examples/mariadb.sql
180
+
181
+ export GITDATA_EXAMPLE_PASSWORD=example
182
+ gitdata ls 'mysql://root@127.0.0.1:3307/gitdata_example?password_env=GITDATA_EXAMPLE_PASSWORD'
183
+ gitdata scan --limit 5 'mysql://root@127.0.0.1:3307/gitdata_example.customers?password_env=GITDATA_EXAMPLE_PASSWORD'
184
+ ```
185
+
186
+ Remove the example when finished:
187
+
188
+ ```bash
189
+ docker rm -f gitdata-example-mariadb
190
+ ```
191
+
192
+ ## Command reference
193
+
194
+ ```text
195
+ gitdata ls <source> list databases, tables, or columns
196
+ gitdata ls -l <source> show a detailed listing
197
+ gitdata ls -a <source> include system objects
198
+ gitdata scan <source> preview and profile data
199
+ gitdata scan --limit N ... preview at most N rows
200
+ ```
201
+
202
+ Run a command with `--help` for all options:
203
+
204
+ ```bash
205
+ gitdata ls --help
206
+ gitdata scan --help
207
+ ```
208
+
209
+ ## Oracle
210
+
211
+ Install the optional Oracle driver, then keep the password in an environment
212
+ variable:
213
+
214
+ ```bash
215
+ python3 -m pip install 'gitdata-lib[oracle]'
216
+ export ORACLE_PASSWORD='your-password'
217
+
218
+ DATABASE='oracle://app@db.example.com:1521/FREEPDB1?password_env=ORACLE_PASSWORD'
219
+ TABLE="${DATABASE}#orders"
220
+ ```
221
+
222
+ Explore the service and its tables with the same commands:
223
+
224
+ ```bash
225
+ # List tables owned by the connected user
226
+ gitdata ls "$DATABASE"
227
+
228
+ # Show table counts and sizes
229
+ gitdata ls -l "$DATABASE"
230
+
231
+ # Show column details
232
+ gitdata ls -l "$TABLE"
233
+
234
+ # Preview rows
235
+ gitdata scan --limit 10 "$TABLE"
236
+ ```
237
+
238
+ Oracle references follow this shape:
239
+
240
+ ```text
241
+ oracle://user@host:port/service?password_env=ENVIRONMENT_VARIABLE
242
+ oracle://user@host:port/service?password_env=ENVIRONMENT_VARIABLE#table
243
+ ```
244
+
245
+ Inline passwords are not accepted. Ordinary Oracle table and column names are
246
+ shown in lowercase. Quoted identifiers are shown with their double quotes so
247
+ names that differ only by Oracle quoting remain distinct; use the displayed
248
+ spelling after `#` when selecting one (the quotes may be URL-encoded as `%22`).
@@ -0,0 +1,201 @@
1
+ # GitData
2
+
3
+ GitData gives you one set of commands for exploring files and databases.
4
+ List what is inside a source with `gitdata ls`, then preview its data with
5
+ `gitdata scan`.
6
+
7
+ ## Install
8
+
9
+ GitData supports Python 3.9 through 3.12.
10
+
11
+ ```bash
12
+ python3 -m pip install gitdata-lib
13
+ ```
14
+
15
+ Oracle support is optional:
16
+
17
+ ```bash
18
+ python3 -m pip install 'gitdata-lib[oracle]'
19
+ ```
20
+
21
+ ## Explore a data source
22
+
23
+ The same two commands work across CSV files, SQLite databases,
24
+ MariaDB/MySQL databases, and Oracle databases:
25
+
26
+ ```bash
27
+ gitdata ls <source>
28
+ gitdata scan <source>
29
+ ```
30
+
31
+ Use `-l` for a detailed listing, `-a` to include system objects, and `--limit`
32
+ to choose how many rows to preview.
33
+
34
+ ## CSV
35
+
36
+ List the columns in a CSV file:
37
+
38
+ ```bash
39
+ gitdata ls examples/locations-headered.csv
40
+ ```
41
+
42
+ Preview its rows:
43
+
44
+ ```bash
45
+ gitdata scan --limit 10 examples/locations-headered.csv
46
+ ```
47
+
48
+ ## SQLite
49
+
50
+ Start with the database file, then move into a table or column:
51
+
52
+ ```bash
53
+ # List tables
54
+ gitdata ls examples/inspection.sqlite
55
+
56
+ # Show table details
57
+ gitdata ls -l examples/inspection.sqlite/customers
58
+
59
+ # Preview rows
60
+ gitdata scan --limit 5 examples/inspection.sqlite/customers
61
+
62
+ # Examine one column
63
+ gitdata scan --limit 5 examples/inspection.sqlite/customers.email
64
+ ```
65
+
66
+ SQLite references follow this shape:
67
+
68
+ ```text
69
+ path/to/database.sqlite
70
+ path/to/database.sqlite/table
71
+ path/to/database.sqlite/table.column
72
+ ```
73
+
74
+ ## MariaDB and MySQL
75
+
76
+ Keep passwords in environment variables instead of putting them in database
77
+ references:
78
+
79
+ ```bash
80
+ export GITDATA_DB_PASSWORD='your-password'
81
+
82
+ SERVER='mysql://user@db.example.com?password_env=GITDATA_DB_PASSWORD'
83
+ DATABASE='mysql://user@db.example.com/sales?password_env=GITDATA_DB_PASSWORD'
84
+ TABLE='mysql://user@db.example.com/sales.orders?password_env=GITDATA_DB_PASSWORD'
85
+ ```
86
+
87
+ Explore the server, database, and table with the same commands:
88
+
89
+ ```bash
90
+ # List databases
91
+ gitdata ls "$SERVER"
92
+
93
+ # List tables
94
+ gitdata ls "$DATABASE"
95
+
96
+ # Show columns and indexes
97
+ gitdata ls -l "$TABLE"
98
+
99
+ # Preview rows
100
+ gitdata scan --limit 10 "$TABLE"
101
+ ```
102
+
103
+ MariaDB/MySQL references follow this shape:
104
+
105
+ ```text
106
+ mysql://user@host
107
+ mysql://user@host/database
108
+ mysql://user@host/database.table
109
+ ```
110
+
111
+ If the username is omitted, GitData uses the current operating-system username.
112
+ Use `gitdata ls -a` when you also want to see system databases or tables.
113
+
114
+ ### Try the included MariaDB example
115
+
116
+ The repository includes `examples/mariadb.sql`. Load it into a disposable
117
+ MariaDB container:
118
+
119
+ ```bash
120
+ docker run --name gitdata-example-mariadb \
121
+ -e MARIADB_ROOT_PASSWORD=example \
122
+ -p 3307:3306 \
123
+ -d mariadb:10.7
124
+
125
+ until docker exec gitdata-example-mariadb \
126
+ mariadb-admin ping -h 127.0.0.1 -uroot -pexample --silent
127
+ do
128
+ sleep 1
129
+ done
130
+
131
+ docker exec -i gitdata-example-mariadb \
132
+ mariadb -uroot -pexample < examples/mariadb.sql
133
+
134
+ export GITDATA_EXAMPLE_PASSWORD=example
135
+ gitdata ls 'mysql://root@127.0.0.1:3307/gitdata_example?password_env=GITDATA_EXAMPLE_PASSWORD'
136
+ gitdata scan --limit 5 'mysql://root@127.0.0.1:3307/gitdata_example.customers?password_env=GITDATA_EXAMPLE_PASSWORD'
137
+ ```
138
+
139
+ Remove the example when finished:
140
+
141
+ ```bash
142
+ docker rm -f gitdata-example-mariadb
143
+ ```
144
+
145
+ ## Command reference
146
+
147
+ ```text
148
+ gitdata ls <source> list databases, tables, or columns
149
+ gitdata ls -l <source> show a detailed listing
150
+ gitdata ls -a <source> include system objects
151
+ gitdata scan <source> preview and profile data
152
+ gitdata scan --limit N ... preview at most N rows
153
+ ```
154
+
155
+ Run a command with `--help` for all options:
156
+
157
+ ```bash
158
+ gitdata ls --help
159
+ gitdata scan --help
160
+ ```
161
+
162
+ ## Oracle
163
+
164
+ Install the optional Oracle driver, then keep the password in an environment
165
+ variable:
166
+
167
+ ```bash
168
+ python3 -m pip install 'gitdata-lib[oracle]'
169
+ export ORACLE_PASSWORD='your-password'
170
+
171
+ DATABASE='oracle://app@db.example.com:1521/FREEPDB1?password_env=ORACLE_PASSWORD'
172
+ TABLE="${DATABASE}#orders"
173
+ ```
174
+
175
+ Explore the service and its tables with the same commands:
176
+
177
+ ```bash
178
+ # List tables owned by the connected user
179
+ gitdata ls "$DATABASE"
180
+
181
+ # Show table counts and sizes
182
+ gitdata ls -l "$DATABASE"
183
+
184
+ # Show column details
185
+ gitdata ls -l "$TABLE"
186
+
187
+ # Preview rows
188
+ gitdata scan --limit 10 "$TABLE"
189
+ ```
190
+
191
+ Oracle references follow this shape:
192
+
193
+ ```text
194
+ oracle://user@host:port/service?password_env=ENVIRONMENT_VARIABLE
195
+ oracle://user@host:port/service?password_env=ENVIRONMENT_VARIABLE#table
196
+ ```
197
+
198
+ Inline passwords are not accepted. Ordinary Oracle table and column names are
199
+ shown in lowercase. Quoted identifiers are shown with their double quotes so
200
+ names that differ only by Oracle quoting remain distinct; use the displayed
201
+ spelling after `#` when selecting one (the quotes may be URL-encoded as `%22`).
@@ -1,4 +1,4 @@
1
- """
1
+ r"""
2
2
  ____ _ _ ____ _
3
3
  / ___(_) |_| _ \ __ _| |_ __ _
4
4
  | | _| | __| | | |/ _` | __/ _` |
@@ -0,0 +1 @@
1
+ __version__ = '0.0.19'
@@ -24,12 +24,62 @@ import sys
24
24
  from docopt import docopt
25
25
 
26
26
  import gitdata
27
+ from gitdata.connectors.common import ConnectorError
27
28
  from gitdata.utils import trim
28
29
 
29
30
 
30
31
  root_logger = logging.getLogger()
31
32
 
32
33
 
34
+ def _redact_inline_url_password(value):
35
+ scheme_end = value.find('://')
36
+ if scheme_end < 1:
37
+ return value
38
+ authority_start = scheme_end + 3
39
+ separators = [
40
+ position for position in (
41
+ value.find('/', authority_start),
42
+ value.find('?', authority_start),
43
+ value.find('#', authority_start),
44
+ )
45
+ if position >= 0
46
+ ]
47
+ authority_end = min(separators) if separators else len(value)
48
+ authority = value[authority_start:authority_end]
49
+ at = authority.rfind('@')
50
+ colon = authority.find(':')
51
+ if at < 0 or colon < 0 or colon > at:
52
+ return value
53
+ redacted = authority[:colon + 1] + '***' + authority[at:]
54
+ return value[:authority_start] + redacted + value[authority_end:]
55
+
56
+
57
+ def _redact_debug_value(value):
58
+ """Remove URL passwords before rendering parsed debug arguments."""
59
+ if isinstance(value, str):
60
+ return _redact_inline_url_password(value)
61
+ if isinstance(value, list):
62
+ return [_redact_debug_value(item) for item in value]
63
+ if isinstance(value, tuple):
64
+ return tuple(_redact_debug_value(item) for item in value)
65
+ if isinstance(value, dict):
66
+ return {
67
+ key: _redact_debug_value(item)
68
+ for key, item in value.items()
69
+ }
70
+ return value
71
+
72
+
73
+ def terminal_text(value):
74
+ """Render text without terminal control characters."""
75
+ return ''.join(
76
+ character
77
+ if character.isprintable()
78
+ else character.encode('unicode_escape').decode('ascii')
79
+ for character in str(value)
80
+ )
81
+
82
+
33
83
  def print_help(doc):
34
84
  """Print help text"""
35
85
  print(trim(doc))
@@ -53,6 +103,9 @@ def main():
53
103
  except KeyboardInterrupt:
54
104
  print('\nInterrupted.', file=sys.stderr)
55
105
  raise SystemExit(130)
106
+ except ConnectorError as error:
107
+ print('gitdata: {}'.format(error), file=sys.stderr)
108
+ raise SystemExit(1)
56
109
 
57
110
 
58
111
  def _main():
@@ -69,7 +122,7 @@ def _main():
69
122
  )
70
123
 
71
124
  if args['--debug']:
72
- print(args)
125
+ print(_redact_debug_value(args))
73
126
  root_logger.setLevel(logging.DEBUG)
74
127
 
75
128
  argv = [args['<command>']] + args['<args>']
@@ -7,6 +7,7 @@ options:
7
7
  -h, --help show help
8
8
  """
9
9
 
10
+ from gitdata.cli import terminal_text
10
11
  from gitdata.connectors import fetch
11
12
  from gitdata.inspection import list_items
12
13
 
@@ -35,7 +36,7 @@ def _display(value):
35
36
  return '-'
36
37
  if isinstance(value, int):
37
38
  return '{:,}'.format(value)
38
- return str(value)
39
+ return terminal_text(value)
39
40
 
40
41
 
41
42
  def _row(values, widths):
@@ -81,4 +82,4 @@ def ls_to_console(args):
81
82
  _print_verbose(root, items)
82
83
  return
83
84
  for item in items:
84
- print(item['name'])
85
+ print(terminal_text(item['name']))
@@ -12,6 +12,7 @@ from decimal import Decimal
12
12
  import shutil
13
13
  import sys
14
14
 
15
+ from gitdata.cli import terminal_text
15
16
  from gitdata.connectors import fetch
16
17
  from gitdata.inspection import scan
17
18
 
@@ -31,7 +32,12 @@ def _title(report):
31
32
  )
32
33
  row_label = 'row' if row_label_count == 1 else 'rows'
33
34
  return '{}: {:,} {}, {} {}{}'.format(
34
- report['name'], columns, column_label, rows, row_label, sampled
35
+ terminal_text(report['name']),
36
+ columns,
37
+ column_label,
38
+ rows,
39
+ row_label,
40
+ sampled,
35
41
  )
36
42
 
37
43
 
@@ -48,6 +54,7 @@ def _format_value(value):
48
54
  text = '{:%Y-%m-%d}'.format(value)
49
55
  else:
50
56
  text = str(value)
57
+ text = terminal_text(text)
51
58
  if len(text) > 12:
52
59
  return text[:12] + '...'
53
60
  return text
@@ -81,7 +88,7 @@ def _column_widths():
81
88
 
82
89
 
83
90
  def _cell(value, width, right=False):
84
- text = str(value)
91
+ text = terminal_text(value)
85
92
  if len(text) > width:
86
93
  half = round(width / 2)
87
94
  text = (text[:half - 2] + ' ... ' + text[-half + 3:])[:width]
@@ -98,6 +98,10 @@ def explore(node, destination):
98
98
  # yield a, b
99
99
 
100
100
 
101
+ class ConnectorError(Exception):
102
+ """Raised when a Connector cannot complete an expected operation."""
103
+
104
+
101
105
  class UnsupportedRef(ValueError):
102
106
  """Raised when no Connector can resolve a ref."""
103
107