diff options
-rw-r--r-- | .git-blame-ignore-revs | 2 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 44 | ||||
-rw-r--r-- | .pre-commit-config.yaml | 2 | ||||
-rw-r--r-- | .travis.yml | 29 | ||||
-rw-r--r-- | CHANGELOG.md | 9 | ||||
-rw-r--r-- | litecli/__init__.py | 2 | ||||
-rw-r--r-- | litecli/liteclirc | 1 | ||||
-rw-r--r-- | litecli/main.py | 4 | ||||
-rw-r--r-- | litecli/packages/parseutils.py | 2 | ||||
-rw-r--r-- | litecli/packages/special/iocommands.py | 3 | ||||
-rw-r--r-- | litecli/sqlexecute.py | 1 | ||||
-rw-r--r-- | requirements-dev.txt | 1 | ||||
-rw-r--r-- | tasks.py | 4 | ||||
-rw-r--r-- | tests/liteclirc | 1 | ||||
-rw-r--r-- | tests/test_completion_engine.py | 4 | ||||
-rw-r--r-- | tests/test_smart_completion_public_schema_only.py | 20 | ||||
-rw-r--r-- | tests/test_sqlexecute.py | 19 |
17 files changed, 95 insertions, 53 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..c433202 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Black +f767afc80bd5bcc8f1b1cc1a134babc2dec4d239
\ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..372fbbb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,44 @@ +name: litecli + +on: + pull_request: + paths-ignore: + - '**.md' + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install requirements + run: | + python -m pip install -U pip setuptools + pip install --no-cache-dir -e . + pip install -r requirements-dev.txt -U --upgrade-strategy=only-if-needed + + - name: Run unit tests + env: + PYTEST_PASSWORD: root + run: | + ./setup.py test --pytest-args="--cov-report= --cov=litecli" + + - name: Run Black + run: | + ./setup.py lint + if: matrix.python-version == '3.6' + + - name: Coverage + run: | + coverage report + codecov diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b268b62..be3886f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/ambv/black - rev: stable + rev: 20.8b1 hooks: - id: black language_version: python3.7 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 896e7f7..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: python -python: - - "3.6" - -matrix: - include: - - python: 3.7 - dist: xenial - sudo: true - -install: - - pip install -r requirements-dev.txt - - if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then pip install black; fi - - pip install -e . - -script: - - ./setup.py test --pytest-args="--cov-report= --cov=litecli" - - coverage report - - if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then ./setup.py lint; fi - -after_success: - - codecov - -notifications: - webhooks: - urls: - - YOUR_WEBHOOK_URL - on_success: change # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always diff --git a/CHANGELOG.md b/CHANGELOG.md index ec98b08..d170c9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,23 @@ ## Unreleased - TBD -<!-- add upcoming change notes here --> +### Features + +### Bug Fixes + + +## 1.6.0 - 2021-03-15 ### Features - Add verbose feature to `favorite_query` command. (Thanks: [Zhaolong Zhu]) - `\f query` does not show the full SQL. - `\f+ query` shows the full SQL. +- Add prompt format of file's basename. (Thanks: [elig0n]) ### Bug Fixes - Fix compatibility with sqlparse >= 0.4.0. (Thanks: [chocolateboy]) +- Fix invalid utf-8 exception. (Thanks: [Amjith]) ## 1.4.1 - 2020-07-27 diff --git a/litecli/__init__.py b/litecli/__init__.py index 5b60188..e4adfb8 100644 --- a/litecli/__init__.py +++ b/litecli/__init__.py @@ -1 +1 @@ -__version__ = "1.5.0" +__version__ = "1.6.0" diff --git a/litecli/liteclirc b/litecli/liteclirc index e3331d1..5bfffbd 100644 --- a/litecli/liteclirc +++ b/litecli/liteclirc @@ -55,6 +55,7 @@ wider_completion_menu = False # litecli prompt # \D - The full current date # \d - Database name +# \f - File basename of the "main" database # \m - Minutes of the current time # \n - Newline # \P - AM/PM diff --git a/litecli/main.py b/litecli/main.py index 5768851..24b1bb4 100644 --- a/litecli/main.py +++ b/litecli/main.py @@ -704,8 +704,7 @@ class LiteCli(object): ] def _on_completions_refreshed(self, new_completer): - """Swap the completer object in cli with the newly created completer. - """ + """Swap the completer object in cli with the newly created completer.""" with self._completer_lock: self.completer = new_completer @@ -725,6 +724,7 @@ class LiteCli(object): sqlexecute = self.sqlexecute now = datetime.now() string = string.replace("\\d", sqlexecute.dbname or "(none)") + string = string.replace("\\f", os.path.basename(sqlexecute.dbname or "(none)")) string = string.replace("\\n", "\n") string = string.replace("\\D", now.strftime("%a %b %d %H:%M:%S %Y")) string = string.replace("\\m", now.strftime("%M")) diff --git a/litecli/packages/parseutils.py b/litecli/packages/parseutils.py index 92fe365..3f5ca61 100644 --- a/litecli/packages/parseutils.py +++ b/litecli/packages/parseutils.py @@ -166,7 +166,7 @@ def extract_tables(sql): def find_prev_keyword(sql): - """ Find the last sql keyword in an SQL statement + """Find the last sql keyword in an SQL statement Returns the value of the last keyword, and the text of the query with everything after the last keyword stripped diff --git a/litecli/packages/special/iocommands.py b/litecli/packages/special/iocommands.py index 8940057..43c3577 100644 --- a/litecli/packages/special/iocommands.py +++ b/litecli/packages/special/iocommands.py @@ -276,8 +276,7 @@ def save_favorite_query(arg, **_): @special_command("\\fd", "\\fd [name]", "Delete a favorite query.") def delete_favorite_query(arg, **_): - """Delete an existing favorite query. - """ + """Delete an existing favorite query.""" usage = "Syntax: \\fd name.\n\n" + favoritequeries.usage if not arg: return [(None, None, None, usage)] diff --git a/litecli/sqlexecute.py b/litecli/sqlexecute.py index 7ef103c..2b8fce3 100644 --- a/litecli/sqlexecute.py +++ b/litecli/sqlexecute.py @@ -61,6 +61,7 @@ class SQLExecute(object): raise Exception("Path does not exist: {}".format(db_dir_name)) conn = sqlite3.connect(database=db_name, isolation_level=None) + conn.text_factory = lambda x: x.decode("utf-8", "backslashreplace") if self.conn: self.conn.close() diff --git a/requirements-dev.txt b/requirements-dev.txt index b95211a..c517d59 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,3 +7,4 @@ pexpect coverage codecov click +black
\ No newline at end of file @@ -83,7 +83,9 @@ class test(TestCommand): self.pytest_args = "" def run_tests(self): - unit_test_errno = subprocess.call("pytest " + self.pytest_args, shell=True) + unit_test_errno = subprocess.call( + "pytest tests " + self.pytest_args, shell=True + ) # cli_errno = subprocess.call('behave test/features', shell=True) # sys.exit(unit_test_errno or cli_errno) sys.exit(unit_test_errno) diff --git a/tests/liteclirc b/tests/liteclirc index e31942f..979b409 100644 --- a/tests/liteclirc +++ b/tests/liteclirc @@ -54,6 +54,7 @@ wider_completion_menu = False # litecli prompt # \D - The full current date # \d - Database name +# \f - File basename of the "main" database # \m - Minutes of the current time # \n - Newline # \P - AM/PM diff --git a/tests/test_completion_engine.py b/tests/test_completion_engine.py index 84d5536..760f275 100644 --- a/tests/test_completion_engine.py +++ b/tests/test_completion_engine.py @@ -36,7 +36,9 @@ def test_order_by_suggests_cols_with_qualified_table_scope(): "SELECT * FROM sch.tabl ORDER BY ", "SELECT * FROM sch.tabl ORDER BY " ) assert sorted_dicts(suggestions) == sorted_dicts( - [{"type": "column", "tables": [("sch", "tabl", None)]},] + [ + {"type": "column", "tables": [("sch", "tabl", None)]}, + ] ) diff --git a/tests/test_smart_completion_public_schema_only.py b/tests/test_smart_completion_public_schema_only.py index ea5c580..e532118 100644 --- a/tests/test_smart_completion_public_schema_only.py +++ b/tests/test_smart_completion_public_schema_only.py @@ -367,15 +367,17 @@ def test_auto_escaped_col_names(completer, complete_event): Document(text=text, cursor_position=position), complete_event ) ) - assert result == [ - Completion(text="*", start_position=0), - Completion(text="`ABC`", start_position=0), - Completion(text="`insert`", start_position=0), - Completion(text="id", start_position=0), - ] + list(map(Completion, completer.functions)) + [ - Completion(text="`select`", start_position=0) - ] + list( - map(Completion, sorted(completer.keywords)) + assert ( + result + == [ + Completion(text="*", start_position=0), + Completion(text="`ABC`", start_position=0), + Completion(text="`insert`", start_position=0), + Completion(text="id", start_position=0), + ] + + list(map(Completion, completer.functions)) + + [Completion(text="`select`", start_position=0)] + + list(map(Completion, sorted(completer.keywords))) ) diff --git a/tests/test_sqlexecute.py b/tests/test_sqlexecute.py index 2dde4d4..029c64b 100644 --- a/tests/test_sqlexecute.py +++ b/tests/test_sqlexecute.py @@ -102,6 +102,17 @@ def test_unicode_support_in_output(executor): @dbtest +def test_invalid_unicode_values_dont_choke(executor): + run(executor, "create table unicodechars(t text)") + # \xc3 is not a valid utf-8 char. But we can insert it into the database + # which can break querying if not handled correctly. + run(executor, u"insert into unicodechars (t) values (cast(x'c3' as text))") + + results = run(executor, u"select * from unicodechars") + assert_result_equal(results, headers=["t"], rows=[("\\xc3",)]) + + +@dbtest def test_multiple_queries_same_line(executor): results = run(executor, "select 'foo'; select 'bar'") @@ -186,6 +197,7 @@ def test_bind_parameterized_favorite_query(executor): with pytest.raises(ProgrammingError): results = run(executor, "\\f+ q_param 1 2") + @dbtest def test_verbose_feature_of_favorite_query(executor): set_expanded_output(False) @@ -198,11 +210,7 @@ def test_verbose_feature_of_favorite_query(executor): results = run(executor, "\\f sh_param 1") assert_result_equal( - results, - title=None, - headers=["a", "id"], - rows=[("abc", 1)], - auto_status=False, + results, title=None, headers=["a", "id"], rows=[("abc", 1)], auto_status=False, ) results = run(executor, "\\f+ sh_param 1") @@ -214,6 +222,7 @@ def test_verbose_feature_of_favorite_query(executor): auto_status=False, ) + @dbtest def test_shell_parameterized_favorite_query(executor): set_expanded_output(False) |