Mercurial > vim
comparison plugins/dbtables.vim.new @ 4:1a705d7a7521
working on stuff
| author | luka |
|---|---|
| date | Thu, 23 Oct 2025 12:33:51 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 3:951569ccb9c7 | 4:1a705d7a7521 |
|---|---|
| 1 let g:db_user = "" " Replace with your default database username | |
| 2 let g:db_password = "" " Replace with your default database password | |
| 3 let g:db_name = "" " Replace with your default database name | |
| 4 let g:db_host = "" " Replace with your default database name | |
| 5 | |
| 6 let s:popup_table = "" | |
| 7 | |
| 8 | |
| 9 " Helper function to execute a command and handle errors | |
| 10 function! s:ExecuteShellCommand(command) | |
| 11 let result = system(a:command . ' 2>&1') | |
| 12 if v:shell_error != 0 | |
| 13 return [v:false, result] | |
| 14 endif | |
| 15 return [v:true, result] | |
| 16 endfunction | |
| 17 | |
| 18 function! s:ExecuteDBQuery(query) | |
| 19 let db_user = shellescape(g:db_user) | |
| 20 let db_password = shellescape(g:db_password) | |
| 21 let db_name = shellescape(g:db_name) | |
| 22 let db_host = shellescape(g:db_host) | |
| 23 | |
| 24 let command = 'mariadb --user=' . db_user | |
| 25 \ . ' --password=' . db_password | |
| 26 \ . ' --database=' . db_name | |
| 27 \ . ' --host=' . db_host | |
| 28 \ . ' -e ' . shellescape(a:query) | |
| 29 | |
| 30 let [success, result] = s:ExecuteShellCommand(command) | |
| 31 | |
| 32 if !success | |
| 33 call s:HandleDBError(result, command) | |
| 34 return [] | |
| 35 endif | |
| 36 return split(result, "\n") | |
| 37 endfunction | |
| 38 | |
| 39 function! s:HandleDBError(result, command) | |
| 40 echoerr 'Shell command failed: ' . a:command | |
| 41 echoerr a:result | |
| 42 | |
| 43 if a:result =~# 'Access denied' | |
| 44 echoerr 'Authentication error: Check your username and password.' | |
| 45 elseif a:result =~# 'Unknown database' | |
| 46 echoerr 'Database error: The specified database does not exist.' | |
| 47 elseif a:result =~# 'Could not connect' | |
| 48 echoerr 'Connection error: Verify host and network connectivity.' | |
| 49 elseif a:result =~# 'You have an error in your SQL syntax' | |
| 50 echoerr 'Syntax error in SQL query.' | |
| 51 else | |
| 52 echoerr 'Unexpected error: ' . a:result | |
| 53 endif | |
| 54 endfunction | |
| 55 | |
| 56 | |
| 57 " Show the structure/schema of the selected table | |
| 58 function! s:ShowTableSchema(table) | |
| 59 " Open a new tab for schema | |
| 60 tabnew | |
| 61 enew | |
| 62 execute 'file ' . table . '_schema' | |
| 63 " Describe the table structure | |
| 64 let data = s:ExecuteDBQuery('DESCRIBE ' . table . ';') | |
| 65 if len(data) > 0 | |
| 66 call append(0, data) | |
| 67 else | |
| 68 call append(0, 'No schema found or an error occurred.') | |
| 69 endif | |
| 70 " Set buffer options and syntax | |
| 71 setlocal filetype=sql buftype=nofile bufhidden=wipe nobuflisted noswapfile nomodifiable | |
| 72 endfunction | |
| 73 | |
| 74 | |
| 75 " Popup selection for table actions | |
| 76 function! s:ShowTablePopup() | |
| 77 " Use Vim popup_menu if available | |
| 78 if exists('*popup_menu') | |
| 79 s:popup_table = getline(line('.')) | |
| 80 let items = ['View Data', 'View Schema', 'Cancel'] | |
| 81 popup_menu(items, {}) | |
| 82 | |
| 83 nnoremap <buffer> <CR> :call <SID>HandlePopupSelection()<CR> | |
| 84 return | |
| 85 endif | |
| 86 " Popup_menu not available | |
| 87 echoerr 'Floating popup requires Vim8.2+.' | |
| 88 endfunction | |
| 89 | |
| 90 function! s:HandlePopupSelection() | |
| 91 let choice = getline('.') | |
| 92 let table = s:popup_table | |
| 93 call s:ClosePopup() | |
| 94 if choice ==# 'View Data' | |
| 95 call s:OpenTableData(table) | |
| 96 elseif choice ==# 'View Schema' | |
| 97 call s:OpenTableSchema(table) | |
| 98 else | |
| 99 call s:ClosePopup() | |
| 100 endif | |
| 101 endfunction | |
| 102 | |
| 103 function! s:ClosePopup() | |
| 104 unlet! s:popup_table | |
| 105 endfunction | |
| 106 | |
| 107 | |
| 108 " Modal menu: let user pick Data or Schema from a simple list | |
| 109 function! s:ShowTableMenuModal() | |
| 110 let table = getline(line('.')) | |
| 111 let opts = [ 'Select action for "' . table . '"', 'View Data', 'View Schema', 'Cancel' ] | |
| 112 let choice = inputlist(opts) | |
| 113 if choice == 1 | |
| 114 call s:ShowTableData() | |
| 115 elseif choice == 2 | |
| 116 call s:ShowTableSchema() | |
| 117 endif | |
| 118 endfunction | |
| 119 | |
| 120 " Internal: remove any existing dropdown option lines from the DBTables buffer | |
| 121 function! s:ClearTableOptions() | |
| 122 let to_del = [] | |
| 123 for lnum in range(1, line('$')) | |
| 124 let ln = getline(lnum) | |
| 125 if ln =~# '^\s\+\(Data\|Schema\)$' | |
| 126 call add(to_del, lnum) | |
| 127 endif | |
| 128 endfor | |
| 129 if !empty(to_del) | |
| 130 for lnum in reverse(to_del) | |
| 131 call deletebufline('%', lnum) | |
| 132 endfor | |
| 133 endif | |
| 134 endfunction | |
| 135 | |
| 136 " Internal: insert Data/Schema options under the selected table | |
| 137 function! s:InsertTableOptions() | |
| 138 call s:ClearTableOptions() | |
| 139 let tlnum = line('.') | |
| 140 " Insert indented options | |
| 141 call append(tlnum, ' Data') | |
| 142 call append(tlnum+1, ' Schema') | |
| 143 " Move cursor to the 'Data' line | |
| 144 call cursor(tlnum+1, 1) | |
| 145 endfunction | |
| 146 | |
| 147 " Internal: find the nearest table name above the cursor (first non-indented line) | |
| 148 function! s:GetNearestTableName() | |
| 149 let lnum = line('.') | |
| 150 while lnum > 0 | |
| 151 let text = getline(lnum) | |
| 152 if text =~# '^\S' | |
| 153 if text ==# 'Available Tables:' | |
| 154 return '' | |
| 155 endif | |
| 156 return text | |
| 157 endif | |
| 158 let lnum -= 1 | |
| 159 endwhile | |
| 160 return '' | |
| 161 endfunction | |
| 162 | |
| 163 | |
| 164 " Open table data for a given table name | |
| 165 function! s:OpenTableData(table) | |
| 166 tabnew | |
| 167 enew | |
| 168 execute 'file ' . a:table | |
| 169 let data = s:ExecuteDBQuery('SELECT * FROM ' . a:table . ';') | |
| 170 if !empty(data) | |
| 171 call append(0, data) | |
| 172 else | |
| 173 call append(0, 'No data found.') | |
| 174 endif | |
| 175 setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nomodifiable | |
| 176 endfunction | |
| 177 | |
| 178 " Open table schema for a given table name | |
| 179 function! s:OpenTableSchema(table) | |
| 180 tabnew | |
| 181 enew | |
| 182 execute 'file ' . a:table . '_schema' | |
| 183 let data = s:ExecuteDBQuery('DESCRIBE ' . a:table . ';') | |
| 184 if !empty(data) | |
| 185 call append(0, data) | |
| 186 else | |
| 187 call append(0, 'No schema found or an error occurred.') | |
| 188 endif | |
| 189 setlocal filetype=sql buftype=nofile bufhidden=wipe nobuflisted noswapfile nomodifiable | |
| 190 endfunction | |
| 191 | |
| 192 function! s:OpenDBTablesWindow() | |
| 193 " Open a new vertical split window | |
| 194 execute '34 vsplit' | |
| 195 " Create a new buffer | |
| 196 enew | |
| 197 " Set buffer name to "DBTables" | |
| 198 file DBTables | |
| 199 | |
| 200 let tables = s:ExecuteDBQuery("SHOW TABLES;") | |
| 201 if empty(tables) | |
| 202 echo "No tables found or an error occurred." | |
| 203 return | |
| 204 endif | |
| 205 | |
| 206 " Display the tables in the buffer | |
| 207 call append(0, 'Available Tables:') | |
| 208 call remove(tables, 0) | |
| 209 for table in tables | |
| 210 call append('$', table) | |
| 211 endfor | |
| 212 | |
| 213 " Set buffer options | |
| 214 setlocal buftype=nofile | |
| 215 setlocal bufhidden=wipe | |
| 216 setlocal nobuflisted | |
| 217 setlocal noswapfile | |
| 218 setlocal nomodifiable | |
| 219 setlocal nonumber | |
| 220 setlocal norelativenumber | |
| 221 setlocal winfixwidth | |
| 222 | |
| 223 " Map <Enter> to a modal menu (data or schema) | |
| 224 nnoremap <buffer> <CR> :call <SID>ShowTablePopup()<CR> | |
| 225 endfunction | |
| 226 | |
| 227 | |
| 228 function! s:ShowTableData() | |
| 229 " Get the current line (table name) | |
| 230 let lnum = line('.') | |
| 231 let table_name = getline(lnum) | |
| 232 | |
| 233 " Open a new tab and create a new buffer | |
| 234 tabnew | |
| 235 enew | |
| 236 " Set buffer name to the table name | |
| 237 execute 'file ' . table_name | |
| 238 | |
| 239 let data = s:ExecuteDBQuery("SELECT * FROM " . table_name . ";") | |
| 240 | |
| 241 " Display the table data in the buffer | |
| 242 if len(data) > 0 | |
| 243 call append(0, data) | |
| 244 else | |
| 245 call append(0, 'No data found.') | |
| 246 endif | |
| 247 | |
| 248 " Set buffer options | |
| 249 setlocal buftype=nofile | |
| 250 setlocal bufhidden=wipe | |
| 251 setlocal nobuflisted | |
| 252 setlocal noswapfile | |
| 253 setlocal nomodifiable | |
| 254 endfunction | |
| 255 | |
| 256 let s:query_history = [] | |
| 257 | |
| 258 function! s:ExecuteSQLQuery() | |
| 259 " Get the content of the current buffer (SQL query) | |
| 260 let query = join(getline(1, '$'), " ") | |
| 261 | |
| 262 " Append the query to history | |
| 263 call add(s:query_history, query) | |
| 264 | |
| 265 let data = s:ExecuteDBQuery(query) | |
| 266 | |
| 267 tabnew | |
| 268 enew | |
| 269 execute 'file SQLQueryResult' | |
| 270 call append(0, data) | |
| 271 | |
| 272 " Set the buffer file type to SQL for syntax highlighting | |
| 273 setlocal filetype=sql | |
| 274 | |
| 275 setlocal buftype=nofile | |
| 276 setlocal bufhidden=wipe | |
| 277 setlocal nobuflisted | |
| 278 setlocal noswapfile | |
| 279 setlocal nomodifiable | |
| 280 endfunction | |
| 281 | |
| 282 " Execute SQL from a visual selection | |
| 283 function! s:ExecuteVisualSQLQuery() range | |
| 284 " Get the content of the selected lines as a single SQL query | |
| 285 let lines = getline(a:firstline, a:lastline) | |
| 286 let query = join(lines, " ") | |
| 287 | |
| 288 " Append the query to history | |
| 289 call add(s:query_history, query) | |
| 290 | |
| 291 " Execute the query and capture results | |
| 292 let data = s:ExecuteDBQuery(query) | |
| 293 | |
| 294 " Open results in a new tab | |
| 295 tabnew | |
| 296 enew | |
| 297 execute 'file SQLQueryResult' | |
| 298 call append(0, data) | |
| 299 | |
| 300 " Set buffer options and highlight | |
| 301 setlocal filetype=sql | |
| 302 setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nomodifiable | |
| 303 endfunction | |
| 304 | |
| 305 function! s:OpenQueryHistory() | |
| 306 " Open the query history in a new split window | |
| 307 execute 'vsplit' | |
| 308 enew | |
| 309 call setline(1, s:query_history) | |
| 310 | |
| 311 " Allow selecting a query to be put into a new buffer to execute | |
| 312 nnoremap <buffer> <CR> :call <SID>ExecuteHistoryQuery(line('.'))<CR> | |
| 313 | |
| 314 " Set buffer options | |
| 315 setlocal buftype=nofile | |
| 316 setlocal bufhidden=wipe | |
| 317 setlocal nobuflisted | |
| 318 setlocal noswapfile | |
| 319 endfunction | |
| 320 | |
| 321 function! s:ExecuteHistoryQuery(lnum) | |
| 322 " Execute the selected query from history | |
| 323 let query = getline(a:lnum) | |
| 324 execute 'normal! i' . query | |
| 325 " Optionally call the execute function directly or process | |
| 326 endfunction | |
| 327 | |
| 328 | |
| 329 function! DBConsole() | |
| 330 " Save the current cursor position | |
| 331 let save_cursor = getpos(".") | |
| 332 | |
| 333 "Format the files | |
| 334 let db_user = g:db_user | |
| 335 let db_password = g:db_password | |
| 336 let db_name = g:db_name | |
| 337 " let db_host = shellescape(g:db_host) | |
| 338 let db_host = g:db_host | |
| 339 | |
| 340 | |
| 341 | |
| 342 let command = 'mariadb --user=' . db_user . ' --password=' . db_password . ' --database=' . db_name . ' --host=' . db_host . ' ' | |
| 343 let command = substitute(command, '\n', '', 'g') | |
| 344 execute ':term ' . command | |
| 345 call setpos(".", save_cursor) | |
| 346 endfunction | |
| 347 | |
| 348 function! OpenMariaDBConsole() | |
| 349 " The command to connect to MariaDB. Customize it with your actual connection details. | |
| 350 let cmd = 'mariadb -u your_username -p your_database_name' | |
| 351 | |
| 352 " Open a new terminal window at the bottom with 10 lines height. | |
| 353 " Split the window horizontally; you can adjust the height by changing `10`. | |
| 354 botright 10split | |
| 355 call termopen(cmd) | |
| 356 endfunction | |
| 357 | |
| 358 " Keybinding to open query history | |
| 359 nnoremap <Leader>qh :call <SID>OpenQueryHistory()<CR> | |
| 360 nnoremap <Leader>db :call DBConsole()<cr> | |
| 361 | |
| 362 command! DBTables call s:OpenDBTablesWindow() | |
| 363 command! ExecuteSQL call s:ExecuteSQLQuery() | |
| 364 | |
| 365 " Function to refresh the list of tables | |
| 366 nnoremap <Leader>rt :DBTables<CR> | |
| 367 | |
| 368 " Function to execute the contents of the current buffer as an SQL query | |
| 369 nnoremap <Leader>eq :ExecuteSQL<CR> | |
| 370 | |
| 371 " Function to open the database tables window | |
| 372 nnoremap <Leader>dt :DBTables<CR> | |
| 373 | |
| 374 " Optional: Shortcut to open MariaDB console | |
| 375 nnoremap <Leader>mc :call DBConsole()<CR> | |
| 376 " Map visual selection to execute selected SQL | |
| 377 xnoremap <silent> <Leader>ev :call <SID>ExecuteVisualSQLQuery()<CR> |
