Merge pull request #431 from xmujay/0609_monitor
[phpmyadmin/aamir.git] / js / db_structure.js
blob63d6f43ee6e1efdbfb7d2096c0663987cbf95700
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    functions used on the database structure page
4  * @name            Database Structure
5  *
6  * @requires    jQuery
7  * @requires    jQueryUI
8  * @required    js/functions.js
9  */
11 /**
12  * AJAX scripts for db_structure.php
13  *
14  * Actions ajaxified here:
15  * Drop Database
16  * Truncate Table
17  * Drop Table
18  *
19  */
21 /**
22  * Unbind all event handlers before tearing down a page
23  */
24 AJAX.registerTeardown('db_structure.js', function () {
25     $("span.fkc_switch").unbind('click');
26     $('#fkc_checkbox').unbind('change');
27     $("a.truncate_table_anchor.ajax").die('click');
28     $("a.drop_table_anchor.ajax").die('click');
29     $('a.drop_tracking_anchor.ajax').die('click');
30     $('#real_end_input').die('click');
31 });
33 /**
34  * Adjust number of rows and total size in the summary
35  * when truncating, creating, dropping or inserting into a table
36  */
37 function PMA_adjustTotals() {
38     var byteUnits = new Array(
39         PMA_messages.strB,
40         PMA_messages.strKiB,
41         PMA_messages.strMiB,
42         PMA_messages.strGiB,
43         PMA_messages.strTiB,
44         PMA_messages.strPiB,
45         PMA_messages.strEiB
46     );
47     /**
48      * @var $allTr jQuery object that references all the rows in the list of tables
49      */
50     var $allTr = $("#tablesForm table.data tbody:first tr");
51     // New summary values for the table
52     var tableSum = $allTr.size();
53     var rowsSum = 0;
54     var sizeSum = 0;
55     var overheadSum = 0;
56     var rowSumApproximated = false;
58     $allTr.each(function () {
59         var $this = $(this);
60         var i, tmpVal;
61         // Get the number of rows for this SQL table
62         var strRows = $this.find('.tbl_rows').text();
63         // If the value is approximated
64         if (strRows.indexOf('~') === 0) {
65             rowSumApproximated = true;
66             // The approximated value contains a preceding ~ and a following 2 (Eg 100 --> ~1002)
67             strRows = strRows.substring(1, strRows.length - 1);
68         }
69         strRows = strRows.replace(/[,.]/g, '');
70         var intRow = parseInt(strRows, 10);
71         if (! isNaN(intRow)) {
72             rowsSum += intRow;
73         }
74         // Extract the size and overhead
75         var valSize         = 0;
76         var valOverhead     = 0;
77         var strSize         = $.trim($this.find('.tbl_size span:not(.unit)').text());
78         var strSizeUnit     = $.trim($this.find('.tbl_size span.unit').text());
79         var strOverhead     = $.trim($this.find('.tbl_overhead span:not(.unit)').text());
80         var strOverheadUnit = $.trim($this.find('.tbl_overhead span.unit').text());
81         // Given a value and a unit, such as 100 and KiB, for the table size
82         // and overhead calculate their numeric values in bytes, such as 102400
83         for (i = 0; i < byteUnits.length; i++) {
84             if (strSizeUnit == byteUnits[i]) {
85                 tmpVal = parseFloat(strSize);
86                 valSize = tmpVal * Math.pow(1024, i);
87                 break;
88             }
89         }
90         for (i = 0; i < byteUnits.length; i++) {
91             if (strOverheadUnit == byteUnits[i]) {
92                 tmpVal = parseFloat(strOverhead);
93                 valOverhead = tmpVal * Math.pow(1024, i);
94                 break;
95             }
96         }
97         sizeSum += valSize;
98         overheadSum += valOverhead;
99     });
100     // Add some commas for readablility:
101     // 1000000 becomes 1,000,000
102     var strRowSum = rowsSum + "";
103     var regex = /(\d+)(\d{3})/;
104     while (regex.test(strRowSum)) {
105         strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
106     }
107     // If approximated total value add ~ in front
108     if (rowSumApproximated) {
109         strRowSum = "~" + strRowSum;
110     }
111     // Calculate the magnitude for the size and overhead values
112     var size_magnitude = 0, overhead_magnitude = 0;
113     while (sizeSum >= 1024) {
114         sizeSum /= 1024;
115         size_magnitude++;
116     }
117     while (overheadSum >= 1024) {
118         overheadSum /= 1024;
119         overhead_magnitude++;
120     }
122     sizeSum = Math.round(sizeSum * 10) / 10;
123     overheadSum = Math.round(overheadSum * 10) / 10;
125     // Update summary with new data
126     var $summary = $("#tbl_summary_row");
127     $summary.find('.tbl_num').text($.sprintf(PMA_messages.strTables, tableSum));
128     $summary.find('.tbl_rows').text(strRowSum);
129     $summary.find('.tbl_size').text(sizeSum + " " + byteUnits[size_magnitude]);
130     $summary.find('.tbl_overhead').text(overheadSum + " " + byteUnits[overhead_magnitude]);
133 AJAX.registerOnload('db_structure.js', function () {
134     /**
135      * Handler for the print view multisubmit.
136      * All other multi submits can be handled via ajax, but this one needs
137      * special treatment as the results need to open in another browser window
138      */
139     $('#tablesForm').submit(function (event) {
140         var $form = $(this);
141         if ($form.find('select[name=submit_mult]').val() === 'print') {
142             event.preventDefault();
143             event.stopPropagation();
144             $('form#clone').remove();
145             var $clone = $form
146                 .clone()
147                 .hide()
148                 .appendTo('body');
149             $clone
150                 .find('select[name=submit_mult]')
151                 .val('print');
152             $clone
153                 .attr('target', 'printview')
154                 .attr('id', 'clone')
155                 .submit();
156         }
157     });
159      /**
160      * Event handler for 'Foreign Key Checks' disabling option
161      * in the drop table confirmation form
162      */
163     $("span.fkc_switch").click(function (event) {
164         if ($("#fkc_checkbox").prop('checked')) {
165             $("#fkc_checkbox").prop('checked', false);
166             $("#fkc_status").html(PMA_messages.strForeignKeyCheckDisabled);
167             return;
168         }
169         $("#fkc_checkbox").prop('checked', true);
170         $("#fkc_status").html(PMA_messages.strForeignKeyCheckEnabled);
171     });
173     $('#fkc_checkbox').change(function () {
174         if ($(this).prop("checked")) {
175             $("#fkc_status").html(PMA_messages.strForeignKeyCheckEnabled);
176             return;
177         }
178         $("#fkc_status").html(PMA_messages.strForeignKeyCheckDisabled);
179     }); // End of event handler for 'Foreign Key Check'
181     /**
182      * Ajax Event handler for 'Truncate Table'
183      */
184     $("a.truncate_table_anchor.ajax").live('click', function (event) {
185         event.preventDefault();
187         /**
188          * @var $this_anchor Object  referring to the anchor clicked
189          */
190         var $this_anchor = $(this);
192         //extract current table name and build the question string
193         /**
194          * @var curr_table_name String containing the name of the table to be truncated
195          */
196         var curr_table_name = $this_anchor.parents('tr').children('th').children('a').text();
197         /**
198          * @var question    String containing the question to be asked for confirmation
199          */
200         var question = PMA_messages.strTruncateTableStrongWarning + ' ' +
201             $.sprintf(PMA_messages.strDoYouReally, 'TRUNCATE ' + escapeHtml(curr_table_name));
203         $this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
205             PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
207             $.get(url, {'is_js_confirmed' : 1, 'ajax_request' : true}, function (data) {
208                 if (data.success === true) {
209                     PMA_ajaxShowMessage(data.message);
210                     // Adjust table statistics
211                     var $tr = $this_anchor.closest('tr');
212                     $tr.find('.tbl_rows').text('0');
213                     $tr.find('.tbl_size, .tbl_overhead').text('-');
214                     //Fetch inner span of this anchor
215                     //and replace the icon with its disabled version
216                     var span = $this_anchor.html().replace(/b_empty/, 'bd_empty');
217                     //To disable further attempts to truncate the table,
218                     //replace the a element with its inner span (modified)
219                     $this_anchor
220                         .replaceWith(span)
221                         .removeClass('truncate_table_anchor');
222                     PMA_adjustTotals();
223                 } else {
224                     PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + " : " + data.error, false);
225                 }
226             }); // end $.get()
227         }); //end $.PMA_confirm()
228     }); //end of Truncate Table Ajax action
230     /**
231      * Ajax Event handler for 'Drop Table' or 'Drop View'
232      */
233     $("a.drop_table_anchor.ajax").live('click', function (event) {
234         event.preventDefault();
236         var $this_anchor = $(this);
238         //extract current table name and build the question string
239         /**
240          * @var $curr_row    Object containing reference to the current row
241          */
242         var $curr_row = $this_anchor.parents('tr');
243         /**
244          * @var curr_table_name String containing the name of the table to be truncated
245          */
246         var curr_table_name = $curr_row.children('th').children('a').text();
247         /**
248          * @var is_view Boolean telling if we have a view
249          */
250         var is_view = $curr_row.hasClass('is_view') || $this_anchor.hasClass('view');
251         /**
252          * @var question    String containing the question to be asked for confirmation
253          */
254         var question;
255         if (! is_view) {
256             question = PMA_messages.strDropTableStrongWarning + ' ' +
257                 $.sprintf(PMA_messages.strDoYouReally, 'DROP TABLE ' + escapeHtml(curr_table_name));
258         } else {
259             question =
260                 $.sprintf(PMA_messages.strDoYouReally, 'DROP VIEW ' + escapeHtml(curr_table_name));
261         }
263         $this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
265             var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
267             $.get(url, {'is_js_confirmed' : 1, 'ajax_request' : true}, function (data) {
268                 if (data.success === true) {
269                     PMA_ajaxShowMessage(data.message);
270                     toggleRowColors($curr_row.next());
271                     $curr_row.hide("medium").remove();
272                     PMA_adjustTotals();
273                     PMA_reloadNavigation();
274                     PMA_ajaxRemoveMessage($msg);
275                 } else {
276                     PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + " : " + data.error, false);
277                 }
278             }); // end $.get()
279         }); // end $.PMA_confirm()
280     }); //end of Drop Table Ajax action
282     /**
283      * Ajax Event handler for 'Drop tracking'
284      */
285     $('a.drop_tracking_anchor.ajax').live('click', function (event) {
286         event.preventDefault();
288         var $anchor = $(this);
290         /**
291          * @var curr_tracking_row   Object containing reference to the current tracked table's row
292          */
293         var $curr_tracking_row = $anchor.parents('tr');
294          /**
295          * @var question    String containing the question to be asked for confirmation
296          */
297         var question = PMA_messages.strDeleteTrackingData;
299         $anchor.PMA_confirm(question, $anchor.attr('href'), function (url) {
301             PMA_ajaxShowMessage(PMA_messages.strDeletingTrackingData);
303             $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) {
304                 if (data.success === true) {
305                     var $tracked_table = $curr_tracking_row.parents('table');
306                     var table_name = $curr_tracking_row.find('td:nth-child(2)').text();
308                     // Check how many rows will be left after we remove
309                     if ($tracked_table.find('tbody tr').length === 1) {
310                         // We are removing the only row it has
311                         $('#tracked_tables').hide("slow").remove();
312                     } else {
313                         // There are more rows left after the deletion
314                         toggleRowColors($curr_tracking_row.next());
315                         $curr_tracking_row.hide("slow", function () {
316                             $(this).remove();
317                         });
318                     }
320                     // Make the removed table visible in the list of 'Untracked tables'.
321                     var $untracked_table = $('table#noversions');
323                     // This won't work if no untracked tables are there.
324                     if ($untracked_table.length > 0) {
325                         var $rows = $untracked_table.find('tbody tr');
327                         $rows.each(function (index) {
328                             var $row = $(this);
329                             var tmp_tbl_name = $row.find('td:first-child').text();
330                             var is_last_iteration = (index == ($rows.length - 1));
332                             if (tmp_tbl_name > table_name || is_last_iteration) {
333                                 var $cloned = $row.clone();
335                                 // Change the table name of the cloned row.
336                                 $cloned.find('td:first-child').text(table_name);
338                                 // Change the link of the cloned row.
339                                 var new_url = $cloned
340                                     .find('td:nth-child(2) a')
341                                     .attr('href')
342                                     .replace('table=' + tmp_tbl_name, 'table=' + encodeURIComponent(table_name));
343                                 $cloned.find('td:nth-child(2) a').attr('href', new_url);
345                                 // Insert the cloned row in an appropriate location.
346                                 if (tmp_tbl_name > table_name) {
347                                     $cloned.insertBefore($row);
348                                     toggleRowColors($row);
349                                     return false;
350                                 } else {
351                                     $cloned.insertAfter($row);
352                                     toggleRowColors($cloned);
353                                 }
354                             }
355                         });
356                     }
358                     PMA_ajaxShowMessage(data.message);
359                 } else {
360                     PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + " : " + data.error, false);
361                 }
362             }); // end $.get()
363         }); // end $.PMA_confirm()
364     }); //end Drop Tracking
366     //Calculate Real End for InnoDB
367     /**
368      * Ajax Event handler for calculatig the real end for a InnoDB table
369      *
370      */
371     $('#real_end_input').live('click', function (event) {
372         event.preventDefault();
374         /**
375          * @var question    String containing the question to be asked for confirmation
376          */
377         var question = PMA_messages.strOperationTakesLongTime;
379         $(this).PMA_confirm(question, '', function () {
380             return true;
381         });
382         return false;
383     }); //end Calculate Real End for InnoDB
385 }); // end $()