MySQL_PDO.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. /** @package verysimple::DB::DataDriver */
  3. require_once("IDataDriver.php");
  4. require_once("verysimple/DB/ISqlFunction.php");
  5. require_once("verysimple/DB/DatabaseException.php");
  6. require_once("verysimple/DB/DatabaseConfig.php");
  7. /**
  8. * An implementation of IDataDriver that communicates with
  9. * a MySQL server. This is one of the native drivers
  10. * supported by Phreeze
  11. *
  12. * @package verysimple::DB::DataDriver
  13. * @author VerySimple Inc. <[email protected]>
  14. * @copyright 1997-2010 VerySimple Inc.
  15. * @license http://www.gnu.org/licenses/lgpl.html LGPL
  16. * @version 1.0
  17. */
  18. class DataDriverMySQL_PDO implements IDataDriver
  19. {
  20. /** @var characters that will be escaped */
  21. static $BAD_CHARS = array("\\","\0","\n","\r","\x1a","'",'"');
  22. /** @var characters that will be used to replace bad chars */
  23. static $GOOD_CHARS = array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
  24. /**
  25. * @inheritdocs
  26. */
  27. function GetServerType()
  28. {
  29. return "MySQL";
  30. }
  31. function Ping($connection)
  32. {
  33. return mysql_ping($connection);
  34. }
  35. /**
  36. * @inheritdocs
  37. */
  38. function Open($connectionstring,$database,$username,$password,$charset='',$bootstrap='')
  39. {
  40. if (!class_exists("PDO")) throw new DatabaseException('PDO extension is not enabled on this server.',DatabaseException::$CONNECTION_ERROR);
  41. $connection = null;
  42. try
  43. {
  44. // if the port is provided in the connection string then strip it out and provide it as a separate param
  45. $hostAndPort = explode(":",$connectionstring);
  46. $host = $hostAndPort[0];
  47. $port = count($hostAndPort) > 1 ? $hostAndPort[1] : null;
  48. $dsn = 'mysql:dbname='. $this->Escape($database) .';host=' . $this->Escape($host);
  49. if ($port) {
  50. $dsn .= ";port=" . $this->Escape($port);
  51. }
  52. if ($charset) {
  53. $dsn .= ";charset=" . $this->Escape($charset);
  54. }
  55. $connection = new PDO($dsn, $username, $password);
  56. }
  57. catch (Exception $e)
  58. {
  59. throw new DatabaseException("Error connecting to database: " . $e->getMessage(),DatabaseException::$CONNECTION_ERROR);
  60. }
  61. if ($bootstrap)
  62. {
  63. $statements = explode(';',$bootstrap);
  64. foreach ($statements as $sql)
  65. {
  66. try
  67. {
  68. $this->Execute($connection, $sql);
  69. }
  70. catch (Exception $ex)
  71. {
  72. throw new DatabaseException("Connection Bootstrap Error: " . $ex->getMessage(),DatabaseException::$ERROR_IN_QUERY);
  73. }
  74. }
  75. }
  76. return $connection;
  77. }
  78. /**
  79. * @inheritdocs
  80. */
  81. function Close($connection)
  82. {
  83. $connection = null; // ignore warnings
  84. }
  85. /**
  86. * @inheritdocs
  87. */
  88. function Query($connection,$sql)
  89. {
  90. if (!$stmt = $connection->query($sql)) {
  91. throw new DatabaseException($this->GetErrorDescription($connection),DatabaseException::$ERROR_IN_QUERY);
  92. }
  93. return $stmt;
  94. }
  95. /**
  96. * @inheritdocs
  97. */
  98. function Execute($connection,$sql)
  99. {
  100. $stmt = $connection->prepare($sql);
  101. if (!$stmt) {
  102. throw new DatabaseException($this->GetErrorDescription($connection),DatabaseException::$ERROR_IN_QUERY);
  103. }
  104. if (!$numRows = $stmt->execute())
  105. {
  106. throw new DatabaseException($this->GetErrorDescription($sth),DatabaseException::$ERROR_IN_QUERY);
  107. }
  108. return $numRows;
  109. }
  110. /**
  111. * Given a PDO object, return the last error
  112. * @param PDO:errorInfo $errorInfo
  113. */
  114. private function GetErrorDescription($obj)
  115. {
  116. $errorInfo = $obj->errorInfo();
  117. return $errorInfo[2];
  118. }
  119. /**
  120. * @inheritdocs
  121. */
  122. public function GetQuotedSql($val)
  123. {
  124. if ($val === null) return DatabaseConfig::$CONVERT_NULL_TO_EMPTYSTRING ? "''" : 'NULL';
  125. if ($val instanceof ISqlFunction) return $val->GetQuotedSql($this);
  126. return "'" . $this->Escape($val) . "'";
  127. }
  128. /**
  129. * @inheritdocs
  130. */
  131. function Fetch($connection,$rs)
  132. {
  133. return $rs->fetch(PDO::FETCH_ASSOC);
  134. }
  135. /**
  136. * @inheritdocs
  137. */
  138. function GetLastInsertId($connection)
  139. {
  140. return $connection->lastInsertId();
  141. }
  142. /**
  143. * @inheritdocs
  144. */
  145. function GetLastError($connection)
  146. {
  147. return $this->GetErrorDescription($connection);
  148. }
  149. /**
  150. * @inheritdocs
  151. */
  152. function Release($connection,$rs)
  153. {
  154. $rs = null;
  155. }
  156. /**
  157. * @inheritdocs
  158. * this method currently uses replacement and not mysql_real_escape_string
  159. * so that a database connection is not necessary in order to escape.
  160. * this way cached queries can be used without connecting to the DB server
  161. */
  162. function Escape($val)
  163. {
  164. return str_replace(self::$BAD_CHARS, self::$GOOD_CHARS, $val);
  165. // return mysql_real_escape_string($val);
  166. }
  167. /**
  168. * @inheritdocs
  169. */
  170. function GetTableNames($connection, $dbname, $ommitEmptyTables = false)
  171. {
  172. $sql = "SHOW TABLE STATUS FROM `" . $this->Escape($dbname) . "`";
  173. $rs = $this->Query($connection,$sql);
  174. $tables = array();
  175. while ( $row = $this->Fetch($connection,$rs) )
  176. {
  177. if ( $ommitEmptyTables == false || $rs['Data_free'] > 0 )
  178. {
  179. $tables[] = $row['Name'];
  180. }
  181. }
  182. return $tables;
  183. }
  184. /**
  185. * @inheritdocs
  186. */
  187. function Optimize($connection,$table)
  188. {
  189. $result = "";
  190. $rs = $this->Query($connection,"optimize table `". $this->Escape($table)."`");
  191. while ( $row = $this->Fetch($connection,$rs) )
  192. {
  193. $tbl = $row['Table'];
  194. if (!isset($results[$tbl])) $results[$tbl] = "";
  195. $result .= trim($results[$tbl] . " " . $row['Msg_type'] . "=\"" . $row['Msg_text'] . "\"");
  196. }
  197. return $result;
  198. }
  199. /**
  200. * @inheritdocs
  201. */
  202. function StartTransaction($connection)
  203. {
  204. $connection->beginTransaction();
  205. }
  206. /**
  207. * @inheritdocs
  208. */
  209. function CommitTransaction($connection)
  210. {
  211. $connection->commit();
  212. }
  213. /**
  214. * @inheritdocs
  215. */
  216. function RollbackTransaction($connection)
  217. {
  218. $connection->rollBack();
  219. }
  220. }
  221. ?>