diff options
-rw-r--r-- | application/config.php | 2 | ||||
-rw-r--r-- | modules/database/classes/driver/mysql/query.php | 199 | ||||
-rw-r--r-- | modules/database/classes/driver/pdo/db.php | 147 | ||||
-rw-r--r-- | modules/database/classes/driver/pdo/query.php | 249 | ||||
-rw-r--r-- | system/classes/misc.php | 120 |
5 files changed, 392 insertions, 325 deletions
diff --git a/application/config.php b/application/config.php index 132b989..e0c1463 100644 --- a/application/config.php +++ b/application/config.php @@ -18,7 +18,7 @@ Config::$data = array( 'connection'=>'mysql:host=localhost;dbname=phpixie',
// 'db' and 'host' are required if you use Mysql driver
- 'db' => 'webcomics',
+ 'db' => 'phpixie',
'host'=>'localhost'
)
)
diff --git a/modules/database/classes/driver/mysql/query.php b/modules/database/classes/driver/mysql/query.php index d2767b9..e0ceacd 100644 --- a/modules/database/classes/driver/mysql/query.php +++ b/modules/database/classes/driver/mysql/query.php @@ -3,197 +3,20 @@ /**
* Mysqli implementation of the database Query
*/
-class Query_Mysql_Driver extends Query_Database{
-
- /**
- * If a string is passed escapes a field by enclosing it in `` quotes.
- * If you pass an Expression_Database object the value will be inserted into the query unescaped
- *
- * @param mixed $field Field to be escaped or an Expression_Database object
- * if the field must not be escaped
- * @return string Escaped field representation
- * @access public
- * @see Expression_Database
- */
- public function escape_field($field) {
- if (is_object($field) && get_class($field) == 'Expression_Database')
- return $field->value.' ';
- $field = explode('.', $field);
- if (count($field) == 1)
- array_unshift($field,$this->lastAlias());
- $str = '`'.$field[0].'`.';
- if (trim($field[1]) == '*')
- return $str.'* ';
- return $str."`{$field[1]}` ";
- }
-
- /**
- * Replaces the value with ? and appends it to the parameters array
- * If you pass an Expression_Database object the value will be inserted into the query unescaped
- * @param mixed $val Value to be escaped or an Expression_Database object
- * if the value must not be escaped
- * @param array &$params Reference to parameters array
- * @return string Escaped value representation
- * @access public
- */
- public function escape_value($val,&$params) {
- if (is_object($val) && get_class($val) == 'Expression_Database')
- return $val->value.' ';
- $params[] = $val;
- return '? ';
- }
-
- /**
- * Builds a query and fills the $params array with parameter values
- *
- * @return array An array with a prepared query string and an array of parameters
- * @access public
- */
- public function query() {
-
- $query = '';
- $params = array();
- if ($this->_type == 'insert') {
- $query.= "INSERT INTO `{$this->_table}`";
- $columns = '';
- $values = '';
- $first = true;
- foreach($this->_data as $key => $val) {
- if (!$first) {
- $values.= ',';
- $columns.= ',';
- }else {
- $first=false;
- }
- $columns.= "`{$key}` ";
- $values.=$this->escape_value($val,$params);
- }
- $query.= "({$columns}) VALUES({$values})";
- }else{
- if ($this->_type == 'select'){
- $query.= "SELECT ";
- if($this->_fields==null){
- $query.= "* ";
- }else{
- $first = true;
- foreach($this->_fields as $f) {
- if (!$first) {
- $query.=", ";
- }else {
- $first = false;
- }
- $query.="{$this->escape_field($f)} ";
- }
- }
- $query.= "FROM `{$this->_table}` ";
- }
- if ($this->_type == 'count') {
- $query.= "SELECT COUNT(*) as `count` FROM `{$this->_table}` ";
- }
- if($this->_type=='delete')
- $query.= "DELETE FROM `{$this->_table}` ";
- if($this->_type=='update'){
- $query.= "UPDATE `{$this->_table}` SET ";
- $first = true;
- foreach($this->_data as $key=>$val){
- if (!$first) {
- $query.=',';
- }else {
- $first=false;
- }
- $query.= "`{$key}`=".$this->escape_value($val,$params);
- }
- }
-
- foreach($this->_joins as $join) {
- $table = $join[0];
- if (is_array($table)){
- $table = "`{$table[0]}` as `{$table[1]}`";
- }else {
- $table="`{$table}`";
- }
- $query.= strtoupper($join[1])." JOIN {$table} ON ".$this->get_condition_query($join[2],$params,true,true);
- }
-
- if (!empty($this->_conditions)) {
- $query.="WHERE ".$this->get_condition_query($this->_conditions,$params,true);
- }
- if (($this->_type == 'select' || $this->_type == 'count') && $this->_group_by!=null) {
- $query.="GROUP BY ".$this->escape_field($this->_group_by);
- }
- if (($this->_type == 'select' || $this->_type == 'count') && !empty($this->_having)) {
- $query.="HAVING ".$this->get_condition_query($this->_having,$params,true);
- }
-
- if ($this->_type == 'select' && !empty($this->_orderby)) {
- $query.="ORDER BY ";
- $first = true;
- foreach($this->_orderby as $order) {
- if (!$first) {
- $query.=',';
- }else {
- $first=false;
- }
- $query.= $this->escape_field($order[0]);
- if (isset($order[1])) {
- $dir = strtoupper($order[1]);
- $query.=$dir." ";
- }
- }
- }
- if($this->_type != 'count'){
- if ($this->_limit != null)
- $query.= "LIMIT {$this->_limit} ";
- if ($this->_offset != null)
- $query.= "OFFSET {$this->_offset} ";
- }
-
- }
-
- return array($query,$params);
- }
+class Query_Mysql_Driver extends Query_PDO_Driver {
/**
- * Recursively parses conditions array into a query string
+ * Creates a new query object, sets mysql specific parameters to get correct queries
*
- * @param array $p Element of the cobditions array
- * @param array &$params Reference to parameters array
- * @param boolean $skip_first_operator Flag to skip the first logical operator in a query
- * to prevent AND or OR to be at the beginning of the query
- * @param boolean $value_is_field Flag if the the value in the logical operations should
- * be treated as a field. E.g. for joins where the fields are
- * compared between themselves and not with actual values
- * @return string String representation of the conditions
- * @access public
- * @throws Exception If condition cannot be parsed
+ * @param DB $db Database connection
+ * @param string $type Query type. Available types: select, update, insert, delete, count
+ * @return void
+ * @access public
+ * @see Query_PDO_Driver::__construct()
*/
- public function get_condition_query($p,&$params,$skip_first_operator,$value_is_field=false) {
- if (isset($p['field'])) {
- if ($value_is_field){
- $param = $this->escape_field($p['value']);
- }else {
- $param = $this->escape_value($p['value'],$params);
- }
- return $this->escape_field($p['field']).' '.$p['operator'].' '.$param;
- }
- if (isset($p['logic'])) {
- return ($skip_first_operator?'':strtoupper($p['logic'])).' '
- .$this->get_condition_query($p['conditions'],$params,false,$value_is_field);
- }
-
- $conds = '';
- $skip=$skip_first_operator||(count($p) > 1);
- foreach($p as $q) {
- $conds.=$this->get_condition_query($q,$params,$skip,$value_is_field);
- $skip=false;
- }
- if (count($p) > 1 && !$skip_first_operator)
- return "( ".$conds." ) ";
- return $conds;
-
- throw new Exception("Cannot parse condition:\n".var_export($p,true));
+ public function __construct($db, $type) {
+ Query_Database::__construct($db, $type);
+ $this->_db_type = 'mysql';
}
-
-
-
+
}
\ No newline at end of file diff --git a/modules/database/classes/driver/pdo/db.php b/modules/database/classes/driver/pdo/db.php index 89c7165..18f278d 100644 --- a/modules/database/classes/driver/pdo/db.php +++ b/modules/database/classes/driver/pdo/db.php @@ -1,70 +1,79 @@ -<?php - -/** - * PDO Database implementation. - */ -class DB_PDO_Driver extends DB{ - - /** - * Connection object - * @var PDO - * @access public - * @link http://php.net/manual/en/class.pdo.php - */ - public $conn; - - /** - * Initializes database connection - * - * @param string $config Name of the connection to initialize - * @return void - * @access public - */ - public function __construct($config) { - $this->conn = new PDO( - Config::get("database.{$config}.connection"), - Config::get("database.{$config}.user",''), - Config::get("database.{$config}.password",'') - ); - } - - /** - * Builds a new Query implementation - * - * @param string $type Query type. Available types: select,update,insert,delete,count - * @return Query_PDO_Driver Returns a PDO implementation of a Query. - * @access public - * @see Query_Database - */ - public function build_query($type) { - return new Query_PDO_Driver($this,$type); - } - - /** - * Gets the id of the last inserted row. - * - * @return mixed Row id - * @access public - */ - public function get_insert_id() { - return $this->conn->lastInsertId(); - } - - /** - * Executes a prepared statement query - * - * @param string $query A prepared statement query - * @param array $params Parameters for the query - * @return Result_PDO_Driver PDO implementation of a database result - * @access public - * @throws Exception If the query resulted in an error - * @see Database_Result - */ - public function execute($query, $params = array()) { - $cursor = $this->conn->prepare($query); - if(!$cursor->execute($params)) - throw new Exception("Database error: ".implode(' ',$this->conn->errorInfo())." \n in query:\n{$query}"); - - return new Result_PDO_Driver($cursor); - } +<?php
+
+/**
+ * PDO Database implementation.
+ */
+class DB_PDO_Driver extends DB{
+
+ /**
+ * Connection object
+ * @var PDO
+ * @access public
+ * @link http://php.net/manual/en/class.pdo.php
+ */
+ public $conn;
+
+ /**
+ * Type of the database, e.g. mysql, pgsql etc.
+ * @var string
+ * @access public
+ */
+ public $db_type;
+
+ /**
+ * Initializes database connection
+ *
+ * @param string $config Name of the connection to initialize
+ * @return void
+ * @access public
+ */
+ public function __construct($config) {
+ $this->conn = new PDO(
+ Config::get("database.{$config}.connection"),
+ Config::get("database.{$config}.user",''),
+ Config::get("database.{$config}.password",'')
+ );
+ $this->db_type=strtolower(str_replace('PDO_', '', $this->conn->getAttribute(PDO::ATTR_DRIVER_NAME)));
+ }
+
+ /**
+ * Builds a new Query implementation
+ *
+ * @param string $type Query type. Available types: select,update,insert,delete,count
+ * @return Query_PDO_Driver Returns a PDO implementation of a Query.
+ * @access public
+ * @see Query_Database
+ */
+ public function build_query($type) {
+ return new Query_PDO_Driver($this,$type);
+ }
+
+ /**
+ * Gets the id of the last inserted row.
+ *
+ * @return mixed Row id
+ * @access public
+ */
+ public function get_insert_id() {
+ if ($this->db_type == 'pgsql')
+ return $this->execute('SELECT lastval() as id')->current()->id;
+ return $this->conn->lastInsertId();
+ }
+
+ /**
+ * Executes a prepared statement query
+ *
+ * @param string $query A prepared statement query
+ * @param array $params Parameters for the query
+ * @return Result_PDO_Driver PDO implementation of a database result
+ * @access public
+ * @throws Exception If the query resulted in an error
+ * @see Database_Result
+ */
+ public function execute($query, $params = array()) {
+ $cursor = $this->conn->prepare($query);
+ if(!$cursor->execute($params))
+ throw new Exception("Database error: ".implode(' ',$this->conn->errorInfo())." \n in query:\n{$query}");
+ return new Result_PDO_Driver($cursor);
+ }
}
\ No newline at end of file diff --git a/modules/database/classes/driver/pdo/query.php b/modules/database/classes/driver/pdo/query.php index 4a3d7c2..963a95a 100644 --- a/modules/database/classes/driver/pdo/query.php +++ b/modules/database/classes/driver/pdo/query.php @@ -1,8 +1,243 @@ -<?php - -/** - * PDO Database Query implementation. Mimics Mysql implementation. - */ -class Query_PDO_Driver extends Query_Mysql_Driver{ - +<?php
+
+/**
+ * PDO implementation of the database Query
+ */
+class Query_PDO_Driver extends Query_Database {
+
+ /**
+ * Type of the database, e.g. mysql, pgsql etc.
+ * @var string
+ * @access public
+ */
+ protected $_db_type;
+
+ /**
+ * Character to use for quoting fields
+ * @var string
+ * @access public
+ */
+ protected $_quote;
+
+ /**
+ * Creates a new query object, checks which driver we are using and set the character used for quoting
+ *
+ * @param DB $db Database connection
+ * @param string $type Query type. Available types: select, update, insert, delete, count
+ * @return void
+ * @access public
+ * @see Query_Database::__construct()
+ */
+ public function __construct($db, $type) {
+ parent::__construct($db, $type);
+ $this->_db_type = $this->_db->db_type;
+ $this->_quote=$this->_db_type=='mysql'?'`':'"';
+ }
+
+ /**
+ * Puts quotes around a string
+ *
+ * @param string $str String to be enclosed in quotes
+ * @return string String surrounded with quotes
+ * @access protected
+ */
+ protected function quote($str) {
+ return $this->_quote.$str.$this->_quote;
+ }
+
+ /**
+ * If a string is passed escapes a field by enclosing it in specified quotes.
+ * If you pass an Expression_Database object the value will be inserted into the query unescaped
+ *
+ * @param mixed $field Field to be escaped or an Expression_Database object
+ * if the field must not be escaped
+ * @return string Escaped field representation
+ * @access public
+ * @see Expression_Database
+ */
+ public function escape_field($field) {
+ if (is_object($field) && get_class($field) == 'Expression_Database')
+ return $field->value.' ';
+ $field = explode('.', $field);
+ if (count($field) == 1)
+ array_unshift($field,$this->lastAlias());
+ $str = $this->quote($field[0]).'.';
+ if (trim($field[1]) == '*')
+ return $str.'* ';
+ return $str.$this->quote($field[1]);
+ }
+
+ /**
+ * Replaces the value with ? and appends it to the parameters array
+ * If you pass an Expression_Database object the value will be inserted into the query unescaped
+ * @param mixed $val Value to be escaped or an Expression_Database object
+ * if the value must not be escaped
+ * @param array &$params Reference to parameters array
+ * @return string Escaped value representation
+ * @access public
+ */
+ public function escape_value($val,&$params) {
+ if (is_object($val) && get_class($val) == 'Expression_Database')
+ return $val->value.' ';
+ $params[] = $val;
+ return '? ';
+ }
+
+ /**
+ * Builds a query and fills the $params array with parameter values
+ *
+ * @return array An array with a prepared query string and an array of parameters
+ * @access public
+ */
+ public function query() {
+
+ $query = '';
+ $params = array();
+ if ($this->_type == 'insert') {
+ $query.= "INSERT INTO {$this->quote($this->_table)} ";
+ if (empty($this->_data) && $this->_db_type == 'pgsql'){
+ $query.= "DEFAULT VALUES ";
+ }else{
+ $columns = '';
+ $values = '';
+ $first = true;
+ foreach($this->_data as $key => $val) {
+ if (!$first) {
+ $values.= ',';
+ $columns.= ',';
+ }else {
+ $first=false;
+ }
+ $columns.= $this->quote($key)." ";
+ $values.=$this->escape_value($val,$params);
+ }
+ $query.= "({$columns}) VALUES({$values})";
+ }
+ }else{
+ if ($this->_type == 'select'){
+ $query.= "SELECT ";
+ if($this->_fields==null){
+ $query.= "* ";
+ }else{
+ $first = true;
+ foreach($this->_fields as $f) {
+ if (!$first) {
+ $query.=", ";
+ }else {
+ $first = false;
+ }
+ $query.="{$this->escape_field($f)} ";
+ }
+ }
+ $query.= "FROM {$this->quote($this->_table)} ";
+ }
+ if ($this->_type == 'count') {
+ $query.= "SELECT COUNT(*) as {$this->quote('count')} FROM {$this->quote($this->_table)} ";
+ }
+ if($this->_type=='delete')
+ $query.= "DELETE FROM {$this->quote($this->_table)} ";
+ if($this->_type=='update'){
+ $query.= "UPDATE {$this->quote($this->_table)} SET ";
+ $first = true;
+ foreach($this->_data as $key=>$val){
+ if (!$first) {
+ $query.=',';
+ }else {
+ $first=false;
+ }
+ $query.= "{$this->quote($key)}=".$this->escape_value($val,$params);
+ }
+ }
+
+ foreach($this->_joins as $join) {
+ $table = $join[0];
+ if (is_array($table)){
+ $table = "{$this->quote($table[0])} as {$this->quote($table[1])}";
+ }else {
+ $table="{$this->quote($table)}";
+ }
+ $query.= strtoupper($join[1])." JOIN {$table} ON ".$this->get_condition_query($join[2],$params,true,true);
+ }
+
+ if (!empty($this->_conditions)) {
+ $query.="WHERE ".$this->get_condition_query($this->_conditions,$params,true);
+ }
+ if (($this->_type == 'select' || $this->_type == 'count') && $this->_group_by!=null) {
+ $query.="GROUP BY ".$this->escape_field($this->_group_by);
+ }
+ if (($this->_type == 'select' || $this->_type == 'count') && !empty($this->_having)) {
+ $query.="HAVING ".$this->get_condition_query($this->_having,$params,true);
+ }
+
+ if ($this->_type == 'select' && !empty($this->_orderby)) {
+ $query.="ORDER BY ";
+ $first = true;
+ foreach($this->_orderby as $order) {
+ if (!$first) {
+ $query.=',';
+ }else {
+ $first=false;
+ }
+ $query.= $this->escape_field($order[0]);
+ if (isset($order[1])) {
+ $dir = strtoupper($order[1]);
+ $query.=$dir." ";
+ }
+ }
+ }
+ if($this->_type != 'count'){
+ if ($this->_limit != null)
+ $query.= "LIMIT {$this->_limit} ";
+ if ($this->_offset != null)
+ $query.= "OFFSET {$this->_offset} ";
+ }
+
+ }
+
+ return array($query,$params);
+ }
+
+ /**
+ * Recursively parses conditions array into a query string
+ *
+ * @param array $p Element of the cobditions array
+ * @param array &$params Reference to parameters array
+ * @param boolean $skip_first_operator Flag to skip the first logical operator in a query
+ * to prevent AND or OR to be at the beginning of the query
+ * @param boolean $value_is_field Flag if the the value in the logical operations should
+ * be treated as a field. E.g. for joins where the fields are
+ * compared between themselves and not with actual values
+ * @return string String representation of the conditions
+ * @access public
+ * @throws Exception If condition cannot be parsed
+ */
+ public function get_condition_query($p,&$params,$skip_first_operator,$value_is_field=false) {
+ if (isset($p['field'])) {
+ if ($value_is_field){
+ $param = $this->escape_field($p['value']);
+ }else {
+ $param = $this->escape_value($p['value'],$params);
+ }
+ return $this->escape_field($p['field']).' '.$p['operator'].' '.$param;
+ }
+ if (isset($p['logic'])) {
+ return ($skip_first_operator?'':strtoupper($p['logic'])).' '
+ .$this->get_condition_query($p['conditions'],$params,false,$value_is_field);
+ }
+
+ $conds = '';
+ $skip=$skip_first_operator||(count($p) > 1);
+ foreach($p as $q) {
+ $conds.=$this->get_condition_query($q,$params,$skip,$value_is_field);
+ $skip=false;
+ }
+ if (count($p) > 1 && !$skip_first_operator)
+ return "( ".$conds." ) ";
+ return $conds;
+
+ throw new Exception("Cannot parse condition:\n".var_export($p,true));
+ }
+
+
+
}
\ No newline at end of file diff --git a/system/classes/misc.php b/system/classes/misc.php index ab04b11..8aad4ec 100644 --- a/system/classes/misc.php +++ b/system/classes/misc.php @@ -1,61 +1,61 @@ -<?php - -/** - * Miscellaneous useful functions - */ -class Misc{ - - /** - * Retrieve value from array by key, with default value support. - * - * @param array $array Input array - * @param string $key Key to retrieve from the array - * @param mixed $default Default value to return if the key is not found - * @return mixed An array value if it was found or default value if it is not - * @access public - * @static - */ - public static function arr($array,$key,$default=null){ - if (isset($array[$key])) - return $array[$key]; - return $default; - } - - /** - * Find full path to either a class or view by name. - * It will search in the /system folder first, then the /application folder - * and then in all enabled modules. - * - * @param string $type Type of the file to find. Either 'class' or 'view' - * @param string $name Name of the file to find - * @return boolean Return Full path to the file or False if it is not found - * @access public - * @static - */ - public static function find_file($type, $name) { - $folders = array(SYSDIR, APPDIR); - foreach(Config::get('modules') as $module) - $folders[] = MODDIR.$module.'/'; - - if($type=='class'){ - $subfolder = 'classes/'; - $dirs = array_reverse(explode('_', strtolower($name))); - $fname = array_pop($dirs); - $subfolder.=implode('/',$dirs).'/'; - } - - if ($type == 'view') { - $subfolder = 'views/'; - $fname=$name; - } - - foreach($folders as $folder) { - $file = $folder.$subfolder.$fname.'.php'; - - if (file_exists($file)) { - return($file); - } - } - return false; - } +<?php
+
+/**
+ * Miscellaneous useful functions
+ */
+class Misc{
+
+ /**
+ * Retrieve value from array by key, with default value support.
+ *
+ * @param array $array Input array
+ * @param string $key Key to retrieve from the array
+ * @param mixed $default Default value to return if the key is not found
+ * @return mixed An array value if it was found or default value if it is not
+ * @access public
+ * @static
+ */
+ public static function arr($array,$key,$default=null){
+ if (isset($array[$key]))
+ return $array[$key];
+ return $default;
+ }
+
+ /**
+ * Find full path to either a class or view by name.
+ * It will search in the /application folder first, then all enabled modules
+ * and then the /system folder
+ *
+ * @param string $type Type of the file to find. Either 'class' or 'view'
+ * @param string $name Name of the file to find
+ * @return boolean Return Full path to the file or False if it is not found
+ * @access public
+ * @static
+ */
+ public static function find_file($type, $name) {
+ $folders = array(APPDIR);
+ foreach(Config::get('modules') as $module)
+ $folders[] = MODDIR.$module.'/';
+ $folders[]=SYSDIR;
+ if($type=='class'){
+ $subfolder = 'classes/';
+ $dirs = array_reverse(explode('_', strtolower($name)));
+ $fname = array_pop($dirs);
+ $subfolder.=implode('/',$dirs).'/';
+ }
+
+ if ($type == 'view') {
+ $subfolder = 'views/';
+ $fname=$name;
+ }
+
+ foreach($folders as $folder) {
+ $file = $folder.$subfolder.$fname.'.php';
+
+ if (file_exists($file)) {
+ return($file);
+ }
+ }
+ return false;
+ }
}
\ No newline at end of file |