Skip to content

Commit d6dbd33

Browse files
bagyi0vim-scripts
authored andcommitted
Version 5.11
Posted by David Fishburn. New Features ------------ - Added support for Oracle Rdb on an Open VMS Node. For vim on Open VMS look at http://www.polarhome.com/vim/. For Open VMS http://h71000.www7.hp.com/openvms/. Development of Rdb support by Andi Stern
1 parent 6103cc4 commit d6dbd33

File tree

4 files changed

+275
-28
lines changed

4 files changed

+275
-28
lines changed

autoload/dbext.vim

Lines changed: 257 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
" dbext.vim - Commn Database Utility
22
" Copyright (C) 2002-7, Peter Bagyinszki, David Fishburn
33
" ---------------------------------------------------------------
4-
" Version: 5.06
4+
" Version: 5.11
55
" Maintainer: David Fishburn <[email protected]>
66
" Authors: Peter Bagyinszki <[email protected]>
77
" David Fishburn <[email protected]>
8-
" Last Modified: Wed 15 Aug 2007 04:49:24 PM Eastern Daylight Time
8+
" Last Modified: Mon 10 Sep 2007 09:34:14 AM Eastern Daylight Time
99
" Based On: sqlplus.vim (author: Jamis Buck)
1010
" Created: 2002-05-24
1111
" Homepage: http://vim.sourceforge.net/script.php?script_id=356
1212
" Contributors: Joerg Schoppet <[email protected]>
1313
" Hari Krishna Dara <[email protected]>
1414
" Ron Aaron
15+
" Andi Stern
1516
"
1617
" SourceForge: $Revision: 1.38 $
1718
"
@@ -38,7 +39,7 @@ if v:version < 700
3839
echomsg "dbext: Version 4.00 or higher requires Vim7. Version 3.50 can stil be used with Vim6."
3940
finish
4041
endif
41-
let g:loaded_dbext_auto = 506
42+
let g:loaded_dbext_auto = 511
4243

4344
" call confirm("Loaded dbext autoload", "&Ok")
4445
" Script variable defaults, these are used internal and are never displayed
@@ -47,7 +48,7 @@ let s:dbext_buffers_with_dict_files = ''
4748
" +shellslash is set on windows so it can be used to decide
4849
" what type of slash to use
4950
let s:dbext_tempfile = fnamemodify(tempname(), ":h").
50-
\ ((has('win32') && ! exists('+shellslash'))?'\':'/').
51+
\ ((has('win32') && ! exists('+shellslash'))?'\':(has('vms')?'':'/')).
5152
\ 'dbext.sql'
5253
let s:dbext_prev_sql = ''
5354
" }}}
@@ -76,6 +77,8 @@ function! s:DB_buildLists()
7677
call add(s:db_types_mv, 'SQLSRV')
7778
" SQLite (fishburn)
7879
call add(s:db_types_mv, 'SQLITE')
80+
" Oracle Rdb (stern)
81+
call add(s:db_types_mv, 'RDB')
7982

8083
" The following are only available with the
8184
" Perl DBI extension plug.
@@ -232,26 +235,19 @@ function! s:DB_buildLists()
232235

233236

234237
" Check if the user has any profiles defined in his vimrc
235-
let saveA = @a
236-
redir @a
237-
silent! exec 'let'
238+
redir => vars
239+
silent! let g:
238240
redir END
239-
let l:global_vars = @a
240-
let @a = saveA
241+
let varlist = split(vars, '\n')
242+
call map(varlist, 'matchstr(v:val, ''^\S\+'')')
243+
call filter(varlist, 'v:val =~ ''^dbext_default_profile_''')
241244

242-
let prof_nm_re = 'dbext_default_profile_\zs\(\w\+\)'
243-
let index = match(l:global_vars, prof_nm_re)
244-
while index > -1
245-
" Retrieve the name of option
246-
let prof_name = matchstr(l:global_vars, '\w\+', index)
245+
for item in varlist
246+
let prof_name = matchstr(item, 'dbext_default_profile_\zs\(\w\+\)')
247247
if strlen(prof_name) > 0
248-
let prof_value = matchstr(l:global_vars, '\s*\zs[^'."\<C-J>".']\+',
249-
\ (index + strlen(prof_name)) )
250248
call add(s:conn_profiles_mv, prof_name)
251249
endif
252-
let index = index + strlen(prof_name)+ strlen(prof_value) + 1
253-
let index = match(l:global_vars, prof_nm_re, index)
254-
endwhile
250+
endfor
255251
" Sort the list ignoring CaSe
256252
let s:conn_profiles_mv = sort(s:conn_profiles_mv,1)
257253
" Build the profile prompt string
@@ -260,6 +256,35 @@ function! s:DB_buildLists()
260256
\ loop_count . '. ' . item
261257
let loop_count += 1
262258
endfor
259+
" " Check if the user has any profiles defined in his vimrc
260+
" let saveA = @a
261+
" redir @a
262+
" silent! exec 'let'
263+
" redir END
264+
" let l:global_vars = @a
265+
" let @a = saveA
266+
267+
" let prof_nm_re = 'dbext_default_profile_\zs\(\w\+\)'
268+
" let index = match(l:global_vars, prof_nm_re)
269+
" while index > -1
270+
" " Retrieve the name of option
271+
" let prof_name = matchstr(l:global_vars, '\w\+', index)
272+
" if strlen(prof_name) > 0
273+
" let prof_value = matchstr(l:global_vars, '\s*\zs[^'."\<C-J>".']\+',
274+
" \ (index + strlen(prof_name)) )
275+
" call add(s:conn_profiles_mv, prof_name)
276+
" endif
277+
" let index = index + strlen(prof_name)+ strlen(prof_value) + 1
278+
" let index = match(l:global_vars, prof_nm_re, index)
279+
" endwhile
280+
" " Sort the list ignoring CaSe
281+
" let s:conn_profiles_mv = sort(s:conn_profiles_mv,1)
282+
" " Build the profile prompt string
283+
" for item in s:conn_profiles_mv
284+
" let s:prompt_profile_list = s:prompt_profile_list . "\n" .
285+
" \ loop_count . '. ' . item
286+
" let loop_count += 1
287+
" endfor
263288

264289
" Check if we are using Cygwin, if so, let the user override
265290
" the temporary filename to use backslashes
@@ -749,10 +774,13 @@ function! s:DB_getDefault(name)
749774
elseif a:name ==# "DB2_SQL_Top_pat" |return (exists("g:dbext_default_DB2_SQL_Top_pat")?g:dbext_default_DB2_SQL_Top_pat.'':'\(\cselect\)')
750775
elseif a:name ==# "DB2_SQL_Top_sub" |return (exists("g:dbext_default_DB2_SQL_Top_sub")?g:dbext_default_DB2_SQL_Top_sub.'':'\1 TOP @dbext_topX ')
751776
elseif a:name ==# "INGRES_bin" |return (exists("g:dbext_default_INGRES_bin")?g:dbext_default_INGRES_bin.'':'sql')
777+
elseif a:name ==# "INGRES_cmd_options" |return (exists("g:dbext_default_INGRES_cmd_options")?g:dbext_default_INGRES_cmd_options.'':'')
752778
elseif a:name ==# "INGRES_cmd_terminator" |return (exists("g:dbext_default_INGRES_cmd_terminator")?g:dbext_default_INGRES_cmd_terminator.'':'\p\g')
753779
elseif a:name ==# "INTERBASE_bin" |return (exists("g:dbext_default_INTERBASE_bin")?g:dbext_default_INTERBASE_bin.'':'isql')
780+
elseif a:name ==# "INTERBASE_cmd_options" |return (exists("g:dbext_default_INTERBASE_cmd_options")?g:dbext_default_INTERBASE_cmd_options.'':'')
754781
elseif a:name ==# "INTERBASE_cmd_terminator"|return (exists("g:dbext_default_INTERBASE_cmd_terminator")?g:dbext_default_INTERBASE_cmd_terminator.'':';')
755782
elseif a:name ==# "MYSQL_bin" |return (exists("g:dbext_default_MYSQL_bin")?g:dbext_default_MYSQL_bin.'':'mysql')
783+
elseif a:name ==# "MYSQL_cmd_options" |return (exists("g:dbext_default_MYSQL_cmd_options")?g:dbext_default_MYSQL_cmd_options.'':'')
756784
elseif a:name ==# "MYSQL_cmd_terminator" |return (exists("g:dbext_default_MYSQL_cmd_terminator")?g:dbext_default_MYSQL_cmd_terminator.'':';')
757785
elseif a:name ==# "MYSQL_version" |return (exists("g:dbext_default_MYSQL_version")?g:dbext_default_MYSQL_version.'':'5')
758786
elseif a:name ==# "MYSQL_SQL_Top_pat" |return (exists("g:dbext_default_MYSQL_SQL_Top_pat")?g:dbext_default_MYSQL_SQL_Top_pat.'':'\(.*\)')
@@ -771,11 +799,21 @@ function! s:DB_getDefault(name)
771799
elseif a:name ==# "ORA_SQL_Top_pat" |return (exists("g:dbext_default_ORA_SQL_Top_pat")?g:dbext_default_ORA_SQL_Top_pat.'':'\(.*\)')
772800
elseif a:name ==# "ORA_SQL_Top_sub" |return (exists("g:dbext_default_ORA_SQL_Top_sub")?g:dbext_default_ORA_SQL_Top_sub.'':'SELECT * FROM (\1) WHERE rownum <= @dbext_topX ')
773801
elseif a:name ==# "PGSQL_bin" |return (exists("g:dbext_default_PGSQL_bin")?g:dbext_default_PGSQL_bin.'':'psql')
802+
elseif a:name ==# "PGSQL_cmd_options" |return (exists("g:dbext_default_PGSQL_cmd_options")?g:dbext_default_PGSQL_cmd_options.'':'')
774803
elseif a:name ==# "PGSQL_cmd_terminator" |return (exists("g:dbext_default_PGSQL_cmd_terminator")?g:dbext_default_PGSQL_cmd_terminator.'':';')
775804
elseif a:name ==# "PGSQL_SQL_Top_pat" |return (exists("g:dbext_default_PGSQL_SQL_Top_pat")?g:dbext_default_PGSQL_SQL_Top_pat.'':'\(.*\)')
776805
elseif a:name ==# "PGSQL_SQL_Top_sub" |return (exists("g:dbext_default_PGSQL_SQL_Top_sub")?g:dbext_default_PGSQL_SQL_Top_sub.'':'\1 LIMIT @dbext_topX ')
806+
elseif a:name ==# "RDB_bin" |return (exists("g:dbext_default_RDB_bin")?g:dbext_default_RDB_bin.'':'mc sql$')
807+
elseif a:name ==# "RDB_cmd_header" |return (exists("g:dbext_default_RDB_cmd_header")?g:dbext_default_RDB_cmd_header.'':"".
808+
\ "set line length 10000\n" .
809+
\ "set page length 10000\n")
810+
elseif a:name ==# "RDB_cmd_options" |return (exists("g:dbext_default_RDB_cmd_options")?g:dbext_default_RDB_cmd_options.'':"")
811+
elseif a:name ==# "RDB_cmd_terminator" |return (exists("g:dbext_default_RDB_cmd_terminator")?g:dbext_default_RDB_cmd_terminator.'':";\n")
812+
elseif a:name ==# "RDB_SQL_Top_pat" |return (exists("g:dbext_default_RDB_SQL_Top_pat")?g:dbext_default_RDB_SQL_Top_pat.'':'\(.*\)')
813+
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 ')
777814
elseif a:name ==# "SQLITE_bin" |return (exists("g:dbext_default_SQLITE_bin")?g:dbext_default_SQLITE_bin.'':'sqlite')
778815
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")
816+
elseif a:name ==# "SQLITE_cmd_options" |return (exists("g:dbext_default_SQLITE_cmd_options")?g:dbext_default_SQLITE_cmd_options.'':'')
779817
elseif a:name ==# "SQLITE_cmd_terminator" |return (exists("g:dbext_default_SQLITE_cmd_terminator")?g:dbext_default_SQLITE_cmd_terminator.'':';')
780818
elseif a:name ==# "SQLSRV_bin" |return (exists("g:dbext_default_SQLSRV_bin")?g:dbext_default_SQLSRV_bin.'':'osql')
781819
elseif a:name ==# "SQLSRV_cmd_options" |return (exists("g:dbext_default_SQLSRV_cmd_options")?g:dbext_default_SQLSRV_cmd_options.'':'-w 10000 -r -b -n')
@@ -2733,6 +2771,205 @@ function! s:DB_PGSQL_getDictionaryView()
27332771
return s:DB_PGSQL_stripHeaderFooter(result)
27342772
endfunction
27352773
"}}}
2774+
" RDB exec {{{
2775+
function! s:DB_RDB_describeProcedure(procedure_name) "{{{
2776+
return s:DB_RDB_execSql("show procedure " . a:procedure_name)
2777+
endfunction "}}}
2778+
function! s:DB_RDB_describeTable(table_name) "{{{
2779+
return s:DB_RDB_execSql("show table " . a:table_name)
2780+
endfunction "}}}
2781+
function! s:DB_RDB_execSql(str) "{{{
2782+
let host = s:DB_get("host")
2783+
let srvname = s:DB_get("srvname")
2784+
let user = s:DB_get("user")
2785+
let passwd = s:DB_get("passwd")
2786+
let sup = ''
2787+
2788+
if host != ''
2789+
let srvname = host
2790+
endif
2791+
if srvname != ''
2792+
if user != ''
2793+
if passwd != ''
2794+
let sup = srvname . '"' . user . ' ' . passwd . '"::'
2795+
else
2796+
let sup = srvname . '"' . user . '"::'
2797+
endif
2798+
else
2799+
let sup = srvname . '::'
2800+
endif
2801+
endif
2802+
2803+
" All defaults are specified in the DB_getDefault function.
2804+
" This contains the defaults settings for all database types
2805+
let output = s:DB_option(
2806+
\ 'attach ''filename ',
2807+
\ sup . s:DB_get("dbname"),
2808+
\ ''''
2809+
\ ) .
2810+
\ dbext#DB_getWType("cmd_terminator") .
2811+
\ dbext#DB_getWType("cmd_header") .
2812+
\ a:str
2813+
" Only include a command terminator if one has not already
2814+
" been added
2815+
if output !~ s:DB_escapeStr(dbext#DB_getWType("cmd_terminator")) .
2816+
\ '['."\n".' \t]*$'
2817+
let output = output . dbext#DB_getWType("cmd_terminator")
2818+
endif
2819+
" Added quit to the end of the command to exit SQLPLUS
2820+
if output !~ s:DB_escapeStr("\nquit".dbext#DB_getWType("cmd_terminator")) .
2821+
\ '['."\n".' \t]*$'
2822+
let output = output . "\nquit".dbext#DB_getWType("cmd_terminator")
2823+
endif
2824+
2825+
exe 'redir! > ' . s:dbext_tempfile
2826+
silent echo output
2827+
redir END
2828+
2829+
let dbext_bin = s:DB_fullPath2Bin(dbext#DB_getWType("bin"))
2830+
2831+
let cmd = dbext_bin . ' @' . s:dbext_tempfile
2832+
let result = s:DB_runCmd(cmd, output, "")
2833+
2834+
return result
2835+
endfunction "}}}
2836+
function! s:DB_RDB_getDictionaryProcedure() "{{{
2837+
let result = s:DB_RDB_execSql(
2838+
\ "select ".(s:DB_get('dict_show_owner')==1?"decode(bitstring (RDB$FLAGS from 20 for 1),0,trim(RDB$ROUTINE_CREATOR),'SYS')||'.'||":'').
2839+
\ "RDB$ROUTINE_NAME ".
2840+
\ "from RDB$ROUTINES ".
2841+
\ "where bitstring (RDB$FLAGS from 20 for 1) = 0 ".
2842+
\ "order by RDB$ROUTINE_NAME "
2843+
\ )
2844+
return s:DB_RDB_stripHeaderFooter(result)
2845+
endfunction "}}}
2846+
function! s:DB_RDB_getDictionaryTable() "{{{
2847+
let result = s:DB_RDB_execSql(
2848+
\ "select ".(s:DB_get('dict_show_owner')==1?"decode(RDB$SYSTEM_FLAG,0,trim(RDB$RELATION_CREATOR),'SYS')||'.'||":'').
2849+
\ "RDB$RELATION_NAME ".
2850+
\ "from RDB$RELATIONS ".
2851+
\ "where RDB$VIEW_BLR is null " .
2852+
\ "order by RDB$RELATION_NAME "
2853+
\ )
2854+
return s:DB_RDB_stripHeaderFooter(result)
2855+
endfunction "}}}
2856+
function! s:DB_RDB_getDictionaryView() "{{{
2857+
let result = s:DB_RDB_execSql(
2858+
\ "select ".(s:DB_get('dict_show_owner')==1?"decode(RDB$SYSTEM_FLAG,0,trim(RDB$RELATION_CREATOR),'SYS')||'.'||":'').
2859+
\ "RDB$RELATION_NAME " .
2860+
\ "from RDB$RELATIONS " .
2861+
\ "where RDB$VIEW_BLR is not null " .
2862+
\ "order by RDB$RELATION_NAME "
2863+
\ )
2864+
return s:DB_RDB_stripHeaderFooter(result)
2865+
endfunction "}}}
2866+
function! s:DB_RDB_getListColumn(table_name) "{{{
2867+
let owner = toupper(s:DB_getObjectOwner(a:table_name))
2868+
let table_name = toupper(s:DB_getObjectName(a:table_name))
2869+
let query = "select RDB$FIELD_NAME \"\"".
2870+
\ "from RDB$RELATION_FIELDS RF inner join RDB$RELATIONS R using (RDB$RELATION_NAME) ".
2871+
\ "where RDB$RELATION_NAME = '".table_name."' "
2872+
if strlen(owner) > 0
2873+
let query = query .
2874+
\ "and decode(R.RDB$SYSTEM_FLAG,0,R.RDB$RELATION_CREATOR,'SYS') = '".owner."' "
2875+
endif
2876+
let query = query .
2877+
\ "order by RF.RDB$FIELD_POSITION "
2878+
let result = s:DB_RDB_execSql( query )
2879+
return s:DB_RDB_stripHeaderFooter(result)
2880+
endfunction "}}}
2881+
function! s:DB_RDB_getListProcedure(proc_prefix) "{{{
2882+
let owner = toupper(s:DB_getObjectOwner(a:proc_prefix))
2883+
let obj_name = toupper(s:DB_getObjectName(a:proc_prefix))
2884+
" RDB$ROUTINES.RDB$FLAGS "{{{
2885+
" Represents flags for RDB$ROUTINES system table.
2886+
"
2887+
" Bit
2888+
" Position Description
2889+
"
2890+
" 0 Routine is a function. (Call returns a result.)
2891+
" 1 Routine is not valid. (Invalidated by a metadata
2892+
" change.)
2893+
" 2 The function is not deterministic (that is, the routine
2894+
" is variant). A subsequent invocation of the routine
2895+
" with identical parameters may return different results.
2896+
" 3 Routine can change the transaction state.
2897+
" 4 Routine is in a secured shareable image.
2898+
" 5 Reserved for future use.
2899+
" 6 Routine is not valid. (Invalidated by a metadata change
2900+
" to the object upon which this routine depends. This
2901+
" dependency is a language semantics dependency.)
2902+
" 7 Reserved for future use.
2903+
" 8 External function returns NULL when called with any
2904+
" NULL parameter.
2905+
" 9 Routine has been analyzed (used for trigger dependency
2906+
" tracking).
2907+
" 10 Routine inserts rows.
2908+
" 11 Routine modifies rows.
2909+
" 12 Routine deletes rows.
2910+
" 13 Routine selects rows.
2911+
" 14 Routine calls other routines.
2912+
" 15 Reserved for future use.
2913+
" 16 Routine created with USAGE IS LOCAL clause.
2914+
" 17 Reserved for future use.
2915+
" 18 Reserved for future use.
2916+
" 19 Routine is a SYSTEM routine.
2917+
" 20 Routine generated by Oracle Rdb.
2918+
" Other bits are reserved for future use. "}}}
2919+
2920+
let query = "select RDB$ROUTINE_NAME, ".
2921+
\ "decode(bitstring (RDB$FLAGS from 20 for 1),0,RDB$ROUTINE_CREATOR,'SYS') RDB$ROUTINE_CREATOR ".
2922+
\ "from RDB$ROUTINES ".
2923+
\ "where RDB$ROUTINE_NAME LIKE '".obj_name."%' "
2924+
if strlen(owner) > 0
2925+
let query = query .
2926+
\ "and decode(bitstring (RDB$FLAGS from 20 for 1),0,RDB$ROUTINE_CREATOR,'SYS') = '".owner."' "
2927+
endif
2928+
let query = query .
2929+
\ " order by RDB$ROUTINE_NAME"
2930+
return s:DB_RDB_execSql( query )
2931+
endfunction "}}}
2932+
function! s:DB_RDB_getListTable(table_prefix) "{{{
2933+
let owner = toupper(s:DB_getObjectOwner(a:table_prefix))
2934+
let table_name = toupper(s:DB_getObjectName(a:table_prefix))
2935+
let query = "select RDB$RELATION_NAME, decode(RDB$SYSTEM_FLAG,0,RDB$RELATION_CREATOR,'SYS'), 'RDB_TABLESPACE' ".
2936+
\ "from RDB$RELATIONS ".
2937+
\ "where RDB$RELATION_NAME LIKE '".table_name."%' "
2938+
if strlen(owner) > 0
2939+
let query = query .
2940+
\ "and decode(RDB$SYSTEM_FLAG,0,RDB$RELATION_CREATOR,'SYS') = '".owner."' "
2941+
endif
2942+
let query = query .
2943+
\ "order by RDB$RELATION_NAME"
2944+
return s:DB_RDB_execSql( query )
2945+
endfunction "}}}
2946+
function! s:DB_RDB_getListView(view_prefix) "{{{
2947+
let owner = toupper(s:DB_getObjectOwner(a:view_prefix))
2948+
let obj_name = toupper(s:DB_getObjectName(a:view_prefix))
2949+
let query = "select RDB$RELATION_NAME, decode(RDB$SYSTEM_FLAG,0,RDB$RELATION_CREATOR,'SYS') ".
2950+
\ "from RDB$RELATIONS ".
2951+
\ "where RDB$RELATION_NAME LIKE '".obj_name."%' " .
2952+
\ "and RDB$VIEW_BLR is not null "
2953+
if strlen(owner) > 0
2954+
let query = query .
2955+
\ "and decode(RDB$SYSTEM_FLAG,0,RDB$RELATION_CREATOR,'SYS') = '".owner."' "
2956+
endif
2957+
let query = query .
2958+
\ "order by RDB$RELATION_NAME"
2959+
return s:DB_RDB_execSql( query )
2960+
endfunction "}}}
2961+
function! s:DB_RDB_stripHeaderFooter(result) "{{{
2962+
" Strip off column headers ending with a newline
2963+
let stripped = substitute( a:result, '\_.*-\s*'."[\<C-J>]", '', '' )
2964+
" Strip off query statistics
2965+
let stripped = substitute( stripped, '\d\+ rows\_.*', '', '' )
2966+
" Strip off no rows selected
2967+
let stripped = substitute( stripped, 'no rows selected\_.*', '', '' )
2968+
" Strip off trailing spaces
2969+
let stripped = substitute( stripped, '\(\<\w\+\>\)\s*', '\1', 'g' )
2970+
return stripped
2971+
endfunction "}}}
2972+
"}}}
27362973
" SQLSRV exec {{{
27372974
function! s:DB_SQLSRV_execSql(str)
27382975
let output = dbext#DB_getWType("cmd_header") . a:str
@@ -5107,7 +5344,7 @@ function! s:DB_runCmd(cmd, sql, result)
51075344
if (v:shell_error && s:DB_get('type') !~ '\<DBI\>\|\<ODBC\>') ||
51085345
\ (dbi_result == -1 && s:DB_get('type') =~ '\<DBI\>\|\<ODBC\>')
51095346
let output = "To change connection parameters:\n" .
5110-
\ ":DBPromptForParameters\n" .
5347+
\ ":DBPromptForBufferParameters\n" .
51115348
\ "Or\n" .
51125349
\ ":DBSetOption user\|passwd\|dsnname\|srvname\|dbname\|host\|port\|...=<value>\n" .
51135350
\ ":DBSetOption user=tiger:passwd=scott\n" .

0 commit comments

Comments
 (0)