COciCommandBuilder.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. /**
  3. * COciCommandBuilder class file.
  4. *
  5. * @author Ricardo Grana <rickgrana@yahoo.com.br>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * COciCommandBuilder provides basic methods to create query commands for tables.
  12. *
  13. * @author Ricardo Grana <rickgrana@yahoo.com.br>
  14. * @package system.db.schema.oci
  15. */
  16. class COciCommandBuilder extends CDbCommandBuilder
  17. {
  18. /**
  19. * @var integer the last insertion ID
  20. */
  21. public $returnID;
  22. /**
  23. * Returns the last insertion ID for the specified table.
  24. * @param mixed $table the table schema ({@link CDbTableSchema}) or the table name (string).
  25. * @return mixed last insertion id. Null is returned if no sequence name.
  26. */
  27. public function getLastInsertID($table)
  28. {
  29. return $this->returnID;
  30. }
  31. /**
  32. * Alters the SQL to apply LIMIT and OFFSET.
  33. * @param string $sql SQL query string without LIMIT and OFFSET.
  34. * @param integer $limit maximum number of rows, -1 to ignore limit.
  35. * @param integer $offset row offset, -1 to ignore offset.
  36. * @return string SQL with LIMIT and OFFSET
  37. */
  38. public function applyLimit($sql,$limit,$offset)
  39. {
  40. if (($limit < 0) and ($offset < 0)) return $sql;
  41. $filters = array();
  42. if($offset>0){
  43. $filters[] = 'rowNumId > '.(int)$offset;
  44. }
  45. if($limit>=0){
  46. $filters[]= 'rownum <= '.(int)$limit;
  47. }
  48. if (count($filters) > 0){
  49. $filter = implode(' and ', $filters);
  50. $filter= " WHERE ".$filter;
  51. }else{
  52. $filter = '';
  53. }
  54. $sql = <<<EOD
  55. WITH USER_SQL AS ({$sql}),
  56. PAGINATION AS (SELECT USER_SQL.*, rownum as rowNumId FROM USER_SQL)
  57. SELECT *
  58. FROM PAGINATION
  59. {$filter}
  60. EOD;
  61. return $sql;
  62. }
  63. /**
  64. * Creates an INSERT command.
  65. * @param mixed $table the table schema ({@link CDbTableSchema}) or the table name (string).
  66. * @param array $data data to be inserted (column name=>column value). If a key is not a valid column name, the corresponding value will be ignored.
  67. * @return CDbCommand insert command
  68. */
  69. public function createInsertCommand($table,$data)
  70. {
  71. $this->ensureTable($table);
  72. $fields=array();
  73. $values=array();
  74. $placeholders=array();
  75. $i=0;
  76. foreach($data as $name=>$value)
  77. {
  78. if(($column=$table->getColumn($name))!==null && ($value!==null || $column->allowNull))
  79. {
  80. $fields[]=$column->rawName;
  81. if($value instanceof CDbExpression)
  82. {
  83. $placeholders[]=$value->expression;
  84. foreach($value->params as $n=>$v)
  85. $values[$n]=$v;
  86. }
  87. else
  88. {
  89. $placeholders[]=self::PARAM_PREFIX.$i;
  90. $values[self::PARAM_PREFIX.$i]=$column->typecast($value);
  91. $i++;
  92. }
  93. }
  94. }
  95. $sql="INSERT INTO {$table->rawName} (".implode(', ',$fields).') VALUES ('.implode(', ',$placeholders).')';
  96. if(is_string($table->primaryKey) && ($column=$table->getColumn($table->primaryKey))!==null && $column->type!=='string')
  97. {
  98. $sql.=' RETURNING '.$column->rawName.' INTO :RETURN_ID';
  99. $command=$this->getDbConnection()->createCommand($sql);
  100. $command->bindParam(':RETURN_ID', $this->returnID, PDO::PARAM_INT, 12);
  101. $table->sequenceName='RETURN_ID';
  102. }
  103. else
  104. $command=$this->getDbConnection()->createCommand($sql);
  105. foreach($values as $name=>$value)
  106. $command->bindValue($name,$value);
  107. return $command;
  108. }
  109. /**
  110. * Creates a multiple INSERT command.
  111. * This method could be used to achieve better performance during insertion of the large
  112. * amount of data into the database tables.
  113. * @param mixed $table the table schema ({@link CDbTableSchema}) or the table name (string).
  114. * @param array[] $data list data to be inserted, each value should be an array in format (column name=>column value).
  115. * If a key is not a valid column name, the corresponding value will be ignored.
  116. * @return CDbCommand multiple insert command
  117. * @since 1.1.14
  118. */
  119. public function createMultipleInsertCommand($table,array $data)
  120. {
  121. $templates=array(
  122. 'main'=>'INSERT ALL {{rowInsertValues}} SELECT * FROM dual',
  123. 'columnInsertValue'=>'{{value}}',
  124. 'columnInsertValueGlue'=>', ',
  125. 'rowInsertValue'=>'INTO {{tableName}} ({{columnInsertNames}}) VALUES ({{columnInsertValues}})',
  126. 'rowInsertValueGlue'=>' ',
  127. 'columnInsertNameGlue'=>', ',
  128. );
  129. return $this->composeMultipleInsertCommand($table,$data,$templates);
  130. }
  131. }