powered by nequal
Home » Net_Q4M » Timeline » 222

Diffs

Net_Q4M/trunk/Net/Q4M/Connection/ResultSet.php

@@ -0,0 +1,104 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+class Net_Q4M_Connection_ResultSet
+{
+  private $_data;
+
+  /**
+   * Constructor
+   */
+  public function __construct()
+  {
+    $this->_data = false;
+  }
+
+  /**
+   * Set result records
+   *
+   * @access public
+   * @param  array $data
+   */
+  public function setData($data)
+  {
+    if (is_array($data)) {
+      $this->_data = $data;
+    }
+  }
+
+  /**
+   * Add result record
+   *
+   * @access public
+   * @param  array $data
+   */
+  public function addData($data)
+  {
+    if (!is_array($this->_data)) {
+      $this->_data = array();
+    }
+    $this->_data[] = $data;
+  }
+
+  /**
+   * fetch a record from result data
+   *
+   * @access public
+   * @return array
+   */
+  public function fetchRow()
+  {
+    if ($this->hasData()) {
+      return array_shift($this->_data);
+    }
+    return false;
+  }
+
+  /**
+   * Returns true if object has any data
+   *
+   * @access public
+   * @return bool
+   */
+  public function hasData()
+  {
+    if ($this->_data) {
+      return true;
+    }
+    return false;
+  }
+}
+
+?>

Net_Q4M/trunk/Net/Q4M/Connection/MySQLi.php

@@ -0,0 +1,121 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once 'Net/Q4M/Connection/MySQL.php';
+
+class Net_Q4M_Connection_MySQLi extends Net_Q4M_Connection_MySQL
+{
+  /**
+   * Connect to MySQL server
+   *
+   * @access  public
+   * @param   mixed $dsn    DSN string or parsed DSN array
+   * @return  Net_Q4M_Connection_MySQLi
+   * @throws  Net_Q4M_Exception
+   */
+  public function connect($dsn)
+  {
+    if (!is_array($dsn)) {
+      $dsn = Net_Q4M_Connection::parseDSN($dsn);
+    }
+
+    $this->_dbh = new mysqli($dsn['host'], $dsn['username'], $dsn['password'],
+      $dsn['database'], $dsn['port']);
+
+    if (mysqli_connect_errno()) {
+      throw new Net_Q4M_Exception('Connect failed: '. mysqli_connect_error(), mysqli_connect_errno());
+    }
+
+    return $this->_dbh;
+  }
+
+  /**
+   * Disconnect from MySQL server
+   *
+   * @access  public
+   * @return  bool
+   */
+  public function close()
+  {
+    return $this->_dbh->close();
+  }
+
+  /**
+   * Send a query
+   *
+   * @access  public
+   * @param   string  $sql
+   * @param   array   $param
+   * @return  Net_Q4M_Connection_ResultSet
+   * throws   Net_Q4M_Exception
+   */
+  public function query($sql, $param = array())
+  {
+    $sql = $this->buildSqlString($sql, $param);
+    $result = $this->_dbh->query($sql);
+    if ($result === false) {
+      throw new Net_Q4M_Exception('query() error: '. $this->_dbh->error, $this->_dbh->errno);
+    } else if ($result === true) {
+      return $result;
+    }
+
+    $data = array();
+    while ($_data = $result->fetch_array(MYSQL_BOTH)) {
+      $data[] = $_data;
+    }
+    $result->close();
+
+    $resultSet = new Net_Q4M_Connection_ResultSet();
+    $resultSet->setData($data);
+    return $resultSet;
+  }
+
+  /**
+   * Escapes special characters in a string for use in a SQL statement
+   *
+   * @access  protected
+   * @param   string $str
+   * @return  string      Returns the escaped string
+   */
+  protected function escape($str)
+  {
+    if (is_numeric($str)) {
+      return $str;
+    }
+    return "'". $this->_dbh->real_escape_string($str) ."'";
+  }
+}
+
+?>

Net_Q4M/trunk/Net/Q4M/Connection/MySQL.php

@@ -0,0 +1,150 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once 'Net/Q4M/Connection.php';
+require_once 'Net/Q4M/Connection/ResultSet.php';
+require_once 'Net/Q4M/Exception.php';
+
+class Net_Q4M_Connection_MySQL extends Net_Q4M_Connection
+{
+  /**
+   * Connect to MySQL server
+   *
+   * @access  public
+   * @param   mixed $dsn    DSN string or parsed DSN array
+   * @return  Net_Q4M_Connection_MySQL
+   * @throws  Net_Q4M_Exception
+   */
+  public function connect($dsn)
+  {
+    if (!is_array($dsn)) {
+      $dsn = Net_Q4M_Connection::parseDSN($dsn);
+    }
+
+    $_host = $dsn['host'] .':'. $dsn['port'];
+    $this->_dbh = mysql_connect($_host, $dsn['username'], $dsn['password']);
+    if ($this->_dbh === false) {
+      throw new Net_Q4M_Exception('Connect failed: '. mysql_error(), mysql_errno());
+    }
+    if (!mysql_select_db($dsn['database'], $this->_dbh)) {
+      throw new Net_Q4M_Exception('Connect failed: '. mysql_error(), mysql_errno());
+    }
+
+    return $this->_dbh;
+  }
+
+  /**
+   * Disconnect from MySQL server
+   *
+   * @access  public
+   * @return  bool
+   */
+  public function close()
+  {
+    return mysql_close($this->_dbh);
+  }
+
+  /**
+   * Send a query
+   *
+   * @access  public
+   * @param   string  $sql
+   * @param   array   $param
+   * @return  Net_Q4M_Connection_ResultSet
+   * throws   Net_Q4M_Exception
+   */
+  public function query($sql, $param = array())
+  {
+    $sql = $this->buildSqlString($sql, $param);
+    $result = mysql_query($sql, $this->_dbh);
+    if ($result === false) {
+      throw new Net_Q4M_Exception('query() error: '. mysql_error(), mysql_errno());
+    } else if ($result === true) {
+      return $result;
+    }
+
+    $data = array();
+    while ($_data = mysql_fetch_array($result, MYSQL_BOTH)) {
+      $data[] = $_data;
+    }
+    mysql_free_result($result);
+
+    $resultSet = new Net_Q4M_Connection_ResultSet();
+    $resultSet->setData($data);
+    return $resultSet;
+  }
+
+  /**
+   * Build sql string (binds a vale to a parameter)
+   *
+   * @access protected
+   * @param  string $sql
+   * @param  array $param
+   * @return string
+   */
+  protected function buildSqlString($sql, $param = array())
+  {
+    while (($pos = strpos($sql, '?')) !== false) {
+       $_value = array_shift($param);
+      if ($_value === null) break;
+
+      $_value = $this->escape($_value);
+      $_left = substr($sql, 0, $pos);
+      $_right = ($pos < strlen($sql))? substr($sql, $pos+1) : '';
+
+      $sql = $_left. $_value .$_right;
+    }
+
+    $this->debug('buildQueryString(): '. $sql);
+    return $sql;
+  }
+
+  /**
+   * Escapes special characters in a string for use in a SQL statement
+   *
+   * @access  protected
+   * @param   string $str
+   * @return  string      Returns the escaped string
+   */
+  protected function escape($str)
+  {
+    if (is_numeric($str)) {
+      return $str;
+    }
+    return "'". mysql_real_escape_string($str, $this->_dbh) ."'";
+  }
+}
+
+?>

Net_Q4M/trunk/Net/Q4M/Connection/PdoMySQL.php

@@ -0,0 +1,127 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once 'Net/Q4M/Connection.php';
+require_once 'Net/Q4M/Connection/ResultSet.php';
+require_once 'Net/Q4M/Exception.php';
+
+class Net_Q4M_Connection_PdoMySQL extends Net_Q4M_Connection
+{
+  /**
+   * Connect to MySQL server
+   *
+   * @access  public
+   * @param   mixed $dsn    DSN string or parsed DSN array
+   * @return  Net_Q4M_Connection_PdoMySQL
+   * @throws  Net_Q4M_Exception
+   */
+  public function connect($dsn)
+  {
+    if (!is_array($dsn)) {
+      $dsn = Net_Q4M_Connection::parseDSN($dsn);
+    }
+    $pdo_dsn = sprintf("mysql:host=%s;port=%d;dbname=%s",
+      $dsn['host'], $dsn['port'], $dsn['database']);
+
+    try {
+      $this->_dbh = new PDO($pdo_dsn, $dsn['username'], $dsn['password']);
+      $this->_dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+    } catch (PDOException $e) {
+      throw new Net_Q4M_Exception('Connect failed: '. $e->getMessage());
+    }
+
+    return $this->_dbh;
+  }
+
+  /**
+   * Disconnect from MySQL server
+   *
+   * @access  public
+   * @return  bool
+   */
+  public function close()
+  {
+    $this->_dbh = null;
+    return true;
+  }
+
+  /**
+   * Send a query
+   *
+   * @access  public
+   * @param   string  $sql
+   * @param   array   $param
+   * @return  Net_Q4M_Connection_ResultSet
+   * throws   Net_Q4M_Exception
+   */
+  public function query($sql, $param = array())
+  {
+    try {
+      $sth = $this->_dbh->prepare($sql);
+      if ($param) {
+        $sth->execute($param);
+      } else {
+        $sth->execute();
+      }
+      if (!$this->isSelectQuery($sql)) {
+        return true;
+      }
+    } catch (Exception $e) {
+      throw new Net_Q4M_Exception('query() error: '. $e->getMessage());
+    }
+
+    $data = $sth->fetchAll(PDO::FETCH_BOTH);
+    $resultSet = new Net_Q4M_Connection_ResultSet();
+    $resultSet->setData($data);
+    return $resultSet;
+  }
+
+  /**
+   * Returns true if SELECT, SHOW, EXPLAIN or DESCRIBE query string
+   *
+   * @access  protected
+   * @param   string $sql
+   * @return  bool
+   */
+  protected function isSelectQuery($sql)
+  {
+    if (preg_match('/^\s*(select|explain|show|describe)/i', $sql)) {
+      return true;
+    }
+    return false;
+  }
+}
+
+?>

Net_Q4M/trunk/Net/Q4M/Exception.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+class Net_Q4M_Exception extends Exception
+{
+}
+
+?>

Net_Q4M/trunk/Net/Q4M/Connection.php

@@ -0,0 +1,194 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+class Net_Q4M_Connection
+{
+  protected $_dbh;
+  protected $_debug;
+
+  /**
+   * Construct database connection object
+   *
+   * @access  public
+   * @param   string $dsn
+   */
+  public function __construct()
+  {
+    $this->_dbh = null;
+    $this->_debug = true;
+  }
+
+  /**
+   * Connect to database
+   *
+   * @access  public
+   * @param   mixed $dsn    DSN string or parsed DSN array
+   * @return  bool
+   */
+  public function connect($dsn)
+  {
+    return false;
+  }
+
+  /**
+   * Disconnect from MySQL server
+   *
+   * @access  public
+   * @return  bool
+   */
+  public function close()
+  {
+    return false;
+  }
+
+  /**
+   * Return database connection status
+   *
+   * @access  public
+   * @return  bool    true if connected, false if not connected
+   */
+  public function isConnected()
+  {
+    return ($this->_dbh)? true : false;
+  }
+
+  /**
+   * Send a query
+   *
+   * @access  public
+   * @param   string  $sql
+   * @param   array   $param
+   * @return  Net_Q4M_Connection_ResultSet
+   */
+  public function query($sql, $param = array())
+  {
+    return false;
+  }
+
+  /**
+   * Switch debug mode
+   *
+   * @access  public
+   * @param   bool  $debug
+   */
+  public function setDebug($debug)
+  {
+    $this->_debug = $debug;
+  }
+
+  /**
+   * Output debug message
+   *
+   * @access  protected
+   * @param   string $msg
+   */
+  protected function debug($msg)
+  {
+    if ($this->_debug) {
+      error_log($msg);
+    }
+  }
+
+
+  /**
+   * Create Net_Q4M_Connection Object, and connect to database
+   *
+   * @access  public
+   * @param   string $dsn    DSN string
+   * @return  Net_Q4M_Connection
+   */
+  public static function getConnection($dsn)
+  {
+    $conn = null;
+    $parsed_dsn = self::parseDSN($dsn);
+
+    switch ($parsed_dsn['phptype']) {
+    case 'mysql':
+      require_once 'Net/Q4M/Connection/MySQL.php';
+      $conn = new Net_Q4M_Connection_MySQL();
+      break;
+    case 'mysqli':
+      require_once 'Net/Q4M/Connection/MySQLi.php';
+      $conn = new Net_Q4M_Connection_MySQLi();
+      break;
+    case 'pdo_mysql':
+      require_once 'Net/Q4M/Connection/PdoMySQL.php';
+      $conn = new Net_Q4M_Connection_PdoMySQL();
+      break;
+    default:
+      $conn = new Net_Q4M_Connection();
+    }
+
+    return $conn;
+  }
+
+  /**
+   * Parse a DSN string (simplified implementation)
+   *
+   * The string format of DSN is only partly supported.
+   * (not support dbsyntax, protocol and options)
+   *
+   * @todo fully support DSN format
+   *
+   * @access  private
+   * @param   string $dsn
+   * @return  array  parsed data source value
+   */
+  protected static function parseDSN($dsn)
+  {
+    $parsed_dsn = array(
+      'phptype' => '',
+      'username' => '',
+      'password' => '',
+      'host' => '',
+      'port' => 3306,
+      'database' => ''
+    );
+
+    $pattern = '!^([a-z0-9_]+)://([^:@]+):?([^@]*)@([^/:]+):?(\d*)/([^\?\./\\\]+)!';
+    if (preg_match($pattern, $dsn, $matches)) {
+      $parsed_dsn['phptype'] = $matches[1];
+      $parsed_dsn['username'] = $matches[2];
+      $parsed_dsn['password'] = ($matches[3])? $matches[3] : $parsed_dsn['password'];
+      $parsed_dsn['host'] = $matches[4];
+      $parsed_dsn['port'] = ($matches[5])? $matches[5] : $parsed_dsn['port'];
+      $parsed_dsn['database'] = $matches[6];
+    }
+
+    return $parsed_dsn;
+  }
+}
+
+?>

Net_Q4M/trunk/Net/Q4M.php

@@ -0,0 +1,280 @@
+<?php
+/**
+ * Net_Q4M
+ *
+ * Q4M (Queue for MySQL)
+ * @link http://q4m.31tools.com/
+ *
+ * @category  Net
+ * @package   Net_Q4M
+ * @version   0.1.0
+ * @author    castor <castor.4bit@gmail.com>
+ * @license   http://opensource.org/licenses/mit-license.html
+ *
+ * The MIT License
+ * Copyright (c) 2008 castor <castor.4bit@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once 'Net/Q4M/Connection.php';
+require_once 'Net/Q4M/Connection/ResultSet.php';
+
+class Net_Q4M
+{
+  private $_conn;
+  private $_dsn;
+
+  /**
+   * Construct a new Q4M object.
+   *
+   * @access  public
+   * @param   string $dsn   PEAR::DB style DSN string (i.e.: mysql://user:pass@localhost:3306/database)
+   */
+  public function __construct($dsn)
+  {
+    $this->_dsn = $dsn;
+    $this->_conn = Net_Q4M_Connection::getConnection($dsn);
+  }
+
+  /**
+   * Establish connection to MySQL server
+   *
+   * @access public
+   * @return bool
+   * @throws Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  public function connect()
+  {
+    if (!$this->_conn->isConnected()) {
+      $this->_conn->connect($this->_dsn);
+    }
+    return $this->_conn->isConnected();
+  }
+
+  /**
+   * Disconnect from MySQL server
+   *
+   * @access public
+   * @return bool
+   */
+  public function disconnect()
+  {
+    if ($this->_conn->isConnected()) {
+      return $this->_conn->close();
+    }
+    return true;
+  }
+
+  /**
+   * Returns an array contains the first queue
+   *
+   * <code>
+   * $queue = new Net_Q4M();
+   * $queue->connect('mysql://user:pass@localhost:3306/database');
+   *
+   * $row = $queue->dequeue('my_queue');
+   * //$row = $queue->dequeue('my_queue', 5);   // set timeout to 5 seconds
+   * //$row = $queue->dequeue('my_queue', 'my_queue2', 'my_queue3', 10);
+   * if (process_row($row)) {
+   *   $queue->abort();
+   * }
+   * $queue->end();
+   * $queue->disconnect();
+   * </code>
+   *
+   * @access  public
+   * @param   string $table_name1[$table_name2, $table_name3, ...]
+   * @param   int $timeout
+   * @return  array     returns first queue row, or false if not available any data
+   * @throws  Net_Q4M_Exception
+   */
+  public function dequeue()
+  {
+    $args = func_get_args();
+    $tables = $args;
+
+    if (func_num_args() == 0) {
+      throw new Net_Q4M_Exception('dequeue($table_name[, $table_name...][, $timeout]): argument error');
+    } else if (func_num_args() >= 2) {
+      array_pop($tables);
+    }
+
+    $index = $this->getTableIndex($args);
+    if (($index == 0) || ($index > count($tables))) {
+      return false;
+    }
+    return $this->receiveData($tables[$index - 1]);
+  }
+
+  /**
+   * Adds data to the queue
+   *
+   * @access  public
+   * @param   string $table
+   * @param   array $values
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  public function enqueue($table, $values)
+  {
+    $sql_columns = '';
+    $sql_values = '';
+    $param = array();
+
+    foreach ($values as $key => $value) {
+      $sql_columns .= ($sql_columns)? ",$key": $key;
+      $sql_values .= ($sql_values)? ',?' : '?';
+      $param[] = $value;
+    }
+    $sql = 'INSERT INTO '. $table .'('
+      . $sql_columns
+      . ') VALUES ('
+      . $sql_values
+      . ')';
+
+    return $this->_conn->query($sql, $param);
+  }
+
+  /**
+   * Count items in the queue
+   *
+   * @access  public
+   * @param   string $table
+   * @return  int
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  public function count($table)
+  {
+    $sql = 'SELECT count(*) FROM '. $table;
+
+    $result = $this->_conn->query($sql);
+    if ($result !== false) {
+      $data = $result->fetchRow();
+      if ($data !== false) {
+        return intval($data[0]);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Return ithe index of the table.
+   *
+   * When any data becomes available, queue_wait function will
+   * return the index of the table. The tables are prioritized
+   * from left to right, i.e. if more than one table contains
+   * any messages, the index of the leftmost table is returned.
+   * If none of the table have any data available, 0 is returned.
+   *
+   * @access  protected
+   * @param   array $args
+   * @return  int   table index (return 0, if not available any data)
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  protected function getTableIndex($args)
+  {
+    $sql_cond = '';
+    for ($i=0; $i<count($args); ++$i) {
+      $sql_cond .= ($sql_cond)? ',?' : '?';
+    }
+    $sql = 'SELECT queue_wait('. $sql_cond .')';
+
+    $result = $this->_conn->query($sql, $args);
+    if ($data = $result->fetchRow()) {
+      return $data[0];
+    }
+    return 0;
+  }
+
+  /**
+   * Receive data
+   *
+   * only one row becomes ready at once
+   *
+   * @access  protcted
+   * @param   string $table   table name
+   * @return  array
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  protected function receiveData($table)
+  {
+    if (preg_match('/^([^:\s]+)/', trim($table), $matches)) {
+      $table = $matches[1];
+    } else {
+      throw new Net_Q4M_Exception('Invalid table name: '. $table);
+    }
+
+    $sql = 'SELECT * FROM '. $table;
+    $result = $this->_conn->query($sql);
+    return $result->fetchRow();
+  }
+
+  /**
+   * Remove owned-row from the table, and return to NON-OWNER mode
+   *
+   * @access  public
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  public function end()
+  {
+    // always return 1
+    $this->_conn->query('SELECT queue_end()');
+  }
+
+  /**
+   * Returns owned-row to the table, and return to NON-OWNER mode
+   *
+   * @access  public
+   * @return  bool
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  public function abort()
+  {
+    // always return 1
+    $this->_conn->query('SELECT queue_abort()');
+  }
+
+  /**
+   * Returns queue status
+   *
+   * Returns parsed output of `SHOW ENGINE QUEUE STATUS`
+   *
+   * @access  public
+   * @return  array   queue status
+   * @throws  Net_Q4M_Exception Low-level errors will bubble up through this method.
+   */
+  public function status()
+  {
+    $sql = 'SHOW ENGINE QUEUE STATUS';
+    $result = $this->_conn->query($sql);
+
+    $status = array();
+    $lines = $result->fetchRow();
+    if ($lines) {
+      $lines = explode("\n", $lines[2]);
+      foreach ($lines as $line) {
+        if (preg_match('/^([^\s]+)\s+(\d+)$/', $line, $matches)) {
+          $status[$matches[1]] = $matches[2];
+        }
+      }
+    }
+    return $status;
+  }
+}
+?>