PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/MDB2/Driver/Reverse/mssql.php

https://github.com/chregu/fluxcms
PHP | 250 lines | 114 code | 26 blank | 110 comment | 24 complexity | 941d568d64d6b2c603342689ea690c94 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP versions 4 and 5 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
  6. // | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
  7. // | All rights reserved. |
  8. // +----------------------------------------------------------------------+
  9. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
  10. // | API as well as database abstraction for PHP applications. |
  11. // | This LICENSE is in the BSD license style. |
  12. // | |
  13. // | Redistribution and use in source and binary forms, with or without |
  14. // | modification, are permitted provided that the following conditions |
  15. // | are met: |
  16. // | |
  17. // | Redistributions of source code must retain the above copyright |
  18. // | notice, this list of conditions and the following disclaimer. |
  19. // | |
  20. // | Redistributions in binary form must reproduce the above copyright |
  21. // | notice, this list of conditions and the following disclaimer in the |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // | |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission. |
  28. // | |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
  40. // | POSSIBILITY OF SUCH DAMAGE. |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@backendmedia.com> |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id$
  46. //
  47. require_once 'MDB2/Driver/Reverse/Common.php';
  48. /**
  49. * MDB2 MSSQL driver for the schema reverse engineering module
  50. *
  51. * @package MDB2
  52. * @category Database
  53. * @author Lukas Smith <smith@dybnet.de>
  54. */
  55. class MDB2_Driver_Reverse_mssql extends MDB2_Driver_Reverse_Common
  56. {
  57. // {{{ tableInfo()
  58. /**
  59. * Returns information about a table or a result set.
  60. *
  61. * NOTE: only supports 'table' and 'flags' if <var>$result</var>
  62. * is a table name.
  63. *
  64. * @param object|string $result MDB2_result object from a query or a
  65. * string containing the name of a table
  66. * @param int $mode a valid tableInfo mode
  67. * @return array an associative array with the information requested
  68. * or an error object if something is wrong
  69. * @access public
  70. * @internal
  71. * @see MDB2_Driver_Common::tableInfo()
  72. */
  73. function tableInfo($result, $mode = null)
  74. {
  75. $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
  76. if ($db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
  77. $case_func = 'strtolower';
  78. } else {
  79. $case_func = 'strval';
  80. }
  81. if (is_string($result)) {
  82. /*
  83. * Probably received a table name.
  84. * Create a result resource identifier.
  85. */
  86. if (MDB2::isError($connect = $db->connect())) {
  87. return $connect;
  88. }
  89. $id = @mssql_query("SELECT * FROM $result WHERE 1=0",
  90. $db->connection);
  91. $got_string = true;
  92. } else {
  93. /*
  94. * Probably received a result object.
  95. * Extract the result resource identifier.
  96. */
  97. $id = $result->getResource();
  98. if (empty($id)) {
  99. return $db->raiseError();
  100. }
  101. $got_string = false;
  102. }
  103. if (!is_resource($id)) {
  104. return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
  105. }
  106. $count = @mssql_num_fields($id);
  107. // made this IF due to performance (one if is faster than $count if's)
  108. if (!$mode) {
  109. for ($i=0; $i<$count; $i++) {
  110. $res[$i]['table'] = $got_string ? $case_func($result) : '';
  111. $res[$i]['name'] = $case_func(@mssql_field_name($id, $i));
  112. $res[$i]['type'] = @mssql_field_type($id, $i);
  113. $res[$i]['len'] = @mssql_field_length($id, $i);
  114. // We only support flags for tables
  115. $res[$i]['flags'] = $got_string ? $this->_mssql_field_flags($result, $res[$i]['name']) : '';
  116. }
  117. } else { // full
  118. $res['num_fields']= $count;
  119. for ($i=0; $i<$count; $i++) {
  120. $res[$i]['table'] = $got_string ? $case_func($result) : '';
  121. $res[$i]['name'] = $case_func(@mssql_field_name($id, $i));
  122. $res[$i]['type'] = @mssql_field_type($id, $i);
  123. $res[$i]['len'] = @mssql_field_length($id, $i);
  124. // We only support flags for tables
  125. $res[$i]['flags'] = $got_string ? $this->_mssql_field_flags($result, $res[$i]['name']) : '';
  126. if ($mode & MDB2_TABLEINFO_ORDER) {
  127. $res['order'][$res[$i]['name']] = $i;
  128. }
  129. if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
  130. $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
  131. }
  132. }
  133. }
  134. // free the result only if we were called on a table
  135. if ($got_string) {
  136. @mssql_free_result($id);
  137. }
  138. return $res;
  139. }
  140. // }}}
  141. // {{{ _mssql_field_flags()
  142. /**
  143. * Get the flags for a field, currently supports "not_null", "primary_key",
  144. * "auto_increment" (mssql identity), "timestamp" (mssql timestamp),
  145. * "unique_key" (mssql unique index, unique check or primary_key) and
  146. * "multiple_key" (multikey index)
  147. *
  148. * mssql timestamp is NOT similar to the mysql timestamp so this is maybe
  149. * not useful at all - is the behaviour of mysql_field_flags that primary
  150. * keys are alway unique? is the interpretation of multiple_key correct?
  151. *
  152. * @param string The table name
  153. * @param string The field
  154. * @author Joern Barthel <j_barthel@web.de>
  155. * @access private
  156. */
  157. function _mssql_field_flags($table, $column)
  158. {
  159. $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
  160. static $tableName = null;
  161. static $flags = array();
  162. if ($table != $tableName) {
  163. $flags = array();
  164. $tableName = $table;
  165. // get unique and primary keys
  166. $res = $db->queryAll("EXEC SP_HELPINDEX[$table]", null, MDB2_FETCHMODE_ASSOC);
  167. foreach ($res as $val) {
  168. $keys = explode(', ', $val['index_keys']);
  169. if (sizeof($keys) > 1) {
  170. foreach ($keys as $key) {
  171. $this->_add_flag($flags[$key], 'multiple_key');
  172. }
  173. }
  174. if (strpos($val['index_description'], 'primary key')) {
  175. foreach ($keys as $key) {
  176. $this->_add_flag($flags[$key], 'primary_key');
  177. }
  178. } elseif (strpos($val['index_description'], 'unique')) {
  179. foreach ($keys as $key) {
  180. $this->_add_flag($flags[$key], 'unique_key');
  181. }
  182. }
  183. }
  184. // get auto_increment, not_null and timestamp
  185. $res = $db->queryAll("EXEC SP_COLUMNS[$table]", null, MDB2_FETCHMODE_ASSOC);
  186. foreach ($res as $val) {
  187. $val = array_change_key_case($val, CASE_LOWER);
  188. if ($val['nullable'] == '0') {
  189. $this->_add_flag($flags[$val['column_name']], 'not_null');
  190. }
  191. if (strpos($val['type_name'], 'identity')) {
  192. $this->_add_flag($flags[$val['column_name']], 'auto_increment');
  193. }
  194. if (strpos($val['type_name'], 'timestamp')) {
  195. $this->_add_flag($flags[$val['column_name']], 'timestamp');
  196. }
  197. }
  198. }
  199. if (array_key_exists($column, $flags)) {
  200. return implode(' ', $flags[$column]);
  201. }
  202. return '';
  203. }
  204. // }}}
  205. // {{{ _add_flag()
  206. /**
  207. * Adds a string to the flags array if the flag is not yet in there
  208. * - if there is no flag present the array is created.
  209. *
  210. * @param reference Reference to the flag-array
  211. * @param value The flag value
  212. * @access private
  213. * @author Joern Barthel <j_barthel@web.de>
  214. */
  215. function _add_flag(&$array, $value)
  216. {
  217. if (!is_array($array)) {
  218. $array = array($value);
  219. } elseif (!in_array($value, $array)) {
  220. array_push($array, $value);
  221. }
  222. }
  223. }
  224. ?>