PageRenderTime 23ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/phpSurvey/library/Snake/Db/Model.php

http://devj.googlecode.com/
PHP | 612 lines | 356 code | 2 blank | 254 comment | 68 complexity | d09b1dbc3c09cb9605d6a8591463e1a8 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. <?php
  2. // ??????
  3. Basic::loadClass('Helper_Cache');
  4. /**
  5. * ???????
  6. * ?????????????-CURD
  7. *
  8. * @package Db
  9. * @author Snake.Zero
  10. * @copyright Snake.Zero
  11. */
  12. class Db_Model
  13. {
  14. /**
  15. * ?????
  16. *
  17. * @var string
  18. */
  19. var $tablePrefix = '';
  20. /**
  21. * ?????
  22. *
  23. * @var string
  24. */
  25. var $tableName = '';
  26. /**
  27. * ?????
  28. *
  29. * @var string
  30. */
  31. var $tableFullName;
  32. /**
  33. * ?????
  34. *
  35. * @var handle
  36. */
  37. var $handle;
  38. /**
  39. * ?????
  40. *
  41. * @var array
  42. */
  43. var $fieldsName;
  44. /**
  45. * ????????
  46. *
  47. * @var array
  48. */
  49. var $fields;
  50. /**
  51. * ??(???DB???????????????????????)
  52. *
  53. * @var string
  54. */
  55. var $primaryKey;
  56. /**
  57. * ??????????
  58. *
  59. * @var boolean
  60. */
  61. var $autoupdated = true;
  62. /**
  63. * ??????????????????
  64. *
  65. * ????????????????? create() ????????
  66. * ???????????????
  67. *
  68. * @var array
  69. */
  70. var $createdTimeFields = array('created' , 'dateline');
  71. /**
  72. * ????
  73. *
  74. * @param array $config
  75. * @return Db_Model
  76. */
  77. function Db_Model ($config = null)
  78. {
  79. // ??????????????
  80. if (empty($config)) {
  81. $config = Basic::get_config_db();
  82. }
  83. $this->handle = $this->connect($config);
  84. // ??????
  85. if (empty($this->tablePrefix) && ! empty($config['prefix'])) {
  86. $this->tablePrefix = $config['prefix'];
  87. }
  88. // ???????
  89. $this->tableFullName = $this->tablePrefix . $this->tableName;
  90. // ????????????????????
  91. if (! empty($this->fields)) {
  92. $_fieldsName = array_keys($this->fields);
  93. foreach ((array)$_fieldsName as $v) {
  94. $this->fieldsName[$v] = $v;
  95. }
  96. }
  97. if (empty($this->fieldsName) && ! empty($this->tableName)) {
  98. if (is_file(CACHEPATH . DS . 'array_CTABLE_' . $this->tableFullName . '.php')) {
  99. $this->fieldsName = include (CACHEPATH . DS . 'array_CTABLE_' . $this->tableFullName . '.php');
  100. } else {
  101. $this->fieldsName = $this->_getFields();
  102. $this->_cacheTable($this->fieldsName);
  103. }
  104. }
  105. }
  106. /**
  107. * ???????????
  108. *
  109. * @param array $config
  110. * @return handle
  111. */
  112. function connect ($config)
  113. {
  114. // ????????MD5??
  115. $configMD5 = md5(serialize($config));
  116. // ????????????????????
  117. if (! empty($GLOBALS['_SNAKE_DB_HANDLES_'][$configMD5])) {
  118. return $GLOBALS['_SNAKE_DB_HANDLES_'][$configMD5];
  119. }
  120. // ??????????????
  121. $_hd = mysql_connect($config['host'], $config['username'], $config['password']) or die('Unable to connect to the database.');
  122. mysql_select_db($config['database'], $_hd) or die('Unable to selete this database:' . $config['database']);
  123. $this->_execute("SET NAMES {$config['charset']}", $_hd);
  124. // ??????????
  125. $GLOBALS['_SNAKE_DB_HANDLES_'][$configMD5] = $_hd;
  126. return $_hd;
  127. }
  128. /**
  129. * ????
  130. *
  131. * @param mixed $fields
  132. * @return string
  133. */
  134. function _parseFields ($fields)
  135. {
  136. if ($fields == '*' || $fields == '') {
  137. return '*';
  138. }
  139. if (is_array($fields)) {
  140. return '`' . implode('` , `', $fields) . '`';
  141. } else {
  142. return $fields;
  143. }
  144. }
  145. /**
  146. * parse the order by subsentence
  147. *
  148. * @param mixed $order
  149. * @return string
  150. */
  151. function _parseOrderBy ($order)
  152. {
  153. if (empty($order)) {
  154. return ' ORDER BY ' . "`$this->primaryKey`";
  155. }
  156. if (strtoupper($order) == 'DESC') {
  157. return ' ORDER BY ' . "`$this->primaryKey`" . ' DESC';
  158. }
  159. if (is_array($order)) {
  160. $total = count($order);
  161. $i = 1;
  162. foreach ((array)$order as $key => $value) {
  163. if (is_numeric($key)) {
  164. $orderBy .= "`{$value}` ";
  165. } else {
  166. $orderBy .= "`{$key}` {$value}";
  167. }
  168. if ($i < $total) {
  169. $orderBy .= ' , ';
  170. }
  171. $i ++;
  172. }
  173. } else {
  174. $orderBy = $order;
  175. }
  176. return ' ORDER BY ' . $orderBy;
  177. }
  178. /**
  179. * parse the limit subsentence
  180. *
  181. * @param mixed $limit
  182. * @return string
  183. */
  184. function _parseLimit ($limit)
  185. {
  186. if ($limit == 0) {
  187. return '';
  188. }
  189. if (is_numeric($limit)) {
  190. $limit = array(0 , $limit);
  191. }
  192. if (is_array($limit)) {
  193. $limit = "{$limit[0]},{$limit[1]}";
  194. }
  195. return ' LIMIT ' . $limit;
  196. }
  197. /**
  198. * ??????????
  199. *
  200. * @param string $field
  201. * @return boolean
  202. */
  203. function hasField ($field)
  204. {
  205. $fds = $this->fieldsName;
  206. if (in_array($field, $fds)) {
  207. return true;
  208. }
  209. return false;
  210. }
  211. /**
  212. * ??SQL??
  213. *
  214. * @param string $sql
  215. * @return result
  216. */
  217. function _execute ($sql, $HADLE = null, $log = true)
  218. {
  219. $HADLE = empty($HADLE) ? $this->handle : $HADLE;
  220. if ($log) {
  221. $GLOBALS['SNAKE']['SQL'][] = $sql;
  222. }
  223. return mysql_query($sql, $HADLE);
  224. }
  225. /**
  226. * ??SQL??,????????
  227. *
  228. * @param string $sql
  229. * @param string $key
  230. * @return result
  231. */
  232. function _hexecute ($sql, $key = 'test', $HADLE = null)
  233. {
  234. $GLOBALS['SNAKE']['SQL'][$key][] = $sql;
  235. return $this->_execute($sql, $HADLE, false);
  236. }
  237. /**
  238. * ??
  239. *
  240. */
  241. function total ($conditions = '')
  242. {
  243. $row = $this->findAll($conditions, "COUNT(*) AS `total`", '', '');
  244. return $row[0]['total'];
  245. }
  246. /**
  247. * ??
  248. *
  249. * @param mixed $conditions
  250. * @param mixed $fields
  251. * @param mixed $orderBy
  252. * @param mixed $limit
  253. * @param string $foc ??
  254. * @return array
  255. */
  256. function findAll ($conditions = array(), $fields = '*', $orderBy = '', $limit = array(0,30), $foc = null)
  257. {
  258. // ????
  259. $condition = $this->_parseConditions($conditions);
  260. // ????
  261. $fields = $this->_parseFields($fields);
  262. // ????
  263. $orderBy = $this->_parseOrderBy($orderBy);
  264. // ????
  265. $limit = $this->_parseLimit($limit);
  266. // ??SQL??
  267. $SQL = "SELECT {$fields} FROM `{$this->tableFullName}`{$condition}{$orderBy}{$limit};";
  268. $result = $this->_execute($SQL);
  269. return $this->fetchAll($result, $foc);
  270. }
  271. /**
  272. * ????????
  273. *
  274. * @param mixed $conditions
  275. * @param mixed $limit
  276. * @param mixed $foc
  277. * @return array
  278. */
  279. function findAllDESC ($conditions = array(), $limit = array(0,30), $foc = null)
  280. {
  281. return $this->findAll($conditions, '*', 'DESC', $limit, $foc);
  282. }
  283. /**
  284. * ??$foc??
  285. *
  286. */
  287. function findAllFoc ($foc = null, $conditions = array(), $fields = '*', $orderBy = '', $limit = array(0,30))
  288. {
  289. if (empty($foc)) {
  290. $foc = $this->primaryKey;
  291. }
  292. return $this->findAll($conditions, $fields, $orderBy, $limit, $foc);
  293. }
  294. function find ($conditions = array(), $fields = '*', $orderBy = '')
  295. {
  296. $rows = $this->findAll($conditions, $fields, $orderBy, 1);
  297. return $rows[0];
  298. }
  299. /**
  300. * ??(??)????
  301. * ???(INSERT INTO)??
  302. * $high ????????TRUE?????????????
  303. *
  304. * @param array $row
  305. * @param boolean $high
  306. * @return int
  307. */
  308. function create ($row, $high = false)
  309. {
  310. // ????????????
  311. $row = $this->_columnCollect($row);
  312. if (in_array('created', $this->fieldsName)) {
  313. $row['created'] = time();
  314. }
  315. if ($this->autoupdated && in_array('updated', $this->fieldsName)) {
  316. $row['updated'] = time();
  317. }
  318. if ($high == false) {
  319. unset($row[$this->primaryKey]);
  320. }
  321. // ?????
  322. if (empty($row)) {
  323. return;
  324. }
  325. $keys = array_keys($row);
  326. $keys = '`' . implode('` , `', $keys) . '`';
  327. // ???
  328. $values = '\'' . implode('\' , \'', $row) . '\'';
  329. $SQL = "INSERT INTO `{$this->tableFullName}` ({$keys}) VALUES ({$values});";
  330. $this->_execute($SQL);
  331. return mysql_insert_id($this->handle);
  332. }
  333. /**
  334. * ?????????
  335. *
  336. * @param mixed $conditons
  337. * @param mixed $values
  338. * @return mixed
  339. */
  340. function updateByCondition ($conditons, $values)
  341. {
  342. // ???????????????????????
  343. if (empty($conditons) || empty($values)) {
  344. return;
  345. }
  346. // ????
  347. $conditons = $this->_parseConditions($conditons);
  348. if (is_array($values)) {
  349. // ?????????????????????????
  350. unset($values[$this->primaryKey]);
  351. if (in_array('updated', $this->fieldsName)) {
  352. $values['updated'] = time();
  353. }
  354. // ???????????
  355. $values = $this->_columnCollect($values);
  356. // ?????
  357. $keysValues = $this->kvstring($values);
  358. } else {
  359. $keysValues = $values;
  360. }
  361. if (empty($conditons) || empty($keysValues)) {
  362. return;
  363. }
  364. $SQL = "UPDATE `{$this->tableFullName}` SET{$keysValues}{$conditons}";
  365. return $this->_execute($SQL);
  366. }
  367. /**
  368. * ?????????
  369. *
  370. * @param array $row
  371. * @return mixed
  372. */
  373. function update (& $row)
  374. {
  375. return $this->updateByCondition($row[$this->primaryKey], $row);
  376. }
  377. /**
  378. * ????
  379. *
  380. * @param int $id
  381. * @param mixed $keys
  382. * @param string $plus
  383. * @param int $step
  384. * @return unknown
  385. */
  386. function updatecounter ($id, $keys, $plus = '+', $step = 1)
  387. {
  388. if (is_array($keys)) {
  389. foreach ((array)$keys as $key) {
  390. $updaterows[] = "`$key` = `{$key}`{$plus}{$step}";
  391. $updaterow = ' ' . implode(' , ', $updaterows);
  392. }
  393. } else {
  394. $updaterow = " `{$keys}` = `{$keys}`{$plus}{$step}";
  395. }
  396. return $this->updateByCondition($id, $updaterow);
  397. }
  398. /**
  399. * ????
  400. *
  401. * @param unknown_type $conditions
  402. * @param unknown_type $limit
  403. * @return unknown
  404. */
  405. function _delete ($conditions, $limit = 1)
  406. {
  407. $limitStr = '';
  408. $conditions = $this->_parseConditions($conditions);
  409. if ($limit != 0) {
  410. $limitStr = 'LIMIT ' . $limit;
  411. }
  412. if (! empty($conditions)) {
  413. $SQL = "DELETE FROM `{$this->tableFullName}` {$conditions} {$limitStr}";
  414. return $this->_execute($SQL);
  415. }
  416. return false;
  417. }
  418. function remove ($conditions)
  419. {
  420. return $this->_delete(array($this->primaryKey => $conditions), 1);
  421. }
  422. /**
  423. * ??mysql_fetch_all????
  424. *
  425. * @param mysql result $result
  426. * @return array
  427. */
  428. function fetchAll ($result, $key = '', $mysqlMethod = 'mysql_fetch_assoc')
  429. {
  430. $usedMethod = array('mysql_fetch_assoc' , 'mysql_fetch_row' , 'mysql_fetch_array' , 'mysql_fetch_field' , 'mysql_fetch_object');
  431. if (! in_array($mysqlMethod, $usedMethod)) {
  432. $mysqlMethod = 'mysql_fetch_assoc';
  433. }
  434. if (! is_resource($result) && is_string($result)) {
  435. if (trim($result) != '') {
  436. $result = $this->_execute($result);
  437. }
  438. }
  439. while ($row = $mysqlMethod($result)) {
  440. if ($key == '') {
  441. $rows[] = $row;
  442. } else {
  443. $rows[$row[$key]] = $row;
  444. }
  445. }
  446. return $rows;
  447. }
  448. function fetchRow ($result, $key = '')
  449. {
  450. $rows = $this->fetchAll($result, $key);
  451. return $rows[0];
  452. }
  453. /**
  454. * ???????????2????
  455. *
  456. * @param array $array
  457. * @return array[string x 2]
  458. */
  459. function fieldsValues ($array)
  460. {
  461. $fields = array_keys($array);
  462. $return['fields'] = '`' . implode('`, `', $fields) . '`';
  463. $return['values'] = "'" . implode("', '", $array) . "'";
  464. return $return;
  465. }
  466. /**
  467. * ?Key?Value?????????
  468. *
  469. * @param unknown_type $row
  470. * @return unknown
  471. */
  472. function kvstring ($row)
  473. {
  474. foreach ((array)$row as $key => $value) {
  475. $return[] = " `{$key}` = '{$value}' ";
  476. }
  477. return implode(',', $return);
  478. }
  479. /**
  480. * ??????????????
  481. *
  482. * @param array $row
  483. * @return array
  484. */
  485. function _columnCollect ($row)
  486. {
  487. $keys = array_intersect(array_keys($row), $this->fieldsName);
  488. foreach ((array)$keys as $key) {
  489. $return[$key] = addslashes($row[$key]);
  490. }
  491. return $return;
  492. }
  493. /**
  494. * ????
  495. *
  496. * @param mixed $conditions
  497. * @return string
  498. */
  499. function _parseConditions ($conditions)
  500. {
  501. if (empty($conditions)) {
  502. return;
  503. }
  504. if (is_numeric($conditions)) {
  505. $conditions = $this->_intConditions($conditions);
  506. }
  507. if (is_array($conditions)) {
  508. $conditions = $this->_columnCollect($conditions);
  509. if (empty($conditions)) {
  510. return;
  511. }
  512. $conditions = $this->_arrayCondition($conditions);
  513. }
  514. if (is_string($conditions)) {
  515. $conditions = $this->_stringCondition($conditions);
  516. }
  517. return $conditions;
  518. }
  519. /**
  520. * ?????
  521. *
  522. * @param int $conditions
  523. * @return array
  524. */
  525. function _intConditions ($conditions)
  526. {
  527. $return[$this->primaryKey] = "{$conditions}";
  528. return $return;
  529. }
  530. /**
  531. * ?????
  532. *
  533. * @param array $conditions
  534. * @return string
  535. */
  536. function _arrayCondition ($conditions)
  537. {
  538. if (empty($conditions)) {
  539. return null;
  540. }
  541. foreach ((array)$conditions as $key => $value) {
  542. if (! is_array($value)) {
  543. $condition[] = "`{$key}` = '{$value}'";
  544. } else {
  545. $value = implode('\' , \'', array_unique($value));
  546. $condition[] = "`{$key}` IN ('{$value}')";
  547. }
  548. }
  549. $condition = implode(' AND ', $condition);
  550. return $condition;
  551. }
  552. /**
  553. * ?????
  554. *
  555. * @return string
  556. */
  557. function _stringCondition ($string)
  558. {
  559. return ' WHERE ' . $string;
  560. }
  561. function _getFields ()
  562. {
  563. $fields = $this->showColumns();
  564. $collected = $this->collectKeys($fields);
  565. return $collected;
  566. }
  567. /**
  568. * ???
  569. *
  570. * @param unknown_type $array
  571. * @return unknown
  572. */
  573. function collectKeys ($array)
  574. {
  575. foreach ((array)$array as $key => $value) {
  576. $keys[$value['Field']] = $value['Field'];
  577. }
  578. return $keys;
  579. }
  580. /**
  581. * ??????
  582. *
  583. * @return array
  584. */
  585. function showColumns ()
  586. {
  587. $sql = "SHOW COLUMNS FROM `{$this->tableFullName}`;";
  588. $result = $this->_execute($sql);
  589. $rows = $this->fetchAll($result);
  590. if (empty($this->primaryKey)) {
  591. foreach ((array)$rows as $row) {
  592. if ($row['Key'] == 'PRI') {
  593. $this->primaryKey = $row['Field'];
  594. break;
  595. }
  596. }
  597. }
  598. return $rows;
  599. }
  600. /**
  601. * ???????
  602. *
  603. * @param array $array
  604. */
  605. function _cacheTable ($array)
  606. {
  607. $cache = & new Helper_Cache();
  608. $cache->cacheArray('CTABLE_' . $this->tableFullName, $array);
  609. }
  610. }