mysqli.dbi.lib.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Interface to the improved MySQL extension (MySQLi)
  5. *
  6. * @package PhpMyAdmin-DBI
  7. * @subpackage MySQLi
  8. */
  9. if (! defined('PHPMYADMIN')) {
  10. exit;
  11. }
  12. require_once './libraries/logging.lib.php';
  13. /**
  14. * MySQL client API
  15. */
  16. if (!defined('PMA_MYSQL_CLIENT_API')) {
  17. $client_api = explode('.', mysqli_get_client_info());
  18. define(
  19. 'PMA_MYSQL_CLIENT_API',
  20. (int)sprintf(
  21. '%d%02d%02d',
  22. $client_api[0], $client_api[1], intval($client_api[2])
  23. )
  24. );
  25. unset($client_api);
  26. }
  27. /**
  28. * some PHP versions are reporting extra messages like "No index used in query"
  29. */
  30. mysqli_report(MYSQLI_REPORT_OFF);
  31. /**
  32. * some older mysql client libs are missing these constants ...
  33. */
  34. if (! defined('MYSQLI_BINARY_FLAG')) {
  35. define('MYSQLI_BINARY_FLAG', 128);
  36. }
  37. /**
  38. * @see http://bugs.php.net/36007
  39. */
  40. if (! defined('MYSQLI_TYPE_NEWDECIMAL')) {
  41. define('MYSQLI_TYPE_NEWDECIMAL', 246);
  42. }
  43. if (! defined('MYSQLI_TYPE_BIT')) {
  44. define('MYSQLI_TYPE_BIT', 16);
  45. }
  46. // for Drizzle
  47. if (! defined('MYSQLI_TYPE_VARCHAR')) {
  48. define('MYSQLI_TYPE_VARCHAR', 15);
  49. }
  50. /**
  51. * Helper function for connecting to the database server
  52. *
  53. * @param mysqli $link connection link
  54. * @param string $host mysql hostname
  55. * @param string $user mysql user name
  56. * @param string $password mysql user password
  57. * @param string $dbname database name
  58. * @param int $server_port server port
  59. * @param string $server_socket server socket
  60. * @param int $client_flags client flags of connection
  61. * @param bool $persistent whether to use peristent connection
  62. *
  63. * @return bool
  64. */
  65. function PMA_DBI_real_connect(
  66. $link, $host, $user, $password, $dbname, $server_port,
  67. $server_socket, $client_flags = null, $persistent = false
  68. ) {
  69. global $cfg;
  70. // mysqli persistent connections only on PHP 5.3+
  71. if (PMA_PHP_INT_VERSION >= 50300) {
  72. if ($cfg['PersistentConnections'] || $persistent) {
  73. $host = 'p:' . $host;
  74. }
  75. }
  76. if ($client_flags === null) {
  77. return @mysqli_real_connect(
  78. $link,
  79. $host,
  80. $user,
  81. $password,
  82. $dbname,
  83. $server_port,
  84. $server_socket
  85. );
  86. } else {
  87. return @mysqli_real_connect(
  88. $link,
  89. $host,
  90. $user,
  91. $password,
  92. $dbname,
  93. $server_port,
  94. $server_socket,
  95. $client_flags
  96. );
  97. }
  98. }
  99. /**
  100. * connects to the database server
  101. *
  102. * @param string $user mysql user name
  103. * @param string $password mysql user password
  104. * @param bool $is_controluser whether this is a control user connection
  105. * @param array $server host/port/socket/persistent
  106. * @param bool $auxiliary_connection (when true, don't go back to login if
  107. * connection fails)
  108. *
  109. * @return mixed false on error or a mysqli object on success
  110. */
  111. function PMA_DBI_connect(
  112. $user, $password, $is_controluser = false, $server = null,
  113. $auxiliary_connection = false
  114. ) {
  115. global $cfg;
  116. if ($server) {
  117. $server_port = (empty($server['port']))
  118. ? false
  119. : (int)$server['port'];
  120. $server_socket = (empty($server['socket']))
  121. ? ''
  122. : $server['socket'];
  123. $server['host'] = (empty($server['host']))
  124. ? 'localhost'
  125. : $server['host'];
  126. } else {
  127. $server_port = (empty($cfg['Server']['port']))
  128. ? false
  129. : (int) $cfg['Server']['port'];
  130. $server_socket = (empty($cfg['Server']['socket']))
  131. ? null
  132. : $cfg['Server']['socket'];
  133. }
  134. // NULL enables connection to the default socket
  135. $link = mysqli_init();
  136. if (defined('PMA_ENABLE_LDI')) {
  137. mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
  138. } else {
  139. mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, false);
  140. }
  141. $client_flags = 0;
  142. /* Optionally compress connection */
  143. if ($cfg['Server']['compress'] && defined('MYSQLI_CLIENT_COMPRESS')) {
  144. $client_flags |= MYSQLI_CLIENT_COMPRESS;
  145. }
  146. /* Optionally enable SSL */
  147. if ($cfg['Server']['ssl'] && defined('MYSQLI_CLIENT_SSL')) {
  148. $client_flags |= MYSQLI_CLIENT_SSL;
  149. }
  150. if (!$server) {
  151. $return_value = @PMA_DBI_real_connect(
  152. $link,
  153. $cfg['Server']['host'],
  154. $user,
  155. $password,
  156. false,
  157. $server_port,
  158. $server_socket,
  159. $client_flags
  160. );
  161. // Retry with empty password if we're allowed to
  162. if ($return_value == false
  163. && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword']
  164. && !$is_controluser
  165. ) {
  166. $return_value = @PMA_DBI_real_connect(
  167. $link,
  168. $cfg['Server']['host'],
  169. $user,
  170. '',
  171. false,
  172. $server_port,
  173. $server_socket,
  174. $client_flags
  175. );
  176. }
  177. } else {
  178. $return_value = @PMA_DBI_real_connect(
  179. $link,
  180. $server['host'],
  181. $user,
  182. $password,
  183. false,
  184. $server_port,
  185. $server_socket
  186. );
  187. }
  188. if ($return_value == false) {
  189. if ($is_controluser) {
  190. trigger_error(
  191. __('Connection for controluser as defined in your configuration failed.'),
  192. E_USER_WARNING
  193. );
  194. return false;
  195. }
  196. // we could be calling PMA_DBI_connect() to connect to another
  197. // server, for example in the Synchronize feature, so do not
  198. // go back to main login if it fails
  199. if (! $auxiliary_connection) {
  200. PMA_log_user($user, 'mysql-denied');
  201. global $auth_plugin;
  202. $auth_plugin->authFails();
  203. } else {
  204. return false;
  205. }
  206. } else {
  207. PMA_DBI_postConnect($link, $is_controluser);
  208. }
  209. return $link;
  210. }
  211. /**
  212. * selects given database
  213. *
  214. * @param string $dbname database name to select
  215. * @param mysqli $link the mysqli object
  216. *
  217. * @return boolean
  218. */
  219. function PMA_DBI_select_db($dbname, $link = null)
  220. {
  221. if (empty($link)) {
  222. if (isset($GLOBALS['userlink'])) {
  223. $link = $GLOBALS['userlink'];
  224. } else {
  225. return false;
  226. }
  227. }
  228. return mysqli_select_db($link, $dbname);
  229. }
  230. /**
  231. * runs a query and returns the result
  232. *
  233. * @param string $query query to execute
  234. * @param mysqli $link mysqli object
  235. * @param int $options query options
  236. *
  237. * @return mysqli_result|bool
  238. */
  239. function PMA_DBI_real_query($query, $link, $options)
  240. {
  241. if ($options == ($options | PMA_DBI_QUERY_STORE)) {
  242. $method = MYSQLI_STORE_RESULT;
  243. } elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) {
  244. $method = MYSQLI_USE_RESULT;
  245. } else {
  246. $method = 0;
  247. }
  248. return mysqli_query($link, $query, $method);
  249. }
  250. /**
  251. * Run the multi query and output the results
  252. *
  253. * @param mysqli $link mysqli object
  254. * @param string $query multi query statement to execute
  255. *
  256. * @return mysqli_result collection | boolean(false)
  257. */
  258. function PMA_DBI_real_multi_query($link, $query)
  259. {
  260. return mysqli_multi_query($link, $query);
  261. }
  262. /**
  263. * returns array of rows with associative and numeric keys from $result
  264. *
  265. * @param mysqli_result $result result set identifier
  266. *
  267. * @return array
  268. */
  269. function PMA_DBI_fetch_array($result)
  270. {
  271. return mysqli_fetch_array($result, MYSQLI_BOTH);
  272. }
  273. /**
  274. * returns array of rows with associative keys from $result
  275. *
  276. * @param mysqli_result $result result set identifier
  277. *
  278. * @return array
  279. */
  280. function PMA_DBI_fetch_assoc($result)
  281. {
  282. return mysqli_fetch_array($result, MYSQLI_ASSOC);
  283. }
  284. /**
  285. * returns array of rows with numeric keys from $result
  286. *
  287. * @param mysqli_result $result result set identifier
  288. *
  289. * @return array
  290. */
  291. function PMA_DBI_fetch_row($result)
  292. {
  293. return mysqli_fetch_array($result, MYSQLI_NUM);
  294. }
  295. /**
  296. * Adjusts the result pointer to an arbitrary row in the result
  297. *
  298. * @param resource $result database result
  299. * @param integer $offset offset to seek
  300. *
  301. * @return bool true on success, false on failure
  302. */
  303. function PMA_DBI_data_seek($result, $offset)
  304. {
  305. return mysqli_data_seek($result, $offset);
  306. }
  307. /**
  308. * Frees memory associated with the result
  309. *
  310. * @param mysqli_result $result database result
  311. *
  312. * @return void
  313. */
  314. function PMA_DBI_free_result($result)
  315. {
  316. if ($result instanceof mysqli_result) {
  317. mysqli_free_result($result);
  318. }
  319. }
  320. /**
  321. * Check if there are any more query results from a multi query
  322. *
  323. * @param mysqli $link the mysqli object
  324. *
  325. * @return bool true or false
  326. */
  327. function PMA_DBI_more_results($link = null)
  328. {
  329. if (empty($link)) {
  330. if (isset($GLOBALS['userlink'])) {
  331. $link = $GLOBALS['userlink'];
  332. } else {
  333. return false;
  334. }
  335. }
  336. return mysqli_more_results($link);
  337. }
  338. /**
  339. * Prepare next result from multi_query
  340. *
  341. * @param mysqli $link the mysqli object
  342. *
  343. * @return bool true or false
  344. */
  345. function PMA_DBI_next_result($link = null)
  346. {
  347. if (empty($link)) {
  348. if (isset($GLOBALS['userlink'])) {
  349. $link = $GLOBALS['userlink'];
  350. } else {
  351. return false;
  352. }
  353. }
  354. return mysqli_next_result($link);
  355. }
  356. /**
  357. * Store the result returned from multi query
  358. *
  359. * @return mixed false when empty results / result set when not empty
  360. */
  361. function PMA_DBI_store_result()
  362. {
  363. if (isset($GLOBALS['userlink'])) {
  364. $link = $GLOBALS['userlink'];
  365. } else {
  366. return false;
  367. }
  368. return mysqli_store_result($link);
  369. }
  370. /**
  371. * Returns a string representing the type of connection used
  372. *
  373. * @param resource $link mysql link
  374. *
  375. * @return string type of connection used
  376. */
  377. function PMA_DBI_get_host_info($link = null)
  378. {
  379. if (null === $link) {
  380. if (isset($GLOBALS['userlink'])) {
  381. $link = $GLOBALS['userlink'];
  382. } else {
  383. return false;
  384. }
  385. }
  386. return mysqli_get_host_info($link);
  387. }
  388. /**
  389. * Returns the version of the MySQL protocol used
  390. *
  391. * @param resource $link mysql link
  392. *
  393. * @return integer version of the MySQL protocol used
  394. */
  395. function PMA_DBI_get_proto_info($link = null)
  396. {
  397. if (null === $link) {
  398. if (isset($GLOBALS['userlink'])) {
  399. $link = $GLOBALS['userlink'];
  400. } else {
  401. return false;
  402. }
  403. }
  404. return mysqli_get_proto_info($link);
  405. }
  406. /**
  407. * returns a string that represents the client library version
  408. *
  409. * @return string MySQL client library version
  410. */
  411. function PMA_DBI_get_client_info()
  412. {
  413. return mysqli_get_client_info();
  414. }
  415. /**
  416. * returns last error message or false if no errors occured
  417. *
  418. * @param resource $link mysql link
  419. *
  420. * @return string|bool $error or false
  421. */
  422. function PMA_DBI_getError($link = null)
  423. {
  424. $GLOBALS['errno'] = 0;
  425. /* Treat false same as null because of controllink */
  426. if ($link === false) {
  427. $link = null;
  428. }
  429. if (null === $link && isset($GLOBALS['userlink'])) {
  430. $link =& $GLOBALS['userlink'];
  431. // Do not stop now. We still can get the error code
  432. // with mysqli_connect_errno()
  433. }
  434. if (null !== $link) {
  435. $error_number = mysqli_errno($link);
  436. $error_message = mysqli_error($link);
  437. } else {
  438. $error_number = mysqli_connect_errno();
  439. $error_message = mysqli_connect_error();
  440. }
  441. if (0 == $error_number) {
  442. return false;
  443. }
  444. // keep the error number for further check after the call to PMA_DBI_getError()
  445. $GLOBALS['errno'] = $error_number;
  446. return PMA_DBI_formatError($error_number, $error_message);
  447. }
  448. /**
  449. * returns the number of rows returned by last query
  450. *
  451. * @param mysqli_result $result result set identifier
  452. *
  453. * @return string|int
  454. */
  455. function PMA_DBI_num_rows($result)
  456. {
  457. // see the note for PMA_DBI_try_query();
  458. if (!is_bool($result)) {
  459. return @mysqli_num_rows($result);
  460. } else {
  461. return 0;
  462. }
  463. }
  464. /**
  465. * returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
  466. *
  467. * @param mysqli $link the mysqli object
  468. *
  469. * @return string|int
  470. */
  471. function PMA_DBI_insert_id($link = null)
  472. {
  473. if (empty($link)) {
  474. if (isset($GLOBALS['userlink'])) {
  475. $link = $GLOBALS['userlink'];
  476. } else {
  477. return false;
  478. }
  479. }
  480. // When no controluser is defined, using mysqli_insert_id($link)
  481. // does not always return the last insert id due to a mixup with
  482. // the tracking mechanism, but this works:
  483. return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
  484. // Curiously, this problem does not happen with the mysql extension but
  485. // there is another problem with BIGINT primary keys so PMA_DBI_insert_id()
  486. // in the mysql extension also uses this logic.
  487. }
  488. /**
  489. * returns the number of rows affected by last query
  490. *
  491. * @param mysqli $link the mysqli object
  492. * @param bool $get_from_cache whether to retrieve from cache
  493. *
  494. * @return string|int
  495. */
  496. function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
  497. {
  498. if (empty($link)) {
  499. if (isset($GLOBALS['userlink'])) {
  500. $link = $GLOBALS['userlink'];
  501. } else {
  502. return false;
  503. }
  504. }
  505. if ($get_from_cache) {
  506. return $GLOBALS['cached_affected_rows'];
  507. } else {
  508. return mysqli_affected_rows($link);
  509. }
  510. }
  511. /**
  512. * returns metainfo for fields in $result
  513. *
  514. * @param mysqli_result $result result set identifier
  515. *
  516. * @return array meta info for fields in $result
  517. */
  518. function PMA_DBI_get_fields_meta($result)
  519. {
  520. // Build an associative array for a type look up
  521. $typeAr = array();
  522. $typeAr[MYSQLI_TYPE_DECIMAL] = 'real';
  523. $typeAr[MYSQLI_TYPE_NEWDECIMAL] = 'real';
  524. $typeAr[MYSQLI_TYPE_BIT] = 'int';
  525. $typeAr[MYSQLI_TYPE_TINY] = 'int';
  526. $typeAr[MYSQLI_TYPE_SHORT] = 'int';
  527. $typeAr[MYSQLI_TYPE_LONG] = 'int';
  528. $typeAr[MYSQLI_TYPE_FLOAT] = 'real';
  529. $typeAr[MYSQLI_TYPE_DOUBLE] = 'real';
  530. $typeAr[MYSQLI_TYPE_NULL] = 'null';
  531. $typeAr[MYSQLI_TYPE_TIMESTAMP] = 'timestamp';
  532. $typeAr[MYSQLI_TYPE_LONGLONG] = 'int';
  533. $typeAr[MYSQLI_TYPE_INT24] = 'int';
  534. $typeAr[MYSQLI_TYPE_DATE] = 'date';
  535. $typeAr[MYSQLI_TYPE_TIME] = 'time';
  536. $typeAr[MYSQLI_TYPE_DATETIME] = 'datetime';
  537. $typeAr[MYSQLI_TYPE_YEAR] = 'year';
  538. $typeAr[MYSQLI_TYPE_NEWDATE] = 'date';
  539. $typeAr[MYSQLI_TYPE_ENUM] = 'unknown';
  540. $typeAr[MYSQLI_TYPE_SET] = 'unknown';
  541. $typeAr[MYSQLI_TYPE_TINY_BLOB] = 'blob';
  542. $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob';
  543. $typeAr[MYSQLI_TYPE_LONG_BLOB] = 'blob';
  544. $typeAr[MYSQLI_TYPE_BLOB] = 'blob';
  545. $typeAr[MYSQLI_TYPE_VAR_STRING] = 'string';
  546. $typeAr[MYSQLI_TYPE_STRING] = 'string';
  547. $typeAr[MYSQLI_TYPE_VARCHAR] = 'string'; // for Drizzle
  548. // MySQL returns MYSQLI_TYPE_STRING for CHAR
  549. // and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY
  550. // so this would override TINYINT and mark all TINYINT as string
  551. // https://sourceforge.net/p/phpmyadmin/bugs/2205/
  552. //$typeAr[MYSQLI_TYPE_CHAR] = 'string';
  553. $typeAr[MYSQLI_TYPE_GEOMETRY] = 'geometry';
  554. $typeAr[MYSQLI_TYPE_BIT] = 'bit';
  555. $fields = mysqli_fetch_fields($result);
  556. // this happens sometimes (seen under MySQL 4.0.25)
  557. if (!is_array($fields)) {
  558. return false;
  559. }
  560. foreach ($fields as $k => $field) {
  561. $fields[$k]->_type = $field->type;
  562. $fields[$k]->type = $typeAr[$field->type];
  563. $fields[$k]->_flags = $field->flags;
  564. $fields[$k]->flags = PMA_DBI_field_flags($result, $k);
  565. // Enhance the field objects for mysql-extension compatibilty
  566. //$flags = explode(' ', $fields[$k]->flags);
  567. //array_unshift($flags, 'dummy');
  568. $fields[$k]->multiple_key
  569. = (int) (bool) ($fields[$k]->_flags & MYSQLI_MULTIPLE_KEY_FLAG);
  570. $fields[$k]->primary_key
  571. = (int) (bool) ($fields[$k]->_flags & MYSQLI_PRI_KEY_FLAG);
  572. $fields[$k]->unique_key
  573. = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNIQUE_KEY_FLAG);
  574. $fields[$k]->not_null
  575. = (int) (bool) ($fields[$k]->_flags & MYSQLI_NOT_NULL_FLAG);
  576. $fields[$k]->unsigned
  577. = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNSIGNED_FLAG);
  578. $fields[$k]->zerofill
  579. = (int) (bool) ($fields[$k]->_flags & MYSQLI_ZEROFILL_FLAG);
  580. $fields[$k]->numeric
  581. = (int) (bool) ($fields[$k]->_flags & MYSQLI_NUM_FLAG);
  582. $fields[$k]->blob
  583. = (int) (bool) ($fields[$k]->_flags & MYSQLI_BLOB_FLAG);
  584. }
  585. return $fields;
  586. }
  587. /**
  588. * return number of fields in given $result
  589. *
  590. * @param mysqli_result $result result set identifier
  591. *
  592. * @return int field count
  593. */
  594. function PMA_DBI_num_fields($result)
  595. {
  596. return mysqli_num_fields($result);
  597. }
  598. /**
  599. * returns the length of the given field $i in $result
  600. *
  601. * @param mysqli_result $result result set identifier
  602. * @param int $i field
  603. *
  604. * @return int length of field
  605. */
  606. function PMA_DBI_field_len($result, $i)
  607. {
  608. return mysqli_fetch_field_direct($result, $i)->length;
  609. }
  610. /**
  611. * returns name of $i. field in $result
  612. *
  613. * @param mysqli_result $result result set identifier
  614. * @param int $i field
  615. *
  616. * @return string name of $i. field in $result
  617. */
  618. function PMA_DBI_field_name($result, $i)
  619. {
  620. return mysqli_fetch_field_direct($result, $i)->name;
  621. }
  622. /**
  623. * returns concatenated string of human readable field flags
  624. *
  625. * @param mysqli_result $result result set identifier
  626. * @param int $i field
  627. *
  628. * @return string field flags
  629. */
  630. function PMA_DBI_field_flags($result, $i)
  631. {
  632. // This is missing from PHP 5.2.5, see http://bugs.php.net/bug.php?id=44846
  633. if (! defined('MYSQLI_ENUM_FLAG')) {
  634. define('MYSQLI_ENUM_FLAG', 256); // see MySQL source include/mysql_com.h
  635. }
  636. $f = mysqli_fetch_field_direct($result, $i);
  637. $type = $f->type;
  638. $charsetnr = $f->charsetnr;
  639. $f = $f->flags;
  640. $flags = '';
  641. if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
  642. $flags .= 'unique ';
  643. }
  644. if ($f & MYSQLI_NUM_FLAG) {
  645. $flags .= 'num ';
  646. }
  647. if ($f & MYSQLI_PART_KEY_FLAG) {
  648. $flags .= 'part_key ';
  649. }
  650. if ($f & MYSQLI_SET_FLAG) {
  651. $flags .= 'set ';
  652. }
  653. if ($f & MYSQLI_TIMESTAMP_FLAG) {
  654. $flags .= 'timestamp ';
  655. }
  656. if ($f & MYSQLI_AUTO_INCREMENT_FLAG) {
  657. $flags .= 'auto_increment ';
  658. }
  659. if ($f & MYSQLI_ENUM_FLAG) {
  660. $flags .= 'enum ';
  661. }
  662. // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
  663. // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
  664. // but instead the charsetnr member of the MYSQL_FIELD
  665. // structure. Watch out: some types like DATE returns 63 in charsetnr
  666. // so we have to check also the type.
  667. // Unfortunately there is no equivalent in the mysql extension.
  668. if (($type == MYSQLI_TYPE_TINY_BLOB || $type == MYSQLI_TYPE_BLOB
  669. || $type == MYSQLI_TYPE_MEDIUM_BLOB || $type == MYSQLI_TYPE_LONG_BLOB
  670. || $type == MYSQLI_TYPE_VAR_STRING || $type == MYSQLI_TYPE_STRING)
  671. && 63 == $charsetnr
  672. ) {
  673. $flags .= 'binary ';
  674. }
  675. if ($f & MYSQLI_ZEROFILL_FLAG) {
  676. $flags .= 'zerofill ';
  677. }
  678. if ($f & MYSQLI_UNSIGNED_FLAG) {
  679. $flags .= 'unsigned ';
  680. }
  681. if ($f & MYSQLI_BLOB_FLAG) {
  682. $flags .= 'blob ';
  683. }
  684. if ($f & MYSQLI_MULTIPLE_KEY_FLAG) {
  685. $flags .= 'multiple_key ';
  686. }
  687. if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
  688. $flags .= 'unique_key ';
  689. }
  690. if ($f & MYSQLI_PRI_KEY_FLAG) {
  691. $flags .= 'primary_key ';
  692. }
  693. if ($f & MYSQLI_NOT_NULL_FLAG) {
  694. $flags .= 'not_null ';
  695. }
  696. return trim($flags);
  697. }
  698. ?>