Spaces:
Sleeping
Sleeping
processmaker-community / processmaker-files /thirdparty /propel-generator /classes /propel /phing /PropelCreoleTransformTask.php
| /* | |
| * $Id: PropelCreoleTransformTask.php 538 2007-01-10 14:36:03Z heltem $ | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * This software consists of voluntary contributions made by many individuals | |
| * and is licensed under the LGPL. For more information please see | |
| * <http://propel.phpdb.org>. | |
| */ | |
| include_once 'creole/Connection.php'; | |
| require_once 'phing/TaskPhing.php'; | |
| /** | |
| * This class generates an XML schema of an existing database from | |
| * Creole metadata. | |
| * | |
| * @author Hans Lellelid <hans@xmpl.org> (Propel) | |
| * @author Jason van Zyl <jvanzyl@periapt.com> (Torque) | |
| * @author Fedor Karpelevitch <fedor.karpelevitch@barra.com> (Torque) | |
| * @version $Revision: 538 $ | |
| * @package propel.phing | |
| */ | |
| class PropelCreoleTransformTask extends TaskPhing { | |
| /** Name of XML database schema produced. */ | |
| protected $xmlSchema; | |
| /** Creole URL. */ | |
| protected $dbUrl; | |
| /** Creole driver. */ | |
| protected $dbDriver; | |
| /** Creole user name. */ | |
| protected $dbUser; | |
| /** Creole password. */ | |
| protected $dbPassword; | |
| /** DB encoding to use */ | |
| protected $dbEncoding = 'iso-8859-1'; | |
| /** DB schema to use. */ | |
| protected $dbSchema; | |
| /** parsed DB DSN */ | |
| protected $dsn; | |
| /** DOM document produced. */ | |
| protected $doc; | |
| /** The document root element. */ | |
| protected $databaseNode; | |
| /** Hashtable of columns that have primary keys. */ | |
| protected $primaryKeys; | |
| /** Hashtable to track what table a column belongs to. */ | |
| // doesn't seem to be used | |
| // protected $columnTableMap; | |
| /** whether to use same name for phpName or not */ | |
| protected $samePhpName; | |
| /** whether to add vendor info or not */ | |
| protected $addVendorInfo; | |
| /** | |
| * Bitfield to switch on/off which validators will be created. | |
| * | |
| * @var int | |
| */ | |
| protected $validatorBits; | |
| /** | |
| * Collect validatorInfos to create validators. | |
| * | |
| * @var int | |
| */ | |
| protected $validatorInfos; | |
| /** | |
| * Zero bit for no validators | |
| */ | |
| const VALIDATORS_NONE = 0; | |
| /** | |
| * Bit for maxLength validator | |
| */ | |
| const VALIDATORS_MAXLENGTH = 1; | |
| /** | |
| * Bit for maxValue validator | |
| */ | |
| const VALIDATORS_MAXVALUE = 2; | |
| /** | |
| * Bit for type validator | |
| */ | |
| const VALIDATORS_TYPE = 4; | |
| /** | |
| * Bit for required validator | |
| */ | |
| const VALIDATORS_REQUIRED = 8; | |
| /** | |
| * Bit for unique validator | |
| */ | |
| const VALIDATORS_UNIQUE = 16; | |
| /** | |
| * Bit for all validators | |
| */ | |
| const VALIDATORS_ALL = 255; | |
| /** | |
| * Maps validator type tokens to bits | |
| * | |
| * The tokens are used in the propel.addValidators property to define | |
| * which validators are to be added | |
| * | |
| * @static | |
| * @var array | |
| */ | |
| static protected $validatorBitMap = array ( | |
| 'none' => PropelCreoleTransformTask::VALIDATORS_NONE, | |
| 'maxlength' => PropelCreoleTransformTask::VALIDATORS_MAXLENGTH, | |
| 'maxvalue' => PropelCreoleTransformTask::VALIDATORS_MAXVALUE, | |
| 'type' => PropelCreoleTransformTask::VALIDATORS_TYPE, | |
| 'required' => PropelCreoleTransformTask::VALIDATORS_REQUIRED, | |
| 'unique' => PropelCreoleTransformTask::VALIDATORS_UNIQUE, | |
| 'all' => PropelCreoleTransformTask::VALIDATORS_ALL, | |
| ); | |
| /** | |
| * Defines messages that are added to validators | |
| * | |
| * @static | |
| * @var array | |
| */ | |
| static protected $validatorMessages = array ( | |
| 'maxlength' => array ( | |
| 'msg' => 'The field %s must be not longer than %s characters.', | |
| 'var' => array('colName', 'value') | |
| ), | |
| 'maxvalue' => array ( | |
| 'msg' => 'The field %s must be not greater than %s.', | |
| 'var' => array('colName', 'value') | |
| ), | |
| 'type' => array ( | |
| 'msg' => 'The field %s is not a valid value.', | |
| 'var' => array('colName') | |
| ), | |
| 'required' => array ( | |
| 'msg' => 'The field %s is required.', | |
| 'var' => array('colName') | |
| ), | |
| 'unique' => array ( | |
| 'msg' => 'This %s already exists in table %s.', | |
| 'var' => array('colName', 'tableName') | |
| ), | |
| ); | |
| public function getDbSchema() | |
| { | |
| return $this->dbSchema; | |
| } | |
| public function setDbSchema($dbSchema) | |
| { | |
| $this->dbSchema = $dbSchema; | |
| } | |
| public function setDbUrl($v) | |
| { | |
| $this->dbUrl = $v; | |
| } | |
| public function setDbDriver($v) | |
| { | |
| $this->dbDriver = $v; | |
| } | |
| public function setDbUser($v) | |
| { | |
| $this->dbUser = $v; | |
| } | |
| public function setDbPassword($v) | |
| { | |
| $this->dbPassword = $v; | |
| } | |
| public function setDbEncoding($v) | |
| { | |
| $this->dbEncoding = $v; | |
| } | |
| public function setOutputFile($v) | |
| { | |
| $this->xmlSchema = $v; | |
| } | |
| public function setSamePhpName($v) | |
| { | |
| $this->samePhpName = $v; | |
| } | |
| public function setAddVendorInfo($v) | |
| { | |
| $this->addVendorInfo = (boolean) $v; | |
| } | |
| /** | |
| * Sets set validator bitfield from propel.addValidators property | |
| * | |
| * @param string $v The propel.addValidators property | |
| * @return void | |
| */ | |
| public function setAddValidators($v) | |
| { | |
| // lowercase input | |
| $v = strtolower($v); | |
| // make it a bit expression | |
| $v = str_replace( | |
| array_keys(self::$validatorBitMap), self::$validatorBitMap, $v); | |
| // check if it's a valid boolean expression | |
| if (!preg_match('/[^\d|&~ ]/', $v)) { | |
| // eval the expression | |
| eval("\$v = $v;"); | |
| } else { | |
| $this->log("\n\nERROR: NO VALIDATORS ADDED!\n\nThere is an error in propel.addValidators build property.\n\nAllowed tokens are: " . implode(', ', array_keys(self::$validatorBitMap)) . "\n\nAllowed operators are (like in php.ini):\n\n| bitwise OR\n& bitwise AND\n~ bitwise NOT\n\n", PROJECT_MSG_ERR); | |
| $v = self::VALIDATORS_NONE; | |
| } | |
| $this->validatorBits = $v; | |
| } | |
| public function isSamePhpName() | |
| { | |
| return $this->samePhpName; | |
| } | |
| /** | |
| * Default constructor. | |
| * @return void | |
| * @throws BuildException | |
| */ | |
| public function main() | |
| { | |
| $this->log("Propel - CreoleToXMLSchema starting"); | |
| $this->log("Your DB settings are:"); | |
| $this->log("driver : " . ($this->dbDriver ? $this->dbDriver : "(default)")); | |
| $this->log("URL : " . $this->dbUrl); | |
| //(not yet supported) $this->log("schema : " . $this->dbSchema); | |
| //DocumentTypeImpl docType = new DocumentTypeImpl(null, "database", null, | |
| // "http://jakarta.apache.org/turbine/dtd/database.dtd"); | |
| $this->doc = new DOMDocument('1.0', 'utf-8'); | |
| $this->doc->formatOutput = true; // pretty printing | |
| $this->doc->appendChild($this->doc->createComment("Autogenerated by CreoleToXMLSchema!")); | |
| try { | |
| $this->generateXML(); | |
| $this->log("Writing XML to file: " . $this->xmlSchema); | |
| $outFile = new PhingFile($this->xmlSchema); | |
| $out = new FileWriter($outFile); | |
| $xmlstr = $this->doc->saveXML(); | |
| $out->write($xmlstr); | |
| $out->close(); | |
| } catch (Exception $e) { | |
| $this->log("There was an error building XML from metadata: " . $e->getMessage(), PROJECT_MSG_ERR); | |
| } | |
| $this->log("Propel - CreoleToXMLSchema finished"); | |
| } | |
| /** | |
| * Generates an XML database schema from Creole metadata. | |
| * | |
| * @return void | |
| * @throws Exception a generic exception. | |
| */ | |
| public function generateXML() | |
| { | |
| // Establish db connection | |
| $con = $this->getConnection(); | |
| // Get the database Metadata. | |
| $dbInfo = $con->getDatabaseInfo(); | |
| // create and add the database node | |
| $databaseNode = $this->createDatabaseNode($dbInfo); | |
| $this->doc->appendChild($databaseNode); | |
| } | |
| /** | |
| * Establishes a Creole database connection | |
| * | |
| * @return object The connection | |
| */ | |
| protected function getConnection() { | |
| // Attemtp to connect to a database. | |
| $this->dsn = Creole::parseDSN($this->dbUrl); | |
| if($this->dbUser) { | |
| $this->dsn["username"] = $this->dbUser; | |
| } | |
| if ($this->dbPassword) { | |
| $this->dsn["password"] = $this->dbPassword; | |
| } | |
| if ($this->dbDriver) { | |
| Creole::registerDriver($this->dsn['phptype'], $this->dbDriver); | |
| } | |
| $con = Creole::getConnection($this->dsn); | |
| $this->log("DB connection established"); | |
| return $con; | |
| } | |
| /** | |
| * Creates a database node | |
| * | |
| * @param object $dbInfo The dbInfo for this db | |
| * @return object The database node instance | |
| */ | |
| protected function createDatabaseNode($dbInfo) { | |
| $this->log("Processing database"); | |
| $node = $this->doc->createElement("database"); | |
| $node->setAttribute("name", $dbInfo->getName()); | |
| if ($vendorNode = $this->createVendorInfoNode($dbInfo->getVendorSpecificInfo())) { | |
| $node->appendChild($vendorNode); | |
| } | |
| // create and add table nodes | |
| foreach($dbInfo->getTables() as $table) { | |
| $tableNode = $this->createTableNode($table); | |
| $node->appendChild($tableNode); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Creates a table node | |
| * | |
| * @param object $table The table | |
| * @return object The table node instance | |
| */ | |
| protected function createTableNode($table) { | |
| $this->log("Processing table: " . $table->toString()); | |
| $node = $this->doc->createElement("table"); | |
| $node->setAttribute("name", $table->getName()); | |
| if ($this->isSamePhpName()) { | |
| $node->setAttribute("phpName", $table->getName()); | |
| } | |
| if ($vendorNode = $this->createVendorInfoNode($table->getVendorSpecificInfo())) { | |
| $node->appendChild($vendorNode); | |
| } | |
| // Create and add column nodes, register column validators | |
| $columns = $table->getColumns(); | |
| foreach($columns as $column) { | |
| $columnNode = $this->createColumnNode($column); | |
| $node->appendChild($columnNode); | |
| $this->registerValidatorsForColumn($column); | |
| if ($column->isAutoIncrement()) { | |
| $idMethod = 'native'; | |
| } | |
| } | |
| if (isset($idMethod)) { | |
| $node->setAttribute("idMethod", $idMethod); | |
| } | |
| // Create and add foreign key nodes. | |
| $foreignKeys = $table->getForeignKeys(); | |
| foreach($foreignKeys as $foreignKey) { | |
| $foreignKeyNode = $this->createForeignKeyNode($foreignKey); | |
| $node->appendChild($foreignKeyNode); | |
| } | |
| // Create and add index nodes. | |
| $indices = $table->getIndices(); | |
| foreach($indices as $index) { | |
| $indexNode = $this->createIndexNode($index); | |
| $node->appendChild($indexNode); | |
| } | |
| // add an id-method-parameter if we have a sequence that matches table_colname_seq | |
| // | |
| // | |
| $pkey = $table->getPrimaryKey(); | |
| if ($pkey) { | |
| $cols = $pkey->getColumns(); | |
| if (count($cols) === 1) { | |
| $col = array_shift($cols); | |
| if ($col->isAutoIncrement()) { | |
| $seq_name = $table->getName().'_'.$col->getName().'_seq'; | |
| if ($table->getDatabase()->isSequence($seq_name)) { | |
| $idMethodParameterNode = $this->doc->createElement("id-method-parameter"); | |
| $idMethodParameterNode->setAttribute("value", $seq_name); | |
| $node->appendChild($idMethodParameterNode); | |
| } | |
| } | |
| } | |
| } | |
| // Create and add validator and rule nodes. | |
| $nodes = array(); | |
| $tableName = $table->getName(); | |
| if (isset($this->validatorInfos[$tableName])) { | |
| foreach ($this->validatorInfos[$tableName] as $colName => $rules) { | |
| $column = $table->getColumn($colName); | |
| $colName = $column->getName(); | |
| foreach ($rules as $rule) { | |
| if (!isset($nodes[$colName])) { | |
| $nodes[$colName] = $this->createValidator($column, $rule['type']); | |
| $node->appendChild($nodes[$colName]); | |
| } | |
| $ruleNode = $this->createRuleNode($column, $rule); | |
| $nodes[$colName]->appendChild($ruleNode); | |
| } | |
| } | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Creates an column node | |
| * | |
| * @param object $column The Creole column | |
| * @return object The column node instance | |
| */ | |
| protected function createColumnNode($column) { | |
| $node = $this->doc->createElement("column"); | |
| $table = $column->getTable(); | |
| $colName = $column->getName(); | |
| $colType = $column->getType(); | |
| $colSize = $column->getSize(); | |
| $colScale = $column->getScale(); | |
| if ($colType === CreoleTypes::OTHER) { | |
| $this->log("Column [" . $table->getName() . "." . $colName . "] has a column type (".$column->getNativeType().") that Propel does not support.", PROJECT_MSG_WARN); | |
| } | |
| $node->setAttribute("name", $colName); | |
| if ($this->isSamePhpName()) { | |
| $node->setAttribute("phpName", $colName); | |
| } | |
| $node->setAttribute("type", PropelTypes::getPropelType($colType)); | |
| if ($colSize > 0 && ( | |
| $colType == CreoleTypes::CHAR | |
| || $colType == CreoleTypes::VARCHAR | |
| || $colType == CreoleTypes::LONGVARCHAR | |
| || $colType == CreoleTypes::DECIMAL | |
| || $colType == CreoleTypes::FLOAT | |
| || $colType == CreoleTypes::NUMERIC)) { | |
| $node->setAttribute("size", (string) $colSize); | |
| } | |
| if ($colScale > 0 && ( | |
| $colType == CreoleTypes::DECIMAL | |
| || $colType == CreoleTypes::FLOAT | |
| || $colType == CreoleTypes::NUMERIC)) { | |
| $node->setAttribute("scale", (string) $colScale); | |
| } | |
| if (!$column->isNullable()) { | |
| $node->setAttribute("required", "true"); | |
| } | |
| if ($column->isAutoIncrement()) { | |
| $node->setAttribute("autoIncrement", "true"); | |
| } | |
| if (in_array($colName, $this->getTablePkCols($table))) { | |
| $node->setAttribute("primaryKey", "true"); | |
| } | |
| if (($defValue = $column->getDefaultValue()) !== null) { | |
| $node->setAttribute("default", iconv($this->dbEncoding, 'utf-8', $defValue)); | |
| } | |
| if ($vendorNode = $this->createVendorInfoNode($column->getVendorSpecificInfo())) { | |
| $node->appendChild($vendorNode); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Returns the primary key columns for a table | |
| * | |
| * @param object $table The table | |
| * @return array The primary keys | |
| */ | |
| protected function getTablePkCols($table) { | |
| static $columns = array(); | |
| $tableName = $table->getName(); | |
| if (!isset($columns[$tableName])) { | |
| $columns[$tableName] = array(); | |
| $primaryKey = $table->getPrimaryKey(); | |
| if ($primaryKey) { | |
| foreach($primaryKey->getColumns() as $colObject) { | |
| $columns[$tableName][] = $colObject->getName(); | |
| } | |
| } | |
| } | |
| return $columns[$tableName]; | |
| } | |
| /** | |
| * Creates an foreign key node | |
| * | |
| * @param object $foreignKey The foreign key | |
| * @return object The foreign key node instance | |
| */ | |
| protected function createForeignKeyNode($foreignKey) { | |
| $node = $this->doc->createElement("foreign-key"); | |
| if ($vendorNode = $this->createVendorInfoNode($foreignKey->getVendorSpecificInfo())) { | |
| $node->appendChild($vendorNode); | |
| } | |
| $refs = $foreignKey->getReferences(); | |
| // all references must be to same table, so we can grab table from the first, foreign column | |
| $node->setAttribute("foreignTable", $refs[0][1]->getTable()->getName()); | |
| $node->setAttribute("onDelete", $refs[0][2]); | |
| $node->setAttribute("onUpdate", $refs[0][3]); | |
| for($m = 0, $size = count($refs); $m < $size; $m++) { | |
| $refNode = $this->doc->createElement("reference"); | |
| $refData = $refs[$m]; | |
| $refNode->setAttribute("local", $refData[0]->getName()); | |
| $refNode->setAttribute("foreign", $refData[1]->getName()); | |
| $node->appendChild($refNode); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Creates an index node | |
| * | |
| * @param object $index The index | |
| * @return object The index node instance | |
| */ | |
| protected function createIndexNode($index) { | |
| $indexType = $index->isUnique() ? 'unique' : 'index'; | |
| $node = $this->doc->createElement($indexType); | |
| $node->setAttribute("name", $index->getName()); | |
| $columns = $index->getColumns(); | |
| foreach ($columns as $column) { | |
| $tableName = $column->getTable()->getName(); | |
| $colName = $column->getName(); | |
| $columnNode = $this->doc->createElement("{$indexType}-column"); | |
| $columnNode->setAttribute("name", $colName); | |
| $node->appendChild($columnNode); | |
| if ($indexType == 'unique' && $this->isValidatorRequired('unique')) { | |
| $this->validatorInfos[$tableName][$colName][] = array('type' => 'unique'); | |
| } | |
| } | |
| if ($vendorNode = $this->createVendorInfoNode($index->getVendorSpecificInfo())) { | |
| $node->appendChild($vendorNode); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Checks whether to add validators of specified type or not | |
| * | |
| * @param string $type The validator type | |
| * @return boolean | |
| */ | |
| protected function isValidatorRequired($type) { | |
| $type = strtolower($type); | |
| return ($this->validatorBits & self::$validatorBitMap[$type] ? true : false); | |
| } | |
| /** | |
| * Registers column type specific validators if necessary | |
| * | |
| * We'll first collect the validators/rule infos and add them later on to | |
| * have them appended to the table tag as a block. | |
| * | |
| * CreoleTypes are: | |
| * | |
| * BOOLEAN | |
| * BIGINT, SMALLINT, TINYINT, INTEGER | |
| * FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL | |
| * BIGINT, SMALLINT, TINYINT, INTEGER | |
| * TEXT | |
| * BLOB, CLOB, BINARY, VARBINARY, LONGVARBINARY | |
| * DATE, YEAR, TIME | |
| * TIMESTAMP | |
| * | |
| * We will add the following type specific validators: | |
| * | |
| * for notNull columns: required validator | |
| * for unique indexes: unique validator | |
| * for varchar types: maxLength validators (CHAR, VARCHAR, LONGVARCHAR) | |
| * for numeric types: maxValue validators (BIGINT, SMALLINT, TINYINT, INTEGER, FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL) | |
| * for integer and timestamp types: notMatch validator with [^\d]+ (BIGINT, SMALLINT, TINYINT, INTEGER, TIMESTAMP) | |
| * for float types: notMatch validator with [^\d\.]+ (FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL) | |
| * | |
| * @param object $column The Creole column | |
| * @return void | |
| * @todo find out how to evaluate the appropriate size and adjust maxValue rule values appropriate | |
| * @todo find out if float type column values must always notMatch('[^\d\.]+'), i.e. digits and point for any db vendor, language etc. | |
| */ | |
| protected function registerValidatorsForColumn($column) { | |
| $table = $column->getTable(); | |
| $tableName = $table->getName(); | |
| $colName = $column->getName(); | |
| $colType = $column->getType(); | |
| $colSize = $column->getSize(); | |
| if ($this->isValidatorRequired('required')) { | |
| $ruleInfo = array('type' => 'required'); | |
| $this->validatorInfos[$tableName][$colName][] = $ruleInfo; | |
| } | |
| $isPrimarykeyCol = in_array($colName, $this->getTablePkCols($table)); | |
| if ($this->isValidatorRequired('unique') && $isPrimarykeyCol) { | |
| $ruleInfo = array('type' => 'unique'); | |
| $this->validatorInfos[$tableName][$colName][] = $ruleInfo; | |
| } | |
| if ($this->isValidatorRequired('maxLength') && | |
| $colSize > 0 && in_array($colType, array( | |
| CreoleTypes::CHAR, | |
| CreoleTypes::VARCHAR, | |
| CreoleTypes::LONGVARCHAR))) { | |
| $ruleInfo = array('type' => 'maxLength', 'value' => $colSize); | |
| $this->validatorInfos[$tableName][$colName][] = $ruleInfo; | |
| } | |
| if ($this->isValidatorRequired('maxValue') && | |
| $colSize > 0 && in_array($colType, array( | |
| CreoleTypes::SMALLINT, | |
| CreoleTypes::TINYINT, | |
| CreoleTypes::INTEGER, | |
| CreoleTypes::BIGINT, | |
| CreoleTypes::FLOAT, | |
| CreoleTypes::DOUBLE, | |
| CreoleTypes::NUMERIC, | |
| CreoleTypes::DECIMAL, | |
| CreoleTypes::REAL))) { | |
| // TODO: how to evaluate the appropriate size?? | |
| $this->log("WARNING: maxValue validator added for column $colName. You will have to adjust the size value manually.", PROJECT_MSG_WARN); | |
| $ruleInfo = array('type' => 'maxValue', 'value' => $colSize); | |
| $this->validatorInfos[$tableName][$colName][] = $ruleInfo; | |
| } | |
| if ($this->isValidatorRequired('type') && | |
| $colSize > 0 && in_array($colType, array( | |
| CreoleTypes::SMALLINT, | |
| CreoleTypes::TINYINT, | |
| CreoleTypes::INTEGER, | |
| CreoleTypes::TIMESTAMP))) { | |
| $ruleInfo = array('type' => 'type', 'value' => '[^\d]+'); | |
| $this->validatorInfos[$tableName][$colName][] = $ruleInfo; | |
| } | |
| if ($this->isValidatorRequired('type') && | |
| $colSize > 0 && in_array($colType, array( | |
| CreoleTypes::FLOAT, | |
| CreoleTypes::DOUBLE, | |
| CreoleTypes::NUMERIC, | |
| CreoleTypes::DECIMAL, | |
| CreoleTypes::REAL))) { | |
| // TODO: is this always true?? | |
| $ruleInfo = array('type' => 'type', 'value' => '[^\d\.]+'); | |
| $this->validatorInfos[$tableName][$colName][] = $ruleInfo; | |
| } | |
| } | |
| /** | |
| * Creates a validator node | |
| * | |
| * @param object $column The Creole column | |
| * @param integer $type The validator type | |
| * @return object The validator node instance | |
| */ | |
| protected function createValidator($column, $type) { | |
| $node = $this->doc->createElement('validator'); | |
| $node->setAttribute('column', $column->getName()); | |
| return $node; | |
| } | |
| /** | |
| * Creates a rule node | |
| * | |
| * @param object $column The Creole column | |
| * @param array $rule The rule info | |
| * @return object The rule node instance | |
| */ | |
| protected function createRuleNode($column, $rule) { | |
| extract($rule); | |
| // create message | |
| $colName = $column->getName(); | |
| $tableName = $column->getTable()->getName(); | |
| $msg = self::$validatorMessages[strtolower($rule)]; | |
| array_unshift($tmp = compact($msg['var']), $msg['msg']); | |
| $msg = call_user_func_array('sprintf', $tmp); | |
| // add node | |
| $node = $this->doc->createElement('rule'); | |
| $node->setAttribute('name', $rule == 'type' ? 'notMatch' : $rule); | |
| $node->setAttribute('message', $msg); | |
| return $node; | |
| } | |
| /** | |
| * Creates a vendor info node | |
| * | |
| * returns false if no vendor info can or has to be added | |
| * | |
| * @param array $vendorInfo The validator info | |
| * @return object|boolean The vendor info instance or false | |
| */ | |
| protected function createVendorInfoNode($vendorInfo) | |
| { | |
| if(!$vendorInfo OR !$this->addVendorInfo) { | |
| return false; | |
| } | |
| $vendorNode = $this->doc->createElement("vendor"); | |
| $vendorNode->setAttribute("type", $this->dsn["phptype"]); | |
| foreach($vendorInfo as $key => $value) { | |
| $parameterNode = $this->doc->createElement("parameter"); | |
| $value = iconv($this->dbEncoding, "utf-8", $value); | |
| $parameterNode->setAttribute("name", $key); | |
| $parameterNode->setAttribute("value", $value); | |
| $vendorNode->appendChild($parameterNode); | |
| } | |
| return $vendorNode; | |
| } | |
| } | |