DbMysql.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <?php
  2. // +--------------------------------------------------------------------------
  3. // | Senthot [ DEVELOPED BY ME ]
  4. // +--------------------------------------------------------------------------
  5. // | Copyright (c) 2005-2013 http://www.senthot.com All rights reserved.
  6. // | License ( http://www.apache.org/licenses/LICENSE-2.0 )
  7. // | Author: ms134n ( [email protected] )
  8. // +--------------------------------------------------------------------------
  9. defined('SEN_PATH') or exit();
  10. /**
  11. * Mysql database driver class
  12. * @category Sen
  13. * @package Sen
  14. * @subpackage Driver.Db
  15. * @author ms134n <[email protected]>
  16. */
  17. class DbMysql extends Db{
  18. /**
  19. * Architecture function Read the database configuration information
  20. * @access public
  21. * @param array $config Database configuration array
  22. */
  23. public function __construct($config=''){
  24. if ( !extension_loaded('mysql') ) {
  25. throw_exception(L('_NOT_SUPPERT_').':mysql');
  26. }
  27. if(!empty($config)) {
  28. $this->config = $config;
  29. if(empty($this->config['params'])) {
  30. $this->config['params'] = '';
  31. }
  32. }
  33. }
  34. /**
  35. * Connection database method
  36. * @access public
  37. * @throws SenExecption
  38. */
  39. public function connect($config='',$linkNum=0,$force=false) {
  40. if ( !isset($this->linkID[$linkNum]) ) {
  41. if(empty($config)) $config = $this->config;
  42. // Deal with the port number of the socket connection
  43. $host = $config['hostname'].($config['hostport']?":{$config['hostport']}":'');
  44. // Whether long connection
  45. $pconnect = !empty($config['params']['persist'])? $config['params']['persist']:$this->pconnect;
  46. if($pconnect) {
  47. $this->linkID[$linkNum] = mysql_pconnect( $host, $config['username'], $config['password'],131072);
  48. }else{
  49. $this->linkID[$linkNum] = mysql_connect( $host, $config['username'], $config['password'],true,131072);
  50. }
  51. if ( !$this->linkID[$linkNum] || (!empty($config['database']) && !mysql_select_db($config['database'], $this->linkID[$linkNum])) ) {
  52. throw_exception(mysql_error());
  53. }
  54. $dbVersion = mysql_get_server_info($this->linkID[$linkNum]);
  55. //Access database using UTF8
  56. mysql_query("SET NAMES '".C('DB_CHARSET')."'", $this->linkID[$linkNum]);
  57. //Setup sql_model
  58. if($dbVersion >'5.0.1'){
  59. mysql_query("SET sql_mode=''",$this->linkID[$linkNum]);
  60. }
  61. // Mark connection successful
  62. $this->connected = true;
  63. // Unregister database connection configuration information
  64. if(1 != C('DB_DEPLOY_TYPE')) unset($this->config);
  65. }
  66. return $this->linkID[$linkNum];
  67. }
  68. /**
  69. * Query results released
  70. * @access public
  71. */
  72. public function free() {
  73. mysql_free_result($this->queryID);
  74. $this->queryID = null;
  75. }
  76. /**
  77. * Execute the query Returns a DataSet
  78. * @access public
  79. * @param string $str SQL commands
  80. * @return mixed
  81. */
  82. public function query($str) {
  83. if(0===stripos($str, 'call')){ // Stored procedure query Support
  84. $this->close();
  85. }
  86. $this->initConnect(false);
  87. if ( !$this->_linkID ) return false;
  88. $this->queryStr = $str;
  89. //Release the previous query results
  90. if ( $this->queryID ) { $this->free(); }
  91. N('db_query',1);
  92. // Record the start time
  93. G('queryStartTime');
  94. $this->queryID = mysql_query($str, $this->_linkID);
  95. $this->debug();
  96. if ( false === $this->queryID ) {
  97. $this->error();
  98. return false;
  99. } else {
  100. $this->numRows = mysql_num_rows($this->queryID);
  101. return $this->getAll();
  102. }
  103. }
  104. /**
  105. * Execute the statement
  106. * @access public
  107. * @param string $str SQL commands
  108. * @return integer|false
  109. */
  110. public function execute($str) {
  111. $this->initConnect(true);
  112. if ( !$this->_linkID ) return false;
  113. $this->queryStr = $str;
  114. //Release the previous query results
  115. if ( $this->queryID ) { $this->free(); }
  116. N('db_write',1);
  117. // Record the start time
  118. G('queryStartTime');
  119. $result = mysql_query($str, $this->_linkID) ;
  120. $this->debug();
  121. if ( false === $result) {
  122. $this->error();
  123. return false;
  124. } else {
  125. $this->numRows = mysql_affected_rows($this->_linkID);
  126. $this->lastInsID = mysql_insert_id($this->_linkID);
  127. return $this->numRows;
  128. }
  129. }
  130. /**
  131. * Start transaction
  132. * @access public
  133. * @return void
  134. */
  135. public function startTrans() {
  136. $this->initConnect(true);
  137. if ( !$this->_linkID ) return false;
  138. //Data rollback Support
  139. if ($this->transTimes == 0) {
  140. mysql_query('START TRANSACTION', $this->_linkID);
  141. }
  142. $this->transTimes++;
  143. return ;
  144. }
  145. /**
  146. * For non-autocommit State the following query submission
  147. * @access public
  148. * @return boolen
  149. */
  150. public function commit() {
  151. if ($this->transTimes > 0) {
  152. $result = mysql_query('COMMIT', $this->_linkID);
  153. $this->transTimes = 0;
  154. if(!$result){
  155. $this->error();
  156. return false;
  157. }
  158. }
  159. return true;
  160. }
  161. /**
  162. * Transaction rollback
  163. * @access public
  164. * @return boolen
  165. */
  166. public function rollback() {
  167. if ($this->transTimes > 0) {
  168. $result = mysql_query('ROLLBACK', $this->_linkID);
  169. $this->transTimes = 0;
  170. if(!$result){
  171. $this->error();
  172. return false;
  173. }
  174. }
  175. return true;
  176. }
  177. /**
  178. * Get all the query data
  179. * @access private
  180. * @return array
  181. */
  182. private function getAll() {
  183. //Returns a DataSet
  184. $result = array();
  185. if($this->numRows >0) {
  186. while($row = mysql_fetch_assoc($this->queryID)){
  187. $result[] = $row;
  188. }
  189. mysql_data_seek($this->queryID,0);
  190. }
  191. return $result;
  192. }
  193. /**
  194. * Information obtained field data sheet
  195. * @access public
  196. * @return array
  197. */
  198. public function getFields($tableName) {
  199. $result = $this->query('SHOW COLUMNS FROM '.$this->parseKey($tableName));
  200. $info = array();
  201. if($result) {
  202. foreach ($result as $key => $val) {
  203. $info[$val['Field']] = array(
  204. 'name' => $val['Field'],
  205. 'type' => $val['Type'],
  206. 'notnull' => (bool) ($val['Null'] === ''), // not null is empty, null is yes
  207. 'default' => $val['Default'],
  208. 'primary' => (strtolower($val['Key']) == 'pri'),
  209. 'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
  210. );
  211. }
  212. }
  213. return $info;
  214. }
  215. /**
  216. * Obtain information about the database table
  217. * @access public
  218. * @return array
  219. */
  220. public function getTables($dbName='') {
  221. if(!empty($dbName)) {
  222. $sql = 'SHOW TABLES FROM '.$dbName;
  223. }else{
  224. $sql = 'SHOW TABLES ';
  225. }
  226. $result = $this->query($sql);
  227. $info = array();
  228. foreach ($result as $key => $val) {
  229. $info[$key] = current($val);
  230. }
  231. return $info;
  232. }
  233. /**
  234. * Replace Record
  235. * @access public
  236. * @param mixed $data Data
  237. * @param array $options Parameter expression
  238. * @return false | integer
  239. */
  240. public function replace($data,$options=array()) {
  241. foreach ($data as $key=>$val){
  242. $value = $this->parseValue($val);
  243. if(is_scalar($value)) { // Filtering non-scalar data
  244. $values[] = $value;
  245. $fields[] = $this->parseKey($key);
  246. }
  247. }
  248. $sql = 'REPLACE INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
  249. return $this->execute($sql);
  250. }
  251. /**
  252. * Insert records
  253. * @access public
  254. * @param mixed $datas Data
  255. * @param array $options Parameter expression
  256. * @param boolean $replace Whether or replace
  257. * @return false | integer
  258. */
  259. public function insertAll($datas,$options=array(),$replace=false) {
  260. if(!is_array($datas[0])) return false;
  261. $fields = array_keys($datas[0]);
  262. array_walk($fields, array($this, 'parseKey'));
  263. $values = array();
  264. foreach ($datas as $data){
  265. $value = array();
  266. foreach ($data as $key=>$val){
  267. $val = $this->parseValue($val);
  268. if(is_scalar($val)) { // Filtering non-scalar data
  269. $value[] = $val;
  270. }
  271. }
  272. $values[] = '('.implode(',', $value).')';
  273. }
  274. $sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values);
  275. return $this->execute($sql);
  276. }
  277. /**
  278. * Close the database
  279. * @access public
  280. * @return void
  281. */
  282. public function close() {
  283. if ($this->_linkID){
  284. mysql_close($this->_linkID);
  285. }
  286. $this->_linkID = null;
  287. }
  288. /**
  289. * Database Error Messages
  290. * And displays the current SQL statement
  291. * @access public
  292. * @return string
  293. */
  294. public function error() {
  295. $this->error = mysql_error($this->_linkID);
  296. if('' != $this->queryStr){
  297. $this->error .= "\n [ SQL statement ] : ".$this->queryStr;
  298. }
  299. trace($this->error,'','ERR');
  300. return $this->error;
  301. }
  302. /**
  303. * SQL commands security filtering
  304. * @access public
  305. * @param string $str SQL string
  306. * @return string
  307. */
  308. public function escapeString($str) {
  309. if($this->_linkID) {
  310. return mysql_real_escape_string($str,$this->_linkID);
  311. }else{
  312. return mysql_escape_string($str);
  313. }
  314. }
  315. /**
  316. * Field and table names added processing`
  317. * @access protected
  318. * @param string $key
  319. * @return string
  320. */
  321. protected function parseKey(&$key) {
  322. $key = trim($key);
  323. if(!preg_match('/[,\'\"\*\(\)`.\s]/',$key)) {
  324. $key = '`'.$key.'`';
  325. }
  326. return $key;
  327. }
  328. }