Skip to content

Commit e908321

Browse files
committed
Added implementation Phalcon\Db\Dialect\Oracle
1 parent 9d381ad commit e908321

File tree

2 files changed

+365
-4
lines changed

2 files changed

+365
-4
lines changed

phalcon/db/dialect.zep

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ namespace Phalcon\Db;
2424
* Phalcon\Db\Dialect
2525
*
2626
* This is the base class to each database dialect. This implements
27-
* common methods to transform intermediate code into its RDBM related syntax
27+
* common methods to transform intermediate code into its RDBMS related syntax
2828
*/
29-
abstract class Dialect
29+
abstract class Dialect implements DialectInterface
3030
{
3131

3232
protected _escapeChar;

phalcon/db/dialect/oracle.zep

+363-2
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,378 @@
1515
| Authors: Andres Gutierrez <andres@phalconphp.com> |
1616
| Eduar Carvajal <eduar@phalconphp.com> |
1717
| Marcio Paiva <mpaivabarbosa@gmail.com> |
18+
| Stanislav Kiryukhin <korsar.zn@gmail.com> |
1819
+------------------------------------------------------------------------+
1920
*/
2021

2122
namespace Phalcon\Db\Dialect;
2223

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+
2332
/**
2433
* Phalcon\Db\Dialect\Oracle
2534
*
26-
* Generates database specific SQL for the Oracle RBDM
35+
* Generates database specific SQL for the Oracle RDBMS
2736
*/
28-
class Oracle //extends \Phalcon\Db\Dialect //implements Phalcon\Db\DialectInterface
37+
class Oracle extends Dialect
2938
{
3039
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+
}
31392
}

0 commit comments

Comments
 (0)