diff --git a/lib/Doctrine/Connection/Mysql.php b/lib/Doctrine/Connection/Mysql.php index 478300988..7a9845243 100644 --- a/lib/Doctrine/Connection/Mysql.php +++ b/lib/Doctrine/Connection/Mysql.php @@ -24,146 +24,16 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common { return 'RLIKE'; } /** - * deletes all data access object from the collection - * @param Doctrine_Collection $coll - */ - - /** - public function deleteCollection(Doctrine_Collection $coll) { - - $a = $coll->getTable()->getCompositePaths(); - $a = array_merge(array($coll->getTable()->getComponentName()),$a); - - $graph = new Doctrine_Query(); - foreach($coll as $k=>$record) { - switch($record->getState()): - case Doctrine_Record::STATE_DIRTY: - case Doctrine_Record::STATE_CLEAN: - $ids[] = $record->getID(); - break; - endswitch; - } - if(empty($ids)) - return array(); - - $graph->parseQuery("FROM ".implode(", ",$a)." WHERE ".$coll->getTable()->getTableName().".id IN(".implode(", ",$ids).")"); - - $query = $graph->buildDelete(); - - $this->getDBH()->query($query); - return $ids; - } - */ - /** - * returns maximum identifier values + * Returns string to concatenate two or more string parameters * - * @param array $names an array of component names - * @return array + * @param string $value1 + * @param string $value2 + * @param string $values... + * @return string a concatenation of two or more strings */ - public function getMaximumValues2(array $names) { - $values = array(); - foreach($names as $name) { - $table = $this->tables[$name]; - $keys = $table->getPrimaryKeys(); - $tablename = $table->getTableName(); - - if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) { - // record uses auto_increment column - - $sql[] = "SELECT MAX(".$tablename.".".$table->getIdentifier().") as $tablename FROM ".$tablename; - $values[$tablename] = 0; - $array[] = $tablename; - } - } - $sql = implode(" UNION ",$sql); - $stmt = $this->getDBH()->query($sql); - $data = $stmt->fetchAll(PDO::FETCH_NUM); - - foreach($data as $k => $v) { - $values[$array[$k]] = $v[0]; - } - return $values; + public function concat($value1, $value2) { + $args = func_get_args(); + return "CONCAT(".implode(', ', $args).")"; } - /** - * bulkInsert - * inserts all the objects in the pending insert list into database - * TODO: THIS IS NOT WORKING YET AS THERE ARE BUGS IN COMPONENTS USING SELF-REFERENCENCING - * - * @return boolean - */ - - /** - public function bulkInsert() { - if(empty($this->insert)) - return false; - - foreach($this->insert as $name => $inserts) { - if( ! isset($inserts[0])) - continue; - - $record = $inserts[0]; - $table = $record->getTable(); - $seq = $table->getSequenceName(); - $keys = $table->getPrimaryKeys(); - - $marks = array(); - $params = array(); - foreach($inserts as $k => $record) { - $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreSave($record); - // listen the onPreInsert event - $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreInsert($record); - - $array = $record->getPrepared(); - - if(isset($this->validator)) { - if( ! $this->validator->validateRecord($record)) { - continue; - } - } - - $key = implode(", ",array_keys($array)); - if( ! isset($params[$key])) - $params[$key] = array(); - - $marks[$key][] = "(".substr(str_repeat("?, ",count($array)),0,-2).")"; - $params[$key] = array_merge($params[$key], array_values($array)); - - - // listen the onInsert event - $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record); - - $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record); - } - - if( ! empty($marks)) { - foreach($marks as $key => $list) { - $query = "INSERT INTO ".$table->getTableName()." (".$key.") VALUES ".implode(", ", $list); - $stmt = $this->getDBH()->prepare($query); - $stmt->execute($params[$key]); - } - } - if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) { - - // record uses auto_increment column - - $sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName(); - $stmt = $this->getDBH()->query($sql); - $data = $stmt->fetch(PDO::FETCH_NUM); - $id = $data[0]; - $stmt->closeCursor(); - - foreach(array_reverse($inserts) as $record) { - - $record->setID((int) $id); - $id--; - } - } - } - - $this->insert = array(); - return true; - } - */ - } diff --git a/lib/Doctrine/Connection/Oracle.php b/lib/Doctrine/Connection/Oracle.php index 5e9d46d49..c08a07634 100644 --- a/lib/Doctrine/Connection/Oracle.php +++ b/lib/Doctrine/Connection/Oracle.php @@ -28,5 +28,44 @@ class Doctrine_Connection_Oracle extends Doctrine_Connection { $data = $stmt->fetch(PDO::FETCH_NUM); return $data[0]; } + /** + * Return string to call a variable with the current timestamp inside an SQL statement + * There are three special variables for current date and time: + * - CURRENT_TIMESTAMP (date and time, TIMESTAMP type) + * - CURRENT_DATE (date, DATE type) + * - CURRENT_TIME (time, TIME type) + * + * @return string to call a variable with the current timestamp + * @access public + */ + function now($type = 'timestamp') + { + switch ($type) { + case 'date': + case 'time': + case 'timestamp': + default: + return 'TO_CHAR(CURRENT_TIMESTAMP, \'YYYY-MM-DD HH24:MI:SS\')'; + } + } + /** + * substring + * + * @return string SQL substring function with given parameters + */ + function substring($value, $position = 1, $length = null) { + if($length !== null) + return "SUBSTR($value, $position, $length)"; + + return "SUBSTR($value, $position)"; + } + /** + * random + * + * @return string an oracle SQL string that generates a float between 0 and 1 + */ + function random() { + return 'dbms_random.value'; + } } diff --git a/lib/Doctrine/Connection/Pgsql.php b/lib/Doctrine/Connection/Pgsql.php index b76fd8c9e..bf0fa7889 100644 --- a/lib/Doctrine/Connection/Pgsql.php +++ b/lib/Doctrine/Connection/Pgsql.php @@ -15,13 +15,21 @@ class Doctrine_Connection_Pgsql extends Doctrine_Connection_Common { return $data[0]; } /** - * returns the regular expression operator - * (implemented by the connection drivers) + * getRegexpOperator * - * @return string + * @return string the regular expression operator */ public function getRegexpOperator() { return 'SIMILAR TO'; } + /** + * return string to call a function to get random value inside an SQL statement + * + * @return return string to generate float between 0 and 1 + * @access public + */ + public function random() { + return 'RANDOM()'; + } } diff --git a/lib/Doctrine/DataDict/Mssql.php b/lib/Doctrine/DataDict/Mssql.php index 22a635f19..fa1887cbc 100644 --- a/lib/Doctrine/DataDict/Mssql.php +++ b/lib/Doctrine/DataDict/Mssql.php @@ -24,10 +24,137 @@ * @url http://www.phpdoctrine.com * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) * @version $Id$ */ class Doctrine_DataDict_Mssql extends Doctrine_DataDict { + /** + * Obtain DBMS specific SQL code portion needed to declare an text type + * field to be used in statements like CREATE TABLE. + * + * @param array $field associative array with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * @return string DBMS specific SQL code portion that should be used to + * declare the specified field. + */ + public function getTypeDeclaration($field) { + switch ($field['type']) { + case 'text': + $length = !empty($field['length']) + ? $field['length'] : false; + $fixed = !empty($field['fixed']) ? $field['fixed'] : false; + return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')') + : ($length ? 'VARCHAR('.$length.')' : 'TEXT'); + case 'clob': + if (!empty($field['length'])) { + $length = $field['length']; + if ($length <= 8000) { + return 'VARCHAR('.$length.')'; + } + } + return 'TEXT'; + case 'blob': + if (!empty($field['length'])) { + $length = $field['length']; + if ($length <= 8000) { + return "VARBINARY($length)"; + } + } + return 'IMAGE'; + case 'integer': + return 'INT'; + case 'boolean': + return 'BIT'; + case 'date': + return 'CHAR ('.strlen('YYYY-MM-DD').')'; + case 'time': + return 'CHAR ('.strlen('HH:MM:SS').')'; + case 'timestamp': + return 'CHAR ('.strlen('YYYY-MM-DD HH:MM:SS').')'; + case 'float': + return 'FLOAT'; + case 'decimal': + $length = !empty($field['length']) ? $field['length'] : 18; + return 'DECIMAL('.$length.','.$db->options['decimal_places'].')'; + } + return ''; + } + /** + * Maps a native array description of a field to a MDB2 datatype and length + * + * @param array $field native field description + * @return array containing the various possible types, length, sign, fixed + */ + public function mapNativeDatatype($field) { + $db_type = preg_replace('/\d/','', strtolower($field['type']) ); + $length = $field['length']; + if ((int)$length <= 0) { + $length = null; + } + $type = array(); + // todo: unsigned handling seems to be missing + $unsigned = $fixed = null; + switch ($db_type) { + case 'bit': + $type[0] = 'boolean'; + break; + case 'int': + $type[0] = 'integer'; + break; + case 'datetime': + $type[0] = 'timestamp'; + break; + case 'float': + case 'real': + case 'numeric': + $type[0] = 'float'; + break; + case 'decimal': + case 'money': + $type[0] = 'decimal'; + break; + case 'text': + case 'varchar': + $fixed = false; + case 'char': + $type[0] = 'text'; + if ($length == '1') { + $type[] = 'boolean'; + if (preg_match('/^[is|has]/', $field['name'])) { + $type = array_reverse($type); + } + } elseif (strstr($db_type, 'text')) { + $type[] = 'clob'; + } + if ($fixed !== false) { + $fixed = true; + } + break; + case 'image': + case 'varbinary': + $type[] = 'blob'; + $length = null; + break; + default: + throw new Doctrine_DataDict_Mssql_Exception('mapNativeDatatype: unknown database attribute type: '.$db_type); + } + + return array($type, $length, $unsigned, $fixed); + } /** * lists all databases * diff --git a/lib/Doctrine/DataDict/Oracle.php b/lib/Doctrine/DataDict/Oracle.php index 1674efa9c..c9384e873 100644 --- a/lib/Doctrine/DataDict/Oracle.php +++ b/lib/Doctrine/DataDict/Oracle.php @@ -27,7 +27,7 @@ * @version $Id$ */ -class Doctrine_DataDict_Mssql extends Doctrine_DataDict { +class Doctrine_DataDict_Oracle extends Doctrine_DataDict { /** * Obtain DBMS specific SQL code portion needed to declare an text type * field to be used in statements like CREATE TABLE.