CCubridSchema.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * CCubridSchema class file.
  4. *
  5. * @author Esen Sagynov <kadismal@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CCubridSchema is the class for retrieving metadata information from a CUBRID database (version 8.4.0 and later).
  12. *
  13. * @author Esen Sagynov <kadismal@gmail.com>
  14. * @package system.db.schema.cubrid
  15. * @since 1.1.16
  16. */
  17. class CCubridSchema extends CDbSchema
  18. {
  19. public $columnTypes=array(
  20. 'pk' => 'INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY',
  21. // same as STRING or CHARACTER VARYING
  22. 'string' => 'VARCHAR(255)',
  23. 'text' => 'VARCHAR(65535)',
  24. 'integer' => 'INTEGER',
  25. 'float' => 'NUMERIC',
  26. 'real' => 'NUMERIC',
  27. 'decimal' => 'NUMERIC',
  28. 'datetime' => 'DATETIME',
  29. 'timestamp' => 'TIMESTAMP',
  30. 'time' => 'TIME',
  31. 'date' => 'DATE',
  32. 'binary' => 'BIT VARYING',
  33. 'bool' => 'SHORT',
  34. 'boolean' => 'SHORT',
  35. 'money' => 'NUMERIC(19,4)',
  36. );
  37. /**
  38. * Quotes a table name for use in a query.
  39. * A simple table name does not schema prefix.
  40. * @param string $name table name
  41. * @return string the properly quoted table name
  42. */
  43. public function quoteSimpleTableName($name)
  44. {
  45. return '`'.$name.'`';
  46. }
  47. /**
  48. * Quotes a column name for use in a query.
  49. * A simple column name does not contain prefix.
  50. * @param string $name column name
  51. * @return string the properly quoted column name
  52. */
  53. public function quoteSimpleColumnName($name)
  54. {
  55. return '`'.$name.'`';
  56. }
  57. /**
  58. * Compares two table names.
  59. * The table names can be either quoted or unquoted. This method
  60. * will consider both cases.
  61. * @param string $name1 table name 1
  62. * @param string $name2 table name 2
  63. * @return boolean whether the two table names refer to the same table.
  64. */
  65. public function compareTableNames($name1,$name2)
  66. {
  67. return parent::compareTableNames(strtolower($name1),strtolower($name2));
  68. }
  69. /**
  70. * Resets the sequence value of a table's primary key.
  71. * The sequence will be reset such that the primary key of the next new row inserted
  72. * will have the specified value or 1.
  73. * @param CDbTableSchema $table the table schema whose primary key sequence will be reset
  74. * @param mixed $value the value for the primary key of the next new row inserted. If this is not set,
  75. * the next new row's primary key will have a value 1.
  76. */
  77. public function resetSequence($table,$value=null)
  78. {
  79. if($table->sequenceName!==null)
  80. {
  81. if($value===null)
  82. $value=$this->getDbConnection()->createCommand("SELECT MAX(`{$table->primaryKey}`) FROM {$table->rawName}")->queryScalar()+1;
  83. else
  84. $value=(int)$value;
  85. $this->getDbConnection()->createCommand("ALTER TABLE {$table->rawName} AUTO_INCREMENT=$value")->execute();
  86. }
  87. }
  88. /**
  89. * Creates a table instance representing the metadata for the named table.
  90. * @param string $name table name
  91. * @return CCubridTableSchema driver dependent table metadata. Null if the table does not exist.
  92. */
  93. protected function loadTable($name)
  94. {
  95. $table=new CCubridTableSchema;
  96. $this->resolveTableNames($table,$name);
  97. if($this->findColumns($table))
  98. {
  99. $this->findPrimaryKeys($table);
  100. $this->findConstraints($table);
  101. return $table;
  102. }
  103. else
  104. return null;
  105. }
  106. /**
  107. * Generates various kinds of table names.
  108. * @param CCubridTableSchema $table the table instance
  109. * @param string $name the unquoted table name
  110. */
  111. protected function resolveTableNames($table,$name)
  112. {
  113. $parts=explode('.',str_replace('`','',$name));
  114. if(isset($parts[1]))
  115. {
  116. $table->schemaName=$parts[0];
  117. $table->name=$parts[1];
  118. $table->rawName=$this->quoteTableName($table->schemaName).'.'.$this->quoteTableName($table->name);
  119. }
  120. else
  121. {
  122. $table->name=$parts[0];
  123. $table->rawName=$this->quoteTableName($table->name);
  124. }
  125. }
  126. /**
  127. * Collects the table column metadata.
  128. * @param CCubridTableSchema $table the table metadata
  129. * @return boolean whether the table exists in the database
  130. */
  131. protected function findColumns($table)
  132. {
  133. // it may be good to use CUBRID PHP API to retrieve column info.
  134. $sql='SHOW COLUMNS FROM '.$table->rawName;
  135. try
  136. {
  137. $columns=$this->getDbConnection()->createCommand($sql)->queryAll();
  138. }
  139. catch(Exception $e)
  140. {
  141. return false;
  142. }
  143. foreach($columns as $column)
  144. {
  145. $c=$this->createColumn($column);
  146. $table->columns[$c->name]=$c;
  147. }
  148. return true;
  149. }
  150. /**
  151. * Creates a table column.
  152. * @param array $column column metadata
  153. * @return CDbColumnSchema normalized column metadata
  154. */
  155. protected function createColumn($column)
  156. {
  157. $c=new CCubridColumnSchema;
  158. $c->name=$column['Field'];
  159. $c->rawName=$this->quoteColumnName($c->name);
  160. $c->allowNull=$column['Null']==='YES';
  161. $c->isPrimaryKey=strpos($column['Key'],'PRI')!==false;
  162. $c->isForeignKey=false;
  163. $c->init($column['Type'],$column['Default']);
  164. $c->autoIncrement=strpos(strtolower($column['Extra']),'auto_increment')!==false;
  165. return $c;
  166. }
  167. /**
  168. * @return float server version.
  169. */
  170. protected function getServerVersion()
  171. {
  172. $version=$this->getDbConnection()->getAttribute(PDO::ATTR_SERVER_VERSION);
  173. $digits=array();
  174. preg_match('/(\d+)\.(\d+)\.(\d+).(\d+)/', $version, $digits);
  175. return floatval($digits[1].'.'.$digits[2].$digits[3].'.'.$digits[4]);
  176. }
  177. /**
  178. * Collects the foreign key column details for the given table.
  179. * @param CCubridTableSchema $table the table metadata
  180. */
  181. protected function findConstraints($table)
  182. {
  183. $schemas=$this->getDbConnection()->getPdoInstance()->cubrid_schema(PDO::CUBRID_SCH_IMPORTED_KEYS,$table->name);
  184. foreach($schemas as $schema)
  185. {
  186. $table->foreignKeys[$schema["FKCOLUMN_NAME"]]=array($schema["PKTABLE_NAME"],$schema["PKCOLUMN_NAME"]);
  187. if(isset($table->columns[$schema["FKCOLUMN_NAME"]]))
  188. $table->columns[$schema["FKCOLUMN_NAME"]]->isForeignKey=true;
  189. }
  190. }
  191. /**
  192. * Collects the primary key column details for the given table.
  193. * @param CCubridTableSchema $table the table metadata
  194. */
  195. protected function findPrimaryKeys($table)
  196. {
  197. $pks=$this->getDbConnection()->getPdoInstance()->cubrid_schema(PDO::CUBRID_SCH_PRIMARY_KEY,$table->name);
  198. foreach($pks as $pk)
  199. {
  200. $c = $table->columns[$pk['ATTR_NAME']];
  201. $c->isPrimaryKey = true;
  202. if($table->primaryKey===null)
  203. $table->primaryKey=$c->name;
  204. elseif(is_string($table->primaryKey))
  205. $table->primaryKey=array($table->primaryKey,$c->name);
  206. else
  207. $table->primaryKey[]=$c->name;
  208. if($c->autoIncrement)
  209. $table->sequenceName='';
  210. }
  211. }
  212. /**
  213. * Returns all table names in the database.
  214. * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
  215. * If not empty, the returned table names will be prefixed with the schema name.
  216. * @return array all table names in the database.
  217. */
  218. protected function findTableNames($schema='')
  219. {
  220. // CUBRID does not allow to look into another database from within another connection.
  221. // If necessary user has to establish a connection to that particular database and
  222. // query to show all tables. For this reason if a user executes this funtion
  223. // we will return all table names of the currently connected database.
  224. return $this->getDbConnection()->createCommand('SHOW TABLES')->queryColumn();
  225. }
  226. }