Browse files

Merge branch 'master' of git://phpmyadmin.git.sourceforge.net/gitroot…

…/phpmyadmin/phpmyadmin
  • Loading branch information...
2 parents 045499b + 0a6f282 commit 6104ef1ba478e68476963c41b4951baa1a7fc9c7 @lgtkaushalya lgtkaushalya committed Jun 24, 2011
Showing with 138,394 additions and 92,662 deletions.
  1. +10 −0 ChangeLog
  2. +7 −0 Documentation.html
  3. +38 −0 db_events.php
  4. +1 −1 db_operations.php
  5. +1 −1 db_printview.php
  6. +448 −0 db_routines.php
  7. +2 −2 db_search.php
  8. +0 −15 db_structure.php
  9. +38 −0 db_triggers.php
  10. +4 −4 enum_editor.php
  11. +1 −1 import.php
  12. +1 −1 index.php
  13. +2 −0 js/db_events.js
  14. +568 −0 js/db_routines.js
  15. +0 −74 js/db_structure.js
  16. +2 −0 js/display_triggers.js
  17. +183 −44 js/functions.js
  18. +94 −1 js/indexes.js
  19. +5 −0 js/jquery/jquery.event.drag-2.0.min.js
  20. +78 −0 js/jquery/jquery.mousewheel.js
  21. +1,339 −0 js/jquery/jquery.svg.js
  22. +1 −0 js/makegrid.js
  23. +5 −3 js/messages.php
  24. +2,553 −0 js/openlayers/OpenLayers.js
  25. BIN js/openlayers/img/blank.gif
  26. BIN js/openlayers/img/cloud-popup-relative.png
  27. BIN js/openlayers/img/drag-rectangle-off.png
  28. BIN js/openlayers/img/drag-rectangle-on.png
  29. BIN js/openlayers/img/east-mini.png
  30. BIN js/openlayers/img/layer-switcher-maximize.png
  31. BIN js/openlayers/img/layer-switcher-minimize.png
  32. BIN js/openlayers/img/marker-blue.png
  33. BIN js/openlayers/img/marker-gold.png
  34. BIN js/openlayers/img/marker-green.png
  35. BIN js/openlayers/img/marker.png
  36. BIN js/openlayers/img/measuring-stick-off.png
  37. BIN js/openlayers/img/measuring-stick-on.png
  38. BIN js/openlayers/img/north-mini.png
  39. BIN js/openlayers/img/panning-hand-off.png
  40. BIN js/openlayers/img/panning-hand-on.png
  41. BIN js/openlayers/img/slider.png
  42. BIN js/openlayers/img/south-mini.png
  43. BIN js/openlayers/img/west-mini.png
  44. BIN js/openlayers/img/zoom-minus-mini.png
  45. BIN js/openlayers/img/zoom-plus-mini.png
  46. BIN js/openlayers/img/zoom-world-mini.png
  47. BIN js/openlayers/img/zoombar.png
  48. 0 js/openlayers/theme/default/framedCloud.css
  49. +10 −0 js/openlayers/theme/default/google.css
  50. +7 −0 js/openlayers/theme/default/ie6-style.css
  51. BIN js/openlayers/theme/default/img/add_point_off.png
  52. BIN js/openlayers/theme/default/img/add_point_on.png
  53. BIN js/openlayers/theme/default/img/blank.gif
  54. BIN js/openlayers/theme/default/img/close.gif
  55. BIN js/openlayers/theme/default/img/drag-rectangle-off.png
  56. BIN js/openlayers/theme/default/img/drag-rectangle-on.png
  57. BIN js/openlayers/theme/default/img/draw_line_off.png
  58. BIN js/openlayers/theme/default/img/draw_line_on.png
  59. BIN js/openlayers/theme/default/img/draw_point_off.png
  60. BIN js/openlayers/theme/default/img/draw_point_on.png
  61. BIN js/openlayers/theme/default/img/draw_polygon_off.png
  62. BIN js/openlayers/theme/default/img/draw_polygon_on.png
  63. BIN js/openlayers/theme/default/img/editing_tool_bar.png
  64. BIN js/openlayers/theme/default/img/move_feature_off.png
  65. BIN js/openlayers/theme/default/img/move_feature_on.png
  66. BIN js/openlayers/theme/default/img/navigation_history.png
  67. BIN js/openlayers/theme/default/img/overview_replacement.gif
  68. BIN js/openlayers/theme/default/img/pan-panel-NOALPHA.png
  69. BIN js/openlayers/theme/default/img/pan-panel.png
  70. BIN js/openlayers/theme/default/img/pan_off.png
  71. BIN js/openlayers/theme/default/img/pan_on.png
  72. BIN js/openlayers/theme/default/img/panning-hand-off.png
  73. BIN js/openlayers/theme/default/img/panning-hand-on.png
  74. BIN js/openlayers/theme/default/img/remove_point_off.png
  75. BIN js/openlayers/theme/default/img/remove_point_on.png
  76. BIN js/openlayers/theme/default/img/ruler.png
  77. BIN js/openlayers/theme/default/img/save_features_off.png
  78. BIN js/openlayers/theme/default/img/save_features_on.png
  79. BIN js/openlayers/theme/default/img/view_next_off.png
  80. BIN js/openlayers/theme/default/img/view_next_on.png
  81. BIN js/openlayers/theme/default/img/view_previous_off.png
  82. BIN js/openlayers/theme/default/img/view_previous_on.png
  83. BIN js/openlayers/theme/default/img/zoom-panel-NOALPHA.png
  84. BIN js/openlayers/theme/default/img/zoom-panel.png
  85. +397 −0 js/openlayers/theme/default/style.css
  86. +5 −5 js/server_status.js
  87. +74 −2 js/server_variables.js
  88. +3 −3 js/sql.js
  89. +250 −0 js/tbl_gis_visualization.js
  90. +5 −2 libraries/Index.class.php
  91. +6 −5 libraries/RecentTable.class.php
  92. +5 −4 libraries/StorageEngine.class.php
  93. +4 −3 libraries/Table.class.php
  94. +5 −9 libraries/auth/cookie.auth.lib.php
  95. +72 −60 libraries/blowfish.php
  96. +21 −16 libraries/common.inc.php
  97. +269 −1 libraries/common.lib.php
  98. +32 −25 libraries/database_interface.lib.php
  99. +109 −20 libraries/db_events.inc.php
  100. +2 −2 libraries/db_info.inc.php
  101. +22 −0 libraries/db_links.inc.php
  102. +0 −94 libraries/db_routines.inc.php
  103. +1,265 −0 libraries/db_routines.lib.php
  104. +26 −0 libraries/dbi/mysql.dbi.lib.php
  105. +38 −0 libraries/dbi/mysqli.dbi.lib.php
  106. +108 −17 libraries/display_tbl.lib.php
  107. +123 −0 libraries/display_triggers.inc.php
  108. +4 −2 libraries/export/codegen.php
  109. +4 −1 libraries/export/csv.php
  110. +7 −6 libraries/export/excel.php
  111. +3 −2 libraries/export/htmlword.php
  112. +3 −0 libraries/export/json.php
  113. +3 −2 libraries/export/latex.php
  114. +8 −8 libraries/export/mediawiki.php
  115. +2 −1 libraries/export/ods.php
  116. +2 −1 libraries/export/odt.php
  117. +4 −2 libraries/export/pdf.php
  118. +3 −1 libraries/export/php_array.php
  119. +2 −1 libraries/export/sql.php
  120. +2 −1 libraries/export/texytext.php
  121. +21 −20 libraries/export/xls.php
  122. +3 −2 libraries/export/xlsx.php
  123. +2 −2 libraries/export/xml.php
  124. +2 −1 libraries/export/yaml.php
  125. +47 −0 libraries/gis/pma_gis_factory.php
  126. +161 −0 libraries/gis/pma_gis_geometry.php
  127. +225 −0 libraries/gis/pma_gis_geometrycollection.php
  128. +198 −0 libraries/gis/pma_gis_linestring.php
  129. +227 −0 libraries/gis/pma_gis_multilinestring.php
  130. +190 −0 libraries/gis/pma_gis_multipoint.php
  131. +315 −0 libraries/gis/pma_gis_multipolygon.php
  132. +176 −0 libraries/gis/pma_gis_point.php
  133. +290 −0 libraries/gis/pma_gis_polygon.php
  134. +429 −0 libraries/gis/pma_gis_visualization.php
  135. +176 −0 libraries/gis_visualization.lib.php
  136. +2 −1 libraries/import/csv.php
  137. +1 −0 libraries/import/docsql.php
  138. +2 −1 libraries/import/ldi.php
  139. +1 −1 libraries/import/ods.php
  140. +4 −3 libraries/import/sql.php
  141. +9 −8 libraries/import/xls.php
  142. +9 −8 libraries/import/xlsx.php
  143. +20 −20 libraries/import/xml.php
  144. +11 −0 libraries/mult_submits.inc.php
  145. +16 −19 libraries/schema/Dia_Relation_Schema.class.php
  146. +32 −35 libraries/schema/Eps_Relation_Schema.class.php
  147. +0 −4 libraries/schema/Export_Relation_Schema.class.php
  148. +0 −3 libraries/schema/Pdf_Relation_Schema.class.php
  149. +23 −26 libraries/schema/Svg_Relation_Schema.class.php
  150. +0 −4 libraries/schema/User_Schema.class.php
  151. +17 −20 libraries/schema/Visio_Relation_Schema.class.php
  152. +3 −1 libraries/select_lang.lib.php
  153. +2 −2 libraries/sqlparser.lib.php
  154. +1 −1 libraries/string.lib.php
  155. +13 −21 libraries/string_mb.lib.php
  156. +13 −21 libraries/string_native.lib.php
  157. +15 −4 libraries/tbl_links.inc.php
  158. +2 −21 libraries/tbl_properties.inc.php
  159. +0 −58 libraries/tbl_triggers.inc.php
  160. +7 −0 main.php
  161. +9 −3 navigation.php
  162. +1,765 −1,394 po/af.po
  163. +1,831 −1,437 po/ar.po
  164. +1,814 −1,428 po/az.po
  165. +1,849 −1,448 po/be.po
  166. +1,870 −1,468 po/be@latin.po
  167. +1,839 −1,451 po/bg.po
  168. +1,823 −1,431 po/bn.po
  169. +9,868 −0 po/br.po
  170. +1,819 −1,431 po/bs.po
  171. +1,859 −1,448 po/ca.po
  172. +1,820 −1,436 po/cs.po
  173. +1,789 −1,391 po/cy.po
  174. +1,857 −1,450 po/da.po
  175. +1,876 −1,463 po/de.po
  176. +1,868 −1,476 po/el.po
  177. +1,783 −1,439 po/en_GB.po
  178. +1,793 −1,453 po/es.po
  179. +1,830 −1,436 po/et.po
  180. +1,804 −1,421 po/eu.po
  181. +1,783 −1,411 po/fa.po
  182. +1,837 −1,414 po/fi.po
  183. +1,874 −1,466 po/fr.po
  184. +1,881 −1,468 po/gl.po
  185. +1,777 −1,385 po/he.po
  186. +1,852 −1,441 po/hi.po
  187. +1,851 −1,451 po/hr.po
  188. +1,870 −1,464 po/hu.po
  189. +1,821 −1,440 po/id.po
  190. +1,857 −1,444 po/it.po
  191. +1,793 −1,443 po/ja.po
  192. +1,867 −1,459 po/ka.po
  193. +1,770 −1,388 po/ko.po
  194. +1,853 −1,445 po/lt.po
  195. +1,838 −1,447 po/lv.po
  196. +1,833 −1,440 po/mk.po
  197. +1,671 −1,341 po/ml.po
  198. +1,843 −1,449 po/mn.po
  199. +1,806 −1,425 po/ms.po
  200. +1,860 −1,439 po/nb.po
  201. +1,859 −1,448 po/nl.po
  202. +1,670 −1,341 po/phpmyadmin.pot
  203. +1,877 −1,455 po/pl.po
  204. +1,784 −1,391 po/pt.po
  205. +1,859 −1,453 po/pt_BR.po
  206. +1,870 −1,467 po/ro.po
  207. +1,856 −1,444 po/ru.po
  208. +1,851 −1,448 po/si.po
  209. +1,861 −1,449 po/sk.po
  210. +1,852 −1,439 po/sl.po
  211. +1,810 −1,423 po/sq.po
  212. +1,844 −1,441 po/sr.po
  213. +1,858 −1,459 po/sr@latin.po
  214. +1,864 −1,453 po/sv.po
  215. +1,784 −1,443 po/ta.po
  216. +1,751 −1,384 po/te.po
  217. +1,832 −1,435 po/th.po
  218. +1,779 −1,437 po/tr.po
  219. +1,820 −1,430 po/tt.po
  220. +1,784 −1,391 po/ug.po
  221. +1,781 −1,399 po/uk.po
  222. +1,828 −1,429 po/ur.po
  223. +1,862 −1,449 po/uz.po
  224. +1,858 −1,446 po/uz@latin.po
  225. +1,846 −1,436 po/zh_CN.po
  226. +1,806 −1,408 po/zh_TW.po
  227. +2 −2 server_replication.php
  228. +15 −9 server_status.php
  229. +69 −40 server_variables.php
  230. +7 −2 show_config_errors.php
  231. +9 −0 sql.php
  232. +6 −84 tbl_change.php
  233. +1 −1 tbl_create.php
  234. +234 −0 tbl_gis_visualization.php
  235. +12 −3 tbl_indexes.php
  236. +45 −5 tbl_structure.php
  237. +35 −0 tbl_triggers.php
  238. +131 −1 themes/original/css/theme_right.css.php
  239. BIN themes/original/img/b_event_add.png
  240. BIN themes/original/img/b_events.png
  241. BIN themes/original/img/b_globe.gif
  242. BIN themes/original/img/b_nextpage.png
  243. BIN themes/original/img/b_routine_add.png
  244. BIN themes/original/img/b_routines.png
  245. BIN themes/original/img/b_spatial.png
  246. BIN themes/original/img/b_trigger_add.png
  247. BIN themes/original/img/b_triggers.png
  248. BIN themes/original/img/bd_edit.png
  249. BIN themes/original/img/bd_export.png
  250. BIN themes/original/img/bd_nextpage.png
  251. BIN themes/original/img/bd_spatial.png
  252. BIN themes/original/img/east-mini.png
  253. BIN themes/original/img/north-mini.png
  254. BIN themes/original/img/south-mini.png
  255. BIN themes/original/img/west-mini.png
  256. BIN themes/original/img/zoom-minus-mini.png
  257. BIN themes/original/img/zoom-plus-mini.png
  258. BIN themes/original/img/zoom-world-mini.png
  259. +123 −3 themes/pmahomme/css/theme_right.css.php
  260. BIN themes/pmahomme/img/b_event_add.png
  261. BIN themes/pmahomme/img/b_events.png
  262. BIN themes/pmahomme/img/b_globe.gif
  263. BIN themes/pmahomme/img/b_routine_add.png
  264. BIN themes/pmahomme/img/b_routines.png
  265. BIN themes/pmahomme/img/b_spatial.png
  266. BIN themes/pmahomme/img/b_trigger_add.png
  267. BIN themes/pmahomme/img/b_triggers.png
  268. BIN themes/pmahomme/img/bd_edit.png
  269. BIN themes/pmahomme/img/bd_export.png
  270. BIN themes/pmahomme/img/bd_spatial.png
  271. BIN themes/pmahomme/img/east-mini.png
  272. BIN themes/pmahomme/img/north-mini.png
  273. BIN themes/pmahomme/img/south-mini.png
  274. BIN themes/pmahomme/img/west-mini.png
  275. BIN themes/pmahomme/img/zoom-minus-mini.png
  276. BIN themes/pmahomme/img/zoom-plus-mini.png
  277. BIN themes/pmahomme/img/zoom-world-mini.png
  278. +5 −0 themes/svg_gradient.php
View
10 ChangeLog
@@ -20,6 +20,15 @@ phpMyAdmin - ChangeLog
+ [interface] Mouse-based column reordering in query results
+ AJAX for Insert to a table from database Structure page
- Patch #3316969 PMA_ajaxShowMessage() does not respect timeout
++ AJAX for Change on multiple rows in table Browse
++ [interface] Improved support for stored routines
++ [display] More options for browsing GIS data
++ [interface] Support for spatial indexes
++ [display] GIS data visualization
+
+3.4.4.0 (not yet released)
+- bug #3323060 [parser] SQL parser breaks AJAX requests if query has unclosed quotes
+- bug #3323101 [parser] Invalid escape sequence in SQL parser
3.4.3.0 (not yet released)
- bug #3311170 [sync] Missing helper icons in Synchronize
@@ -34,6 +43,7 @@ phpMyAdmin - ChangeLog
- patch #3317206 [privileges] Generate password option missing on new accounts
- bug #3317293 [edit] Inline edit places HTML line breaks in edit area
- bug #3319466 [interface] Inline query edit does not escape special characters
+- minor XSS (require a valid token)
3.4.2.0 (2011-06-07)
- bug #3301249 [interface] Iconic table operations does not remove inline edit label
View
7 Documentation.html
@@ -137,6 +137,8 @@ <h2 id="intro">Introduction</h2>
<abbr title="Frequently Asked Questions">FAQ</abbr> 3.6)</a></li>
<li>support mysqli, the improved MySQL extension <a href="#faq1_17">
(see <abbr title="Frequently Asked Questions">FAQ</abbr> 1.17)</a></li>
+ <li>create, edit, call, export and drop stored procedures and functions</li>
+ <li>create, edit, export and drop events and triggers</li>
<li>communicate in <a href="http://www.phpmyadmin.net/home_page/translations.php">62 different languages</a>
</li>
<li>synchronize two databases residing on the same as well as remote servers
@@ -5152,6 +5154,8 @@ <h2 id="glossary">Glossary</h2>
<li><a href="http://www.wikipedia.org/wiki/Secure_Sockets_Layer">SSL (Secure
Sockets Layer)</a>
- a cryptographic protocol which provides secure communication on the Internet.</li>
+ <li><a href="http://en.wikipedia.org/wiki/Stored_procedure">Stored procedure</a>
+ - a subroutine available to applications accessing a relational database system</li>
<li><a href="http://www.wikipedia.org/wiki/SQL">SQL</a>
- Structured Query Language</li>
<li><a href="http://www.wikipedia.org/wiki/Table_%28database%29">table</a>
@@ -5163,6 +5167,9 @@ <h2 id="glossary">Glossary</h2>
- a type of archive file format: the Tape ARchive format.</li>
<li><a href="http://www.wikipedia.org/wiki/TCP">TCP (Transmission Control Protocol)</a>
- one of the core protocols of the Internet protocol suite.</li>
+ <li><a href="http://en.wikipedia.org/wiki/Database_trigger">trigger</a>
+ - a procedural code that is automatically executed in response to
+ certain events on a particular table or view in a database</li>
<li><a href="http://www.acko.net/node/56">UFPDF</a>
- Unicode/UTF-8 extension for FPDF</li>
<li><a href="http://www.wikipedia.org/wiki/URL">URL (Uniform Resource Locator)</a>
View
38 db_events.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/common.lib.php';
+
+$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
+$GLOBALS['js_include'][] = 'db_events.js';
+
+/**
+ * Create labels for the list
+ */
+$titles = PMA_buildActionTitles();
+
+/**
+ * Displays the header
+ */
+require_once './libraries/db_common.inc.php';
+
+/**
+ * Displays the tabs
+ */
+require_once './libraries/db_info.inc.php';
+
+/**
+ * Displays the list of events
+ */
+require_once './libraries/db_events.inc.php';
+
+/**
+ * Displays the footer
+ */
+require './libraries/footer.inc.php';
+
+
+?>
View
2 db_operations.php
@@ -47,7 +47,7 @@
// lower_case_table_names=1 `DB` becomes `db`
$lower_case_table_names = PMA_DBI_fetch_value('SHOW VARIABLES LIKE "lower_case_table_names"', 0, 1);
if ($lower_case_table_names === '1') {
- $newname = strtolower($newname);
+ $newname = PMA_strtolower($newname);
}
$local_query = 'CREATE DATABASE ' . PMA_backquote($newname);
View
2 db_printview.php
@@ -53,7 +53,7 @@
if ($result != false && PMA_DBI_num_rows($result) > 0) {
while ($tmp = PMA_DBI_fetch_row($result)) {
if (! isset($sot_cache[$tmp[0]])) {
- $sts_result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . addslashes($tmp[0]) . '\';');
+ $sts_result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddSlashes($tmp[0]) . '\';');
$sts_tmp = PMA_DBI_fetch_assoc($sts_result);
$tables[] = $sts_tmp;
} else { // table in use
View
448 db_routines.php
@@ -0,0 +1,448 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package phpMyAdmin
+ */
+
+/**
+ * Include required files
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/common.lib.php';
+require_once './libraries/db_routines.lib.php';
+require_once './libraries/mysql_charsets.lib.php';
+
+/**
+ * Include JavaScript libraries
+ */
+$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
+$GLOBALS['js_include'][] = 'jquery/timepicker.js';
+$GLOBALS['js_include'][] = 'db_routines.js';
+
+/**
+ * Create labels for the list
+ */
+$titles = PMA_buildActionTitles();
+
+if ($GLOBALS['is_ajax_request'] != true) {
+ /**
+ * Displays the header
+ */
+ require_once './libraries/db_common.inc.php';
+ /**
+ * Displays the tabs
+ */
+ require_once './libraries/db_info.inc.php';
+} else {
+ if (strlen($db)) {
+ PMA_DBI_select_db($db);
+ if (! isset($url_query)) {
+ $url_query = PMA_generate_common_url($db);
+ }
+ }
+}
+
+/**
+ * Process all requests
+ */
+
+// Some definitions
+$param_directions = array('IN',
+ 'OUT',
+ 'INOUT');
+$param_opts_num = array('UNSIGNED',
+ 'ZEROFILL',
+ 'UNSIGNED ZEROFILL');
+$param_sqldataaccess = array('NO SQL',
+ 'CONTAINS SQL',
+ 'READS SQL DATA',
+ 'MODIFIES SQL DATA');
+
+/**
+ * Generate the conditional classes that will be used to attach jQuery events to links.
+ */
+$ajax_class = array(
+ 'add' => '',
+ 'edit' => '',
+ 'exec' => '',
+ 'drop' => '',
+ 'export' => ''
+ );
+if ($GLOBALS['cfg']['AjaxEnable']) {
+ $ajax_class['add'] = 'class="add_routine_anchor"';
+ $ajax_class['edit'] = 'class="edit_routine_anchor"';
+ $ajax_class['exec'] = 'class="exec_routine_anchor"';
+ $ajax_class['drop'] = 'class="drop_routine_anchor"';
+ $ajax_class['export'] = 'class="export_routine_anchor"';
+}
+
+/**
+ * Keep a list of errors that occured while processing an 'Add' or 'Edit' operation.
+ */
+$routine_errors = array();
+
+/**
+ * Handle all user requests other than the default of listing routines
+ */
+if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['routine_name'])) {
+ // Build the queries
+ $routine = PMA_RTN_getRoutineDataFromName($db, $_REQUEST['routine_name'], false);
+ if ($routine !== false) {
+ $queries = array();
+ $end_query = array();
+ $args = array();
+ for ($i=0; $i<$routine['num_params']; $i++) {
+ if (isset($_REQUEST['params'][$routine['param_name'][$i]])) {
+ $value = $_REQUEST['params'][$routine['param_name'][$i]];
+ if (is_array($value)) { // is SET type
+ $value = implode(',', $value);
+ }
+ $value = PMA_sqlAddSlashes($value);
+ if (! empty($_REQUEST['funcs'][$routine['param_name'][$i]])
+ && in_array($_REQUEST['funcs'][$routine['param_name'][$i]], $cfg['Functions'])) {
+ $queries[] = "SET @p$i={$_REQUEST['funcs'][$routine['param_name'][$i]]}('$value');\n";
+ } else {
+ $queries[] = "SET @p$i='$value';\n";
+ }
+ $args[] = "@p$i";
+ } else {
+ $args[] = "@p$i";
+ }
+ if ($routine['type'] == 'PROCEDURE') {
+ if ($routine['param_dir'][$i] == 'OUT' || $routine['param_dir'][$i] == 'INOUT') {
+ $end_query[] = "@p$i AS " . PMA_backquote($routine['param_name'][$i]);
+ }
+ }
+ }
+ if ($routine['type'] == 'PROCEDURE') {
+ $queries[] = "CALL " . PMA_backquote($routine['name'])
+ . "(" . implode(', ', $args) . ");\n";
+ if (count($end_query)) {
+ $queries[] = "SELECT " . implode(', ', $end_query) . ";\n";
+ }
+ } else {
+ $queries[] = "SELECT " . PMA_backquote($routine['name'])
+ . "(" . implode(', ', $args) . ") "
+ . "AS " . PMA_backquote($routine['name']) . ";\n";
+ }
+ // Execute the queries
+ $affected = 0;
+ $result = null;
+ $outcome = true;
+ foreach ($queries as $num => $query) {
+ $resource = PMA_DBI_try_query($query);
+ if ($resource === false) {
+ $outcome = false;
+ break;
+ }
+ while (true) {
+ if(! PMA_DBI_more_results()) {
+ break;
+ }
+ PMA_DBI_next_result();
+ }
+ if (substr($query, 0, 6) == 'SELECT') {
+ $result = $resource;
+ } else if (substr($query, 0, 4) == 'CALL') {
+ $affected = PMA_DBI_affected_rows() - PMA_DBI_num_rows($resource);
+ }
+ }
+ // Generate output
+ if ($outcome) {
+ $message = __('Your SQL query has been executed successfully');
+ if ($routine['type'] == 'PROCEDURE') {
+ $message .= '<br />';
+ $message .= sprintf(_ngettext('%d row affected by the last statement inside the procedure', '%d rows affected by the last statement inside the procedure', $affected), $affected);
+ }
+ $message = PMA_message::success($message);
+ // Pass the SQL queries through the "pretty printer"
+ $output = '<code class="sql" style="margin-bottom: 1em;">';
+ $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries)));
+ $output .= '</code>';
+ // Display results
+ if ($result) {
+ $output .= "<fieldset><legend>";
+ $output .= sprintf(__('Execution results of routine %s'),
+ PMA_backquote(htmlspecialchars($routine['name'])));
+ $output .= "</legend>";
+ $output .= "<table><tr>";
+ foreach (PMA_DBI_get_fields_meta($result) as $key => $field) {
+ $output .= "<th>" . htmlspecialchars($field->name) . "</th>";
+ }
+ $output .= "</tr>";
+ // Stored routines can only ever return ONE ROW.
+ $data = PMA_DBI_fetch_single_row($result);
+ foreach ($data as $key => $value) {
+ if ($value === null) {
+ $value = '<i>NULL</i>';
+ } else {
+ $value = htmlspecialchars($value);
+ }
+ $output .= "<td class='odd'>" . $value . "</td>";
+ }
+ $output .= "</table></fieldset>";
+ } else {
+ $notice = __('MySQL returned an empty result set (i.e. zero rows).');
+ $output .= PMA_message::notice($notice)->getDisplay();
+ }
+ } else {
+ $output = '';
+ $message = PMA_message::error(sprintf(__('The following query has failed: "%s"'), $query) . '<br /><br />'
+ . __('MySQL said: ') . PMA_DBI_getError(null));
+ }
+ // Print/send output
+ if ($GLOBALS['is_ajax_request']) {
+ $extra_data = array('dialog' => false);
+ PMA_ajaxResponse($message->getDisplay() . $output, $message->isSuccess(), $extra_data);
+ } else {
+ echo $message->getDisplay() . $output;
+ if ($message->isError()) {
+ // At least one query has failed, so shouldn't
+ // execute any more queries, so we quit.
+ exit;
+ }
+ unset($_POST);
+ // Now deliberately fall through to displaying the routines list
+ }
+ } else {
+ $message = __('Error in processing request') . ' : '
+ . sprintf(__('No routine with name %1$s found in database %2$s'),
+ htmlspecialchars(PMA_backquote($_REQUEST['routine_name'])),
+ htmlspecialchars(PMA_backquote($db)));
+ $message = PMA_message::error($message);
+ if ($GLOBALS['is_ajax_request']) {
+ PMA_ajaxResponse($message, $message->isSuccess());
+ } else {
+ echo $message->getDisplay();
+ unset($_POST);
+ }
+ }
+} else if (! empty($_GET['execute_dialog']) && ! empty($_GET['routine_name'])) {
+ /**
+ * Display the execute form for a routine.
+ */
+ $routine = PMA_RTN_getRoutineDataFromName($db, $_GET['routine_name'], false);
+ if ($routine !== false) {
+ $form = PMA_RTN_getExecuteForm($routine, $GLOBALS['is_ajax_request']);
+ if ($GLOBALS['is_ajax_request'] == true) {
+ $extra_data = array();
+ $extra_data['dialog'] = true;
+ $extra_data['title'] = __("Execute routine") . " ";
+ $extra_data['title'] .= PMA_backquote(htmlentities($_GET['routine_name'], ENT_QUOTES));
+ PMA_ajaxResponse($form, true, $extra_data);
+ } else {
+ echo "\n\n<h2>" . __("Execute routine") . "</h2>\n\n";
+ echo $form;
+ require './libraries/footer.inc.php';
+ // exit;
+ }
+ } else if (($GLOBALS['is_ajax_request'] == true)) {
+ $message = __('Error in processing request') . ' : '
+ . sprintf(__('No routine with name %1$s found in database %2$s'),
+ htmlspecialchars(PMA_backquote($_REQUEST['routine_name'])),
+ htmlspecialchars(PMA_backquote($db)));
+ $message = PMA_message::error($message);
+ PMA_ajaxResponse($message, false);
+ }
+} else if (! empty($_GET['exportroutine']) && ! empty($_GET['routine_name'])) {
+ /**
+ * Display the export for a routine.
+ */
+ $routine_name = htmlspecialchars(PMA_backquote($_GET['routine_name']));
+ $routine_type = PMA_DBI_fetch_value("SELECT ROUTINE_TYPE "
+ . "FROM INFORMATION_SCHEMA.ROUTINES "
+ . "WHERE ROUTINE_SCHEMA='" . PMA_sqlAddslashes($db) . "' "
+ . "AND SPECIFIC_NAME='" . PMA_sqlAddslashes($_GET['routine_name']) . "';");
+ if (! empty($routine_type) && $create_proc = PMA_DBI_get_definition($db, $routine_type, $_GET['routine_name'])) {
+ $create_proc = '<textarea cols="40" rows="15" style="width: 100%;">' . htmlspecialchars($create_proc) . '</textarea>';
+ if ($GLOBALS['is_ajax_request']) {
+ $extra_data = array('title' => sprintf(__('Export of routine %s'), $routine_name));
+ PMA_ajaxResponse($create_proc, true, $extra_data);
+ } else {
+ echo '<fieldset>' . "\n"
+ . ' <legend>' . sprintf(__('Export of routine %s'), $routine_name) . '</legend>' . "\n"
+ . $create_proc . "\n"
+ . '</fieldset>';
+ }
+ } else {
+ $response = __('Error in processing request') . ' : '
+ . sprintf(__('No routine with name %1$s found in database %2$s'),
+ $routine_name, htmlspecialchars(PMA_backquote($db)));
+ $response = PMA_message::error($response);
+ if ($GLOBALS['is_ajax_request']) {
+ PMA_ajaxResponse($response, false);
+ } else {
+ $response->display();
+ }
+ }
+} else if (! empty($_REQUEST['routine_process_addroutine']) || ! empty($_REQUEST['routine_process_editroutine'])) {
+ /**
+ * Handle a request to create/edit a routine
+ */
+ $sql_query = '';
+ $routine_query = PMA_RTN_getQueryFromRequest();
+ if (! count($routine_errors)) { // set by PMA_RTN_getQueryFromRequest()
+ // Execute the created query
+ if (! empty($_REQUEST['routine_process_editroutine'])) {
+ if (! in_array($_REQUEST['routine_original_type'], array('PROCEDURE', 'FUNCTION'))) {
+ $routine_errors[] = sprintf(__('Invalid routine type: "%s"'), htmlspecialchars($_REQUEST['routine_original_type']));
+ } else {
+ // Backup the old routine, in case something goes wrong
+ $create_routine = PMA_DBI_get_definition($db, $_REQUEST['routine_original_type'], $_REQUEST['routine_original_name']);
+ $drop_routine = "DROP {$_REQUEST['routine_original_type']} " . PMA_backquote($_REQUEST['routine_original_name']) . ";\n";
+ $result = PMA_DBI_try_query($drop_routine);
+ if (! $result) {
+ $routine_errors[] = sprintf(__('The following query has failed: "%s"'), $drop_routine) . '<br />'
+ . __('MySQL said: ') . PMA_DBI_getError(null);
+ } else {
+ $result = PMA_DBI_try_query($routine_query);
+ if (! $result) {
+ $routine_errors[] = sprintf(__('The following query has failed: "%s"'), $routine_query) . '<br />'
+ . __('MySQL said: ') . PMA_DBI_getError(null);
+ // We dropped the old routine, but were unable to create the new one
+ // Try to restore the backup query
+ $result = PMA_DBI_try_query($create_routine);
+ if (! $result) {
+ // OMG, this is really bad! We dropped the query, failed to create a new one
+ // and now even the backup query does not execute!
+ // This should not happen, but we better handle this just in case.
+ $routine_errors[] = __('Sorry, we failed to restore the dropped routine.') . '<br />'
+ . __('The backed up query was:') . "\"$create_routine\"" . '<br />'
+ . __('MySQL said: ') . PMA_DBI_getError(null);
+ }
+ } else {
+ $message = PMA_Message::success(__('Routine %1$s has been modified.'));
+ $message->addParam(PMA_backquote($_REQUEST['routine_name']));
+ $sql_query = $drop_routine . $routine_query;
+ }
+ }
+ }
+ } else {
+ // 'Add a new routine' mode
+ $result = PMA_DBI_try_query($routine_query);
+ if (! $result) {
+ $routine_errors[] = sprintf(__('The following query has failed: "%s"'), $routine_query) . '<br /><br />'
+ . __('MySQL said: ') . PMA_DBI_getError(null);
+ } else {
+ $message = PMA_Message::success(__('Routine %1$s has been created.'));
+ $message->addParam(PMA_backquote($_REQUEST['routine_name']));
+ $sql_query = $routine_query;
+ }
+ }
+ }
+
+ if (count($routine_errors)) {
+ $message = PMA_Message::error(__('<b>One or more errors have occured while processing your request:</b>'));
+ $message->addString('<ul>');
+ foreach ($routine_errors as $num => $string) {
+ $message->addString('<li>' . $string . '</li>');
+ }
+ $message->addString('</ul>');
+ }
+
+ $output = PMA_showMessage($message, $sql_query);
+ if ($GLOBALS['is_ajax_request']) {
+ $extra_data = array();
+ if ($message->isSuccess()) {
+ $columns = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`, `DTD_IDENTIFIER`, `ROUTINE_DEFINITION`";
+ $where = "ROUTINE_SCHEMA='" . PMA_sqlAddslashes($db) . "' AND ROUTINE_NAME='" . PMA_sqlAddslashes($_REQUEST['routine_name']) . "'";
+ $routine = PMA_DBI_fetch_single_row("SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE $where;");
+ $extra_data['name'] = htmlspecialchars(strtoupper($_REQUEST['routine_name']));
+ $extra_data['new_row'] = PMA_RTN_getRowForRoutinesList($routine, 0, true);
+ $response = $output;
+ } else {
+ $response = $message;
+ }
+ PMA_ajaxResponse($response, $message->isSuccess(), $extra_data);
+ }
+}
+
+/**
+ * Display a form used to add/edit a routine, if necessary
+ */
+if (count($routine_errors) || ( empty($_REQUEST['routine_process_addroutine']) && empty($_REQUEST['routine_process_editroutine']) &&
+ (! empty($_REQUEST['addroutine']) || ! empty($_REQUEST['editroutine'])
+ || ! empty($_REQUEST['routine_addparameter']) || ! empty($_REQUEST['routine_removeparameter'])
+ || ! empty($_REQUEST['routine_changetype'])))) { // FIXME: this must be simpler than that
+ // Handle requests to add/remove parameters and changing routine type
+ // This is necessary when JS is disabled
+ $operation = '';
+ if (! empty($_REQUEST['routine_addparameter'])) {
+ $operation = 'add';
+ } else if (! empty($_REQUEST['routine_removeparameter'])) {
+ $operation = 'remove';
+ } else if (! empty($_REQUEST['routine_changetype'])) {
+ $operation = 'change';
+ }
+ // Get the data for the form (if any)
+ if (! empty($_REQUEST['addroutine'])) {
+ $title = __("Create routine");
+ $routine = PMA_RTN_getRoutineDataFromRequest();
+ $mode = 'add';
+ } else if (! empty($_REQUEST['editroutine'])) {
+ $title = __("Edit routine");
+ if (! $operation && ! empty($_REQUEST['routine_name']) && empty($_REQUEST['routine_process_editroutine'])) {
+ $routine = PMA_RTN_getRoutineDataFromName($db, $_REQUEST['routine_name']);
+ if ($routine !== false) {
+ $routine['original_name'] = $routine['name'];
+ $routine['original_type'] = $routine['type'];
+ }
+ } else {
+ $routine = PMA_RTN_getRoutineDataFromRequest();
+ }
+ $mode = 'edit';
+ }
+ if ($routine !== false) {
+ // Show form
+ $editor = PMA_RTN_getEditorForm($mode, $operation, $routine, $routine_errors, $GLOBALS['is_ajax_request']);
+ if ($GLOBALS['is_ajax_request']) {
+ $template = PMA_RTN_getParameterRow();
+ $extra_data = array('title' => $title, 'param_template' => $template, 'type' => $routine['type']);
+ PMA_ajaxResponse($editor, true, $extra_data);
+ }
+ echo "\n\n<h2>$title</h2>\n\n$editor";
+ require './libraries/footer.inc.php';
+ // exit;
+ } else {
+ $message = __('Error in processing request') . ' : '
+ . sprintf(__('No routine with name %1$s found in database %2$s'),
+ htmlspecialchars(PMA_backquote($_REQUEST['routine_name'])),
+ htmlspecialchars(PMA_backquote($db)));
+ $message = PMA_message::error($message);
+ if ($GLOBALS['is_ajax_request']) {
+ PMA_ajaxResponse($message, false);
+ } else {
+ $message->display();
+ }
+ }
+}
+
+/**
+ * Display a list of available routines
+ */
+echo PMA_RTN_getRoutinesList();
+
+/**
+ * Display the form for adding a new routine, if the user has the privileges.
+ */
+echo PMA_RTN_getAddRoutineLink();
+
+/**
+ * Display a warning for users with PHP's old "mysql" extension.
+ */
+if ($GLOBALS['cfg']['Server']['extension'] === 'mysql') {
+ trigger_error(__('You are using PHP\'s deprecated \'mysql\' extension, '
+ . 'which is not capable of handling multi queries. '
+ . '<b>The execution of some stored routines may fail!</b> '
+ . 'Please use the improved \'mysqli\' extension to '
+ . 'avoid any problems.'), E_USER_WARNING);
+}
+
+if ($GLOBALS['is_ajax_request'] != true) {
+ /**
+ * Displays the footer
+ */
+ require './libraries/footer.inc.php';
+}
+
+?>
View
4 db_search.php
@@ -297,7 +297,7 @@ function PMA_getSearchSqls($table, $field, $search_str, $search_option)
<legend><?php echo __('Search in database'); ?></legend>
<table class="formlayout">
- <tr><td><?php echo __('Word(s) or value(s) to search for (wildcard: "%"):'); ?></td>
+ <tr><td><?php echo __('Words or values to search for (wildcard: "%"):'); ?></td>
<td><input type="text" name="search_str" size="60"
value="<?php echo $searched; ?>" /></td>
</tr>
@@ -320,7 +320,7 @@ function PMA_getSearchSqls($table, $field, $search_str, $search_option)
</td>
</tr>
<tr><td align="right" valign="top">
- <?php echo __('Inside table(s):'); ?></td>
+ <?php echo __('Inside tables:'); ?></td>
<td rowspan="2">
<?php
echo ' <select name="table_select[]" size="6" multiple="multiple">' . "\n";
View
15 db_structure.php
@@ -59,14 +59,6 @@
if ($num_tables == 0) {
echo '<p>' . __('No tables found in database') . '</p>' . "\n";
- // Routines
- require './libraries/db_routines.inc.php';
-
- // Events
- if (PMA_MYSQL_INT_VERSION > 50100) {
- require './libraries/db_events.inc.php';
- }
-
if (empty($db_is_information_schema)) {
require './libraries/display_create_table.lib.php';
} // end if (Create Table dialog)
@@ -546,13 +538,6 @@
<hr />
<?php
-// Routines
-require './libraries/db_routines.inc.php';
-
-// Events
-if (PMA_MYSQL_INT_VERSION > 50100) {
- require './libraries/db_events.inc.php';
-}
/**
* Work on the database
View
38 db_triggers.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/common.lib.php';
+
+$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
+$GLOBALS['js_include'][] = 'display_triggers.js';
+
+/**
+ * Create labels for the list
+ */
+$titles = PMA_buildActionTitles();
+
+/**
+ * Displays the header
+ */
+require_once './libraries/db_common.inc.php';
+
+/**
+ * Displays the tabs
+ */
+require_once './libraries/db_info.inc.php';
+
+/**
+ * Displays the list of triggers
+ */
+require_once './libraries/display_triggers.inc.php';
+
+/**
+ * Displays the footer
+ */
+require './libraries/footer.inc.php';
+
+
+?>
View
8 enum_editor.php
@@ -53,20 +53,20 @@
?>
</div>
<p>
- <a href="enum_editor.php?token=<?php echo urlencode($_GET['token']); ?>&field=<?php echo urlencode($_GET['field']); ?>&extra_fields=<?php echo $_GET['extra_fields'] + 1; ?>&values=<?php echo urlencode(join(",", $values)); ?>">
+ <a href="enum_editor.php<?php echo PMA_generate_common_url(array('field' => $_GET['field'], 'extra_fields' => $_GET['extra_fields'] + 1, 'values' => join(',', $values))); ?>">
<?php echo __('+ Restart insertion and add a new value'); ?>
</a>
</p>
- <input type="hidden" name="token" value="<?php echo $_GET['token']; ?>" />
- <input type="hidden" name="field" value="<?php echo $_GET['field']; ?>" />
+ <?php echo PMA_generate_common_hidden_inputs(); ?>
+ <input type="hidden" name="field" value="<?php echo htmlspecialchars($_GET['field']); ?>" />
<input type="hidden" name="num_fields" value="<?php echo $total_fields; ?>" />
<input type="submit" value="<?php echo __('Go'); ?>" />
</form>
<div id="enum_editor_output">
<h3><?php echo __('Output'); ?></h3>
<p><?php echo __('Copy and paste the joined values into the "Length/Values" field'); ?></p>
- <textarea id="joined_values" cols="95" rows="5"><?php echo join(",", $values); ?></textarea>
+ <textarea id="joined_values" cols="95" rows="5"><?php echo htmlspecialchars(join(",", $values)); ?></textarea>
</div>
</div>
</body>
View
2 import.php
@@ -108,7 +108,7 @@
}
$err_url = $goto
. '?' . $common
- . (preg_match('@^tbl_[a-z]*\.php$@', $goto) ? '&amp;table=' . urlencode($table) : '');
+ . (preg_match('@^tbl_[a-z]*\.php$@', $goto) ? '&amp;table=' . htmlspecialchars($table) : '');
$_SESSION['Import_message']['go_back_url'] = $err_url;
}
View
2 index.php
@@ -73,7 +73,7 @@
} else {
$_GET['db'] = $GLOBALS['db'];
$_GET['table'] = $GLOBALS['table'];
- $main_target = $GLOBALS['cfg']['DefaultTabTable'];
+ $main_target = isset($GLOBALS['goto']) ? $GLOBALS['goto'] : $GLOBALS['cfg']['DefaultTabTable'];
}
$url_query = PMA_generate_common_url($_GET);
View
2 js/db_events.js
@@ -0,0 +1,2 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+
View
568 js/db_routines.js
@@ -0,0 +1,568 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+
+/**
+ * Validate routine editor form fields.
+ *
+ * @param syntaxHiglighter an object containing the reference to the
+ * codemirror editor. This will be used to
+ * focus the form on the codemirror editor
+ * if it contains invalid data.
+ */
+function validateRoutineEditor(syntaxHiglighter) {
+ /**
+ * @var inputname Will contain the value of the name
+ * attribute of input fields being checked.
+ */
+ var inputname = '';
+ /**
+ * @var $elm a jQuery object containing the reference
+ * to an element that is being validated.
+ */
+ var $elm = null;
+ /**
+ * @var isError Stores the outcome of the validation.
+ */
+ var isError = false;
+
+ $elm = $('.rte_table').last().find('input[name=routine_name]');
+ if ($elm.val() == '') {
+ $elm.focus();
+ isError = true;
+ } else if ($elm.val().length > 64) {
+ alert(PMA_messages['strValueTooLong']);
+ $elm.focus().select();
+ return false;
+ }
+ if (! isError) {
+ $elm = $('.rte_table').find('textarea[name=routine_definition]');
+ if ($elm.val() == '') {
+ syntaxHiglighter.focus();
+ isError = true;
+ }
+ }
+ if (! isError) {
+ $('.routine_params_table').last().find('tr').each(function() {
+ if (! isError) {
+ $(this).find(':input').each(function() {
+ inputname = $(this).attr('name');
+ if (inputname.substr(0, 17) == 'routine_param_dir' ||
+ inputname.substr(0, 18) == 'routine_param_name' ||
+ inputname.substr(0, 18) == 'routine_param_type') {
+ if ($(this).val() == '') {
+ $(this).focus();
+ isError = true;
+ return false;
+ }
+ }
+ });
+ }
+ });
+ }
+ if (! isError) {
+ // SET, ENUM, VARCHAR and VARBINARY fields must have length/values
+ $('.routine_params_table').last().find('tr').each(function() {
+ var $inputtyp = $(this).find('select[name^=routine_param_type]');
+ var $inputlen = $(this).find('input[name^=routine_param_length]');
+ if ($inputtyp.length && $inputlen.length) {
+ if (($inputtyp.val() == 'ENUM' || $inputtyp.val() == 'SET' || $inputtyp.val().substr(0,3) == 'VAR')
+ && $inputlen.val() == '') {
+ $inputlen.focus();
+ isError = true;
+ return false;
+ }
+ }
+ });
+ }
+ if (! isError && $('select[name=routine_type]').find(':selected').val() == 'FUNCTION') {
+ // The length/values of return variable for functions must
+ // be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
+ var $returntyp = $('select[name=routine_returntype]');
+ var $returnlen = $('input[name=routine_returnlength]');
+ if (($returntyp.val() == 'ENUM' || $returntyp.val() == 'SET' || $returntyp.val().substr(0,3) == 'VAR')
+ && $returnlen.val() == '') {
+ $returnlen.focus();
+ isError = true;
+ }
+ }
+ if (! isError && $('select[name=routine_type]').find(':selected').val() == 'FUNCTION') {
+ if ($('.rte_table').find('textarea[name=routine_definition]').val().toLowerCase().indexOf('return') < 0) {
+ syntaxHiglighter.focus();
+ alert(PMA_messages['MissingReturn']);
+ return false;
+ }
+ }
+ if (! isError) {
+ $elm = $('.rte_table').last().find('input[name=routine_comment]');
+ if ($elm.val().length > 64) {
+ alert(PMA_messages['strValueTooLong']);
+ $elm.focus().select();
+ return false;
+ }
+ }
+ if (! isError) {
+ return true;
+ } else {
+ alert(PMA_messages['strFormEmpty']);
+ return false;
+ }
+} // end validateRoutineEditor()
+
+/**
+ * Enable/disable the "options" dropdown and "length" input for
+ * parameters and the return variable in the routine editor
+ * as necessary.
+ *
+ * @param $type a jQuery object containing the reference
+ * to the "Type" dropdown box
+ * @param $len a jQuery object containing the reference
+ * to the "Length" input box
+ * @param $text a jQuery object containing the reference
+ * to the dropdown box with options for
+ * parameters of text type
+ * @param $num a jQuery object containing the reference
+ * to the dropdown box with options for
+ * parameters of numeric type
+ */
+function setOptionsForParameter($type, $len, $text, $num) {
+ // Process for parameter options
+ switch ($type.val()) {
+ case 'TINYINT':
+ case 'SMALLINT':
+ case 'MEDIUMINT':
+ case 'INT':
+ case 'BIGINT':
+ case 'DECIMAL':
+ case 'FLOAT':
+ case 'DOUBLE':
+ case 'REAL':
+ $text.parent().hide();
+ $num.parent().show();
+ break;
+ case 'TINYTEXT':
+ case 'TEXT':
+ case 'MEDIUMTEXT':
+ case 'LONGTEXT':
+ case 'CHAR':
+ case 'VARCHAR':
+ case 'SET':
+ case 'ENUM':
+ $text.parent().show();
+ $text.show();
+ $num.parent().hide();
+ break;
+ default:
+ $text.parent().show();
+ $text.hide();
+ $num.parent().hide();
+ break;
+ }
+ // Process for parameter length
+ switch ($type.val()) {
+ case 'DATE':
+ case 'DATETIME':
+ case 'TIME':
+ case 'TINYBLOB':
+ case 'TINYTEXT':
+ case 'BLOB':
+ case 'TEXT':
+ case 'MEDIUMBLOB':
+ case 'MEDIUMTEXT':
+ case 'LONGBLOB':
+ case 'LONGTEXT':
+ $len.hide();
+ break;
+ default:
+ $len.show();
+ break;
+ }
+}
+
+/**
+ * Attach Ajax event handlers for the Routines functionalities.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+$(document).ready(function() {
+ /**
+ * @var $ajaxDialog jQuery object containing the reference to the
+ * dialog that contains the routine editor.
+ */
+ var $ajaxDialog = null;
+ /**
+ * @var param_template This variable contains the template for one row
+ * of the parameters table that is attached to the
+ * dialog when a new parameter is added.
+ */
+ var param_template = '';
+ /**
+ * @var syntaxHiglighter Reference to the codemirror editor.
+ */
+ var syntaxHiglighter = null;
+ /**
+ * @var button_options Object containing options for jQueryUI dialog buttons
+ */
+ var button_options = {};
+
+ /**
+ * Attach Ajax event handlers for the Add/Edit routine functionality.
+ *
+ * @uses PMA_ajaxShowMessage()
+ * @uses PMA_ajaxRemoveMessage()
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('.add_routine_anchor, .edit_routine_anchor').live('click', function(event) {
+ event.preventDefault();
+ /**
+ * @var $edit_row jQuery object containing the reference to
+ * the row of the the routine being edited
+ * from the list of routines .
+ */
+ var $edit_row = null;
+ if ($(this).hasClass('edit_routine_anchor')) {
+ // Remeber the row of the routine being edited for later,
+ // so that if the edit is successful, we can replace the
+ // row with info about the modified routine.
+ $edit_row = $(this).parents('tr');
+ }
+ /**
+ * @var $msg jQuery object containing the reference to
+ * the AJAX message shown to the user.
+ */
+ var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']);
+ $.get($(this).attr('href'), {'ajax_request': true}, function(data) {
+ if(data.success == true) {
+ PMA_ajaxRemoveMessage($msg);
+ button_options[PMA_messages['strGo']] = function() {
+ syntaxHiglighter.save();
+ // Validate editor and submit request, if passed.
+ if (validateRoutineEditor(syntaxHiglighter)) {
+ /**
+ * @var data Form data to be sent in the AJAX request.
+ */
+ var data = $('.rte_form').last().serialize();
+ $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']);
+ $.post('db_routines.php', data, function (data) {
+ if(data.success == true) {
+ // Routine created successfully
+ PMA_ajaxRemoveMessage($msg);
+ PMA_slidingMessage(data.message);
+ $ajaxDialog.dialog('close');
+ // If we are in 'edit' mode, we must remove the reference to the old row.
+ if (mode == 'edit') {
+ $edit_row.remove();
+ }
+ // Insert the new row at the correct location in the list of routines
+ /**
+ * @var text Contains the name of a routine from the list
+ * that is used in comparisons to find the correct
+ * location where to insert a new row.
+ */
+ var text = '';
+ /**
+ * @var inserted Whether a new has been inserted
+ * in the list of routines or not.
+ */
+ var inserted = false;
+ $('table.data').find('tr').each(function() {
+ text = $(this).children('td').eq(0).find('strong').text().toUpperCase();
+ if (text != '' && text > data.name) {
+ $(this).before(data.new_row);
+ inserted = true;
+ return false;
+ }
+ });
+ if (! inserted) {
+ $('table.data').append(data.new_row);
+ }
+ // Fade-in the new row
+ $('.ajaxInsert').show('slow').removeClass('ajaxInsert');
+ // Now we have inserted the row at the correct position, but surely
+ // at least some row classes are wrong now. So we will itirate
+ // throught all rows and assign correct classes to them.
+ /**
+ * @var ct Count of processed rows.
+ */
+ var ct = 0;
+ $('table.data').find('tr').has('td').each(function() {
+ rowclass = (ct % 2 == 0) ? 'even' : 'odd';
+ $(this).removeClass().addClass(rowclass);
+ ct++;
+ });
+ // If this is the first routine being added, remove the
+ // "No routines" message and show the list of routines.
+ if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) {
+ $('#nothing2display').hide("slow", function () {
+ $('table.data').show("slow");
+ });
+ }
+ } else {
+ PMA_ajaxShowMessage(data.error);
+ }
+ });
+ }
+ } // end of function that handles the submission of the Editor
+ button_options[PMA_messages['strClose']] = function() {
+ $(this).dialog("close");
+ }
+ /**
+ * Display the dialog to the user
+ */
+ $ajaxDialog = $('<div style="font-size: 0.9em;">'+data.message+'</div>').dialog({
+ width: 700, // TODO: make a better decision about the size
+ height: 550, // of the dialog based on the size of the viewport
+ buttons: button_options,
+ title: data.title,
+ modal: true,
+ close: function () {
+ $(this).remove();
+ }
+ });
+ $ajaxDialog.find('input[name=routine_name]').focus();
+ /**
+ * @var mode Used to remeber whether the editor is in
+ * "Edit Routine" or "Add Routine" mode.
+ */
+ var mode = 'add';
+ if ($('input[name=routine_process_editroutine]').length > 0) {
+ mode = 'edit';
+ }
+ // Cache the template for a parameter table row
+ param_template = data.param_template;
+ // Make adjustments in the dialog to make it AJAX compatible
+ $('.routine_param_remove').show();
+ $('input[name=routine_removeparameter]').remove();
+ $('input[name=routine_addparameter]').css('width', '100%');
+ // Enable/disable the 'options' dropdowns for parameters as necessary
+ $('.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
+ $('.routine_params_table').last().find('tr').has('td').each(function() {
+ setOptionsForParameter(
+ $(this).find('select[name^=routine_param_type]'),
+ $(this).find('input[name^=routine_param_length]'),
+ $(this).find('select[name^=routine_param_opts_text]'),
+ $(this).find('select[name^=routine_param_opts_num]')
+ );
+ });
+ // Enable/disable the 'options' dropdowns for function return value as necessary
+ setOptionsForParameter(
+ $('.rte_table').last().find('select[name=routine_returntype]'),
+ $('.rte_table').last().find('input[name=routine_returnlength]'),
+ $('.rte_table').last().find('select[name=routine_returnopts_text]'),
+ $('.rte_table').last().find('select[name=routine_returnopts_num]')
+ );
+ // Attach syntax highlited editor to routine definition
+ /**
+ * @var $elm jQuery object containing the reference to
+ * the "Routine Definition" textarea.
+ */
+ var $elm = $('textarea[name=routine_definition]').last();
+ /**
+ * @var opts Options to pass to the codemirror editor.
+ */
+ var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"};
+ syntaxHiglighter = CodeMirror.fromTextArea($elm[0], opts);
+ // Hack to prevent the syntax highlighter from expanding beyond dialog boundries
+ $('.CodeMirror-scroll').find('div').first().css('width', '1px');
+ } else {
+ PMA_ajaxShowMessage(data.error);
+ }
+ }) // end $.get()
+ }); // end $.live()
+
+ /**
+ * Attach Ajax event handlers for the "Add parameter to routine" functionality.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('input[name=routine_addparameter]').live('click', function(event) {
+ event.preventDefault();
+ /**
+ * @var $routine_params_table jQuery object containing the reference
+ * to the routine parameters table.
+ */
+ var $routine_params_table = $('.routine_params_table').last();
+ /**
+ * @var $new_param_row A string containing the HTML code for the
+ * new row for the routine paramaters table.
+ */
+ var new_param_row = param_template.replace(/%s/g, $routine_params_table.find('tr').length-1);
+ $routine_params_table.append(new_param_row);
+ if ($('.rte_table').find('select[name=routine_type]').val() == 'FUNCTION') {
+ $('.routine_return_row').show();
+ $('.routine_direction_cell').hide();
+ }
+ /**
+ * @var $newrow jQuery object containing the reference to the newly
+ * inserted row in the routine parameters table.
+ */
+ var $newrow = $('.routine_params_table').last().find('tr').has('td').last();
+ setOptionsForParameter(
+ $newrow.find('select[name^=routine_param_type]'),
+ $newrow.find('input[name^=routine_param_length]'),
+ $newrow.find('select[name^=routine_param_opts_text]'),
+ $newrow.find('select[name^=routine_param_opts_num]')
+ );
+ }); // end $.live()
+
+ /**
+ * Attach Ajax event handlers for the "Remove parameter from routine" functionality.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('.routine_param_remove_anchor').live('click', function (event) {
+ event.preventDefault();
+ $(this).parent().parent().remove();
+ // After removing a parameter, the indices of the name attributes in
+ // the input fields lose the correct order and need to be reordered.
+ /**
+ * @var index Counter used for reindexing the input
+ * fields in the routine parameters table.
+ */
+ var index = 0;
+ $('.routine_params_table').last().find('tr').has('td').each(function() {
+ $(this).find(':input').each(function() {
+ /**
+ * @var inputname The value of the name attribute of
+ * the input field being reindexed.
+ */
+ var inputname = $(this).attr('name');
+ if (inputname.substr(0, 17) == 'routine_param_dir') {
+ $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
+ } else if (inputname.substr(0, 18) == 'routine_param_name') {
+ $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']');
+ } else if (inputname.substr(0, 18) == 'routine_param_type') {
+ $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']');
+ } else if (inputname.substr(0, 20) == 'routine_param_length') {
+ $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
+ } else if (inputname.substr(0, 23) == 'routine_param_opts_text') {
+ $(this).attr('name', inputname.substr(0, 23) + '[' + index + ']');
+ } else if (inputname.substr(0, 22) == 'routine_param_opts_num') {
+ $(this).attr('name', inputname.substr(0, 22) + '[' + index + ']');
+ }
+ });
+ index++;
+ });
+ }); // end $.live()
+
+ /**
+ * Attach Ajax event handlers for the "Change routine type" functionality.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('select[name=routine_type]').live('change', function() {
+ $('.routine_return_row, .routine_direction_cell').toggle();
+ }); // end $.live()
+
+ /**
+ * Attach Ajax event handlers for the "Change parameter type" functionality.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('select[name^=routine_param_type]').live('change', function() {
+ /**
+ * @var $row jQuery object containing the reference to
+ * a row in the routine parameters table.
+ */
+ var $row = $(this).parents('tr').first();
+ setOptionsForParameter(
+ $row.find('select[name^=routine_param_type]'),
+ $row.find('input[name^=routine_param_length]'),
+ $row.find('select[name^=routine_param_opts_text]'),
+ $row.find('select[name^=routine_param_opts_num]')
+ );
+ });
+
+ /**
+ * Attach Ajax event handlers for the "Change the type of return
+ * variable of function" functionality.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('select[name=routine_returntype]').live('change', function() {
+ setOptionsForParameter(
+ $('.rte_table').find('select[name=routine_returntype]'),
+ $('.rte_table').find('input[name=routine_returnlength]'),
+ $('.rte_table').find('select[name=routine_returnopts_text]'),
+ $('.rte_table').find('select[name=routine_returnopts_num]')
+ );
+ });
+
+ /**
+ * Attach Ajax event handlers for the Execute routine functionality.
+ *
+ * @uses PMA_ajaxShowMessage()
+ * @uses PMA_ajaxRemoveMessage()
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('.exec_routine_anchor').live('click', function(event) {
+ event.preventDefault();
+ /**
+ * @var $msg jQuery object containing the reference to
+ * the AJAX message shown to the user.
+ */
+ var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']);
+ $.get($(this).attr('href'), {'ajax_request': true}, function(data) {
+ if(data.success == true) {
+ PMA_ajaxRemoveMessage($msg);
+ if (data.dialog) {
+ button_options[PMA_messages['strGo']] = function() {
+ /**
+ * @var data Form data to be sent in the AJAX request.
+ */
+ var data = $('.rte_form').last().serialize();
+ $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']);
+ $.post('db_routines.php', data, function (data) {
+ if(data.success == true) {
+ // Routine executed successfully
+ PMA_ajaxRemoveMessage($msg);
+ PMA_slidingMessage(data.message);
+ $ajaxDialog.dialog('close');
+ } else {
+ PMA_ajaxShowMessage(data.error);
+ }
+ });
+ }
+ button_options[PMA_messages['strClose']] = function() {
+ $(this).dialog("close");
+ }
+ /**
+ * Display the dialog to the user
+ */
+ $ajaxDialog = $('<div style="font-size: 0.9em;">'+data.message+'</div>').dialog({
+ width: 650, // TODO: make a better decision about the size
+ // of the dialog based on the size of the viewport
+ buttons: button_options,
+ title: data.title,
+ modal: true,
+ close: function () {
+ $(this).remove();
+ }
+ });
+ $ajaxDialog.find('input[name^=params]').first().focus();
+ } else {
+ // Routine executed successfully
+ PMA_slidingMessage(data.message);
+ }
+ } else {
+ PMA_ajaxShowMessage(data.error);
+ }
+ });
+ });
+
+ /**
+ * Attach Ajax event handlers for input fields in the routines editor
+ * and the routine execution dialog used to submit the Ajax request
+ * when the ENTER key is pressed.
+ *
+ * @see $cfg['AjaxEnable']
+ */
+ $('input[name^=routine], input[name^=params]').live('keydown', function(e) {
+ if (e.which == 13) {
+ e.preventDefault();
+ if (typeof button_options[PMA_messages['strGo']] == 'function') {
+ button_options[PMA_messages['strGo']].call();
+ }
+ }
+ });
+}); // end of $(document).ready() for the Routine Functionalities
View
74 js/db_structure.js
@@ -270,80 +270,6 @@ $(document).ready(function() {
}); //end of Drop Table Ajax action
/**
- * Ajax Event handler for 'Drop Event'
- *
- * @uses $.PMA_confirm()
- * @uses PMA_ajaxShowMessage()
- * @see $cfg['AjaxEnable']
- */
- $('.drop_event_anchor').live('click', function(event) {
- event.preventDefault();
-
- /**
- * @var curr_event_row Object reference to current event's row
- */
- var curr_event_row = $(this).parents('tr');
- /**
- * @var curr_event_name String containing the name of {@link curr_event_row}
- */
- var curr_event_name = $(curr_event_row).children('td:first').text();
- /**
- * @var question String containing the question to be asked for confirmation
- */
- var question = 'DROP EVENT ' + curr_event_name;
-
- $(this).PMA_confirm(question, $(this).attr('href') , function(url) {
-
- PMA_ajaxShowMessage(PMA_messages['strDroppingEvent']);
-
- $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) {
- if(data.success == true) {
- PMA_ajaxShowMessage(data.message);
- $(curr_event_row).hide("medium").remove();
- }
- else {
- PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error);
- }
- }) // end $.get()
- }) // end $.PMA_confirm()
- }) //end Drop Event
-
- /**
- * Ajax Event handler for 'Drop Procedure'
- *
- * @uses $.PMA_confirm()
- * @uses PMA_ajaxShowMessage()
- * @see $cfg['AjaxEnable']
- */
- $('.drop_procedure_anchor').live('click', function(event) {
- event.preventDefault();
-
- /**
- * @var curr_proc_row Object containing reference to the current procedure's row
- */
- var curr_proc_row = $(this).parents('tr');
- /**
- * @var question String containing the question to be asked for confirmation
- */
- var question = $(curr_proc_row).children('td').children('.drop_procedure_sql').val();
-
- $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
-
- PMA_ajaxShowMessage(PMA_messages['strDroppingProcedure']);
-
- $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) {
- if(data.success == true) {
- PMA_ajaxShowMessage(data.message);
- $(curr_event_row).hide("medium").remove();
- }
- else {
- PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error);
- }
- }) // end $.get()
- }) // end $.PMA_confirm()
- }) //end Drop Procedure
-
- /**
* Ajax Event handler for 'Drop tracking'
*
* @uses $.PMA_confirm()
View
2 js/display_triggers.js
@@ -0,0 +1,2 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+
View
227 js/functions.js
@@ -1300,7 +1300,7 @@ function PMA_ajaxShowMessage(message, timeout) {
* Removes the message shown for an Ajax operation when it's completed
*/
function PMA_ajaxRemoveMessage($this_msgbox) {
- if ($this_msgbox != 'undefined' && $this_msgbox instanceof jQuery) {
+ if ($this_msgbox != undefined && $this_msgbox instanceof jQuery) {
$this_msgbox
.stop(true, true)
.fadeOut('medium');
@@ -1448,7 +1448,7 @@ function PMA_createChart(passedSettings) {
enabled:false
},
xAxis: {
- type: 'datetime',
+ type: 'datetime'
},
yAxis: {
min: 0,
@@ -1480,10 +1480,10 @@ function PMA_createChart(passedSettings) {
passedSettings.realtime.refreshRate = 5000;
if(!passedSettings.realtime.numMaxPoints)
- passedSettings.realtime.numMaxPoints = 32;
+ passedSettings.realtime.numMaxPoints = 30;
settings.xAxis.min = new Date().getTime() - passedSettings.realtime.numMaxPoints * passedSettings.realtime.refreshRate;
- settings.xAxis.max = new Date().getTime() + passedSettings.realtime.refreshRate / 2;
+ settings.xAxis.max = new Date().getTime() + passedSettings.realtime.refreshRate / 4;
}
// Overwrite/Merge default settings with passedsettings
@@ -1750,46 +1750,6 @@ $(document).ready(function() {
}, 'top.frame_content'); //end $(document).ready for 'Create Table'
/**
- * Attach Ajax event handlers for Drop Trigger. Used on tbl_structure.php
- * @see $cfg['AjaxEnable']
- */
-$(document).ready(function() {
-
- $(".drop_trigger_anchor").live('click', function(event) {
- event.preventDefault();
-
- $anchor = $(this);
- /**
- * @var curr_row Object reference to the current trigger's <tr>
- */
- var $curr_row = $anchor.parents('tr');
- /**
- * @var question String containing the question to be asked for confirmation
- */
- var question = 'DROP TRIGGER IF EXISTS `' + $curr_row.children('td:first').text() + '`';
-
- $anchor.PMA_confirm(question, $anchor.attr('href'), function(url) {
-
- PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
- $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) {
- if(data.success == true) {
- PMA_ajaxShowMessage(data.message);
- $("#topmenucontainer")
- .next('div')
- .remove()
- .end()
- .after(data.sql_query);
- $curr_row.hide("medium").remove();
- }
- else {
- PMA_ajaxShowMessage(data.error);
- }
- }) // end $.get()
- }) // end $.PMA_confirm()
- }) // end $().live()
-}, 'top.frame_content'); //end $(document).ready() for Drop Trigger
-
-/**
* Attach Ajax event handlers for Drop Database. Moved here from db_structure.js
* as it was also required on db_create.php
*
@@ -2062,6 +2022,7 @@ $(document).ready(function() {
$table.find("td[class='unique']").remove();
$table.find("td[class='index']").remove();
$table.find("td[class='fulltext']").remove();
+ $table.find("td[class='spatial']").remove();
$table.find("th[class='action']").attr("colspan", 3);
// Display the "more" text
@@ -2448,6 +2409,184 @@ $(document).ready(function() {
}) // end of $(document).ready()
/**
+ * Attach Ajax event handlers for Export of Routines, Triggers and Events.
+ *
+ * @uses PMA_ajaxShowMessage()
+ * @uses PMA_ajaxRemoveMessage()
+ *
+ * @see $cfg['AjaxEnable']
+ */
+$(document).ready(function() {
+ $('.export_routine_anchor, .export_trigger_anchor, .export_event_anchor').live('click', function(event) {
+ event.preventDefault();
+ var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']);
+ $.get($(this).attr('href'), {'ajax_request': true}, function(data) {
+ if(data.success == true) {
+ PMA_ajaxRemoveMessage($msg);
+ /**
+ * @var button_options Object containing options for jQueryUI dialog buttons
+ */
+ var button_options = {};
+ button_options[PMA_messages['strClose']] = function() {$(this).dialog("close").remove();}
+ /**
+ * Display the dialog to the user
+ */
+ var $ajaxDialog = $('<div style="font-size: 0.9em;">'+data.message+'</div>').dialog({
+