From 60323598377cc604bb85524bb7d0b2582cebe198 Mon Sep 17 00:00:00 2001 From: mechatroner Date: Sat, 12 Jun 2021 22:37:48 -0400 Subject: [PATCH] fix rbql integration --- README.md | 6 ++++++ RainbowCSV.sublime-settings | 4 ++++ main.py | 10 ++++++---- sublime_rbql.py | 14 ++++++++------ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0bf439b..4302f5f 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,12 @@ RBQL backend language. Supported values: _"Python"_, _"JS"_ To use RBQL with JavaScript (JS) you need to have Node JS installed and added to your system path. +#### "rbql_with_headers" +Default: false +RBQL will treat first records in all input and join files as headers. +You can set this value to true if most of the CSV files you deal with have headers. +You can override this setting on the query level by either adding `WITH (header)` or `WITH (noheader)` to the end of the query. + #### "rbql_output_format" Format of RBQL result set tables. Supported values: _"tsv"_, _"csv"_, _"input"_ diff --git a/RainbowCSV.sublime-settings b/RainbowCSV.sublime-settings index 6b4b586..7f79406 100644 --- a/RainbowCSV.sublime-settings +++ b/RainbowCSV.sublime-settings @@ -38,6 +38,10 @@ // In order to use RBQL with JavaScript (JS) you need to have Node JS installed and added to your system path. "rbql_backend_language": "Python", + // RBQL will treat first records in all input and join files as headers. + // You can set this value to true if most of the CSV files you deal with have headers. + // You can override this setting on the query level by either adding `WITH (header)` or `WITH (noheader)` to the end of the query. + "rbql_with_headers": false, // RBQL encoding for files and queries. // Supported values: "latin-1", "utf-8" diff --git a/main.py b/main.py index 40f36bc..079f33e 100644 --- a/main.py +++ b/main.py @@ -20,7 +20,7 @@ ######## Test and Debug ######### # To install this package in debug mode: -# 1. Make sure you don't have production rainbow_csv installed, if it installed - uninstall it first, there should be no rainbow_csv folder in the Sublime Text 3/Packages dir +# 1. Make sure you don't have production rainbow_csv installed, if it is installed - uninstall it first, there should be no rainbow_csv folder in the Sublime Text 3/Packages dir # 2. Just copy it into "Sublime Text 3/Packages" folder as "rainbow_csv", e.g.: cp -r sublime_rainbow_csv "/mnt/c/Users/mecha/AppData/Roaming/Sublime Text 3/Packages/rainbow_csv" # To debug this package just use python's own print() function - all output would be redirected to sublime text console. View -> Show Console @@ -586,6 +586,7 @@ def on_done_query_edit(input_line): input_delim, input_policy = input_dialect backend_language = get_backend_language(active_view) output_format = get_setting(active_view, 'rbql_output_format', 'input') + with_headers = get_setting(active_view, 'rbql_with_headers', False) encoding = get_setting(active_view, 'rbql_encoding', 'utf-8') encoding = encoding.lower() if encoding not in ['latin-1', 'utf-8']: @@ -597,7 +598,7 @@ def on_done_query_edit(input_line): sublime.error_message('RBQL Error. "rbql_output_format" must be in [{}]'.format(', '.join(format_map.keys()))) return output_delim, output_policy = format_map[output_format] - query_result = sublime_rbql.converged_execute(backend_language, file_path, input_line, input_delim, input_policy, output_delim, output_policy, encoding) + query_result = sublime_rbql.converged_execute(backend_language, file_path, input_line, input_delim, input_policy, output_delim, output_policy, encoding, with_headers) error_type, error_details, warnings, dst_table_path = query_result if error_type is not None: sublime.error_message('Unable to execute RBQL query :(\nEdit your query and try again!\n\n\n\n\n=============================\nDetails:\n{}\n{}'.format(error_type, error_details)) @@ -794,8 +795,9 @@ def run(self, _edit): previous_query = self.view.settings().get('rbql_previous_query', '') backend_language = get_backend_language(self.view) pretty_language_name = prettify_language_name(backend_language) - encoding = get_setting(self.view, 'rbql_encoding', 'utf-8') - active_window.show_input_panel('Enter SQL-like RBQL query ({}/{}):'.format(pretty_language_name, encoding), previous_query, on_done_query_edit, None, on_query_cancel) + with_headers = get_setting(self.view, 'rbql_with_headers', False) + headers_report = 'with header' if with_headers else 'no header' + active_window.show_input_panel('Enter SQL-like RBQL query ({}/{}):'.format(pretty_language_name, headers_report), previous_query, on_done_query_edit, None, on_query_cancel) self.view.settings().set('rbql_mode', True) show_column_names(self.view, delim, policy) diff --git a/sublime_rbql.py b/sublime_rbql.py index 56645b0..b97fd1b 100644 --- a/sublime_rbql.py +++ b/sublime_rbql.py @@ -24,23 +24,25 @@ def system_has_node_js(): return exit_code == 0 and len(out_data) and len(err_data) == 0 -def execute_python(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path): +def execute_python(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path, with_headers): try: warnings = [] - rbql.query_csv(query, src_table_path, input_delim, input_policy, dst_table_path, out_delim, out_policy, encoding, warnings) + rbql.query_csv(query, src_table_path, input_delim, input_policy, dst_table_path, out_delim, out_policy, encoding, warnings, with_headers) return (None, None, warnings) except Exception as e: error_type, error_msg = rbql.exception_to_error_info(e) return (error_type, error_msg, []) -def execute_js(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path): +def execute_js(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path, with_headers): import json if not system_has_node_js(): return ('Execution Error', 'Node.js is not found in your OS, test command: "node --version"', []) script_dir = os.path.dirname(os.path.realpath(__file__)) rbql_js_script_path = os.path.join(script_dir, 'rbql-js', 'cli_rbql.js') cmd = ['node', rbql_js_script_path, '--query', query, '--delim', input_delim, '--policy', input_policy, '--out-delim', out_delim, '--out-policy', out_policy, '--input', src_table_path, '--output', dst_table_path, '--encoding', encoding, '--error-format', 'json'] + if with_headers: + cmd.append('--with-headers') if os.name == 'nt': # Without the startupinfo magic Windows will show console window for a longer period. si = subprocess.STARTUPINFO() @@ -70,7 +72,7 @@ def execute_js(src_table_path, encoding, query, input_delim, input_policy, out_d return (error_type, error_msg, warnings) -def converged_execute(meta_language, src_table_path, query, input_delim, input_policy, out_delim, out_policy, encoding): +def converged_execute(meta_language, src_table_path, query, input_delim, input_policy, out_delim, out_policy, encoding, with_headers): try: tmp_dir = tempfile.gettempdir() table_name = os.path.basename(src_table_path) @@ -80,9 +82,9 @@ def converged_execute(meta_language, src_table_path, query, input_delim, input_p dst_table_path = os.path.join(tmp_dir, dst_table_name) assert meta_language in ['python', 'js'], 'Meta language must be "python" or "js"' if meta_language == 'python': - exec_result = execute_python(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path) + exec_result = execute_python(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path, with_headers) else: - exec_result = execute_js(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path) + exec_result = execute_js(src_table_path, encoding, query, input_delim, input_policy, out_delim, out_policy, dst_table_path, with_headers) error_type, error_details, warnings = exec_result if error_type is not None: dst_table_path = None