|
15 | 15 | | Authors: Andres Gutierrez <andres@phalconphp.com> |
|
16 | 16 | | Eduar Carvajal <eduar@phalconphp.com> |
|
17 | 17 | | Marcio Paiva <mpaivabarbosa@gmail.com> |
|
| 18 | + | Stanislav Kiryukhin <korsar.zn@gmail.com> | |
18 | 19 | +------------------------------------------------------------------------+
|
19 | 20 | */
|
20 | 21 |
|
21 | 22 | namespace Phalcon\Db\Dialect;
|
22 | 23 |
|
| 24 | +use Phalcon\Db\Dialect; |
| 25 | +use Phalcon\Db\Column; |
| 26 | +use Phalcon\Db\Exception; |
| 27 | +use Phalcon\Db\IndexInterface; |
| 28 | +use Phalcon\Db\ColumnInterface; |
| 29 | +use Phalcon\Db\ReferenceInterface; |
| 30 | +use Phalcon\Text; |
| 31 | + |
23 | 32 | /**
|
24 | 33 | * Phalcon\Db\Dialect\Oracle
|
25 | 34 | *
|
26 |
| - * Generates database specific SQL for the Oracle RBDM |
| 35 | + * Generates database specific SQL for the Oracle RDBMS |
27 | 36 | */
|
28 |
| -class Oracle //extends \Phalcon\Db\Dialect //implements Phalcon\Db\DialectInterface |
| 37 | +class Oracle extends Dialect |
29 | 38 | {
|
30 | 39 | protected _escapeChar = "";
|
| 40 | + |
| 41 | + /** |
| 42 | + * Generates the SQL for LIMIT clause |
| 43 | + */ |
| 44 | + public function limit(string! sqlQuery, var number) -> string |
| 45 | + { |
| 46 | + var limit, offset = 0; |
| 47 | + |
| 48 | + if typeof number == "array" { |
| 49 | + |
| 50 | + if isset number[1] { |
| 51 | + let offset = (int) trim(number[1], "'"); |
| 52 | + } |
| 53 | + |
| 54 | + let limit = (int)trim(number[0], "'") + offset; |
| 55 | + } else { |
| 56 | + let limit = (int)trim(number, "'"); |
| 57 | + } |
| 58 | + |
| 59 | + |
| 60 | + let sqlQuery = "SELECT * FROM (SELECT Z1.*, ROWNUM PHALCON_RN FROM (" . sqlQuery . ") Z1 WHERE ROWNUM <= " . limit . ")"; |
| 61 | + |
| 62 | + if (offset != 0) { |
| 63 | + let sqlQuery .= " WHERE PHALCON_RN >= " . offset; |
| 64 | + } |
| 65 | + |
| 66 | + return sqlQuery; |
| 67 | + } |
| 68 | + |
| 69 | + /** |
| 70 | + * Gets the column name in Oracle |
| 71 | + */ |
| 72 | + public function getColumnDefinition(<ColumnInterface> column) -> string |
| 73 | + { |
| 74 | + var columnSql, size, scale, type; |
| 75 | + |
| 76 | + let type = column->getType(); |
| 77 | + let size = column->getSize(); |
| 78 | + |
| 79 | + switch type { |
| 80 | + |
| 81 | + case Column::TYPE_INTEGER: |
| 82 | + let columnSql = "INTEGER"; |
| 83 | + break; |
| 84 | + |
| 85 | + case Column::TYPE_DATE: |
| 86 | + let columnSql = "DATE"; |
| 87 | + break; |
| 88 | + |
| 89 | + case Column::TYPE_VARCHAR: |
| 90 | + let columnSql = "VARCHAR2(" . size . ")"; |
| 91 | + break; |
| 92 | + |
| 93 | + case Column::TYPE_DECIMAL: |
| 94 | + let scale = column->getScale(); |
| 95 | + let columnSql = "NUMBER(" . size . "," . scale . ")"; |
| 96 | + break; |
| 97 | + |
| 98 | + case Column::TYPE_DATETIME: |
| 99 | + let columnSql = "TIMESTAMP"; |
| 100 | + break; |
| 101 | + |
| 102 | + case Column::TYPE_CHAR: |
| 103 | + let columnSql = "CHAR(" . size . ")"; |
| 104 | + break; |
| 105 | + |
| 106 | + case Column::TYPE_TEXT: |
| 107 | + let columnSql = "TEXT"; |
| 108 | + break; |
| 109 | + |
| 110 | + case Column::TYPE_FLOAT: |
| 111 | + let scale = column->getScale(); |
| 112 | + let columnSql = "FLOAT(" . size . "," . scale .")"; |
| 113 | + break; |
| 114 | + |
| 115 | + case Column::TYPE_BOOLEAN: |
| 116 | + let columnSql = "TINYINT(1)"; |
| 117 | + break; |
| 118 | + |
| 119 | + default: |
| 120 | + throw new Exception("Unrecognized Oracle data type"); |
| 121 | + } |
| 122 | + |
| 123 | + return columnSql; |
| 124 | + } |
| 125 | + |
| 126 | + /** |
| 127 | + * Generates SQL to add a column to a table |
| 128 | + */ |
| 129 | + public function addColumn(string! tableName, string! schemaName, <ColumnInterface> column) -> string |
| 130 | + { |
| 131 | + throw new Exception("Not implemented yet"); |
| 132 | + } |
| 133 | + |
| 134 | + /** |
| 135 | + * Generates SQL to modify a column in a table |
| 136 | + */ |
| 137 | + public function modifyColumn(string! tableName, string! schemaName, <ColumnInterface> column) -> string |
| 138 | + { |
| 139 | + throw new Exception("Not implemented yet"); |
| 140 | + } |
| 141 | + |
| 142 | + /** |
| 143 | + * Generates SQL to delete a column from a table |
| 144 | + */ |
| 145 | + public function dropColumn(string! tableName, string! schemaName, string columnName) -> string |
| 146 | + { |
| 147 | + throw new Exception("Not implemented yet"); |
| 148 | + } |
| 149 | + |
| 150 | + /** |
| 151 | + * Generates SQL to add an index to a table |
| 152 | + */ |
| 153 | + public function addIndex(string! tableName, string! schemaName, <IndexInterface> index) -> string |
| 154 | + { |
| 155 | + throw new Exception("Not implemented yet"); |
| 156 | + } |
| 157 | + |
| 158 | + /** |
| 159 | + /** |
| 160 | + * Generates SQL to delete an index from a table |
| 161 | + */ |
| 162 | + public function dropIndex(string! tableName, string! schemaName, string! indexName) -> string |
| 163 | + { |
| 164 | + throw new Exception("Not implemented yet"); |
| 165 | + } |
| 166 | + |
| 167 | + /** |
| 168 | + * Generates SQL to add the primary key to a table |
| 169 | + */ |
| 170 | + public function addPrimaryKey(string tableName, string schemaName, <IndexInterface> index) -> string |
| 171 | + { |
| 172 | + throw new Exception("Not implemented yet"); |
| 173 | + } |
| 174 | + |
| 175 | + /** |
| 176 | + * Generates SQL to delete primary key from a table |
| 177 | + */ |
| 178 | + public function dropPrimaryKey(string! tableName, string! schemaName) -> string |
| 179 | + { |
| 180 | + throw new Exception("Not implemented yet"); |
| 181 | + } |
| 182 | + |
| 183 | + /** |
| 184 | + * Generates SQL to add an index to a table |
| 185 | + */ |
| 186 | + public function addForeignKey(string! tableName, string! schemaName, <ReferenceInterface> reference) -> string |
| 187 | + { |
| 188 | + throw new Exception("Not implemented yet"); |
| 189 | + } |
| 190 | + |
| 191 | + /** |
| 192 | + * Generates SQL to delete a foreign key from a table |
| 193 | + */ |
| 194 | + public function dropForeignKey(string! tableName, string! schemaName, string! referenceName) -> string |
| 195 | + { |
| 196 | + throw new Exception("Not implemented yet"); |
| 197 | + } |
| 198 | + |
| 199 | + /** |
| 200 | + * Generates SQL to create a table in Oracle |
| 201 | + */ |
| 202 | + public function createTable(string! tableName, string! schemaName, array! definition) -> string |
| 203 | + { |
| 204 | + throw new Exception("Not implemented yet"); |
| 205 | + } |
| 206 | + |
| 207 | + /** |
| 208 | + * Generates SQL to drop a table |
| 209 | + */ |
| 210 | + public function dropTable(string! tableName, string! schemaName, boolean! ifExists = true) -> string |
| 211 | + { |
| 212 | + var table; |
| 213 | + |
| 214 | + if schemaName { |
| 215 | + let table = this->escape(Text::upper(schemaName)) . "." . this->escape(Text::upper(tableName)); |
| 216 | + } else { |
| 217 | + let table = this->escape(Text::upper(tableName)); |
| 218 | + } |
| 219 | + |
| 220 | + if ifExists { |
| 221 | + return "DROP TABLE IF EXISTS " . table; |
| 222 | + } else { |
| 223 | + return "DROP TABLE " . table; |
| 224 | + } |
| 225 | + } |
| 226 | + |
| 227 | + /** |
| 228 | + * Generates SQL to create a view |
| 229 | + */ |
| 230 | + public function createView(string! viewName, array! definition, string schemaName = null) -> string |
| 231 | + { |
| 232 | + var view, viewSql; |
| 233 | + |
| 234 | + if !fetch viewSql, definition["sql"] { |
| 235 | + throw new Exception("The index 'sql' is required in the definition array"); |
| 236 | + } |
| 237 | + |
| 238 | + if schemaName { |
| 239 | + let view = this->escape(Text::upper(schemaName) . "." . Text::upper(viewName)); |
| 240 | + } else { |
| 241 | + let view = this->escape(Text::upper(viewName)); |
| 242 | + } |
| 243 | + |
| 244 | + return "CREATE VIEW " . view . " AS " . viewSql; |
| 245 | + } |
| 246 | + |
| 247 | + /** |
| 248 | + * Generates SQL to drop a view |
| 249 | + */ |
| 250 | + public function dropView(string! viewName, string schemaName = null, boolean! ifExists = true) -> string |
| 251 | + { |
| 252 | + var view; |
| 253 | + |
| 254 | + if schemaName { |
| 255 | + let view = this->escape(Text::upper(schemaName) . "." . Text::upper(viewName)); |
| 256 | + } else { |
| 257 | + let view = this->escape(Text::upper(viewName)); |
| 258 | + } |
| 259 | + |
| 260 | + if ifExists { |
| 261 | + return "DROP VIEW IF EXISTS " . view; |
| 262 | + } else { |
| 263 | + return "DROP VIEW " . view; |
| 264 | + } |
| 265 | + } |
| 266 | + |
| 267 | + /** |
| 268 | + * Generates SQL checking for the existence of a schema.view |
| 269 | + */ |
| 270 | + public function viewExists(string! viewName, string schemaName = null) -> string |
| 271 | + { |
| 272 | + if schemaName != "" { |
| 273 | + return "SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END RET FROM ALL_VIEWS WHERE VIEW_NAME='" . Text::upper(viewName) . "' AND OWNER='" . Text::upper(schemaName) . "'"; |
| 274 | + } else { |
| 275 | + return "SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END RET FROM ALL_VIEWS WHERE VIEW_NAME='" . Text::upper(viewName) . "'"; |
| 276 | + } |
| 277 | + } |
| 278 | + |
| 279 | + /** |
| 280 | + * Generates the SQL to list all views of a schema or user |
| 281 | + */ |
| 282 | + public function listViews(string schemaName = null) -> string |
| 283 | + { |
| 284 | + if schemaName != "" { |
| 285 | + return "SELECT VIEW_NAME FROM ALL_VIEWS WHERE OWNER='" . Text::upper(schemaName) . "' ORDER BY VIEW_NAME"; |
| 286 | + } else { |
| 287 | + return "SELECT VIEW_NAME FROM ALL_VIEWS VIEW_NAME"; |
| 288 | + } |
| 289 | + } |
| 290 | + |
| 291 | + /** |
| 292 | + * Generates SQL checking for the existence of a schema.table |
| 293 | + * |
| 294 | + * <code> |
| 295 | + * echo $dialect->tableExists("posts", "blog"); |
| 296 | + * echo $dialect->tableExists("posts"); |
| 297 | + * </code> |
| 298 | + */ |
| 299 | + public function tableExists(string! tableName, string schemaName = null) -> string |
| 300 | + { |
| 301 | + if schemaName != "" { |
| 302 | + return "SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END RET FROM ALL_TABLES WHERE TABLE_NAME='" . Text::upper(tableName) . "' AND OWNER = '" . Text::upper(schemaName) . "'"; |
| 303 | + } else { |
| 304 | + return "SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END RET FROM ALL_TABLES WHERE TABLE_NAME='" . Text::upper(tableName) . "'"; |
| 305 | + } |
| 306 | + } |
| 307 | + |
| 308 | + /** |
| 309 | + * Generates SQL describing a table |
| 310 | + * |
| 311 | + * <code> |
| 312 | + * print_r($dialect->describeColumns("posts")); |
| 313 | + * </code> |
| 314 | + */ |
| 315 | + public function describeColumns(string! table, string schema = null) -> string |
| 316 | + { |
| 317 | + if schema != "" { |
| 318 | + return "SELECT TC.COLUMN_NAME, TC.DATA_TYPE, TC.DATA_LENGTH, TC.DATA_PRECISION, TC.DATA_SCALE, TC.NULLABLE, C.CONSTRAINT_TYPE, TC.DATA_DEFAULT, CC.POSITION FROM ALL_TAB_COLUMNS TC LEFT JOIN (ALL_CONS_COLUMNS CC JOIN ALL_CONSTRAINTS C ON (CC.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND CC.TABLE_NAME = C.TABLE_NAME AND CC.OWNER = C.OWNER AND C.CONSTRAINT_TYPE = 'P')) ON TC.TABLE_NAME = CC.TABLE_NAME AND TC.COLUMN_NAME = CC.COLUMN_NAME WHERE TC.TABLE_NAME = '" . Text::upper(table) . "' AND TC.OWNER = '" . Text::upper(schema) . "' ORDER BY TC.COLUMN_ID"; |
| 319 | + } else { |
| 320 | + return "SELECT TC.COLUMN_NAME, TC.DATA_TYPE, TC.DATA_LENGTH, TC.DATA_PRECISION, TC.DATA_SCALE, TC.NULLABLE, C.CONSTRAINT_TYPE, TC.DATA_DEFAULT, CC.POSITION FROM ALL_TAB_COLUMNS TC LEFT JOIN (ALL_CONS_COLUMNS CC JOIN ALL_CONSTRAINTS C ON (CC.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND CC.TABLE_NAME = C.TABLE_NAME AND CC.OWNER = C.OWNER AND C.CONSTRAINT_TYPE = 'P')) ON TC.TABLE_NAME = CC.TABLE_NAME AND TC.COLUMN_NAME = CC.COLUMN_NAME WHERE TC.TABLE_NAME = '" . Text::upper(table) . "' ORDER BY TC.COLUMN_ID"; |
| 321 | + } |
| 322 | + } |
| 323 | + |
| 324 | + /** |
| 325 | + * List all tables in database |
| 326 | + * |
| 327 | + * <code> |
| 328 | + * print_r($dialect->listTables("blog")) |
| 329 | + * </code> |
| 330 | + */ |
| 331 | + public function listTables(string schemaName = null) -> string |
| 332 | + { |
| 333 | + if schemaName != "" { |
| 334 | + return "SELECT TABLE_NAME, OWNER FROM ALL_TABLES WHERE OWNER='" . Text::upper(schemaName) . "' ORDER BY OWNER, TABLE_NAME"; |
| 335 | + } else { |
| 336 | + return "SELECT TABLE_NAME, OWNER FROM ALL_TABLES ORDER BY OWNER, TABLE_NAME"; |
| 337 | + } |
| 338 | + } |
| 339 | + |
| 340 | + /** |
| 341 | + * Generates SQL to query indexes on a table |
| 342 | + */ |
| 343 | + public function describeIndexes(string! table, string schema = null) -> string |
| 344 | + { |
| 345 | + if schema != "" { |
| 346 | + return "SELECT I.TABLE_NAME, 0 AS C0, I.INDEX_NAME, IC.COLUMN_POSITION, IC.COLUMN_NAME FROM ALL_INDEXES I JOIN ALL_IND_COLUMNS IC ON I.INDEX_NAME = IC.INDEX_NAME WHERE I.TABLE_NAME = '" . Text::upper(table) . "' AND IC.INDEX_OWNER = '" . Text::upper(schema) . "'"; |
| 347 | + } else { |
| 348 | + return "SELECT I.TABLE_NAME, 0 AS C0, I.INDEX_NAME, IC.COLUMN_POSITION, IC.COLUMN_NAME FROM ALL_INDEXES I JOIN ALL_IND_COLUMNS IC ON I.INDEX_NAME = IC.INDEX_NAME WHERE I.TABLE_NAME = '" . Text::upper(table) ."'"; |
| 349 | + } |
| 350 | + } |
| 351 | + |
| 352 | + /** |
| 353 | + * Generates SQL to query foreign keys on a table |
| 354 | + */ |
| 355 | + public function describeReferences(string! table, string schema = null) -> string |
| 356 | + { |
| 357 | + var sql; |
| 358 | + let sql = "SELECT AC.TABLE_NAME, CC.COLUMN_NAME, AC.CONSTRAINT_NAME, AC.R_OWNER, RCC.TABLE_NAME R_TABLE_NAME, RCC.COLUMN_NAME R_COLUMN_NAME FROM ALL_CONSTRAINTS AC JOIN ALL_CONS_COLUMNS CC ON AC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME JOIN ALL_CONS_COLUMNS RCC ON AC.R_OWNER = RCC.OWNER AND AC.R_CONSTRAINT_NAME = RCC.CONSTRAINT_NAME WHERE AC.CONSTRAINT_TYPE='R' "; |
| 359 | + |
| 360 | + if schema != "" { |
| 361 | + let sql .= "AND AC.OWNER='" . Text::upper(schema) . "' AND AC.TABLE_NAME = '" . Text::upper(table) . "'"; |
| 362 | + } else { |
| 363 | + let sql .= "AND AC.TABLE_NAME = '" . Text::upper(table) . "'"; |
| 364 | + } |
| 365 | + |
| 366 | + return sql; |
| 367 | + } |
| 368 | + |
| 369 | + /** |
| 370 | + * Generates the SQL to describe the table creation options |
| 371 | + */ |
| 372 | + public function tableOptions(string! table, string schema = null) -> string |
| 373 | + { |
| 374 | + return ""; |
| 375 | + } |
| 376 | + |
| 377 | + /** |
| 378 | + * Checks whether the platform supports savepoints |
| 379 | + */ |
| 380 | + public function supportsSavepoints() -> boolean |
| 381 | + { |
| 382 | + return false; |
| 383 | + } |
| 384 | + |
| 385 | + /** |
| 386 | + * Checks whether the platform supports releasing savepoints. |
| 387 | + */ |
| 388 | + public function supportsReleaseSavepoints() -> boolean |
| 389 | + { |
| 390 | + return false; |
| 391 | + } |
31 | 392 | }
|
0 commit comments