From cf46c0a4b667cfedf6e53a7eb369b46919200a5c Mon Sep 17 00:00:00 2001 From: Cosmin Popescu Date: Thu, 29 Sep 2016 21:24:49 +0200 Subject: [PATCH] version 6.1 --- README.md | 54 ++++++++++++++++++- autoload/sw.vim | 19 +++---- autoload/sw/dbexplorer.vim | 85 ++++++++++++++++++++++------- autoload/sw/search.vim | 2 +- autoload/sw/server.vim | 64 +++++++++++++++++----- autoload/sw/sqlwindow.vim | 15 +----- autoload/sw/variables.vim | 106 ------------------------------------- doc/vim-sql-workbench.txt | 90 ++++++++++++++++++++++++++----- plugin/sw.vim | 43 ++++++++------- resources/dbexplorer.vim | 10 ++-- 10 files changed, 286 insertions(+), 202 deletions(-) delete mode 100644 autoload/sw/variables.vim diff --git a/README.md b/README.md index fce2afe..c1b35e5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ it, here is the quick start: *Running sql queries against a DBMS*: -* set the `g:sw_config_dir` variable +* set the `g:sw_config_dir` and `g:sw_exe` variables * open your sql buffer * if you have `CtrlP` installed you can do `CtrlP` and then select `SQL Workbench profiles` and choose your profile @@ -318,6 +318,58 @@ You can also add a panel to an existing tab, using the * The command (this is the SQL command to be sent to the DBMS once this option is selected +##Events + +The database explorer has events to which you can hook a function to be +executed before the command is executed or after the result is received. If +you hook to the before event, your function will receive as a parameter the +command being set to a server and it must return the modified command. If you +hoon to the after event, your function will receive the response from the +server (an array of lines) and can modify it. It has to return the result +which will be displayed in the left or right panel (a new list of lines). + +To hook on the tab events, you can use the function +`sw#dbexplorer#add_tab_event`. The arguments are: + +* the shortcut of the tab +* the event type (`after` or `before`) +* the function name + +*Example:* + +``` +function! BeforeTabObjects(command) + return "show tables" +endfunction + +function! AfterTabObjects(result) + let result = [] + for line in a:result + call add(result, substitute(line, '\v^TABLE_NAME[ \s\t]*$', 'Tables', 'g')) + endfor + return result +endfunction + +call sw#dbexplorer#add_tab_event('O', 'before', 'BeforeTabObjects') +call sw#dbexplorer#add_tab_event('O', 'after', 'AfterTabObjects') +``` + +After executing this example, when you select the Objects tab in the database +explorer, the command executed is going to be `show tables`, instead of +`WbList`, which is the default for objects. Then, when the result is returned, +the line `TABLE_NAME` is going to be replaces with the text "Tables". + +To hook on panel events, you can use the function +`sw#dbexplorer#add_panel_event`. The arguments are: + +* the shortcut of the tab +* the shortcut of the panel +* the type of event (`after` or `before`) +* the function name + +For an example on how to use this function, see the `resources/dbexplorer.vim` +file (the last line) and the `autoload/sw/dbexplorer.vim` file to see the +function hook definition. The SQL buffer ======================================== diff --git a/autoload/sw.vim b/autoload/sw.vim index 59a9b60..7e17987 100644 --- a/autoload/sw.vim +++ b/autoload/sw.vim @@ -82,12 +82,6 @@ if !exists('g:Sw_unique_id') let g:Sw_unique_id = 1 endif -if exists('v:servername') && exists('g:sw_vim_exe') - if v:servername != '' - let s:wake_vim_cmd = g:sw_vim_exe . ' --servername ' . v:servername - endif -endif - function! sw#find_buffer_by_unique_id(uid) for k in keys(g:sw_session) if has_key(g:sw_session[k], 'unique_id') @@ -112,10 +106,6 @@ function! s:get_buff_unique_id() return -1 endfunction -function! s:get_wake_vim_cmd() - return s:wake_vim_cmd . ' --remote-expr "sw#got_async_result(' . s:get_buff_unique_id() . ')"' -endfunction - function! sw#set_on_async_result(value) if exists('b:on_async_result') && exists('b:async_on_progress') && !sw#dbexplorer#is_db_explorer_tab() throw 'There is a command in progress for this buffer. Please wait for it to finish.' @@ -564,10 +554,11 @@ function! sw#put_text_in_buffer(text) endfunction function! sw#put_lines_in_buffer(lines) + let file = g:sw_tmp . "/row-" . sw#servername() setlocal modifiable normal ggdG - call writefile(a:lines, g:sw_tmp . "/row-" . v:servername) - execute "read " . g:sw_tmp . "/row-" . v:servername + call writefile(a:lines, file) + execute "read " . file normal ggdd setlocal nomodifiable endfunction @@ -588,3 +579,7 @@ endfunction function! sw#get_pattern(which) return s:patterns[a:which] endfunction + +function! sw#servername() + return substitute(v:servername, '\v\/', '-', 'g') +endfunction diff --git a/autoload/sw/dbexplorer.vim b/autoload/sw/dbexplorer.vim index 4e6f64e..93214de 100644 --- a/autoload/sw/dbexplorer.vim +++ b/autoload/sw/dbexplorer.vim @@ -22,6 +22,7 @@ if !exists('g:SW_Tabs') endif let s:profiles = {} +let s:events = {'panels': {'before': {}, 'after': {}}, 'tabs': {'before': {}, 'after': {}}} let s:last_command = {} " Local functions{{{1 @@ -189,8 +190,9 @@ endfunction " Change a tab{{{2 function! sw#dbexplorer#change_tab(command, shortcut, title) - let s:last_command = {'command': a:command, 'shortcut': a:shortcut, 'title': a:title, 'type': 1} - call sw#dbexplorer#do_command(a:command) + let command = s:process_events('tabs', 'before', a:shortcut, '', a:command) + let s:last_command = {'command': command, 'shortcut': a:shortcut, 'title': a:title, 'type': 1} + call sw#dbexplorer#do_command(command) endfunction function! sw#dbexplorer#do_command(sql) @@ -254,11 +256,6 @@ function! s:process_result_2(result, tab_shortcut, shortcut, cmd) call sw#session#set_buffer_variable('last_cmd', a:cmd) call sw#session#set_buffer_variable('state', 'resultsets') call sw#put_lines_in_buffer(result) - let pattern = '\v^.*-- AFTER(.*)$' - if a:cmd =~ pattern - let after = substitute(a:cmd, pattern, '\1', 'g') - execute after - endif endfunction function! s:get_object_columns() @@ -275,18 +272,14 @@ endfunction function! s:change_panel(command, shortcut, title, tab_shortcut) echomsg "Processing request..." - let pattern = '\v\c^\/\* BEFORE (.*)\*\/.+$' - if (a:command =~ pattern) - let command = substitute(a:command, pattern, '\1', 'g') - execute command - endif + let command = s:process_events('panels', 'before', a:tab_shortcut, a:shortcut, a:command) if (exists('b:selected_row')) call matchdelete(b:selected_row) endif let object = substitute(getline('.'), '\v^([^ ]+) .*$', '\1', 'g') call sw#session#set_buffer_variable('selected_row', matchadd('SWSelectedObject', '^' . object . ' .*$')) let columns = s:get_object_columns() - let cmd = substitute(a:command, '\v\%object\%', object, 'g') + let cmd = substitute(command, '\v\%object\%', object, 'g') let i = 0 for column in columns let cmd = substitute(cmd, '\v\%' . i . '\%', column, 'g') @@ -406,20 +399,36 @@ endfunction function! s:set_highlights() highlight SWHighlights term=NONE cterm=NONE ctermbg=25 ctermfg=yellow gui=NONE guibg=#808080 guifg=yellow - highlight SWSelectedObject term=NONE cterm=NONE ctermbg=DarkGrey ctermfg=fg gui=NONE guibg=#808080 guifg=yellow + highlight SWSelectedObject term=NONE cterm=NONE ctermbg=DarkGrey ctermfg=NONE gui=NONE guibg=#808080 guifg=yellow let id = matchadd('SWHighlights', b:profile) let id = matchadd('SWHighlights', b:t1_shortcuts) let id = matchadd('SWHighlights', b:t2_shortcuts) let id = matchadd('SWHighlights', b:t3_shortcuts) endfunction +function! s:process_events(which, when, tab_shortcut, shortcut, result) + let result = a:result + if has_key(s:events[a:which][a:when], a:tab_shortcut . a:shortcut) + for command in s:events[a:which][a:when][a:tab_shortcut . a:shortcut] + let Callback = function(command) + let result = Callback(result) + endfor + endif + + return result +endfunction + " Handles a message from the server{{{2 function! sw#dbexplorer#message_handler(channel, message) let result = split(a:message, "\n") if s:last_command.type == 1 + let result = s:process_events('tabs', 'after', s:last_command.shortcut, '', result) call s:process_result_1(result, s:last_command.shortcut, s:last_command.title) elseif s:last_command.type == 2 + let result = s:process_events('panels', 'after', s:last_command.tab_shortcut, s:last_command.shortcut, result) call s:process_result_2(result, s:last_command.tab_shortcut, s:last_command.shortcut, s:last_command.cmd) + elseif s:last_command.type == 3 + call s:process_result_1(result, '', '') endif endfunction @@ -439,6 +448,7 @@ function! sw#dbexplorer#show_panel(profile) let uid = sw#generate_unique_id() execute "badd " . name execute "buffer " . name + let s:last_command = {'type': 3} let channel = sw#server#open_dbexplorer(a:profile) call s:set_special_buffer(profile, channel) call sw#session#set_buffer_variable('unique_id', uid) @@ -455,7 +465,7 @@ function! sw#dbexplorer#show_panel(profile) call sw#session#set_buffer_variable('unique_id', uid) vertical resize 60 call s:iterate('s:get_first_tab') - call sw#dbexplorer#change_tab(b:first_tab['command'], b:first_tab['shortcut'], b:first_tab['title']) + ""call sw#dbexplorer#change_tab(b:first_tab['command'], b:first_tab['shortcut'], b:first_tab['title']) if s_below set splitbelow endif @@ -467,10 +477,45 @@ function! sw#dbexplorer#is_db_explorer_tab() return name =~ '\v^__Info__' || name =~ '\v^__DBExplorer__' || name =~ '\v^__SQL__' endfunction -" Eliminates the first column of the buffer for the source code{{{2 -function! sw#dbexplorer#fix_source_code() - setlocal modifiable - normal gg0G0x - setlocal nomodifiable +function! s:add_event(which, tab_shortcut, shortcut, when, command) + if !has_key(s:events[a:which][a:when], a:tab_shortcut . a:shortcut) + let s:events[a:which][a:when][a:tab_shortcut . a:shortcut] = [] + endif + call add(s:events[a:which][a:when][a:tab_shortcut . a:shortcut], a:command) +endfunction + +function! sw#dbexplorer#add_tab_event(shortcut, when, command) + call s:add_event('tabs', a:shortcut, '', a:when, a:command) +endfunction + +function! sw#dbexplorer#add_panel_event(tab_shortcut, shortcut, when, command) + call s:add_event('panels', a:tab_shortcut, a:shortcut, a:when, a:command) +endfunction + +function! sw#dbexplorer#get_events() + return s:events endfunction + +function! sw#dbexplorer#filtered_data(result) + let params = reverse(copy(sw#server#get_parameters_history())) + let value = '' + + for param in params + if param.prompt =~ '\v^filter' + let value = param.value + break + endif + endfor + + let result = ['Filter value: ' . value] + + for line in a:result + if !(line =~ '\vPlease supply a value for the following variables|filter') + call add(result, line) + endif + endfor + + return result +endfunction + " vim:fdm=marker diff --git a/autoload/sw/search.vim b/autoload/sw/search.vim index ce5a957..f847541 100644 --- a/autoload/sw/search.vim +++ b/autoload/sw/search.vim @@ -110,7 +110,7 @@ endfunction function! sw#search#do(command) echomsg "Searching. Please wait..." call sw#session#init_section() - call sw#execute_sql(a:command . ';') + call sw#server#execute_sql(a:command . ';') endfunction function! sw#search#data_defaults(value) diff --git a/autoload/sw/server.vim b/autoload/sw/server.vim index d88d0fd..3256651 100644 --- a/autoload/sw/server.vim +++ b/autoload/sw/server.vim @@ -18,16 +18,18 @@ "============================================================================" let s:current_file = expand(':p:h') +let s:nvim = has("nvim") let s:channel_handlers = {} let s:pattern_prompt_begin = '\v^([a-zA-Z_0-9\.]+(\@[a-zA-Z_0-9\/\-]+)*\>[ \s\t]*)+' let s:pattern_prompt = s:pattern_prompt_begin . '$' let s:pattern_wait_input = '\v^([a-zA-Z_][a-zA-Z0-9_]*( \[[^\]]+\])?: |([^\>]+\> )?([^\>]+\> )*Username|([^\>]+\> )*Password: |([^\>]+\>[ ]+)?Do you want to run the command UPDATE\? \(Yes\/No\/All\)[ ]+)$' +let s:params_history = [] let s:pattern_new_connection = '\v^Connection to "([^"]+)" successful$' -let s:timer = {'id': '', 'sec' : 0} +let s:timer = {'id': -1, 'sec' : 0} function! s:log_init(channel) if g:sw_log_to_file - let s:channel_handlers[a:channel].log = g:sw_tmp . '/' . v:servername . '-' . substitute(fnamemodify(bufname('%'), ':t'), '\.', '-', 'g') + let s:channel_handlers[a:channel].log = g:sw_tmp . '/' . sw#servername() . '-' . substitute(fnamemodify(bufname('%'), ':t'), '\.', '-', 'g') else let s:channel_handlers[a:channel].log = '' endif @@ -47,6 +49,17 @@ function! sw#server#channel_log(channel) return s:channel_handlers[a:channel].log endfunction +function! sw#server#nvim_handle_message(job, lines, ev) + if a:ev == 'stdout' + let msg = '' + for line in a:lines + let msg .= (msg == '' ? '' : "\n") . line + endfor + + call sw#server#handle_message(a:job, msg) + endif +endfunction + function! sw#server#handle_message(channel, msg) call s:log_channel(a:channel, a:msg) let lines = split(substitute(a:msg, "\r", "", 'g'), "\n") @@ -60,8 +73,13 @@ function! sw#server#handle_message(channel, msg) let got_prompt = 1 endif if line =~ s:pattern_wait_input && !(line =~ '\v^Catalog: $') && !(line =~ '\v^Schema: $') - let value = input('SQL Workbench/J is asking for input for ' . line . ' ', 'abc') - call ch_sendraw(b:sw_channel, value . "\n") + let value = input('SQL Workbench/J is asking for input for ' . line . ' ', '') + call add(s:params_history, {'prompt': line, 'value': value}) + if s:nvim + call jobsend(b:sw_channel, value . "\n") + else + call ch_sendraw(b:sw_channel, value . "\n") + endif endif if line =~ s:pattern_new_connection @@ -89,13 +107,21 @@ function! sw#server#handle_message(channel, msg) endfunction function! s:start_sqlwb(type) - let job = job_start(g:sw_exe . ' -feedback=true -showProgress=false -abortOnError=false -showTiming=true', {'in_mode': 'raw', 'out_mode': 'raw'}) - let channel = job_getchannel(job) - call ch_setoptions(channel, {'callback': 'sw#server#handle_message'}) + let cmd = g:sw_exe . ' -feedback=true -showProgress=false -abortOnError=false -showTiming=true' + if !s:nvim + let job = job_start(cmd, {'in_mode': 'raw', 'out_mode': 'raw'}) + let channel = job_getchannel(job) + call ch_setoptions(channel, {'callback': 'sw#server#handle_message'}) + else + let channel = jobstart(cmd, {'on_stdout': function('sw#server#nvim_handle_message'), 'on_stderr': function('sw#server#nvim_handle_message'), 'on_exit': function('sw#server#nvim_handle_message')}) + endif + let s:channel_handlers[channel] = {'text': '', 'type': a:type, 'buffer': fnamemodify(bufname('%'), ':p'), 'current_url': '', 'tmp_handler': ''} call s:log_init(channel) return channel + + ""return job endfunction function! sw#server#connect_buffer(...) @@ -130,17 +156,23 @@ function! sw#server#execute_sql(sql, ...) elseif a:0 >= 1 let channel = a:1 endif - if ch_status(channel) != 'open' - call sw#display_error("The channel is not open. This means that SQL Workbench/J instance for this answer does not responsd anymore. Please do again SWSqlBufferConnect") - unlet b:sw_channel - return '' + if !s:nvim + if ch_status(channel) != 'open' + call sw#display_error("The channel is not open. This means that SQL Workbench/J instance for this answer does not responsd anymore. Please do again SWSqlBufferConnect") + unlet b:sw_channel + return '' + endif endif let text = a:sql . "\n" call s:log_channel(channel, text) if callback != '' let s:channel_handlers[channel].tmp_handler = callback endif - call ch_sendraw(channel, text) + if s:nvim + call jobsend(channel, text) + else + call ch_sendraw(channel, text) + endif if g:sw_command_timer call s:init_timer() let s:timer.id = timer_start(1000, 'sw#server#timer', {'repeat': -1}) @@ -148,10 +180,10 @@ function! sw#server#execute_sql(sql, ...) endfunction function! s:init_timer() - if s:timer.id != '' + if s:timer.id != -1 call timer_stop(s:timer.id) endif - let s:timer = {'id': '', 'sec': 0} + let s:timer = {'id': -1, 'sec': 0} endfunction function! sw#server#timer(timer) @@ -208,3 +240,7 @@ function! sw#server#open_dbexplorer(profile) return channel endfunction + +function! sw#server#get_parameters_history() + return s:params_history +endfunction diff --git a/autoload/sw/sqlwindow.vim b/autoload/sw/sqlwindow.vim index 50a4b59..badf27c 100644 --- a/autoload/sw/sqlwindow.vim +++ b/autoload/sw/sqlwindow.vim @@ -586,6 +586,7 @@ endfunction function! s:print_line(line_idx, n_resultset, do_filter) let resultset = b:resultsets[a:n_resultset] + let pattern_empty_line = '\v^[ \t\s\|\:]*$' let line = resultset.lines[a:line_idx] @@ -639,7 +640,7 @@ function! s:print_line(line_idx, n_resultset, do_filter) let i += 1 endwhile - if result == '' + if result =~ pattern_empty_line let result = '#IGNORE#' endif return substitute(result, '\v^(.*)[+|]$', '\1', 'g') @@ -841,18 +842,6 @@ function! sw#sqlwindow#execute_sql(sql) let title = title[:255] . '...' endif let _sql = '-- @wbresult ' . title . "\n" . _sql - if !exists('b:no_variables') - let vars = sw#variables#extract(_sql) - if len(vars) > 0 - for var in vars - let value = sw#variables#get(var) - if value != '' - let _sql = w:auto_added1 . 'wbvardef ' . var . ' = ' . value . "\n" . b:delimiter . "\n" . w:auto_added2 . _sql - endif - endfor - let _sql = substitute(_sql, g:parameters_pattern, g:sw_p_prefix . '\1' . g:sw_p_suffix, 'g') - endif - endif call s:do_execute_sql(_sql) endfunction diff --git a/autoload/sw/variables.vim b/autoload/sw/variables.vim deleted file mode 100644 index 782be3c..0000000 --- a/autoload/sw/variables.vim +++ /dev/null @@ -1,106 +0,0 @@ -"============================================================================" -" -" Vim SQL Workbench/J Implementation -" -" Copyright (c) Cosmin Popescu -" -" Author: Cosmin Popescu -" Version: 1.00 (2015-01-08) -" Requires: Vim 7 -" License: GPL -" -" Description: -" -" Provides SQL database access to any DBMS supported by SQL Workbench/J. The -" only dependency is SQL Workbench/J. Also includes powefull intellisense -" autocomplete based on the current selected database -" -"============================================================================" - -function! s:set_delimiters() - if !exists('g:sw_p_suffix') && !exists('g:sw_p_prefix') - let g:sw_prefix = sw#get_sw_setting('workbench.sql.parameter.prefix') - let g:sw_suffix = sw#get_sw_setting('workbench.sql.parameter.suffix') - if g:sw_prefix == '' - let g:sw_p_prefix = '\$\[' - endif - if g:sw_suffix == '' - let g:sw_p_suffix = '\]' - endif - - let g:parameters_pattern = g:sw_p_prefix . '[?&]\([a-zA-Z_].\{\-\}\)' . g:sw_p_suffix - if g:sw_p_suffix == '' - let g:parameters_pattern = g:parameters_pattern . '\>' - endif - endif -endfunction - -function! s:init_vars() - if !exists('b:variables') - call sw#session#set_buffer_variable('variables', {}) - endif -endfunction - -function! sw#variables#set(key, value, ...) - call s:init_vars() - let val = a:value - if a:0 - let i = 1 - while i <= a:0 - execute "let v = a:" . i - if i < a:0 || v != '' - execute "let val = val . ' ' . a:" . i - endif - let i = i + 1 - endwhile - endif - call sw#session#set_buffer_variable("variables." . a:key, val) -endfunction - -function! sw#variables#list() - call s:init_vars() - echo string(b:variables) -endfunction - -function! sw#variables#autocomplete_names(ArgLead, CmdLine, CursorPos) - call s:init_vars() - let words = split('^' . a:CmdLine, '\v\s+') - let result = [] - if len(words) == 1 || (len(words) == 2 && !(a:CmdLine =~ '\v\s+$')) - for key in keys(b:variables) - if key =~ a:ArgLead - call add(result, key) - endif - endfor - endif - return result -endfunction - -function! sw#variables#unset(key) - call s:init_vars() - call sw#session#unset_buffer_variable('variables.' . a:key) -endfunction - -function! sw#variables#get(key) - call s:init_vars() - let value = input('Please input the value for ' . a:key . ': ') - call sw#variables#set(a:key, value) - return value -endfunction - -function! sw#variables#extract(sql) - call s:set_delimiters() - let result = [] - let n = 0 - let i = match(a:sql, g:parameters_pattern, n) - while i != -1 - let l = matchlist(a:sql, g:parameters_pattern, n) - let s = substitute(l[0], '^' . g:sw_p_prefix . '?', '', 'g') - let n = i + strlen(l[0]) + 1 - if index(result, l[1]) == -1 - call add(result, l[1]) - endif - let i = match(a:sql, g:parameters_pattern, n) - endwhile - return result -endfunction diff --git a/doc/vim-sql-workbench.txt b/doc/vim-sql-workbench.txt index e1611f6..e296010 100644 --- a/doc/vim-sql-workbench.txt +++ b/doc/vim-sql-workbench.txt @@ -4,17 +4,18 @@ vim-sql-workbench.txt CONTENTS *vim-sql-workbench-contents* 1. Tutorial...........................................|vim-sql-workbench-tutorial| -2. Introduction...................................|vim-sql-workbench-introduction| -3. Requirements...................................|vim-sql-workbench-requirements| -4. Connecting to a DBMS...................|vim-sql-workbench-connecting_to_a_dbms| -5. The database explorer.................|vim-sql-workbench-the_database_explorer| -6. The SQL buffer...............................|vim-sql-workbench-the_sql_buffer| -7. SQL commands...................................|vim-sql-workbench-sql_commands| -8. Searching.........................................|vim-sql-workbench-searching| -9. Exporting.........................................|vim-sql-workbench-exporting| -10. Variables........................................|vim-sql-workbench-variables| -11. Commands..........................................|vim-sql-workbench-commands| -12. Settings..........................................|vim-sql-workbench-settings| +2. Disclaimer.......................................|vim-sql-workbench-disclaimer| +3. Introduction...................................|vim-sql-workbench-introduction| +4. Requirements...................................|vim-sql-workbench-requirements| +5. Connecting to a DBMS...................|vim-sql-workbench-connecting_to_a_dbms| +6. The database explorer.................|vim-sql-workbench-the_database_explorer| +7. The SQL buffer...............................|vim-sql-workbench-the_sql_buffer| +8. SQL commands...................................|vim-sql-workbench-sql_commands| +9. Searching.........................................|vim-sql-workbench-searching| +10. Exporting........................................|vim-sql-workbench-exporting| +11. Variables........................................|vim-sql-workbench-variables| +12. Commands..........................................|vim-sql-workbench-commands| +13. Settings..........................................|vim-sql-workbench-settings| ================================================================================ TUTORIAL *vim-sql-workbench-tutorial* @@ -29,7 +30,7 @@ it, here is the quick start: Running sql queries against a DBMS: -* set the `g:sw_config_dir` variable +* set the `g:sw_config_dir` and `g:sw_exe` variables * open your sql buffer * if you have `CtrlP` installed you can do `CtrlP` and then select and choose your profile * otherwise, you can do `:SWSqlBufferConnect` and then in the buffer execute @@ -47,6 +48,14 @@ Note: For more detailed explanations, please continue reading this material. +================================================================================ +DISCLAIMER *vim-sql-workbench-disclaimer* + +Please note that this version is no longer compatible with VIM 7. If you +didn't upgraded to VIM 8 yet, then don't install this version. Stick with +5.2.2. But you should consider upgrading your vim anyway. For the +documentation of `5.2.2`, please see here (README-7.md) + ================================================================================ INTRODUCTION *vim-sql-workbench-introduction* @@ -320,6 +329,56 @@ You can also add a panel to an existing tab, using the * The command (this is the SQL command to be sent to the DBMS once this option is selected +##Events + +The database explorer has events to which you can hook a function to be +executed before the command is executed or after the result is received. If +you hook to the before event, your function will receive as a parameter the +command being set to a server and it must return the modified command. If you +hoon to the after event, your function will receive the response from the +server (an array of lines) and can modify it. It has to return the result +which will be displayed in the left or right panel (a new list of lines). + +To hook on the tab events, you can use the function +`sw#dbexplorer#add_tab_event`. The arguments are: + +* the shortcut of the tab +* the event type (`after` or `before`) +* the function name + +Example: +> + function! BeforeTabObjects(command) + return "show tables" + endfunction + function! AfterTabObjects(result) + let result = [] + for line in a:result + call add(result, substitute(line, '\v^TABLE_NAME[ \s\t]*$', 'Tables', 'g')) + endfor + return result + endfunction + call sw#dbexplorer#add_tab_event('O', 'before', 'BeforeTabObjects') + call sw#dbexplorer#add_tab_event('O', 'after', 'AfterTabObjects') +< + +After executing this example, when you select the Objects tab in the database +explorer, the command executed is going to be , instead of +`WbList`, which is the default for objects. Then, when the result is returned, +the line `TABLE_NAME` is going to be replaces with the text "Tables". + +To hook on panel events, you can use the function +`sw#dbexplorer#add_panel_event`. The arguments are: + +* the shortcut of the tab +* the shortcut of the panel +* the type of event (`after` or `before`) +* the function name + +For an example on how to use this function, see the `resources/dbexplorer.vim` +file (the last line) and the `autoload/sw/dbexplorer.vim` file to see the +function hook definition. + ================================================================================ THE SQL BUFFER *vim-sql-workbench-the_sql_buffer* @@ -1119,3 +1178,10 @@ GENERAL SETTINGS: *vim-sql-workbench-general_settings event if you close the resultsets window; to clear the resultsets window, use `SWSqlWipeoutResultsSets` command. + + + + + + + diff --git a/plugin/sw.vim b/plugin/sw.vim index 35e0c91..23e5c60 100644 --- a/plugin/sw.vim +++ b/plugin/sw.vim @@ -158,33 +158,36 @@ else execute "so " . g:sw_dbexplorer_panel endif -for _profile in items(g:extra_sw_tabs) - let profile = _profile[0] - let tabs = _profile[1] - if (!has_key(g:SW_Tabs, profile)) - let g:SW_Tabs[profile] = [] - endif - for tab in tabs - call add(g:SW_Tabs[profile], tab) +if exists('g:extra_sw_tabs') + for _profile in items(g:extra_sw_tabs) + let profile = _profile[0] + let tabs = _profile[1] + if (!has_key(g:SW_Tabs, profile)) + let g:SW_Tabs[profile] = [] + endif + for tab in tabs + call add(g:SW_Tabs[profile], tab) + endfor endfor -endfor +endif -for key in keys(g:SW_Tabs) - let tabs = g:SW_Tabs[key] +if exists('g:extra_sw_panels') + for key in keys(g:SW_Tabs) + let tabs = g:SW_Tabs[key] - for tab in tabs - for shortcut in keys(g:extra_sw_panels) - let panels = g:extra_sw_panels[shortcut] + for tab in tabs + for shortcut in keys(g:extra_sw_panels) + let panels = g:extra_sw_panels[shortcut] - for panel in panels - if tab['shortcut'] == shortcut && key == panel['profile'] - call add(tab['panels'], panel['panel']) - endif + for panel in panels + if tab['shortcut'] == shortcut && key == panel['profile'] + call add(tab['panels'], panel['panel']) + endif + endfor endfor endfor endfor - -endfor +endif command! -nargs=+ -complete=customlist,sw#autocomplete_profile SWDbExplorer call sw#dbexplorer#show_panel() command! -nargs=? SWDbExplorerClose call sw#dbexplorer#hide_panel() diff --git a/resources/dbexplorer.vim b/resources/dbexplorer.vim index a5f6e37..300cbaf 100644 --- a/resources/dbexplorer.vim +++ b/resources/dbexplorer.vim @@ -6,9 +6,10 @@ let sw_columns = {'title': 'Columns', 'shortcut': 'C', 'command': 'desc %object% let sw_sql_source = {'title': 'SQL Source', 'shortcut': 'S', 'command': 'WbGenerateScript -objects="%object%"', 'filetype': 'sql'} let sw_sql_source_triggers = {'title': 'SQL Source', 'shortcut': 'S', 'command': 'wbtriggersource %object%', 'filetype': 'sql', 'hide_header': 1} let sw_data = {'title': 'Data', 'shortcut': 'D', 'command': 'select * from %object%;', 'filetype': 'sw'} +let sw_data_filter = {'title': 'Filtered Data', 'shortcut': 'F', 'command': 'select * from %object% where $[?filter];', 'filetype': 'sw'} let sw_indexes = {'title': 'Indexes', 'shortcut': 'I', 'command': 'WbListIndexes -tableName=%object%;'} let sw_referenced_by = {'title': 'Referenced by', 'shortcut': 'R', 'command': 'WbGrepSource -searchValues="references %object%" -types=TABLE -useRegex=false;', 'skip_columns': [2]} -let objects = {'title': 'Objects', 'shortcut': 'O', 'command': 'WbList -objects=% -types=SYNONYM,SEQUENCE,TABLE,TYPE,VIEW', 'panels': [sw_columns, sw_sql_source, sw_data, sw_indexes, sw_referenced_by]} +let objects = {'title': 'Objects', 'shortcut': 'O', 'command': 'WbList -objects=% -types=SYNONYM,TABLE,TYPE,VIEW', 'panels': [sw_columns, sw_sql_source, sw_data, sw_data_filter, sw_indexes, sw_referenced_by]} let sw_sql_source = {'title': 'SQL Source', 'shortcut': 'S', 'command': 'WbProcSource %object%', 'filetype': 'sql'} let procedures = {'title': 'Procedures', 'shortcut': 'P', 'command': 'WbListProcs;', 'panels': [sw_sql_source]} let triggers = {'title': 'Triggers', 'shortcut': 'T', 'command': 'WbListTriggers;', 'panels': [sw_sql_source_triggers]} @@ -22,7 +23,7 @@ let sw_indexes = {'title': 'Indexes', 'shortcut': 'I', 'command': 'WbListIndexes let sw_referenced_by = {'title': 'Referenced by', 'shortcut': 'R', 'command': 'WbGrepSource -searchValues="references %object%" -types=TABLE -useRegex=false -schemas=*;', 'skip_columns': [2]} let objects = {'title': 'Objects', 'shortcut': 'O', 'command': 'WbList', 'panels': [sw_columns, sw_sql_source, sw_data, sw_indexes, sw_referenced_by]} let sw_sql_source_proc = {'title': 'SQL Source', 'shortcut': 'S', 'command': ':sw#dbexplorer#postgre_proc', 'filetype': 'sql'} -let sw_sql_source_triggers = {'title': 'SQL Source', 'shortcut': 'S', 'command': 'WbGrepSource -searchValues="%object%" -objects=%object% -types=* -useRegex=true -schemas=*; -- AFTERcall sw#dbexplorer#fix_source_code()', 'skip_columns': [0, 1], 'hide_header': 1, 'filetype': 'sql'} +let sw_sql_source_triggers = {'title': 'SQL Source', 'shortcut': 'S', 'command': 'WbGrepSource -searchValues="%object%" -objects=%object% -types=* -useRegex=true -schemas=*;', 'skip_columns': [0, 1], 'hide_header': 1, 'filetype': 'sql'} let procedures = {'title': 'Procedures', 'shortcut': 'P', 'command': 'WbListProcs;', 'panels': [sw_sql_source_proc]} let triggers = {'title': 'Triggers', 'shortcut': 'T', 'command': 'WbListTriggers;', 'panels': [sw_sql_source_triggers]} let schemas = {'title': 'Show schemas', 'shortcut': 'M', 'command': 'wblistschemas;', 'panels': [{'title': 'Select schema', 'shortcut': 'H', 'command': "set search_path to %object%;"}, {'title': 'Select *', 'shortcut': 'A', 'command': "set search_path to '*.*'"}]} @@ -33,4 +34,7 @@ let oracle_dblinks = {'title': 'DB Links', 'shortcut': 'L', 'command': 'select d let oracle_jobs = {'title': 'User Jobs', 'shortcut': 'J', 'command': 'select job_name, job_creator, start_date, repeat_interval from user_scheduler_jobs', 'panels': [{'title': 'Job source', 'shortcut': 'S', 'command': "select job_action from user_scheduler_jobs where job_name = '%object%'", 'hide_header': 1, 'filetype': 'sql'}]} let oracle_packages = {'title': 'Packages', 'shortcut': 'K', 'command': "select OBJECT_NAME, OBJECT_TYPE, STATUS from user_objects where object_type in ('PACKAGE');", 'panels': [{'title': 'SQL Source', 'shortcut': 'S', 'command': "wbprocsource %object%", 'filetype': 'sql'}, {'title': 'Compile', 'shortcut': 'E', 'command': 'alter package %object% compile package'}, {'title': 'Status', 'shortcut': 'v', 'command': "select object_name, OBJECT_TYPE, STATUS from user_objects where object_name = '%object%'"}]} let oracle_schemas = {'title': 'Show schemas', 'shortcut': 'M', 'command': 'wblistschemas;', 'panels': [{'title': 'Select schema', 'shortcut': 'H', 'command': "alter session set current_schema = %object%;"}]} -let g:SW_Tabs[':oracle'] = [oracle_dblinks, oracle_jobs, oracle_packages, oracle_schemas] +let oracle_sequences = {'title': 'Sequences', 'shortcut': 'Q', 'command': 'wblist -types=SEQUENCE -objects=%', 'panels': [sw_sql_source, sw_columns]} +let g:SW_Tabs[':oracle'] = [oracle_dblinks, oracle_jobs, oracle_packages, oracle_schemas, oracle_sequences] + +call sw#dbexplorer#add_panel_event('O', 'F', 'after', 'sw#dbexplorer#filtered_data') -- GitLab