Source for file MySQL.class.php

Documentation is available at MySQL.class.php

  1. <?php
  2. /**
  3. * NACLES MySQL Provider file.
  4. *
  5. * <p>This file defines the {@link NAJAX_Events_Storage_MySQL} Class.</p>
  6. * <p>Example:</p>
  7. * <code>
  8. * <?php
  9. *
  10. * require_once('najax.php');
  11. *
  12. * require_once(NAJAX_BASE . '/classes/events/storage/MySQL.class.php');
  13. *
  14. * $storage = new NAJAX_Events_Storage_MySQL('server=?;user=?;password=?;database=?;[port=?]');
  15. *
  16. * $storage->postEvent('event', 'class');
  17. *
  18. * ?>
  19. * </code>
  20. *
  21. * @author Stanimir Angeloff
  22. *
  23. * @package NAJAX
  24. *
  25. * @subpackage NACLES
  26. *
  27. * @version 0.4.1.0
  28. *
  29. */
  30.  
  31. /**
  32. * Defines the table name in the MySQL database that is used to save the
  33. * events information (default value: najax_events).
  34. *
  35. * @ignore
  36. *
  37. */
  38. define('NAJAX_EVENTS_TABLE_NAME', 'najax_events');
  39.  
  40. /**
  41. * NAJAX Events Storage MySQL Class.
  42. *
  43. * <p>This class is a {@link NAJAX_Events_Storage} successor.</p>
  44. * <p>The class allows you to save events information in
  45. * MySQL database.</p>
  46. * <p>Example:</p>
  47. * <code>
  48. * <?php
  49. *
  50. * require_once('najax.php');
  51. *
  52. * require_once(NAJAX_BASE . '/classes/events/storage/MySQL.class.php');
  53. *
  54. * $storage = new NAJAX_Events_Storage_MySQL('server=?;user=?;password=?;database=?;[port=?]');
  55. *
  56. * $storage->postEvent('event', 'class');
  57. *
  58. * ?>
  59. * </code>
  60. *
  61. * @author Stanimir Angeloff
  62. *
  63. * @package NAJAX
  64. *
  65. * @subpackage NACLES
  66. *
  67. * @version 0.4.1.0
  68. *
  69. */
  70. class NAJAX_Events_Storage_MySQL extends NAJAX_Events_Storage
  71. {
  72. /**
  73. * Holds the MySQL server used in the connection string.
  74. *
  75. * @access private
  76. *
  77. * @var string
  78. *
  79. */
  80. var $sqlServer;
  81.  
  82. /**
  83. * Holds the MySQL user used in the connection string.
  84. *
  85. * @access private
  86. *
  87. * @var string
  88. *
  89. */
  90. var $sqlUser;
  91.  
  92. /**
  93. * Holds the MySQL password used in the connection string.
  94. *
  95. * @access private
  96. *
  97. * @var string
  98. *
  99. */
  100. var $sqlPassword;
  101.  
  102. /**
  103. * Holds the MySQL database used in the connection string.
  104. *
  105. * @access private
  106. *
  107. * @var string
  108. *
  109. */
  110. var $sqlDatabase;
  111.  
  112. /**
  113. * Holds the MySQL port used in the connection string.
  114. *
  115. * @access private
  116. *
  117. * @var string
  118. *
  119. */
  120. var $sqlPort = 3306;
  121.  
  122. /**
  123. * Indicates whether to open a new connection to the MySQL server
  124. * if an old one already exists.
  125. *
  126. * @access private
  127. *
  128. * @var bool
  129. *
  130. */
  131. var $sqlOpenNew;
  132.  
  133. /**
  134. * Creates a new instance of the {@link NAJAX_Events_Storage_MySQL} class.
  135. *
  136. * @access public
  137. *
  138. * @param string $dsn The data source name and parameters to use
  139. * when connecting to MySQL.
  140. *
  141. */
  142. function NAJAX_Events_Storage_MySQL($dsn)
  143. {
  144. $pairs = explode(';', $dsn);
  145.  
  146. foreach ($pairs as $pair) {
  147.  
  148. list($key, $value) = explode('=', $pair, 2);
  149.  
  150. switch (strtolower($key)) {
  151.  
  152. case 'server': {
  153.  
  154. $this->sqlServer = $value;
  155.  
  156. break;
  157. }
  158.  
  159. case 'user': {
  160.  
  161. $this->sqlUser = $value;
  162.  
  163. break;
  164. }
  165.  
  166. case 'password': {
  167.  
  168. $this->sqlPassword = $value;
  169.  
  170. break;
  171. }
  172.  
  173. case 'database': {
  174.  
  175. $this->sqlDatabase = $value;
  176.  
  177. break;
  178. }
  179.  
  180. case 'opennew': {
  181.  
  182. $this->sqlOpenNew = $value;
  183.  
  184. break;
  185. }
  186.  
  187. case 'port': {
  188.  
  189. $this->sqlPort = $value;
  190.  
  191. break;
  192. }
  193. }
  194. }
  195. }
  196.  
  197. /**
  198. * Retrieves a new instance of the {@link NAJAX_Events_Storage_MySQL} class.
  199. *
  200. * <p>This method overrides {@link NAJAX_Events_Storage::getStorage}.</p>
  201. *
  202. * @access public
  203. *
  204. * @param string $dsn The data source name and parameters to use
  205. * when connecting to MySQL.
  206. *
  207. * @return object A singleton instance to the
  208. * {@link NAJAX_Events_Storage_MySQL} class.
  209. *
  210. * @static
  211. *
  212. */
  213. function getStorage($dsn)
  214. {
  215. static $instance;
  216.  
  217. if ( ! isset($instance)) {
  218.  
  219. $instance = new NAJAX_Events_Storage_MySQL($dsn);
  220. }
  221.  
  222. return $instance;
  223. }
  224.  
  225. /**
  226. * Creates a MySQL connection link.
  227. *
  228. * @access private
  229. *
  230. * @return resource
  231. *
  232. */
  233. function getConnection()
  234. {
  235. if ($this->sqlPort != 3306) {
  236.  
  237. $server = "{$this->sqlServer}:{$this->sqlPort}";
  238.  
  239. } else {
  240.  
  241. $server = $this->sqlServer;
  242. }
  243.  
  244. $connection = mysql_connect($server, $this->sqlUser, $this->sqlPassword, $this->sqlOpenNew);
  245.  
  246. mysql_select_db($this->sqlDatabase, $connection);
  247.  
  248. return $connection;
  249. }
  250.  
  251. /**
  252. * Closes a MySQL connection link.
  253. *
  254. * @access private
  255. *
  256. * @return void
  257. *
  258. */
  259. function closeConnection($connection)
  260. {
  261. mysql_close($connection);
  262. }
  263.  
  264. /**
  265. * Escapes special characters in the {@link $unescapedString},
  266. * taking into account the current charset of the connection.
  267. *
  268. * @access private
  269. *
  270. * @return string
  271. *
  272. */
  273. function escapeString($unescapedString, $connection)
  274. {
  275. if (function_exists('mysql_real_escape_string')) {
  276.  
  277. return mysql_real_escape_string($unescapedString, $connection);
  278. }
  279.  
  280. return mysql_escape_string($unescapedString);
  281. }
  282.  
  283. /**
  284. * Posts a single event to the database.
  285. *
  286. * <p>The {@link $event} and {@link $class} arguments are required
  287. * for each event. The {@link $sender}, {@link $data}, {@link $filter},
  288. * {@link $time} and {@link $lifetime} arguments are optional.</p>
  289. * <p>In case you have supplied both {@link $class} and {@link $sender},
  290. * then the {@link $sender}'s class must match the one you've supplied.</p>
  291. * <p>This method calls {@link postMultipleEvents} with the appropriate
  292. * arguments.</p>
  293. *
  294. * @access public
  295. *
  296. * @param string $event The event name (case-sensitive).
  297. *
  298. * @param string $class The class that is the source of the event.
  299. *
  300. * @param object $sender The sender object of the event.
  301. *
  302. * @param mixed $data The data associated with the event.
  303. *
  304. * @param string $filter The event filter data (case-insensitive).
  305. * Using this argument you can post events with
  306. * the same name but with different filter data.
  307. * The client will respond to them individually.
  308. *
  309. * @param int $time The event start time (seconds since the Unix
  310. * Epoch (January 1 1970 00:00:00 GMT).
  311. *
  312. * @param int $lifetime The event lifetime (in seconds).
  313. *
  314. * @return bool true on success, false otherwise.
  315. *
  316. */
  317. function postEvent($event, $class, $sender = null, $data = null, $filter = null, $time = null, $lifetime = null)
  318. {
  319. return $this->postMultipleEvents(array(array(
  320. 'event' => $event,
  321. 'className' => $class,
  322. 'sender' => $sender,
  323. 'data' => $data,
  324. 'filter' => $filter,
  325. 'time' => $time,
  326. 'lifetime' => $lifetime
  327. )));
  328. }
  329.  
  330. /**
  331. * Posts multiple events to the database.
  332. *
  333. * <p>Valid keys for each event are:</p>
  334. * - event - the event name (case-sensitive);
  335. * - className - the class that is the source of the event;
  336. * - sender - the sender object of the event;
  337. * - data - the data associated with the event;
  338. * - filter - the event filter data (case-insensitive);
  339. * using this key you can post events with
  340. * the same name but with different filter data;
  341. * the client will respond to them individually;
  342. * - time - the event start time (seconds since the Unix
  343. * Epoch (January 1 1970 00:00:00 GMT);
  344. * - lifetime - the event lifetime (in seconds);
  345. *
  346. * @access public
  347. *
  348. * @param array $eventsData Array containing associative arrays
  349. * with information for each event.
  350. *
  351. * @return bool true on success, false otherwise.
  352. *
  353. */
  354. function postMultipleEvents($eventsData)
  355. {
  356. $connection = $this->getConnection();
  357.  
  358. foreach ($eventsData as $event) {
  359.  
  360. if (( ! isset($event['time'])) || ($event['time'] === null)) {
  361.  
  362. $event['time'] = NAJAX_Utilities::getMicroTime();
  363. }
  364.  
  365. if (( ! isset($event['lifetime'])) || ($event['lifetime'] === null)) {
  366.  
  367. $event['lifetime'] = NAJAX_EVENTS_LIFETIME;
  368. }
  369.  
  370. if ((isset($event['sender'])) && ($event['sender'] !== null)) {
  371.  
  372. if (NAJAX_Utilities::getType($event['sender']) != 'object') {
  373.  
  374. continue;
  375. }
  376.  
  377. if (strcasecmp($event['className'], get_class($event['sender'])) != 0) {
  378.  
  379. continue;
  380. }
  381. }
  382.  
  383. $sqlQuery = '
  384. INSERT INTO
  385. `' . NAJAX_EVENTS_TABLE_NAME . '`
  386. (
  387. `event`,
  388. `className`,
  389. `filter`,
  390. `sender`,
  391. `data`,
  392. `time`,
  393. `endTime`
  394. )
  395. VALUES
  396. (
  397. \'' . $this->escapeString($event['event'], $connection) . '\',
  398. \'' . $this->escapeString($event['className'], $connection) . '\',
  399. ';
  400.  
  401. if (isset($event['filter'])) {
  402.  
  403. $sqlQuery .= '\'' . $this->escapeString($event['filter'], $connection) . '\',';
  404.  
  405. } else {
  406.  
  407. $sqlQuery .= 'NULL,';
  408. }
  409.  
  410. if (isset($event['sender'])) {
  411.  
  412. $sqlQuery .= '\'' . $this->escapeString(serialize($event['sender']), $connection) . '\',';
  413.  
  414. } else {
  415.  
  416. $sqlQuery .= 'NULL,';
  417. }
  418.  
  419. if (isset($event['data'])) {
  420.  
  421. $sqlQuery .= '\'' . $this->escapeString(serialize($event['data']), $connection) . '\',';
  422.  
  423. } else {
  424.  
  425. $sqlQuery .= 'NULL,';
  426. }
  427.  
  428. $sqlQuery .= '
  429. ' . $this->escapeString($event['time'], $connection) . ',
  430. ' . $this->escapeString($event['time'] + $event['lifetime'], $connection) . '
  431. )';
  432.  
  433. mysql_query($sqlQuery, $connection);
  434. }
  435.  
  436. $this->closeConnection($connection);
  437.  
  438. return true;
  439. }
  440.  
  441. /**
  442. * Deletes old events from the database.
  443. *
  444. * <p>This method is called before calling {@link filterEvents}
  445. * or {@link filterMultipleEvents} to delete all expired events
  446. * from the database.</p>
  447. *
  448. * @access public
  449. *
  450. * @return bool true on success, false otherwise.
  451. *
  452. */
  453. function cleanEvents()
  454. {
  455. $connection = $this->getConnection();
  456.  
  457. $time = NAJAX_Utilities::getMicroTime() - NAJAX_EVENTS_LIFETIME;
  458.  
  459. $sqlQuery = '
  460. DELETE FROM
  461. `' . NAJAX_EVENTS_TABLE_NAME . '`
  462. WHERE
  463. `endTime` < ' . $this->escapeString($time, $connection) . '
  464. ';
  465.  
  466. mysql_query($sqlQuery, $connection);
  467.  
  468. $this->closeConnection($connection);
  469.  
  470. return true;
  471. }
  472.  
  473. /**
  474. * Filters the events in the database using a single criteria.
  475. *
  476. * <p>The {@link $event} and {@link $class} arguments are required
  477. * for each event. The {@link $filter} and {@link $time} arguments
  478. * are optional.</p>
  479. * <p>This method calls {@link filterMultipleEvents} with the appropriate
  480. * arguments.</p>
  481. *
  482. * @access public
  483. *
  484. * @param string $event The event name (case-sensitive).
  485. *
  486. * @param string $class The class that is the source of the event.
  487. *
  488. * @param string $filter The event filter data (case-insensitive).
  489. * Using this argument you can filter events with
  490. * the same name but with different filter data.
  491. *
  492. * @param int $time The event start time (seconds since the Unix
  493. * Epoch (January 1 1970 00:00:00 GMT).
  494. *
  495. * @return array Sequental array that contains all events that match the
  496. * supplied criterias, ordered by time (ascending).
  497. *
  498. */
  499. function filterEvents($event, $class, $filter = null, $time = null)
  500. {
  501. return $this->filterMultipleEvents(array(array(
  502. 'event' => $event,
  503. 'className' => $class,
  504. 'filter' => $filter,
  505. 'time' => $time
  506. )));
  507. }
  508.  
  509. /**
  510. * Filters the events in the database using multiple criterias.
  511. *
  512. * <p>Valid keys for each event are:</p>
  513. * - event - the event name (case-sensitive);
  514. * - className - the class that is the source of the event;
  515. * - filter - the event filter data (case-insensitive);
  516. * using this argument you can filter events with
  517. * the same name but with different filter data;
  518. * - time - the event start time (seconds since the Unix
  519. * Epoch (January 1 1970 00:00:00 GMT).
  520. *
  521. * @access public
  522. *
  523. * @param array $eventsData Array containing associative arrays
  524. * with information for each event.
  525. *
  526. * @return array Sequental array that contains all events that match the
  527. * supplied criterias, ordered by time (ascending).
  528. *
  529. */
  530. function filterMultipleEvents($eventsData)
  531. {
  532. $connection = $this->getConnection();
  533.  
  534. $sqlQuery = '
  535. SELECT
  536. `event`,
  537. `className`,
  538. `filter`,
  539. `sender`,
  540. `data`,
  541. `time`,
  542. `endTime`
  543. FROM
  544. `' . NAJAX_EVENTS_TABLE_NAME . '`
  545. WHERE
  546. ';
  547.  
  548. $index = 0;
  549.  
  550. $length = sizeof($eventsData);
  551.  
  552. foreach ($eventsData as $event) {
  553.  
  554. if (( ! isset($event['time'])) || ($event['time'] === null)) {
  555.  
  556. $event['time'] = NAJAX_Utilities::getMicroTime();
  557. }
  558.  
  559. $sqlQuery .= '(
  560. `time` > ' . $this->escapeString($event['time'], $connection) . '
  561. AND
  562. `event` = \'' . $this->escapeString($event['event'], $connection) . '\'
  563. AND
  564. `className` = \'' . $this->escapeString($event['className'], $connection) . '\'
  565. ';
  566.  
  567. if (isset($event['filter'])) {
  568.  
  569. $sqlQuery .= 'AND `filter` = \'' . $this->escapeString($event['filter'], $connection) . '\'';
  570. }
  571.  
  572. if ($index < $length - 1) {
  573.  
  574. $sqlQuery .= ') OR ';
  575.  
  576. } else {
  577.  
  578. $sqlQuery .= ')';
  579. }
  580.  
  581. $index ++;
  582. }
  583.  
  584. $sqlQuery .= '
  585. ORDER BY
  586. `time` ASC
  587. ';
  588.  
  589. $events = array();
  590.  
  591. $sqlResult = mysql_query($sqlQuery, $connection);
  592.  
  593. while (($row = mysql_fetch_assoc($sqlResult)) !== false) {
  594.  
  595. $events[] = array(
  596. 'event' => $row['event'],
  597. 'className' => $row['className'],
  598. 'filter' => $row['filter'],
  599. 'time' => (float) $row['time'],
  600. 'endTime' => (float) $row['endTime'],
  601. 'eventData' => array(
  602. 'sender' => ($row['sender'] === null ? null : unserialize($row['sender'])),
  603. 'data' => ($row['data'] === null ? null : unserialize($row['data']))
  604. ));
  605. }
  606.  
  607. mysql_free_result($sqlResult);
  608.  
  609. $this->closeConnection($connection);
  610.  
  611. return $events;
  612. }
  613. }

Documentation generated on Tue, 20 Sep 2005 21:40:11 +0300 by phpDocumentor 1.3.0RC3