From ff88f0023572a7dc67fc90bca9876b714865a3bb Mon Sep 17 00:00:00 2001 From: Kris Jenkins Date: Tue, 1 Oct 2013 12:50:01 +0100 Subject: [PATCH 1/2] Version 20.0 --- autoload/dbext.vim | 206 +++++++++++++++++------ autoload/dbext_dbi.vim | 133 +++++++++++---- doc/dbext.txt | 102 ++++++++++-- plugin/dbext.vim | 360 ++++++++++++++++++++++++----------------- 4 files changed, 549 insertions(+), 252 deletions(-) diff --git a/autoload/dbext.vim b/autoload/dbext.vim index b920cfb..060eede 100644 --- a/autoload/dbext.vim +++ b/autoload/dbext.vim @@ -1,11 +1,11 @@ " dbext.vim - Commn Database Utility " Copyright (C) 2002-10, Peter Bagyinszki, David Fishburn " --------------------------------------------------------------- -" Version: 19.00 +" Version: 20.00 " Maintainer: David Fishburn " Authors: Peter Bagyinszki " David Fishburn -" Last Modified: 2013 Apr 29 +" Last Modified: 2013 Sep 18 " Based On: sqlplus.vim (author: Jamis Buck) " Created: 2002-05-24 " Homepage: http://vim.sourceforge.net/script.php?script_id=356 @@ -38,7 +38,7 @@ if v:version < 700 echomsg "dbext: Version 4.00 or higher requires Vim7. Version 3.50 can stil be used with Vim6." finish endif -let g:loaded_dbext_auto = 1900 +let g:loaded_dbext_auto = 2000 " Turn on support for line continuations when creating the script let s:cpo_save = &cpo @@ -60,11 +60,12 @@ let s:dbext_tempfile = s:dbext_tempfile.(s:dbext_tempfile =~ '^/' ? '/' : '\').' let s:dbext_prev_sql = '' let s:dbext_result_count = 0 " Store previous buffer information so we can return to it when we -" " Store previous buffer information so we can return to it when we -" close the Result window " close the Result window let s:dbext_buffer_last_winnr = -1 let s:dbext_buffer_last = -1 +" Define previous window and buffer numbers +" let s:dbext_prev_winnr = 0 +" let s:dbext_prev_bufnr = 0 " }}} " Build internal lists {{{ @@ -217,6 +218,7 @@ function! s:DB_buildLists() " DBI configuration parameters let s:config_dbi_mv = [] call add(s:config_dbi_mv, 'DBI_max_rows') + call add(s:config_dbi_mv, 'DBI_max_column_width') call add(s:config_dbi_mv, 'DBI_disconnect_onerror') call add(s:config_dbi_mv, 'DBI_commit_on_disconnect') call add(s:config_dbi_mv, 'DBI_split_on_pattern') @@ -340,7 +342,8 @@ function! dbext#DB_execFuncWCheck(name,...) let use_defaults = 1 if s:DB_get("buffer_defaulted") != 1 let rc = s:DB_resetBufferParameters(use_defaults) - if rc == -1 + if rc == -1 && a:name != 'promptForParameters' + " if rc == -1 call s:DB_warningMsg( "dbext:A valid database type must be chosen" ) return -1 endif @@ -536,6 +539,16 @@ function! s:DB_set(name, value) " from being set to "@askb", so the user would never " be prompted for a value. let value = toupper(value) + let b:dbext_{a:name} = value + + if value != '' + " If we are setting the database type, default + " all the database specific options to the database + " defaults. + for param in s:db_params_mv + call s:DB_setWType(param, s:DB_getDefault(b:dbext_{a:name}.'_'.param)) + endfor + endif endif " Profile will have to be retrieved from your vimrc " and each option must be processed @@ -552,7 +565,7 @@ function! s:DB_set(name, value) " Only when the database type has been specified " as these parameters are reset often when changing " profiles - if b:dbext_type != '' + if exists('b:dbext_type') && b:dbext_type != '' call s:DB_setWType(tolower(a:name), value) endif elseif index(s:script_params_mv, a:name) > -1 @@ -573,7 +586,14 @@ function! s:DB_set(name, value) if a:name == 'DBI_commit_on_disconnect' " Special case since this option must be set " both in the DBI layer and the dbext plugin - call s:DB_DBI_setOption(a:name, a:value) + " Check the type, as we may be resetting the + " variables to default values. + " Changed to not use s:DB_get since this triggered + " a PromptForParameters during defaulting + " if s:DB_get('type') =~ '\\|\' + if exists('b:dbext_type') && b:dbext_type =~ '\\|\' + call s:DB_DBI_setOption(a:name, a:value) + endif endif elseif index(s:saved_conn_params_mv, a:name) > -1 " Store these parameters as script variables @@ -582,7 +602,10 @@ function! s:DB_set(name, value) else if index(s:db_dbi_mv, a:name) > -1 let rc = 0 - if s:DB_get('type') =~ '\\|\' + " Changed to not use s:DB_get since this triggered + " a PromptForParameters during defaulting + " if s:DB_get('type') =~ '\\|\' + if exists('b:dbext_type') && b:dbext_type =~ '\\|\' let rc = s:DB_DBI_setOption(a:name, a:value) endif return rc @@ -668,7 +691,11 @@ function! dbext#DB_listOption(...) endif let opt_name = param_mv try - let opt_value = opt_name . ' = ' . s:DB_get(opt_name) + if index(s:db_params_mv, opt_name) > -1 + let opt_value = opt_name . ' = ' . dbext#DB_getWTypeDefault(opt_name) + else + let opt_value = opt_name . ' = ' . s:DB_get(opt_name) + endif catch call s:DB_errorMsg('Failed to get:'.opt_name) endtry @@ -719,7 +746,7 @@ function! dbext#DB_listOption(...) " Retrieve the name of option let opt_name = matchstr(l:global_vars, '\w\+', index) if strlen(opt_name) > 0 - let opt_value = matchstr(l:global_vars, '\s*\zs[^'."\".']\+', + let opt_value = matchstr(l:global_vars, '\s*#\?\zs[^'."\".']\+', \ (index + strlen(opt_name)) ) if opt_name !~ 'profile_' let option_list = option_list . opt_name . ' = ' . opt_value . "\n" @@ -729,6 +756,14 @@ function! dbext#DB_listOption(...) let index = match(l:global_vars, dbext_default_prefix, index) endwhile + let option_list = option_list . + \ "-------------------------------\n" . + \ "** dbext Component Versions **\n" . + \ "-------------------------------\n" + let option_list = option_list . "plugin/dbext.vim = " . (exists('g:loaded_dbext') ? g:loaded_dbext : "unknown") . "\n" + let option_list = option_list . "autoload/dbext.vim = " . (exists('g:loaded_dbext_auto') ? g:loaded_dbext_auto : "unknown") . "\n" + let option_list = option_list . "autoload/dbext_dbi.vim = " . (exists('g:loaded_dbext_dbi') ? g:loaded_dbext_dbi : "unknown") . "\n" + let option_list = option_list . \ "-------------------------------\n" . \ "** Vim Version Information **\n" . @@ -775,7 +810,7 @@ function! s:DB_get(name, ...) endif if exists("b:dbext_prompting_user") && b:dbext_prompting_user != 1 - if retval =~? "@ask" + if retval =~? "^@ask" let retval = s:DB_promptForParameters(a:name) endif endif @@ -939,7 +974,7 @@ function! s:DB_getDefault(name) elseif a:name ==# "RDB_cmd_terminator" |return (exists("g:dbext_default_RDB_cmd_terminator")?g:dbext_default_RDB_cmd_terminator.'':";\n") elseif a:name ==# "RDB_SQL_Top_pat" |return (exists("g:dbext_default_RDB_SQL_Top_pat")?g:dbext_default_RDB_SQL_Top_pat.'':'\(.*\)') elseif a:name ==# "RDB_SQL_Top_sub" |return (exists("g:dbext_default_RDB_SQL_Top_sub")?g:dbext_default_RDB_SQL_Top_sub.'':'\1 LIMIT to @dbext_topX rows ') - elseif a:name ==# "SQLITE_bin" |return (exists("g:dbext_default_SQLITE_bin")?g:dbext_default_SQLITE_bin.'':'sqlite') + elseif a:name ==# "SQLITE_bin" |return (exists("g:dbext_default_SQLITE_bin")?g:dbext_default_SQLITE_bin.'':'sqlite3') elseif a:name ==# "SQLITE_cmd_header" |return (exists("g:dbext_default_SQLITE_cmd_header")?g:dbext_default_SQLITE_cmd_header.'':".mode column\n.headers ON\n") elseif a:name ==# "SQLITE_cmd_options" |return (exists("g:dbext_default_SQLITE_cmd_options")?g:dbext_default_SQLITE_cmd_options.'':'') elseif a:name ==# "SQLITE_cmd_terminator" |return (exists("g:dbext_default_SQLITE_cmd_terminator")?g:dbext_default_SQLITE_cmd_terminator.'':';') @@ -978,6 +1013,7 @@ function! s:DB_getDefault(name) elseif a:name ==# "inputdialog_cancel_support" |return (exists("g:dbext_default_inputdialog_cancel_support")?g:dbext_default_inputdialog_cancel_support.'':((v:version>=602)?'1':'0')) " DBI Settings elseif a:name ==# "DBI_max_rows" |return (exists("g:dbext_default_DBI_max_rows")?g:dbext_default_DBI_max_rows.'':'300') + elseif a:name ==# "DBI_max_column_width" |return (exists("g:dbext_default_DBI_max_column_width")?g:dbext_default_DBI_max_column_width.'':'0') elseif a:name ==# "DBI_disconnect_onerror" |return (exists("g:dbext_default_DBI_disconnect_onerror")?g:dbext_default_DBI_disconnect_onerror.'':'1') elseif a:name ==# "DBI_commit_on_disconnect" |return (exists("g:dbext_default_DBI_commit_on_disconnect")?g:dbext_default_DBI_commit_on_disconnect.'':'1') elseif a:name ==# "DBI_split_on_pattern" |return (exists("g:dbext_default_DBI_split_on_pattern")?g:dbext_default_DBI_split_on_pattern.'':"\n".'\s*\\s*'."\n") @@ -994,32 +1030,35 @@ function! s:DB_getDefault(name) elseif a:name ==# "DBI_table_type_ASAny" |return (exists("g:dbext_default_dbi_table_type_ASAny")?g:dbext_default_dbi_table_type_ASAny.'':'%TABLE%') elseif a:name ==# "DBI_view_type_ASAny" |return (exists("g:dbext_default_dbi_view_type_ASAny")?g:dbext_default_dbi_table_type_ASAny.'':'%VIEW%') " Create additional SQL statements for the DBI layer to support listing procedures which is not supported by DBI - elseif a:name ==# "DBI_list_proc_SQLAnywhere" |return (exists("g:dbext_default_DBI_list_proc_SQLAnywhere")?g:dbext_default_DBI_list_proc_SQLAnywhere.'':'select p.proc_name, u.user_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id and p.proc_name like ''dbext_replace_name%'' and u.user_name like ''dbext_replace_owner%'' order by proc_name') - elseif a:name ==# "DBI_list_proc_ASAny" |return (exists("g:dbext_default_DBI_list_proc_ASAny")?g:dbext_default_DBI_list_proc_ASAny.'':'select p.proc_name, u.user_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id and p.proc_name like ''%'' and u.user_name like ''%'' order by proc_name') + elseif a:name ==# "DBI_list_proc_SQLAnywhere" |return (exists("g:dbext_default_DBI_list_proc_SQLAnywhere")?g:dbext_default_DBI_list_proc_SQLAnywhere.'':'select p.proc_name, u.user_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id and p.proc_name like ''dbext_replace_name%'' and u.user_name like ''dbext_replace_owner%'' order by p.proc_name') + elseif a:name ==# "DBI_list_proc_ASAny" |return (exists("g:dbext_default_DBI_list_proc_ASAny")?g:dbext_default_DBI_list_proc_ASAny.'':'select p.proc_name, u.user_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id and p.proc_name like ''%'' and u.user_name like ''%'' order by p.proc_name') elseif a:name ==# "DBI_list_proc_Oracle" |return (exists("g:dbext_default_DBI_list_proc_Oracle")?g:dbext_default_DBI_list_proc_Oracle.'':'select object_name, owner from all_objects where object_type IN (''PROCEDURE'', ''PACKAGE'', ''FUNCTION'') and object_name LIKE ''dbext_replace_name%'' order by object_name') elseif a:name ==# "DBI_list_proc_Sybase" |return (exists("g:dbext_default_DBI_list_proc_Sybase")?g:dbext_default_DBI_list_proc_Sybase.'':'select convert(varchar,o.name), convert(varchar,u.name) from sysobjects o, sysusers u where o.uid=u.uid and o.type=''P'' and o.name like ''dbext_replace_name%'' order by o.name') elseif a:name ==# "DBI_list_proc_DB2" |return (exists("g:dbext_default_DBI_list_proc_DB2")?g:dbext_default_DBI_list_proc_DB2.'':'select CAST(procname AS VARCHAR(40)) AS procname , CAST(procschema AS VARCHAR(15)) AS procschema , CAST(definer AS VARCHAR(15)) AS definer , parm_count , deterministic , fenced , result_sets from syscat.procedures where procname like ''dbext_replace_name%'' order by procname') elseif a:name ==# "DBI_list_proc_mysql" |return (exists("g:dbext_default_DBI_list_proc_mysql")?g:dbext_default_DBI_list_proc_mysql.'':'SELECT specific_name, routine_schema FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name like ''dbext_replace_name%'' AND routine_schema like ''dbext_replace_owner%'' ') elseif a:name ==# "DBI_list_proc_PGSQL" |return (exists("g:dbext_default_DBI_list_proc_PGSQL")?g:dbext_default_DBI_list_proc_PGSQL.'':'SELECT p.proname, pg_get_userbyid(u.usesysid) FROM pg_proc p, pg_user u WHERE p.proowner = u.usesysid AND u.usename like ''dbext_replace_owner%'' AND p.proname like ''dbext_replace_name%'' ORDER BY p.proname') elseif a:name ==# "DBI_list_proc_SQLSRV" |return (exists("g:dbext_default_DBI_list_proc_SQLSRV")?g:dbext_default_DBI_list_proc_SQLSRV.'':'select convert(varchar,o.name) proc_name, convert(varchar,u.name) proc_owner from sysobjects o, sysusers u where o.uid=u.uid and o.xtype=''P'' and o.name like ''dbext_replace_name%'' order by o.name') + elseif a:name ==# "DBI_list_proc_HANA" |return (exists("g:dbext_default_DBI_list_proc_HANA")?g:dbext_default_DBI_list_proc_HANA.'':'select p.PROCEDURE_NAME, p.SCHEMA_NAME from SYS.PROCEDURES as p where p.PROCEDURE_NAME like ''dbext_replace_name%'' and p.SCHEMA_NAME like ''dbext_replace_owner%'' order by p.PROCEDURE_NAME') " Create additional SQL statements for the DBI layer to support creating a dictionary for procedures which is not supported by DBI - elseif a:name ==# "DBI_dict_proc_SQLAnywhere" |return (exists("g:dbext_default_DBI_dict_proc_SQLAnywhere")?g:dbext_default_DBI_dict_proc_SQLAnywhere.'':'select u.user_name ||''.''|| p.proc_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id order by u.user_name, proc_name') - elseif a:name ==# "DBI_dict_proc_ASAny" |return (exists("g:dbext_default_DBI_dict_proc_ASAny")?g:dbext_default_DBI_dict_proc_ASAny.'':'select u.user_name ||''.''|| p.proc_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id order by u.user_name, proc_name') + elseif a:name ==# "DBI_dict_proc_SQLAnywhere" |return (exists("g:dbext_default_DBI_dict_proc_SQLAnywhere")?g:dbext_default_DBI_dict_proc_SQLAnywhere.'':'select u.user_name ||''.''|| p.proc_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id order by u.user_name, p.proc_name') + elseif a:name ==# "DBI_dict_proc_ASAny" |return (exists("g:dbext_default_DBI_dict_proc_ASAny")?g:dbext_default_DBI_dict_proc_ASAny.'':'select u.user_name ||''.''|| p.proc_name from SYS.SYSPROCEDURE as p, SYS.SYSUSERPERM as u where p.creator = u.user_id order by u.user_name, p.proc_name') elseif a:name ==# "DBI_dict_proc_Oracle" |return (exists("g:dbext_default_DBI_dict_proc_Oracle")?g:dbext_default_DBI_dict_proc_Oracle.'':'select owner||''.''||object_name from all_objects where object_type IN (''PROCEDURE'', ''PACKAGE'', ''FUNCTION'') order by object_name') elseif a:name ==# "DBI_dict_proc_Sybase" |return (exists("g:dbext_default_DBI_dict_proc_Sybase")?g:dbext_default_DBI_dict_proc_Sybase.'':'select convert(varchar,u.name)||''.''||convert(varchar,o.name) from sysobjects o, sysusers u where o.uid=u.uid and o.type=''P'' order by o.name') elseif a:name ==# "DBI_dict_proc_DB2" |return (exists("g:dbext_default_DBI_dict_proc_DB2")?g:dbext_default_DBI_dict_proc_DB2.'':'select CAST(procname AS VARCHAR(40)) AS procname from syscat.procedures order by procname') elseif a:name ==# "DBI_dict_proc_mysql" |return (exists("g:dbext_default_DBI_dict_proc_mysql")?g:dbext_default_DBI_dict_proc_mysql.'':'SELECT CONCAT_WS(''.'', routine_schema,specific_name) FROM INFORMATION_SCHEMA.ROUTINES WHERE specific_name like ''%'' AND routine_schema like ''%'' ') elseif a:name ==# "DBI_dict_proc_PGSQL" |return (exists("g:dbext_default_DBI_dict_proc_PGSQL")?g:dbext_default_DBI_dict_proc_PGSQL.'':'SELECT pg_get_userbyid(u.usesysid)||''.''||p.proname FROM pg_proc p, pg_user u WHERE p.proowner = u.usesysid ORDER BY p.proname ') elseif a:name ==# "DBI_dict_proc_SQLSRV" |return (exists("g:dbext_default_DBI_dict_proc_SQLSRV")?g:dbext_default_DBI_dict_proc_SQLSRV.'':'select convert(varchar,u.name)+''.''+convert(varchar,o.name) from sysobjects o, sysusers u where o.uid=u.uid and o.xtype=''P'' order by o.name ') + elseif a:name ==# "DBI_dict_proc_HANA" |return (exists("g:dbext_default_DBI_dict_proc_HANA")?g:dbext_default_DBI_dict_proc_HANA.'':'select p.SCHEMA_NAME ||''.''|| p.PROCEDURE_NAME from SYS.PROCEDURES as p where order by p.SCHEMA_NAME, p.PROCEDURE_NAME') " Create additional SQL statements for the DBI layer to support describing a procedure which is not supported by DBI - elseif a:name ==# "DBI_desc_proc_SQLAnywhere" |return (exists("g:dbext_default_DBI_desc_proc_SQLAnywhere")?g:dbext_default_DBI_desc_proc_SQLAnywhere.'':'select * from SYS.SYSPROCPARMS as pp where pp.parmtype = 0 and pp.procname = ''dbext_replace_name'' ') - elseif a:name ==# "DBI_desc_proc_ASAny" |return (exists("g:dbext_default_DBI_desc_proc_ASAny")?g:dbext_default_DBI_desc_proc_ASAny.'':'select * from SYS.SYSPROCPARMS as pp where pp.parmtype = 0 and pp.procname = ''dbext_replace_name'' ') + elseif a:name ==# "DBI_desc_proc_SQLAnywhere" |return (exists("g:dbext_default_DBI_desc_proc_SQLAnywhere")?g:dbext_default_DBI_desc_proc_SQLAnywhere.'':'select * from SYS.SYSPROCPARMS as pp where pp.parmtype = 0 and pp.procname = ''dbext_replace_name'' ') + elseif a:name ==# "DBI_desc_proc_ASAny" |return (exists("g:dbext_default_DBI_desc_proc_ASAny")?g:dbext_default_DBI_desc_proc_ASAny.'':'select * from SYS.SYSPROCPARMS as pp where pp.parmtype = 0 and pp.procname = ''dbext_replace_name'' ') elseif a:name ==# "DBI_desc_proc_Oracle" |return (exists("g:dbext_default_DBI_desc_proc_Oracle")?g:dbext_default_DBI_desc_proc_Oracle.'':'select object_name, owner from all_objects where object_type IN (''PROCEDURE'', ''PACKAGE'', ''FUNCTION'') and object_name LIKE ''dbext_replace_name%'' order by object_name') elseif a:name ==# "DBI_desc_proc_Sybase" |return (exists("g:dbext_default_DBI_desc_proc_Sybase")?g:dbext_default_DBI_desc_proc_Sybase.'':'exec sp_help dbext_replace_owner.dbext_replace_name ') elseif a:name ==# "DBI_desc_proc_DB2" |return (exists("g:dbext_default_DBI_desc_proc_DB2")?g:dbext_default_DBI_desc_proc_DB2.'':'select ordinal , CAST(parmname AS VARCHAR(40)) AS parmname , CAST(typename AS VARCHAR(10)) AS typename , length , scale , CAST(nulls AS VARCHAR(1)) AS nulls , CAST(procschema AS VARCHAR(30)) AS procschema from syscat.procparms where procname = ''dbext_replace_name%'' order by ordinal ') elseif a:name ==# "DBI_desc_proc_mysql" |return (exists("g:dbext_default_DBI_desc_proc_mysql")?g:dbext_default_DBI_desc_proc_mysql.'':'describe dbext_replace_owner.dbext_replace_name ') elseif a:name ==# "DBI_desc_proc_PGSQL" |return (exists("g:dbext_default_DBI_desc_proc_PGSQL")?g:dbext_default_DBI_desc_proc_PGSQL.'':'SELECT p.* FROM pg_proc p, pg_type t, pg_language l WHERE p.proargtypes = t.oid AND p.prolang = t.oid AND p.proname = ''dbext_replace_name'' ORDER BY p.pronargs ') elseif a:name ==# "DBI_desc_proc_SQLSRV" |return (exists("g:dbext_default_DBI_desc_proc_SQLSRV")?g:dbext_default_DBI_desc_proc_SQLSRV.'':'exec sp_help dbext_replace_owner.dbext_replace_name') + elseif a:name ==# "DBI_desc_proc_HANA" |return (exists("g:dbext_default_DBI_desc_proc_HANA")?g:dbext_default_DBI_desc_proc_HANA.'':'select * from SYS.PROCEDURE_PARAMETERS as pp where pp.PROCEDURE_NAME = ''dbext_replace_name'' order by pp.POSITION ') else |return '' endif endfunction @@ -1126,6 +1165,7 @@ endfunction function! s:DB_resetBufferParameters(use_defaults) let no_defaults = 0 let retval = -2 + let type = '' " Reset configuration parameters to defaults for param in s:config_params_mv @@ -1136,20 +1176,50 @@ function! s:DB_resetBufferParameters(use_defaults) " setup their connection information. silent! doautocmd User dbextPreConnection + " Set all connection parameters + let b:all_params_mv = [] + call extend(b:all_params_mv, s:conn_params_mv) + call extend(b:all_params_mv, s:config_dbi_mv) + + " let type = s:DB_get("type", no_defaults) + " DF " If a database type has been chosen setup it's + " DF " specific defaults + " DF let type = s:DB_get("type", no_defaults) + " DF if type != "" + " DF " \ && a:use_defaults == 1 + " DF " \ && retval == -2 + " DF for param in s:db_params_mv + " DF call add(b:all_params_mv, type.'_'.param) + " DF endfor + " DF endif + + " if s:DB_get('type', no_defaults) =~ '\\|\' + " " Set all DBI parameters + " call extend(b:all_params_mv, s:config_dbi_mv) + " endif + " Reset connection parameters to either blanks or defaults " depending on what was passed into this function " Loop through and prompt the user for all buffer " connection parameters. " Calling this function can be nested, so we must generate " a unique IterCreate name. - for param in s:conn_params_mv + for param in b:all_params_mv if a:use_defaults == 0 call s:DB_set(param, "") else + " DF if type != "" + " DF let value = dbext#DB_getWType(param) + " DF else + " DF let value = s:DB_getDefault(param) + " DF endif " Only set the buffer variable if the default value " is not '@ask' - if s:DB_getDefault(param) !=? '@ask' - let value = s:DB_get(param) + let value = s:DB_getDefault(param) + if value !~? '^@ask' + if value == '' + let value = s:DB_get(param) + endif if value == -1 let retval = value break @@ -1160,10 +1230,6 @@ function! s:DB_resetBufferParameters(use_defaults) endif endfor - " if retval == -1 - " return retval - " endif - " If a database type has not been chosen, do prompt " for connection information if s:DB_get("type", no_defaults) == "" @@ -1172,11 +1238,6 @@ function! s:DB_resetBufferParameters(use_defaults) call s:DB_promptForParameters() endif - " if s:DB_get('filetype') == '' - " let s:DB_set('filetype') = &filetype - " endif - - " call s:DB_validateBufferParameters() let retval = s:DB_validateBufferParameters() return retval @@ -1229,9 +1290,10 @@ function! s:DB_promptForParameters(...) " call s:DB_set('prompting_user', 1) let b:dbext_prompting_user = 1 - let no_default = 1 - let param_prompted = 0 - let param_value = '' + let no_default = 1 + let use_defaults = 1 + let param_prompted = 0 + let param_value = '' " The retval is only set when an optional parameter name " is passed in from DB_get @@ -1343,7 +1405,9 @@ function! s:DB_promptForParameters(...) if param == "profile" " If using the DBI layer, drop any connections which may be active " before switching profiles - if s:DB_get('type') =~ '\\|\' + " Do not use DB_get as this can trigger a prompt if type is unset + " if s:DB_get('type') =~ '\\|\' + if exists('b:dbext_type') && b:dbext_type =~ '\\|\' call dbext#DB_disconnect() endif @@ -1369,10 +1433,11 @@ function! s:DB_promptForParameters(...) else call s:DB_set(param, "") endif + " call s:DB_resetBufferParameters(use_defaults) else " Force string comparison - if l:old_value.'' ==? '@ask' - " If the default value is @ask, then do not set the + if l:new_value.'' =~? '^@ask' + " If the new value is @ask, then do not set the " buffer parameter, just return the value. " The next time we execute something, we will be " prompted for this value again. @@ -1380,7 +1445,6 @@ function! s:DB_promptForParameters(...) endif call s:DB_set(param, l:new_value) - endif endif endfor @@ -3508,12 +3572,11 @@ function! s:DB_SQLSRV_execSql(str) if has("win32") && s:DB_get("integratedlogin") == 1 let cmd = cmd . ' -E' - else - let cmd = cmd . ' -U ' . s:DB_get("user") . - \ ' -P' . s:DB_get("passwd") endif let cmd = cmd . + \ s:DB_option(' -U ', s:DB_get("user"), ' ') . + \ s:DB_option(' -P', s:DB_get("passwd"), ' ') . \ s:DB_option(' -H ', s:DB_get("host"), ' ') . \ s:DB_option(' -S ', s:DB_get("srvname"), ' ') . \ s:DB_option(' -d ', s:DB_get("dbname"), ' ') . @@ -4785,6 +4848,8 @@ function! s:DB_ODBC_describeProcedure(procedure_name) let driver = 'DB2' elseif rdbms =~? 'postgres' let driver = 'PGSQL' + elseif rdbms =~? 'HDB' + let driver = 'HANA' else call s:DB_warningMsg( \ 'dbext:Please report this ODBC driver ['. @@ -4959,6 +5024,8 @@ function! s:DB_ODBC_getListProcedure(proc_prefix) let driver = 'DB2' elseif rdbms =~? 'postgres' let driver = 'PGSQL' + elseif rdbms =~? 'HDB' + let driver = 'HANA' else call s:DB_warningMsg( \ 'dbext:Please report this ODBC driver ['. @@ -5144,6 +5211,8 @@ function! s:DB_ODBC_getDictionaryProcedure() "{{{ let driver = 'DB2' elseif rdbms =~? 'postgres' let driver = 'PGSQL' + elseif rdbms =~? 'HDB' + let driver = 'HANA' else call s:DB_warningMsg( \ 'dbext:Please report this ODBC driver ['. @@ -5718,6 +5787,11 @@ endfunction function! dbext#DB_getQueryUnderCursor() let use_defaults = 1 + + " Record current buffer to return to the correct one + let s:dbext_prev_winnr = winnr() + let s:dbext_prev_bufnr = bufnr('%') + " In order to parse a statement, we must know what database type " we are dealing with to choose the correct cmd_terminator if s:DB_get("buffer_defaulted") != 1 @@ -5799,8 +5873,11 @@ function! dbext#DB_getQueryUnderCursor() " In the above case, we would stop even though the ; was " not the command terminator. - " Start visual mode, find the terminator (should be at end of line) - exe 'silent! norm! v/'.dbext_cmd_terminator."\\s*$/e\n".'"zy``' + " Start visual mode and find + " 1. the terminator (should be at end of line) \s*$ + " 2. or find a blank line \n\n + " 3. or end of file \%$ + exe 'silent! norm! v/\('.dbext_cmd_terminator.'\s*$\|\n\n\|\%$\)/e'."\n".'"zy``' if line("'<") == line("'>") && \ col("'<") == col("'>") @@ -5976,6 +6053,9 @@ function! dbext#DB_DictionaryCreate( drop_dict, which ) "{{{ let temp_file = "-1" + let l:prev_use_result_buffer = s:DB_get('use_result_buffer') + call s:DB_set('use_result_buffer', 0) + " In order to parse a statement, we must know what database type " we are dealing with to choose the correct cmd_terminator if s:DB_get("buffer_defaulted") != 1 @@ -5992,9 +6072,6 @@ function! dbext#DB_DictionaryCreate( drop_dict, which ) "{{{ call s:DB_set('DBI_max_rows', 0) endif - let l:prev_use_result_buffer = s:DB_get('use_result_buffer') - call s:DB_set('use_result_buffer', 0) - " Check if the dictionary has already been created, if so " return the current temporary file holding it let temp_file = s:DB_get("dict_".which_dict."_file") @@ -6962,9 +7039,13 @@ function! s:DB_addToResultBuffer(output, do_clear) " Store the line count of the result buffer let s:dbext_result_count = line('$') - " Return to original window - " exec cur_winnr."wincmd w" - exec s:dbext_prev_winnr."wincmd w" + if exists('s:dbext_prev_winnr') + " Return to original window + " exec cur_winnr."wincmd w" + exec s:dbext_prev_winnr."wincmd w" + else + call s:DB_warningMsg("dbext: No previous window") + endif return endfunction "}}} @@ -7065,12 +7146,37 @@ function! s:DB_searchReplace(str, exp_find_str, exp_get_value, count_matches) " Or the definition of a global variable " CREATE VARIABLE variable ... " If so, ignore the match + " Regex + " \( - Start multiple matches + " \< - Start word boundary + " \w\+ - Match any word character + " \ze - Stop the match + " \s* - Match can be followed by spaces or tabs + " $ - And ends at the end of the line + " \| - OR + " '' - empty string + " \ze - Stop the match + " $ - And ends at the end of the line + " \| - OR + " / - Literal + " \ze - Stop the match + " $ - And ends at the end of the line + " \| - OR + " ? - Literal + " \ze - Stop the match + " $ - And ends at the end of the line + " \| - OR + " @ - Literal + " \ze - Stop the match + " $ - And ends at the end of the line + " \) - End multiiple matches + " let inout = matchstr(strpart(str, 0, index), '\(\<\w\+\ze\s*$\|''\ze$\|/\ze$\|@\ze$\)') " The above query gathers the preceeding text to make the above " determination " if inout !~? '\(in\|out\|inout\|declare\|set\|variable\|''\|/\|@\)' - if s:DB_get('ignore_variable_regex') !~? inout + if inout == '' || s:DB_get('ignore_variable_regex') !~? inout " Check if the variable name is preceeded by a comment character. " If so, ignore and continue. if strpart(str, 0, (index-1)) !~ '\(--\|\/\/\)\s*$' diff --git a/autoload/dbext_dbi.vim b/autoload/dbext_dbi.vim index f6f3e4c..f178b21 100644 --- a/autoload/dbext_dbi.vim +++ b/autoload/dbext_dbi.vim @@ -4,10 +4,10 @@ " It adds transaction support and the ability " to reach any database currently supported " by Perl and DBI. -" Version: 19.00 +" Version: 20.00 " Maintainer: David Fishburn " Authors: David Fishburn -" Last Modified: 2013 Apr 29 +" Last Modified: 2013 Sep 02 " Created: 2007-05-24 " Homepage: http://vim.sourceforge.net/script.php?script_id=356 " @@ -119,7 +119,7 @@ if exists("g:loaded_dbext_dbi") finish endif -let g:loaded_dbext_dbi = 1900 +let g:loaded_dbext_dbi = 2000 " Turn on support for line continuations when creating the script let s:cpo_save = &cpo @@ -138,11 +138,14 @@ function! dbext_dbi#DBI_initialize() if !exists("dbext_dbi_sql") let g:dbext_dbi_sql = "" endif - if !exists("dbext_dbi_max_rows") - let g:dbext_dbi_max_rows = 300 + if !exists("dbext_default_DBI_max_rows") + let g:dbext_default_DBI_max_rows = 300 endif - if !exists("dbext_default_dbi_column_delimiter") - let g:dbext_default_dbi_column_delimiter = " " + if !exists("dbext_default_DBI_max_column_width") + let g:dbext_default_DBI_max_column_width = 0 + endif + if !exists("dbext_default_DBI_column_delimiter") + let g:dbext_default_DBI_column_delimiter = " " endif if !exists("dbext_dbi_trace_level") let g:dbext_dbi_trace_level = 0 @@ -230,7 +233,7 @@ endif " (db_format_array) then place in the global variable @result_set. " " Then I ask dbext for the column separator -" (dbext_default_dbi_column_delimiter, which defaults to 3 blank spaces). +" (dbext_default_DBI_column_delimiter, which defaults to 3 blank spaces). " " Then db_format_array() loops through the array, @result_set and using the " array of column maximums builds an appropriate length string so all columns @@ -279,10 +282,19 @@ my $test_inc = 0; my $conn_inc = 0; my $dbext_dbi_sql = ""; my $col_sep_vert = " "; +my $col_max_width = 0; my $debug = 0; -my $inside_vim = 0; my $native_err = 0; +my $inside_vim = 0; +eval { + VIM::Eval(1); +}; +if ($@) { + $inside_vim = 0; +} else { + $inside_vim = 1; +} # Sets a Vim variable to a value. Will worry about # escaping strings when necessary. @@ -371,13 +383,21 @@ sub db_vim_eval my $val; if( ! $inside_vim ) { + # This sub asks Vim for certain values. + # If we are running this as a Perl program outside of Vim + # then we cannot get Vim to evaluate what we need. + # So, for some of the values that we need to tweak to test + # we can return some default values for them. if( $cmd eq "bufnr('%')" ) { return 1; } - if( $cmd eq "g:dbext_dbi_max_rows" ) { + if( $cmd eq "g:dbext_default_DBI_max_rows" || $cmd eq "b:dbext_DBI_max_rows" ) { return 10; } - if( $cmd eq "g:dbext_default_dbi_column_delimiter" ) { + if( $cmd eq "g:dbext_default_DBI_max_column_width" || $cmd eq "b:dbext_DBI_max_column_width" ) { + return 0; + } + if( $cmd eq "g:dbext_default_DBI_column_delimiter" || $cmd eq "b:dbext_DBI_column_delimiter" ) { return "\t"; } } @@ -466,8 +486,11 @@ sub db_vim_print my $line_nbr = shift; my $line_txt = shift; my $printed_lines = 0; - my $max_col_width = $result_max_col_width + 2; + my $max_col_width = 2; + if( defined $result_max_col_width ) { + $max_col_width += $result_max_col_width; + } if ( ! defined($line_nbr) ) { db_echo('db_vim_print invalid line number'); return -1; @@ -499,7 +522,10 @@ sub db_vim_print db_set_vim_var('g:loaded_dbext_dbi_msg', 'db_get_defaults'); sub db_get_defaults { - $col_sep_vert = db_vim_eval('g:dbext_default_dbi_column_delimiter'); + $max_rows = db_vim_eval('g:dbext_default_DBI_max_rows'); + $col_sep_vert = db_vim_eval('g:dbext_default_DBI_column_delimiter'); + $col_max_width = db_vim_eval('g:dbext_default_DBI_max_column_width'); + db_debug("db_get_defaults:max rows[$max_rows] col separator[$col_sep_vert] max col width[$col_max_width]"); } db_set_vim_var('g:loaded_dbext_dbi_msg', 'db_escape'); @@ -726,9 +752,19 @@ sub db_get_connection return undef; } + # Each time a buffer is requested, look up any specific + # settings for this buffer. Since this is single threaded + # this approach is fine and allows for the settings to be + # changed at anytime. + $max_rows = db_vim_eval('b:dbext_DBI_max_rows'); + $col_sep_vert = db_vim_eval('b:dbext_DBI_column_delimiter'); + $col_max_width = db_vim_eval('b:dbext_DBI_max_column_width'); + db_debug("db_get_connection:max rows[$max_rows] col separator[$col_sep_vert] max col width[$col_max_width]"); + db_debug('db_get_connection:returning:'.$bufnr); $conn_local = $connections{$bufnr}->{'conn'}; $driver = $connections{$bufnr}->{'driver'}; + $connections{$bufnr}->{LastRequest} = localtime; return ($conn_local, $driver); } @@ -1042,18 +1078,20 @@ sub db_set_connection_option } else { # Use global connection object # This expecting a boolean value (ie AutoCommit) - $conn_local->{$option} = $value; - # or die $DBI::errstr; - db_debug("db_set_connection_option ConnLocal->Opt[$option] Val:[".$conn_local->{$option}."]"); - - my( $level, $err, $msg, $state ) = db_check_error($driver); - if ( ! $msg eq "" ) { - $msg = "$level. DBSO:".(($level ne "I")?"SQLCode:$err:":"").$msg.(($state ne "")?":$state":""); - db_set_vim_var('g:dbext_dbi_msg', $msg); - if ( $level eq "E" ) { - db_set_vim_var('g:dbext_dbi_result', -1); - db_debug("db_query:$msg - exiting"); - return -1; + if( defined $conn_local->{$option} ) { + $conn_local->{$option} = $value; + # or die $DBI::errstr; + db_debug("db_set_connection_option ConnLocal->Opt[$option] Val:[".$conn_local->{$option}."]"); + + my( $level, $err, $msg, $state ) = db_check_error($driver); + if ( ! $msg eq "" ) { + $msg = "$level. DBSO:".(($level ne "I")?"SQLCode:$err:":"").$msg.(($state ne "")?":$state":""); + db_set_vim_var('g:dbext_dbi_msg', $msg); + if ( $level eq "E" ) { + db_set_vim_var('g:dbext_dbi_result', -1); + db_debug("db_query:$msg - exiting"); + return -1; + } } } } @@ -1075,6 +1113,9 @@ sub db_query } $debug = db_is_debug(); + # Check for any updated default values + db_get_defaults(); + # db_debug("db_query:SQL:".$sql); if ( length($sql) == 0 ) { $sql = db_vim_eval('g:dbext_dbi_sql'); @@ -1094,7 +1135,7 @@ sub db_query ($conn_local, $driver) = db_get_connection(); my $sth = undef; - $conn_local->{LastRequest} = localtime; + #$conn_local->{LastRequest} = localtime; $sth = $conn_local->prepare( $sql ); # db_echo( "db_query:25".DBI::errstr ); @@ -1131,6 +1172,7 @@ sub db_query my $row_count = $sth->execute; + $row_count = 0 unless defined $row_count; db_debug("db_query:rowcount[$row_count] executed[$sql]"); if ( $row_count eq "0E0" || $row_count lt "0" ) { # 0E0 - Special case which means no rows were affected @@ -1180,11 +1222,13 @@ sub db_format_results my @table; my @headers; + return -1 unless defined $sth; + ($conn_local, $driver) = db_get_connection(); # Check if the NUM_OF_FIELDS is > 0. # In mysql a COMMIT does not provide a result set. - if ( $sth->{NUM_OF_FIELDS} > 0 ) { + if ( defined $sth->{NUM_OF_FIELDS} && $sth->{NUM_OF_FIELDS} > 0 ) { # Add the column list to the array push @headers,[ @{$sth->{NAME}} ]; # Set the initial length of the columns @@ -1192,6 +1236,10 @@ sub db_format_results $temp_length = length($col_name); $temp_length = ($temp_length > $min_col_width ? $temp_length : $min_col_width); $max_col_width = ( $temp_length > $max_col_width ? $temp_length : $max_col_width ); + if ( $col_max_width > 0 ) { + # $col_max_width is set via g:dbext_DBI_max_column_width + $max_col_width = ( $max_col_width > $col_max_width ? $col_max_width : $max_col_width ); + } $col_length[$i] = $temp_length; $i++; } @@ -1206,12 +1254,15 @@ sub db_format_results foreach my $col ( @{$row} ) { $temp_length = length((defined($col)?$col:"")); $col_length[$i] = ( $temp_length > $col_length[$i] ? $temp_length : $col_length[$i] ); + if ( $col_max_width > 0 ) { + # $col_max_width is set via g:dbext_DBI_max_column_width + $col_length[$i] = ( $col_length[$i] > $col_max_width ? $col_max_width : $col_length[$i] ); + } $i++; } # Cap the number of rows displayed. $row_count++; - $max_rows = db_vim_eval("g:dbext_dbi_max_rows"); if ( $max_rows > 0 && $row_count >= $max_rows ) { db_debug('Bailing on row count:'.$max_rows); last; @@ -1253,7 +1304,7 @@ sub db_format_results $result_max_col_width = $max_col_width; db_debug("db_format_results H:".Dumper(@result_headers)); - db_debug('db_format_results:R count:'.length(@result_set)); + db_debug('db_format_results:R count:'.scalar(@result_set)); db_debug("db_format_results R:".Dumper(@result_set)); db_format_array(); @@ -1305,12 +1356,14 @@ sub db_format_array() foreach my $col2 ( @{$row2} ) { $val = (defined($col2)?$col2:"NULL"); # Remove any unprintable characters - $val =~ tr/\x80-\xFF/ /d; + #$val =~ tr/\x80-\xFF/ /d; + $val =~ tr/\x80-\xFF/ /; # Remove the NULL character since Vim will treat this as # the end of the line # For more of these see: # http://www.asciitable.com/ - $val =~ tr/\x00/ /d; + #$val =~ tr/\x00/ /d; + $val =~ tr/\x00/ /; $fragment = substr ($val.(' ' x $result_col_length[$i]), 0, $result_col_length[$i]); $col2 = $fragment; $i++; @@ -1399,7 +1452,11 @@ sub db_print_results } else { my @formatted_headers; my $col_nbr = 0; - my $max_col_width = $result_max_col_width + 1; + my $max_col_width = 1; + + if( defined $result_max_col_width ) { + $max_col_width += $result_max_col_width; + } $i = 0; db_debug("db_print_results: Vertical, looping for col_length"); while ($i < scalar(@result_col_length) ) { @@ -1502,7 +1559,11 @@ sub db_results_variable } else { my @formatted_headers; my $col_nbr = 0; - my $max_col_width = $result_max_col_width + 1; + my $max_col_width = 1; + + if( defined $result_max_col_width ) { + $max_col_width += $result_max_col_width; + } $i = 0; while ($i < scalar(@result_col_length) ) { $fragment = ""; @@ -1595,7 +1656,11 @@ sub db_results_list } else { my @formatted_headers; my $col_nbr = 0; - my $max_col_width = $result_max_col_width + 1; + my $max_col_width = 1; + + if( defined $result_max_col_width ) { + $max_col_width += $result_max_col_width; + } $i = 0; while ($i < scalar(@result_col_length) ) { $fragment = ""; diff --git a/doc/dbext.txt b/doc/dbext.txt index 92dff8f..c6c34e1 100644 --- a/doc/dbext.txt +++ b/doc/dbext.txt @@ -1,4 +1,4 @@ -*dbext.txt* For Vim version 7.0. Last change: 2013 Apr 29 +*dbext.txt* For Vim version 7.0. Last change: 2013 Sep 24 VIM REFERENCE MANUAL @@ -7,7 +7,7 @@ Peter Bagyinszki Database extension plugin (dbext.vim) manual - dbext.vim version 19.00 + dbext.vim version 20.00 For instructions on installing this file, type :help add-local-help @@ -116,6 +116,45 @@ David Fishburn ============================================================================== 2. What's New *dbext-new* +Version 20.00 (September 24, 2013) + + New Features + ------------ + - Added new DBI/ODBC option DBI_max_column_width to restrict the width + displayed in the DBI result window (Luke Mauldin). + - Improved the pattern used to find the query under the cursor. Besides + finding the command terminator, it will also look for the first blank + line or the end of the file (Jason Quirk). + - The dbext menu now uses the maps rather than calls to the commands. + A new option will control this behaviour, g:dbext_map_or_cmd. + - Changed the default SQLite binary to be sqlite3 instead of sqlite + (Greg Kapfhammer). + - Added a profile example for using the "sqsh" binary to connect to + SQL Server instead of "osql" (Brian Iv�n Mart�nez). + - The cmd_terminator displayed under Connection Options in the DBGetOption + output was always blank. + - Improved support for SAP HANA database, pulling objects from the system + catalogue. + + Bug Fixes + --------- + - Controlling the DBI max rows (:DBSetOption DBI_max_rows=100) and DBI + column separator did not work on a per buffer basis. + - Undefined variable, s:dbext_prev_winnr, was reported when using DBI/ODBC + connections through the sqlComplete plugin and completing objects + which require an active database connection (i.e. Tables, + Procedures, ...) which had failed to connect to the database. + - dbext was not prompting for ? parameters in PHP files. This also + affected all languages (J�r�mie). + - Changing a database's global cmd terminator was not necessarily + picked up when using that database type (Jason Quirk). + - ODBC or DBI could report an error about using length() instead + of scalar() (Micah Duke). + - Various errors on Linux with DBI (Micah Duke). + - Using the console version of Vim displayed a number of "debug" messages + during initialization. + + Version 19.00 (April 29, 2013) New Features @@ -145,6 +184,7 @@ Version 19.00 (April 29, 2013) DBSetOption cmd_terminator= DBSetOption cmd_terminator=; + Version 18.00 (Nov 28, 2012) New Features @@ -1758,7 +1798,7 @@ Version 2.00 (Jul 11, 2004) dbext_default_SQLITE_extra = '' dbext_default_SQLSRV_bin = "osql" dbext_default_SQLSRV_cmd_header = "" - dbext_default_SQLSRV_cmd_terminator = "" + dbext_default_SQLSRV_cmd_terminator = "\ngo\n" dbext_default_SQLSRV_cmd_options = '-w 10000 -r -b -n' dbext_default_SQLSRV_extra = '' dbext_default_ORA_bin = "sqlplus" @@ -2130,6 +2170,11 @@ Version 2.00 (Jul 11, 2004) will use your mappings and will not create the default mappings. You can also specify the following to disable the default mappings: > let g:dbext_default_usermaps = 0 +< + By default the dbext menu will use the default mappings to execute commands. + You can change the behaviour to use the dbext commands instead by setting + the following option: > + let g:dbext_map_or_cmd = 'cmd' < Commands (In addition to the above mappings) @@ -2398,7 +2443,12 @@ To specify the type of database you connect to most often, you can place the " Microsoft SQL Server let g:dbext_default_profile_SQLSRV = 'type=SQLSRV:user=sa:passwd=whatever:host=localhost:replace_title=1' - let g:dbext_default_profile_mySQLServer = 'type=SQLSRV:integratedlogin=1:dbname=myDB' + let g:dbext_default_profile_mySQLServer = 'type=SQLSRV:integratedlogin=1:dbname=myDB' + " This SQL Server example uses sqsh to connect instead of the default osql + " binary by using the SQLSRV_bin connection parameter. Since this binary + " requires different parameters than osql, the "extra" connection option + " is used to add additional switches. + let g:dbext_default_profile_SQLSRV_sqsh='type=SQLSRV:user=User:passwd=Pass:host=Ip:SQLSRV_bin=sqsh:SQLSRV_cmd_options=:extra=-SFreetdsProfile -D dbname' " SQLite let g:dbext_default_profile_POPFile = 'type=SQLITE:SQLITE_bin=C:\Programs\POPFile\sqlite.exe:dbname=C:\Programs\POPFile\popfile.db' @@ -2412,7 +2462,7 @@ To specify the type of database you connect to most often, you can place the " HANA " The instance ID is specified via the extra parameter let g:dbext_default_profile_HANA_MySrv = 'type=HANA:user=SYSTEM:passwd=manager:host=myhost:extra=-i 60' - + let g:dbext_default_profile_ODBC_MySrv = 'type=ODBC:user=SYSTEM:passwd=manager:dsnname=My_HANA_DSN' < 9.5 Connection information in modelines *dbext-connect-modelines* *dbext-modelines* @@ -2552,15 +2602,32 @@ To specify the type of database you connect to most often, you can place the > " Since I repeatedly need to edit stored procedures, the CREATE PROCEDURE " statement is preceeded by an IF ... END IF block which will drop - " the procedure or it uses the CREATE OR REPLACE syntax. + " the procedure or it uses the CREATE OR REPLACE syntax. A third alternative + " is an ALTER PROCEDURE statement. " This function will visually select the IF block to the END; statement - " of the stored procedure and execute it. Or check for the + " of the stored procedure and execute it. Or check for the " CREATE OR REPLACE and stop there and look to the end. - function! SQLExecuteIfCreateReplace() + " Here are the 3 structures this will look for (all from column 0): + " Case 1: + " IF .. + " END IF; + " CREATE PROCEDURE + " BEGIN + " END; + " Case 2: + " CREATE OR REPLACE PROCEDURE + " BEGIN + " END; + " Case 3: + " ALTER PROCEDURE + " BEGIN + " END; + " + function! SQLExecuteIfCreateReplace() let l:old_sel = &sel let &sel = 'inclusive' let saveWrapScan=&wrapscan - let saveSearch=@/ + let saveSearch=@/ let l:reg_z = @z let &wrapscan=0 let @z = '' @@ -2569,24 +2636,27 @@ To specify the type of database you connect to most often, you can place the let endLine = 0 let curLine = line(".") let curCol = virtcol(".") - + " Must default the command terminator let l:dbext_cmd_terminator = ";" - + try " Search backwards and do NOT wrap " Find the line beginning with an IF clause " IF EXISTS( SELECT 1 ... " or find an or replace clause " CREATE OR REPLACE PROCEDURE ... - " And execute it until we find an - " END + " or find an ALTER PROCEDURE + " CREATE OR REPLACE PROCEDURE ... + " And execute it until we find an + " END " at the beginning of a line. - let startLine = search('\c\(^\\|\\)', 'bcnW' ) - + let startLine = search('\c\(^\\|^\\|\\)', 'bcnW' ) + if startLine > 0 " Search forward and visually select all lines " until we find an END; clause + " exe 'silent! norm! V/^END'.l:dbext_cmd_terminator."\s*$\n\" let endLine = search('^END'.l:dbext_cmd_terminator.'\s*$', 'cnW') exec startLine.','.endLine.'DBExecRangeSQL' endif @@ -2599,7 +2669,7 @@ To specify the type of database you connect to most often, you can place the let &wrapscan=saveWrapScan let &sel = l:old_sel endtry - endfunction + endfunction < The mapping I use to trigger the function is sbe using the mnemonic sql - begin - end diff --git a/plugin/dbext.vim b/plugin/dbext.vim index 8c58ad8..d98caf7 100644 --- a/plugin/dbext.vim +++ b/plugin/dbext.vim @@ -1,11 +1,11 @@ " dbext.vim - Commn Database Utility " Copyright (C) 2002-10, Peter Bagyinszki, David Fishburn " --------------------------------------------------------------- -" Version: 19.00 +" Version: 20.00 " Maintainer: David Fishburn " Authors: Peter Bagyinszki " David Fishburn -" Last Modified: 2013 Jan 21 +" Last Modified: 2013 Jun 02 " Based On: sqlplus.vim (author: Jamis Buck) " Created: 2002-05-24 " Homepage: http://vim.sourceforge.net/script.php?script_id=356 @@ -36,7 +36,7 @@ if v:version < 700 echomsg "dbext: Version 4.00 or higher requires Vim7. Version 3.50 can stil be used with Vim6." finish endif -let g:loaded_dbext = 1900 +let g:loaded_dbext = 2000 " Turn on support for line continuations when creating the script let s:cpo_save = &cpo @@ -54,6 +54,18 @@ if !exists('g:dbext_map_prefix') let g:dbext_map_prefix = 's' endif +if !exists('g:dbext_default_usermaps') + let g:dbext_default_usermaps = 1 +endif + +if !exists('g:dbext_map_or_cmd') + if g:dbext_default_usermaps != 0 + let g:dbext_map_or_cmd = 'map' + else + let g:dbext_map_or_cmd = 'cmd' + endif +endif + " Commands {{{ command! -nargs=+ DBExecSQL :call dbext#DB_execSql() command! -nargs=+ DBExecSQLTopX :call dbext#DB_execSqlTopX() @@ -224,112 +236,114 @@ if !exists(':DBResultsToggleResize') end "}}} " Mappings {{{ -if maparg(g:dbext_map_prefix.'e', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'e DBExecVisualSQL' -endif -if maparg(g:dbext_map_prefix.'E', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'E DBExecVisualTopXSQL' -endif -if maparg(g:dbext_map_prefix.'e', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'e DBExecSQLUnderCursor' -endif -if maparg(g:dbext_map_prefix.'E', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'E DBExecSQLUnderTopXCursor' -endif -if maparg(g:dbext_map_prefix.'q', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'q DBExecSQL' -endif -if maparg(g:dbext_map_prefix.'ea', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'ea :1,$DBExecRangeSQL' -endif -if maparg(g:dbext_map_prefix.'el', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'el :.,.DBExecRangeSQL' -endif -if maparg(g:dbext_map_prefix.'ep', 'n') == '' - exec 'nmap '.g:dbext_map_prefix."ep :'<,'>".'DBExecRangeSQL' -endif -if maparg(g:dbext_map_prefix.'t', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'t DBSelectFromTable' -endif -if maparg(g:dbext_map_prefix.'t', 'x') == '' - " This concatenation should result in this xmap command: - exec 'xmap '.g:dbext_map_prefix.'t :exec '.'"'."DBSelectFromTable '".'".DB_getVisualBlock()."'."'".'"'.'' -endif -if maparg(g:dbext_map_prefix.'tw', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'tw DBSelectFromTableWithWhere' -endif -if maparg(g:dbext_map_prefix.'ta', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'ta DBSelectFromTableAskName' -endif -if maparg(g:dbext_map_prefix.'T', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'T DBSelectFromTopXTable' -endif -if maparg(g:dbext_map_prefix.'T', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'T :exec '.'"'."DBSelectFromTableTopX '".'".DB_getVisualBlock()."'."'".'"'.'' -endif -if maparg(g:dbext_map_prefix.'dt', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'dt DBDescribeTable' -endif -if maparg(g:dbext_map_prefix.'dt', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'dt :exec '.'"'."DBDescribeTable '".'".DB_getVisualBlock()."'."'".'"'.'' -endif -if maparg(g:dbext_map_prefix.'dta', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'dta DBDescribeTableAskName' -endif -if maparg(g:dbext_map_prefix.'dp', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'dp DBDescribeProcedure' -endif -if maparg(g:dbext_map_prefix.'dp', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'dp :exec '.'"'."DBDescribeProcedure '".'".DB_getVisualBlock()."'."'".'"'.'' -endif -if maparg(g:dbext_map_prefix.'dpa', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'dpa DBDescribeProcedureAskName' -endif -if maparg(g:dbext_map_prefix.'bp', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'bp DBPromptForBufferParameters' -endif -if maparg(g:dbext_map_prefix.'lc', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'lc DBListColumn' -endif -if maparg(g:dbext_map_prefix.'lc', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'lc :exec '.'"'."DBListColumn '".'".DB_getVisualBlock()."'."'".'"'.'' -endif -if maparg(g:dbext_map_prefix.'lt', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'lt DBListTable' -endif -if maparg(g:dbext_map_prefix.'lp', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'lp DBListProcedure' -endif -if maparg(g:dbext_map_prefix.'lv', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'lv DBListView' -endif -if maparg(g:dbext_map_prefix.'tcl', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'tcl DBListColumn' -endif -if maparg(g:dbext_map_prefix.'tcl', 'x') == '' - " exec 'xmap stcl :exec '."'".'DBListColumn "'."'".'.DB_getVisualBlock().'."'".'"'."'".'' - exec 'xmap '.g:dbext_map_prefix.'tcl :exec '.'"'."DBListColumn '".'".DB_getVisualBlock()."'."'".'"'.'' -endif -if maparg(g:dbext_map_prefix.'h', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'h DBHistory' -endif -if maparg(g:dbext_map_prefix.'o', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'o DBOrientationToggle' -endif -if maparg(g:dbext_map_prefix.'as', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'as :1,$DBVarRangeAssign' -endif -if maparg(g:dbext_map_prefix.'al', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'al :.,.DBVarRangeAssign' -endif -if maparg(g:dbext_map_prefix.'ap', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'ap :'."'<,'>".'DBVarRangeAssign' -endif -if maparg(g:dbext_map_prefix.'a', 'x') == '' - exec 'xmap '.g:dbext_map_prefix.'a :DBVarRangeAssign' -endif -if maparg(g:dbext_map_prefix.'lr', 'n') == '' - exec 'nmap '.g:dbext_map_prefix.'lr :DBListVar' +if dbext_default_usermaps != 0 + if maparg(g:dbext_map_prefix.'e', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'e DBExecVisualSQL' + endif + if maparg(g:dbext_map_prefix.'E', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'E DBExecVisualTopXSQL' + endif + if maparg(g:dbext_map_prefix.'e', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'e DBExecSQLUnderCursor' + endif + if maparg(g:dbext_map_prefix.'E', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'E DBExecSQLUnderTopXCursor' + endif + if maparg(g:dbext_map_prefix.'q', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'q DBExecSQL' + endif + if maparg(g:dbext_map_prefix.'ea', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'ea :1,$DBExecRangeSQL' + endif + if maparg(g:dbext_map_prefix.'el', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'el :.,.DBExecRangeSQL' + endif + if maparg(g:dbext_map_prefix.'ep', 'n') == '' + exec 'nmap '.g:dbext_map_prefix."ep :'<,'>".'DBExecRangeSQL' + endif + if maparg(g:dbext_map_prefix.'t', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'t DBSelectFromTable' + endif + if maparg(g:dbext_map_prefix.'t', 'x') == '' + " This concatenation should result in this xmap command: + exec 'xmap '.g:dbext_map_prefix.'t :exec '.'"'."DBSelectFromTable '".'".DB_getVisualBlock()."'."'".'"'.'' + endif + if maparg(g:dbext_map_prefix.'tw', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'tw DBSelectFromTableWithWhere' + endif + if maparg(g:dbext_map_prefix.'ta', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'ta DBSelectFromTableAskName' + endif + if maparg(g:dbext_map_prefix.'T', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'T DBSelectFromTopXTable' + endif + if maparg(g:dbext_map_prefix.'T', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'T :exec '.'"'."DBSelectFromTableTopX '".'".DB_getVisualBlock()."'."'".'"'.'' + endif + if maparg(g:dbext_map_prefix.'dt', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'dt DBDescribeTable' + endif + if maparg(g:dbext_map_prefix.'dt', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'dt :exec '.'"'."DBDescribeTable '".'".DB_getVisualBlock()."'."'".'"'.'' + endif + if maparg(g:dbext_map_prefix.'dta', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'dta DBDescribeTableAskName' + endif + if maparg(g:dbext_map_prefix.'dp', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'dp DBDescribeProcedure' + endif + if maparg(g:dbext_map_prefix.'dp', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'dp :exec '.'"'."DBDescribeProcedure '".'".DB_getVisualBlock()."'."'".'"'.'' + endif + if maparg(g:dbext_map_prefix.'dpa', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'dpa DBDescribeProcedureAskName' + endif + if maparg(g:dbext_map_prefix.'bp', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'bp DBPromptForBufferParameters' + endif + if maparg(g:dbext_map_prefix.'lc', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'lc DBListColumn' + endif + if maparg(g:dbext_map_prefix.'lc', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'lc :exec '.'"'."DBListColumn '".'".DB_getVisualBlock()."'."'".'"'.'' + endif + if maparg(g:dbext_map_prefix.'lt', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'lt DBListTable' + endif + if maparg(g:dbext_map_prefix.'lp', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'lp DBListProcedure' + endif + if maparg(g:dbext_map_prefix.'lv', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'lv DBListView' + endif + if maparg(g:dbext_map_prefix.'tcl', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'tcl DBListColumn' + endif + if maparg(g:dbext_map_prefix.'tcl', 'x') == '' + " exec 'xmap stcl :exec '."'".'DBListColumn "'."'".'.DB_getVisualBlock().'."'".'"'."'".'' + exec 'xmap '.g:dbext_map_prefix.'tcl :exec '.'"'."DBListColumn '".'".DB_getVisualBlock()."'."'".'"'.'' + endif + if maparg(g:dbext_map_prefix.'h', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'h DBHistory' + endif + if maparg(g:dbext_map_prefix.'o', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'o DBOrientationToggle' + endif + if maparg(g:dbext_map_prefix.'as', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'as :1,$DBVarRangeAssign' + endif + if maparg(g:dbext_map_prefix.'al', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'al :.,.DBVarRangeAssign' + endif + if maparg(g:dbext_map_prefix.'ap', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'ap :'."'<,'>".'DBVarRangeAssign' + endif + if maparg(g:dbext_map_prefix.'a', 'x') == '' + exec 'xmap '.g:dbext_map_prefix.'a :DBVarRangeAssign' + endif + if maparg(g:dbext_map_prefix.'lr', 'n') == '' + exec 'nmap '.g:dbext_map_prefix.'lr :DBListVar' + endif endif "}}} " Menus {{{ @@ -348,49 +362,91 @@ if has("gui_running") && has("menu") && g:dbext_default_menu_mode != 0 endif let leader = escape(leader, '\') - exec 'vnoremenu