comparison autoload/dbtables.vim @ 1:8530ebeda72c

Adding actual db tables implementation from original script.
author Luka Sitas <lsitas@avatarasoftware.com>
date Wed, 11 Mar 2026 08:53:55 -0400
parents 238b45cc333b
children
comparison
equal deleted inserted replaced
0:238b45cc333b 1:8530ebeda72c
1 " autoload/dbtables.vim 1 " autoload/dbtables.vim
2 " Functions are loaded on demand 2 " Functions are loaded on demand
3 3
4 if exists('*dbtables#greet') 4 if exists('*dbtables#*')
5 finish 5 finish
6 endif 6 endif
7 7
8 function! dbtables#greet() abort 8
9 echo g:dbtables_greeting 9
10 endfunction 10 "=============================================
11 " Utilities
12 "=============================================
13
14 let s:query_history = []
15 let s:snippets = []
16
17
18
19 " - - - - - - - - - - - - - - - - - - - - - -
20 " DB/shell interaction
21 " - - - - - - - - - - - - - - - - - - - - - -
22
23 " Execute shell commands
24 function! s:ExecuteShellCommand(command)
25 let result = system(a:command . ' 2>&1')
26 return [v:shell_error == 0, result]
27 endfunction
28
29 " Execute a SQL query, directly to the db
30 function! s:ExecuteDBQuery(query)
31 let command = printf('mariadb --user=%s --password=%s --database=%s --host=%s -e %s',
32 \ shellescape(g:db_user), shellescape(g:db_password),
33 \ shellescape(g:db_name), shellescape(g:db_host),
34 \ shellescape(a:query))
35
36 let [success, result] = s:ExecuteShellCommand(command)
37 if success
38 return split(result, "\n")
39 else
40 call s:HandleDBError(result, command)
41 return []
42 endif
43 endfunction
44
45 " Function to execute SQL from the current buffer with parameter prompt
46 function! dbtables#ExecuteSQLQuery()
47 let query = join(getline(1, '$'), "\n")
48 call s:PromptAndExecuteQuery(query)
49 endfunction
50
51 " Function to execute SQL from a visual selection with parameter prompt
52 function! dbtables#ExecuteVisualSQLQuery() range
53 " Get the content of the selected lines as a single SQL query
54 let lines = getline(a:firstline, a:lastline)
55 let query = join(lines, "\n")
56
57 " Execute query with prompt for parameters
58 call s:PromptAndExecuteQuery(query)
59 endfunction
60
61 " Handle parameter prompts and execute query
62 function! s:PromptAndExecuteQuery(query)
63 " Identify parameters in the form of :parameter_name
64 let pattern = ':\(\k\+\)'
65 let params = []
66
67 " Find all matches in the query
68 let start = 0
69 while match(a:query, pattern, start) != -1
70 let match = matchstr(a:query, pattern, start)
71 if index(params, match) == -1
72 call add(params, match)
73 endif
74 let start = matchend(a:query, pattern, start)
75 endwhile
76
77 " Initialize a dictionary for parameters and their values
78 let param_values = {}
79
80 " Prompt user for each parameter
81 for param in params
82 let value = input('Enter value for ' . param . ': ')
83 let param_values[param] = value
84 endfor
85
86 " Replace parameters in the query with user-provided values
87 let updated_query = a:query
88 for [param, value] in items(param_values)
89 let updated_query = substitute(updated_query, param, value, 'g')
90 endfor
91
92 call add(s:query_history, updated_query)
93 call s:OpenInNewTab('SQLQueryResult', s:ExecuteDBQuery(updated_query))
94 endfunction
95
96 " Handle database command errors
97 function! s:HandleDBError(result, command)
98 echoerr 'Shell command failed: ' . a:command
99 if a:result =~# 'Access denied'
100 echoerr 'Authentication error: Check your username and password.'
101 elseif a:result =~# 'Unknown database'
102 echoerr 'Database error: The specified database does not exist.'
103 elseif a:result =~# 'Could not connect'
104 echoerr 'Connection error: Verify host and network connectivity.'
105 elseif a:result =~# 'You have an error in your SQL syntax'
106 echoerr 'Syntax error in SQL query.'
107 else
108 echoerr 'Unexpected error: ' . a:result
109 endif
110 endfunction
111
112
113
114 " - - - - - - - - - - - - - - - - - - - - - -
115 " Visuals
116 " - - - - - - - - - - - - - - - - - - - - - -
117
118 " Display data in a new read only buffer
119 function! s:OpenInNewTab(title, data)
120 tabnew
121 enew
122 execute 'file ' . a:title
123 if !empty(a:data)
124 call append(0, a:data)
125 else
126 call append(0, 'No data found or an error occurred.')
127 endif
128 setlocal filetype=sql buftype=nofile bufhidden=wipe nobuflisted noswapfile nomodifiable
129 endfunction
130
131
132
133 "=============================================
134 " DBTables
135 "=============================================
136 " Open the list of tables in the database as a
137 " buffer on the right side. Selecting a table
138 " shows either the tables schema or the data
139 " in the table.
140
141 function! dbtables#OpenDBTablesWindow()
142 execute '34 vsplit'
143 enew
144 file DBTables
145 let tables = s:ExecuteDBQuery("SHOW TABLES;")
146 if empty(tables)
147 echo "No tables found or an error occurred."
148 else
149 call append(0, ['Available Tables:'] + tables[1:])
150 setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
151 \ nomodifiable nonumber norelativenumber winfixwidth
152 nnoremap <buffer> <CR> :call <SID>ShowTablePopup()<CR>
153 endif
154 endfunction
155
156 " Open the database schema
157 function! s:OpenTableSchema(table)
158 call s:OpenInNewTab(a:table . '_schema', s:ExecuteDBQuery('DESCRIBE ' . a:table . ';'))
159 endfunction
160
161 " Open the table data
162 function! s:OpenTableData(table)
163 call s:OpenInNewTab(a:table, s:ExecuteDBQuery('SELECT * FROM ' . a:table . ';'))
164 endfunction
165
166 let s:popup_table = ""
167
168 " Popup selection for table actions
169 function! s:ShowTablePopup()
170 " Use Vim popup_menu if available
171 if exists('*popup_menu')
172 let s:popup_table = getline(line('.'))
173 let items = ['View Data', 'View Schema', 'Cancel']
174 call popup_menu(items, #{
175 \ callback: '<SID>HandlePopupSelection',
176 \ })
177 return
178 endif
179 " Popup_menu not available
180 echoerr 'Floating popup requires Vim8.2+.'
181 call s:ShowTableMenuModal()
182 endfunction
183
184 function! s:HandlePopupSelection(id, result)
185 let table = s:popup_table
186 call s:ClosePopup()
187 if a:result == 1
188 call s:OpenTableData(table)
189 elseif a:result == 2
190 call s:OpenTableSchema(table)
191 endif
192 endfunction
193
194 function! s:ClosePopup()
195 unlet! s:popup_table
196 endfunction
197
198
199
200 "=============================================
201 " Query History
202 "=============================================
203 " Shows the list of recently ran queries.
204 " Selecting a query will re-run it.
205
206 " View query history
207 function! dbtables#OpenQueryHistory()
208 " Open the query history in a new split window
209 execute 'vsplit'
210 enew
211 call setline(1, s:query_history)
212 nnoremap <buffer> <CR> :call s:OpenInNewTab('SQLQueryResult',
213 \ s:ExecuteDBQuery(getline(line('.'))))<CR>
214 setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile wrap
215 endfunction
216
217
218
219 "=============================================
220 " Query Snippets
221 "=============================================
222 " Shows the list of pre-set query snippets.
223 " Selecting a snippet will open it in a new
224 " tab to be executed or modified.
225
226 " View query snippets
227 function! dbtables#OpenQuerySnippets()
228 " Open the query snippets in a new split window
229 execute '34 vsplit'
230 enew
231
232 " Populate the buffer with the list of snippet files
233 let s:snippets = globpath(g:snippets_directory, '*', 0, 1)
234 let l:display = mapnew(s:snippets, 'fnamemodify(v:val, ":t:r")')
235 call setline(1, l:display)
236
237 nnoremap <buffer> <CR> :call s:OpenInNewTab(line('.'),
238 \ fnameescape(s:snippets[a:lnum-1]))<CR>
239
240 setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile wrap
241 endfunction
242
243
244
245 "=============================================
246 " DB Console
247 "=============================================
248 " Opens a console to interact with the DB.
249
250 " Open MariaDB console
251 function! dbtables#DBConsole()
252 " Save the current cursor position
253 let save_cursor = getpos(".")
254 let command = printf('mariadb --user=%s --password=%s --database=%s --host=%s',
255 \ g:db_user, g:db_password,
256 \ g:db_name, g:db_host)
257
258 let command = substitute(command, '\n', '', 'g')
259 execute ':term ' . command
260 call setpos(".", save_cursor)
261 endfunction