Fixed: Not selecting a datalabel used to issue a notice(undefined offset)
[phpmyadmin/ammaryasirr.git] / js / pmd / history.js
blob3e3a195a40b8a177eda74ed6d0fb2e1da3207fa2
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * @fileoverview    function used in this file builds history tab and generates query.
4   *
5   * @requires    jQuery
6   * @requires    moves.js
7   * @version $Id$
8   */
10 var history_array = []; // Global array to store history objects
11 var select_field = [];  // Global array to store informaation for columns which are used in select clause
12 var g_index;
14 /**
15  * function for panel, hides and shows toggle_container <div>,which is for history elements uses {@link JQuery}.
16  *
17  * @param index has value 1 or 0,decides wheter to hide toggle_container on load.
18 **/
20 function panel(index)
22     if (!index) {
23         $(".toggle_container").hide();
24     }
25     $("h2.tiger").click(function(){
26     $(this).toggleClass("active").next().slideToggle("slow");
27     });
30 /**
31  * Sorts history_array[] first,using table name as the key and then generates the HTML code for history tab,
32  * clubbing all objects of same tables together
33  * This function is called whenever changes are made in history_array[]
34  *
35  * @uses and_or()
36  * @uses history_edit()
37  * @uses history_delete()
38  *
39  * @param {int}  init starting index of unsorted array
40  * @param {int} finit   last index of unsorted array
41  *
42 **/
44 function display(init,finit)
46     var str,i,j,k,sto;
47     // this part sorts the history array based on table name,this is needed for clubbing all object of same name together.
48     for (i = init;i < finit;i++) {
49         sto = history_array[i];
50         var temp = history_array[i].get_tab() ;//+ '.' + history_array[i].get_obj_no(); for Self JOINS
51         for(j = 0;j < i;j++){
52             if(temp > (history_array[j].get_tab())) {//+ '.' + history_array[j].get_obj_no())) { //for Self JOINS
53                 for(k = i;k > j;k--) {
54                     history_array[k] = history_array[k-1];
55                 }
56                 history_array[j] = sto;
57                 break;
58             }
59         }
60     }
61     // this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects.
62     str =''; // string to store Html code for history tab
63     for ( var i=0; i < history_array.length; i++){
64         var temp = history_array[i].get_tab(); //+ '.' + history_array[i].get_obj_no(); for Self JOIN
65         str += '<h2 class="tiger"><a href="#">' + temp + '</a></h2>';
66         str += '<div class="toggle_container">\n';
67         while((history_array[i].get_tab()) == temp) { //+ '.' + history_array[i].get_obj_no()) == temp) {
68             str +='<div class="block"> <table width ="250">';
69             str += '<thead><tr><td>';
70             if(history_array[i].get_and_or()){
71                 str +='<img src="pmd/images/or_icon.png" onclick="and_or('+i+')" title="OR"/></td>';
72             }
73             else {
74                str +='<img src="pmd/images/and_icon.png" onclick="and_or('+i+')" title="AND"/></td>';
75             }
76             str +='<td style="padding-left: 5px;" align="right"><img class="icon ic_b_sbrowse" src="themes/dot.gif" title="column name"/></td><td width="175" style="padding-left: 5px">' + history_array[i].get_column_name();
77             if (history_array[i].get_type() == "GroupBy" || history_array[i].get_type() == "OrderBy") {
78                 str += '</td><td align="center"><img class="icon ic_b_info" src="themes/dot.gif" title="'+detail(i)+'"/><td title="' + detail(i) +'">' + history_array[i].get_type() + '</td></td><td onmouseover="this.className=\'history_table\';" onmouseout="this.className=\'history_table2\'" onclick=history_delete('+ i +')><img class="icon ic_b_drop" src="themes/dot.gif" title="Delete"></td></tr></thead>';
79            }
80            else {
81                str += '</td><td align="center"><img class="icon ic_b_info" src="themes/dot.gif" title="'+detail(i)+'"/></td><td title="' + detail(i) +'">' + history_array[i].               get_type() + '</td><td <td onmouseover="this.className=\'history_table\';" onmouseout="this.className=\'history_table2\'" onclick=history_edit('+ i +')><img class="icon ic_b_edit" src="themes/dot.gif" title="Edit"/></td><td onmouseover="this.className=\'history_table\';" onmouseout="this.className=\'history_table2\'"               onclick=history_delete('+ i +')><img src="themes/original/img/b_drop.png" title="Delete"></td></tr></thead>';
82            }
83            i++;
84            if(i >= history_array.length) {
85                break;
86            }
87            str += '</table></div><br/>';
88         }
89         i--;
90         str += '</div><br/>';
91     }
92     return str;
95 /**
96  * To change And/Or relation in history tab
97  *
98  * @uses panel()
99  *
100  * @param {int} index of history_array where change is to be made
104 function and_or(index)
106     if (history_array[index].get_and_or()) {
107         history_array[index].set_and_or(0);
108     }
109     else {
110         history_array[index].set_and_or(1);
111     }
112     var existingDiv = document.getElementById('ab');
113     existingDiv.innerHTML = display(0,0);
114     panel(1);
118  * To display details of obects(where,rename,Having,aggregate,groupby,orderby,having)
120  * @param index index of history_array where change is to be made
124 function detail (index)
126     var type = history_array[index].get_type();
127     var str;
128     if (type == "Where") {
129         str = 'Where ' + history_array[index].get_column_name() + history_array[index].get_obj().getrelation_operator() + history_array[index].get_obj().getquery();
130     }
131     if (type == "Rename") {
132         str = 'Rename ' + history_array[index].get_column_name() + ' To ' + history_array[index].get_obj().getrename_to();
133     }
134     if (type == "Aggregate") {
135         str = 'Select ' + history_array[index].get_obj().get_operator() + '( ' + history_array[index].get_column_name() + ' )';
136     }
137     if (type == "GroupBy") {
138         str = 'GroupBy ' + history_array[index].get_column_name() ;
139     }
140     if (type == "OrderBy") {
141         str = 'OrderBy ' + history_array[index].get_column_name() ;
142     }
143     if (type == "Having") {
144         str = 'Having ';
145         if (history_array[index].get_obj().get_operator() != 'None') {
146             str += history_array[index].get_obj().get_operator() + '( ' + history_array[index].get_column_name() + ' )';
147             str += history_array[index].get_obj().getrelation_operator() + history_array[index].get_obj().getquery();
148         }
149         else {
150             str = 'Having ' + history_array[index].get_column_name() + history_array[index].get_obj().getrelation_operator() + history_array[index].get_obj().getquery();
151         }
152     }
153     return str;
157  * Deletes entry in history_array
159  * @uses panel()
160  * @uses display()
161  * @param index index of history_array[] which is to be deleted
165 function history_delete(index)
167     for(var k =0 ;k < from_array.length;k++){
168         if(from_array[k] == history_array[index].get_tab()){
169             from_array.splice(k,1);
170             break;
171         }
172     }
173     history_array.splice(index,1);
174     var existingDiv = document.getElementById('ab');
175     existingDiv.innerHTML = display(0,0);
176     panel(1);
180  * To show where,rename,aggregate,having forms to edit a object
182  * @param{int} index index of history_array where change is to be made
186 function history_edit(index)
188     g_index = index;
189     var type = history_array[index].get_type();
190     if (type == "Where") {
191         document.getElementById('eQuery').value = history_array[index].get_obj().getquery();
192         document.getElementById('erel_opt').value = history_array[index].get_obj().getrelation_operator();
193         document.getElementById('query_where').style.left =  '530px';
194         document.getElementById('query_where').style.top  = '130px';
195         document.getElementById('query_where').style.position  = 'absolute';
196         document.getElementById('query_where').style.zIndex = '9';
197         document.getElementById('query_where').style.visibility = 'visible';
198     }
199     if (type == "Having") {
200         document.getElementById('hQuery').value = history_array[index].get_obj().getquery();
201         document.getElementById('hrel_opt').value = history_array[index].get_obj().getrelation_operator();
202         document.getElementById('hoperator').value = history_array[index].get_obj().get_operator();
203         document.getElementById('query_having').style.left =  '530px';
204         document.getElementById('query_having').style.top  = '130px';
205         document.getElementById('query_having').style.position  = 'absolute';
206         document.getElementById('query_having').style.zIndex = '9';
207         document.getElementById('query_having').style.visibility = 'visible';
208     }
209     if (type == "Rename") {
210         document.getElementById('query_rename_to').style.left =  '530px';
211         document.getElementById('query_rename_to').style.top  = '130px';
212         document.getElementById('query_rename_to').style.position  = 'absolute';
213         document.getElementById('query_rename_to').style.zIndex = '9';
214         document.getElementById('query_rename_to').style.visibility = 'visible';
215     }
216     if (type == "Aggregate") {
217         document.getElementById('query_Aggregate').style.left = '530px';
218         document.getElementById('query_Aggregate').style.top  = '130px';
219         document.getElementById('query_Aggregate').style.position  = 'absolute';
220         document.getElementById('query_Aggregate').style.zIndex = '9';
221         document.getElementById('query_Aggregate').style.visibility = 'visible';
222     }
226  * Make changes in history_array when Edit button is clicked
227  * checks for the type of object and then sets the new value
228  * @uses panel()
229  * @uses display()
231  * @param index index of history_array where change is to be made
234 function edit(type)
236     if (type == "Rename") {
237         if (document.getElementById('e_rename').value != "") {
238             history_array[g_index].get_obj().setrename_to(document.getElementById('e_rename').value);
239             document.getElementById('e_rename').value = "";
240         }
241         document.getElementById('query_rename_to').style.visibility = 'hidden';
242     }
243     if (type == "Aggregate") {
244         if (document.getElementById('e_operator').value != '---') {
245             history_array[g_index].get_obj().set_operator(document.getElementById('e_operator').value);
246             document.getElementById('e_operator').value = '---';
247         }
248         document.getElementById('query_Aggregate').style.visibility = 'hidden';
249     }
250     if (type == "Where") {
251         if (document.getElementById('erel_opt').value != '--' && document.getElementById('eQuery').value !="") {
252         history_array[g_index].get_obj().setquery(document.getElementById('eQuery').value);
253         history_array[g_index].get_obj().setrelation_operator(document.getElementById('erel_opt').value);
254         }
255         document.getElementById('query_where').style.visibility = 'hidden';
256     }
257     if (type == "Having") {
258         if (document.getElementById('hrel_opt').value != '--' && document.getElementById('hQuery').value !="") {
259             history_array[g_index].get_obj().setquery(document.getElementById('hQuery').value);
260             history_array[g_index].get_obj().setrelation_operator(document.getElementById('hrel_opt').value);
261             history_array[g_index].get_obj().set_operator(document.getElementById('hoperator').value);
262         }
263         document.getElementById('query_having').style.visibility = 'hidden';
264     }
265     var existingDiv = document.getElementById('ab');
266     existingDiv.innerHTML = display(0,0);
267     panel(1);
271  * history object closure
273  * @param ncolumn_name  name of the column on which conditions are put
274  * @param nobj          object details(where,rename,orderby,groupby,aggregate)
275  * @param ntab          table name of the column on which conditions are applied
276  * @param nobj_no       object no used for inner join
277  * @param ntype         type of object
281 function history(ncolumn_name,nobj,ntab,nobj_no,ntype)
283     var and_or;
284     var obj;
285     var tab;
286     var column_name;
287     var obj_no;
288     var type;
289     this.set_column_name = function (ncolumn_name) {
290         column_name = ncolumn_name;
291     };
292     this.get_column_name = function() {
293         return column_name;
294     };
295     this.set_and_or = function(nand_or) {
296         and_or = nand_or;
297     };
298     this.get_and_or = function() {
299         return and_or;
300     }
301     this.get_relation = function() {
302         return and_or;
303     };
304     this.set_obj = function(nobj) {
305         obj = nobj;
306     };
307     this.get_obj = function() {
308         return obj;
309     };
310     this.set_tab = function(ntab) {
311         tab = ntab;
312     };
313     this.get_tab = function() {
314         return tab;
315     };
316     this.set_obj_no = function(nobj_no) {
317         obj_no = nobj_no;
318      };
319     this.get_obj_no = function() {
320         return obj_no;
321     };
322     this.set_type = function(ntype) {
323         type = ntype;
324     }
325     this.get_type = function() {
326         return type;
327     }
328     this.set_obj_no(nobj_no);
329     this.set_tab(ntab);
330     this.set_and_or(0);
331     this.set_obj(nobj);
332     this.set_column_name(ncolumn_name);
333     this.set_type(ntype);
337  * where object closure, makes an object with all information of where
339  * @param nrelation_operator type of relation operator to be applied
340  * @param nquery             stores value of value/sub-query
345 var where = function (nrelation_operator,nquery) {
346     var relation_operator;
347     var query;
348     this.setrelation_operator = function(nrelation_operator) {
349         relation_operator = nrelation_operator;
350     };
351     this.setquery = function(nquery) {
352         query = nquery;
353     };
354     this.getquery = function() {
355         return query;
356     };
357     this.getrelation_operator = function() {
358         return relation_operator;
359     };
360     this.setquery(nquery);
361     this.setrelation_operator(nrelation_operator);
366  * Having object closure, makes an object with all information of where
368  * @param nrelation_operator type of relation operator to be applied
369  * @param nquery             stores value of value/sub-query
373 var having = function (nrelation_operator,nquery,noperator) {
374     var relation_operator;
375     var query;
376     var operator;
377     this.set_operator = function(noperator) {
378         operator = noperator;
379     };
380     this.setrelation_operator = function(nrelation_operator) {
381         relation_operator = nrelation_operator;
382     };
383     this.setquery = function(nquery) {
384         query = nquery;
385     };
386     this.getquery = function() {
387         return query;
388     };
389     this.getrelation_operator = function() {
390         return relation_operator;
391     };
392     this.get_operator = function() {
393         return operator;
394     };
395     this.setquery(nquery);
396     this.setrelation_operator(nrelation_operator);
397     this.set_operator(noperator);
401  * rename object closure,makes an object with all information of rename
403  * @param nrename_to new name information
407 var rename = function(nrename_to) {
408     var rename_to;
409     this.setrename_to = function(nrename_to) {
410         rename_to = nrename_to;
411     };
412     this.getrename_to =function() {
413         return rename_to;
414     };
415     this.setrename_to(nrename_to);
419  * aggregate object closure
421  * @param noperator aggregte operator
425 var aggregate = function(noperator) {
426     var operator;
427     this.set_operator = function(noperator) {
428         operator = noperator;
429     };
430     this.get_operator = function() {
431         return operator;
432     };
433     this.set_operator(noperator);
437  * This function returns unique element from an array
439  * @param arraName array from which duplicate elem are to be removed.
440  * @return unique array
441  */
443 function unique(arrayName)
445     var newArray=new Array();
446     label:for(var i=0; i<arrayName.length;i++ )
447     {
448         for(var j=0; j<newArray.length;j++ )
449         {
450             if(newArray[j]==arrayName[i])
451                 continue label;
452         }
453         newArray[newArray.length] = arrayName[i];
454     }
455    return newArray;
459  * This function takes in array and a value as input and returns 1 if values is present in array
460  * else returns -1
462  * @param arrayName array
463  * @param value  value which is to be searched in the array
464  */
466 function found(arrayName,value)
468     for(var i=0; i<arrayName.length; i++) {
469         if(arrayName[i] == value) { return 1;}
470     }
471     return -1;
475  * This function is the main function for query building.
476  * uses history object details for this.
478  * @ uses query_where()
479  * @ uses query_groupby()
480  * @ uses query_having()
481  * @ uses query_orderby()
483  * @param formtitle title for the form
484  * @param fadin
485  */
487 function build_query(formtitle, fadin)
489     var q_select = "SELECT ";
490     var temp;
491     for (i = 0;i < select_field.length; i++) {
492         temp = check_aggregate(select_field[i]);
493         if (temp != "") {
494             q_select += temp;
495             temp = check_rename(select_field[i]);
496             q_select += temp + ",";
497         }
498         else {
499             temp = check_rename(select_field[i]);
500             q_select += select_field[i] + temp +",";
501         }
502     }
503     q_select = q_select.substring(0,q_select.length - 1);
504     q_select += " FROM " + query_from();
505     if(query_where() != "") {
506         q_select +="\n WHERE";
507         q_select += query_where();
508     }
509     if(query_groupby() != "") { q_select += "\nGROUP BY " + query_groupby(); }
510     if(query_having() != "") { q_select += "\nHAVING " + query_having(); }
511     if(query_orderby() != "") { q_select += "\nORDER BY " + query_orderby(); }
512     var box = document.getElementById('box');
513     document.getElementById('filter').style.display='block';
514     var btitle = document.getElementById('boxtitle');
515     btitle.innerHTML = 'SELECT';//formtitle;
516     if(fadin){
517         gradient("box", 0);
518         fadein("box");
519     }
520     else{
521         box.style.display='block';
522     }
523     document.getElementById('textSqlquery').innerHTML = q_select;
525  /**
526   * This function builds from clause of query
527   * makes automatic joins.
528   *
529   * @uses unique
530   * @uses add_array
531   * @uses remove_array
532   *
533   */
536 function query_from()
538     var i;
539     var tab_left = [];
540     var tab_used = [];
541     var t_tab_used = [];
542     var t_tab_left = [];
543     var temp;
544     var query = "";
545     var quer = "";
546     var parts = [];
547     var t_array = [];
548     t_array = from_array;
549     var K = 0;
550     for (i = 0; i < history_array.length ; i++) {
551         from_array.push(history_array[i].get_tab());
552     }
553     from_array = unique( from_array );
554     tab_left = from_array;
555     temp = tab_left.shift();
556     quer = temp;
557     tab_used.push(temp);
558     // if master table (key2) matches with tab used get all keys and check if tab_left matches
559     //after this check if master table (key2) matches with tab left then check if any foriegn matches with master .
560     for( i =0; i<2 ; i++) {
561         for (K in contr){
562             for (key in contr[K]){// contr name
563                  for (key2 in contr[K][key]){// table name
564                     parts = key2.split(".");
565                     if(found(tab_used,parts[1]) > 0)  {
566                         for (key3 in contr[K][key][key2]) {
567                             parts1 = contr[K][key][key2][key3][0].split(".");
568                             if(found(tab_left,parts1[1]) > 0) {
569                                 query += "\n" + 'LEFT JOIN ';
570                                 query += '`' + parts1[0] + '`.`' + parts1[1] + '` ON ' ;
571                                 query += '`' + parts[1] +'`.`' + key3 + '` = ';
572                                 query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
573                                 t_tab_left.push(parts1[1]);
574                             }
575                         }
576                     }
577                 }
578             }
579         }
580         K = 0;
581         t_tab_left = unique (t_tab_left);
582         tab_used = add_array(t_tab_left,tab_used);
583         tab_left = remove_array(t_tab_left,tab_left);
584         t_tab_left = [];
585         for (K in contr) {
586              for (key in contr[K]) {
587                  for (key2 in contr[K][key]){// table name
588                      parts = key2.split(".");
589                          if(found(tab_left,parts[1]) > 0){
590                            for (key3 in contr[K][key][key2]){
591                                parts1 = contr[K][key][key2][key3][0].split(".");
592                                if(found(tab_used,parts1[1]) > 0) {
593                                    query += "\n" + 'LEFT JOIN ';
594                                    query += '`' + parts[0] + '`.`' + parts[1] + '` ON ' ;
595                                    query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
596                                    query += '`' + parts[1] + '`.`' + key3 + '` ';
597                                    t_tab_left.push(parts[1]);
598                                }
599                            }
600                      }
601                  }
602             }
603         }
604         t_tab_left = unique (t_tab_left);
605         tab_used = add_array(t_tab_left,tab_used);
606         tab_left = remove_array(t_tab_left,tab_left);
607         t_tab_left = [];
608     }
609     for (k in tab_left) {
610         quer += " , `" + tab_left[k] + "`";
611     }
612         query = quer + query;
613         from_array = t_array;
614         return query;
618  * This function concatenates two array
620  * @params add array elements of which are pushed in
621  * @params arr array in which elemnets are added
622  */
623 function add_array(add,arr)
625     for( var i=0; i<add.length; i++){
626         arr.push(add[i]);
627     }
628     return arr;
631 /* This fucntion removes all elements present in one array from the other.
633  * @params rem array from which each element is removed from other array.
634  * @params arr array from which elements are removed.
636  */
637 function remove_array(rem,arr)
639     for(var i=0; i<rem.length; i++){
640         for(var j=0; j<arr.length; j++)
641             if(rem[i] == arr[j]) { arr.splice(j,1); }
642     }
643     return arr;
647  * This function builds the groupby clause from history object
649  */
651 function query_groupby()
653     var i;
654     var str = "";
655     for (i = 0; i < history_array.length;i++) {
656         if(history_array[i].get_type() == "GroupBy") { str +=history_array[i].get_column_name() + ", ";}
657     }
658     str = str.substr(0,str.length -1);
659     return str;
663  * This function builds the Having clause from the history object.
665  */
667 function query_having()
669     var i;
670     var and = "(";
671     for (i = 0; i < history_array.length;i++) {
672         if(history_array[i].get_type() == "Having") {
673             if (history_array[i].get_obj().get_operator() != 'None') {
674                 and += history_array[i].get_obj().get_operator() + "(" + history_array[i].get_column_name() + " ) " + history_array[i].get_obj().getrelation_operator();
675                 and += " " + history_array[i].get_obj().getquery() + ", " ;
676             }
677             else {
678                 and +=  history_array[i].get_column_name() + " " + history_array[i].get_obj().getrelation_operator() + " " + history_array[i].get_obj().getquery() + ", ";
679             }
680         }
681     }
682     if (and =="(") { and = "" ;}
683     else { and = and.substr(0,and.length -2) + ")";}
684     return and;
689  * This function builds the orderby clause from the history object.
691  */
693 function query_orderby()
695     var i;
696     var str = "" ;
697     for (i = 0; i < history_array.length;i++) {
698         if(history_array[i].get_type() == "OrderBy") { str += history_array[i].get_column_name() + " , "; }
699     }
700     str = str.substr(0,str.length -1);
701     return str;
706  * This function builds the Where clause from the history object.
708  */
710 function query_where()
712     var i;
713     var and = "(";
714     var or = "(";
715     for (i = 0; i < history_array.length;i++) {
716         if(history_array[i].get_type() == "Where") {
717             if(history_array[i].get_and_or() == 0) {
718                 and += "( " + history_array[i].get_column_name() + " " + history_array[i].get_obj().getrelation_operator() +" " + history_array[i].get_obj().getquery() + ")";                and += " AND ";
719             }
720             else {
721                 or +="( " + history_array[i].get_column_name() + " " + history_array[i].get_obj().getrelation_operator() + " " + history_array[i].get_obj().getquery() +")";
722                 or +=" OR " ;
723             }
724         }
725     }
726     if ( or != "(") {
727         or = or.substring(0,(or.length - 4 )) + ")";
728     } else {
729         or = "" ;
730     }
731     if (and !="(") {
732         and = and.substring(0,(and.length - 5)) + ")";
733     } else {
734         and = "" ;
735     }
736     if ( or != "" ) {
737         and = and + " OR " + or + " )";
738     }
739     return and;
742 function check_aggregate(id_this)
744     var i;
745     for (i = 0;i < history_array.length;i++) {
746         var temp = '`' + history_array[i].get_tab() + '`.`' +history_array[i].get_column_name() +'`';
747         if(temp == id_this && history_array[i].get_type() == "Aggregate") {
748             return history_array[i].get_obj().get_operator() + '(' + id_this +')';
749         }
750     }
751     return "";
754 function check_rename(id_this)
756     var i;
757     for (i = 0;i < history_array.length;i++) {
758         var temp = '`' + history_array[i].get_tab() + '`.`' +history_array[i].get_column_name() +'`';
759         if(temp == id_this && history_array[i].get_type() == "Rename") {
760             return  " AS `" + history_array[i].get_obj().getrename_to() +"`";
761         }
762     }
763     return "";
766 function gradient(id, level)
768     var box = document.getElementById(id);
769     box.style.opacity = level;
770     box.style.MozOpacity = level;
771     box.style.KhtmlOpacity = level;
772     box.style.filter = "alpha(opacity=" + level * 100 + ")";
773     box.style.display="block";
774     return;
778 function fadein(id)
780     var level = 0;
781     while(level <= 1){
782         setTimeout( "gradient('" + id + "'," + level + ")", (level* 1000) + 10);
783         level += 0.01;
784     }
787 function closebox()
789     document.getElementById('box').style.display='none';
790     document.getElementById('filter').style.display='none';