Skip to content

Commit f5f6149

Browse files
author
java-tester-x
committed
Implement support of Oracle driver
1 parent 1bd93c3 commit f5f6149

File tree

17 files changed

+209
-0
lines changed

17 files changed

+209
-0
lines changed

laravel/database/connection.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ protected function grammar()
9292
case 'pgsql':
9393
return $this->grammar = new Query\Grammars\Postgres($this);
9494

95+
case 'oracle':
96+
return $this->grammar = new Query\Grammars\Oracle($this);
97+
9598
default:
9699
return $this->grammar = new Query\Grammars\Grammar($this);
97100
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php namespace Laravel\Database\Connectors; use PDO;
2+
3+
/**
4+
* @author zacwasielewski
5+
* @link https://github.com/zacwasielewski/laravel-pdo-oci-driver
6+
*/
7+
class Oracle extends Connector {
8+
9+
/**
10+
* Establish a PDO database connection.
11+
*
12+
* @param array $config
13+
* @return PDO
14+
*/
15+
public function connect($config)
16+
{
17+
extract($config);
18+
19+
// The developer has the freedom of specifying a port for the Oracle database
20+
// or no port will be used to make the connection by PDO.
21+
if (isset($config['port']))
22+
{
23+
$port = ":{$config['port']}";
24+
}
25+
else
26+
{
27+
$port = "";
28+
}
29+
30+
// If no host is specified, the database name must be defined in the
31+
// tnsnames.ora file in %ORACLE_HOME%\network\admin
32+
if (isset($config['host']))
33+
{
34+
$dsn = "oci:dbname={$config['host']}{$port}/{$config['database']}";
35+
}
36+
else
37+
{
38+
$dsn = "oci:dbname={$config['database']}";
39+
}
40+
41+
// If a character set has been specified, we'll execute a query against
42+
// the database to set the correct character set. By default, this is
43+
// set to UTF-8 which should be fine for most scenarios.
44+
if (isset($config['charset']))
45+
{
46+
$dsn .= ";charset={$config['charset']}";
47+
} else {
48+
$dsn .= ";charset=AL32UTF8";
49+
}
50+
51+
$connection = new PDO($dsn, $username, $password, $this->options($config));
52+
53+
return $connection;
54+
}
55+
56+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php namespace Laravel\Database\Query\Grammars;
2+
3+
use Laravel\Database\Query;
4+
5+
class Oracle extends Grammar {
6+
7+
/**
8+
* The format for properly saving a DateTime.
9+
*
10+
* @var string
11+
*/
12+
public $datetime = 'Y-m-d H:i:s';
13+
14+
15+
/**
16+
* Compile a SQL INSERT and get ID statement from a Query instance.
17+
*
18+
* @param Query $query
19+
* @param array $values
20+
* @param string $column
21+
* @return string
22+
*/
23+
public function insert_get_id(Query $query, $values, $column)
24+
{
25+
return $this->insert($query, $values)." RETURNING $column";
26+
}
27+
28+
/**
29+
* Compile a SQL SELECT statement from a Query instance.
30+
*
31+
* @param Query $query
32+
* @return string
33+
*/
34+
public function select(Query $query)
35+
{
36+
$sql = parent::components($query);
37+
38+
// SQL Server does not currently implement an "OFFSET" type keyword, so we
39+
// actually have to generate the ANSI standard SQL for doing offset like
40+
// functionality. OFFSET is in SQL Server 2012, however.
41+
if ($query->offset > 0)
42+
{
43+
return $this->ansi_offset($query, $sql);
44+
}
45+
46+
// Once all of the clauses have been compiled, we can join them all as
47+
// one statement. Any segments that are null or an empty string will
48+
// be removed from the array before imploding.
49+
return $this->concatenate($sql);
50+
}
51+
52+
/**
53+
* Compile the SELECT clause for a query.
54+
*
55+
* @param Query $query
56+
* @return string
57+
*/
58+
protected function selects(Query $query)
59+
{
60+
if ( ! is_null($query->aggregate)) return;
61+
62+
$select = ($query->distinct) ? 'SELECT DISTINCT ' : 'SELECT ';
63+
64+
return $select.$this->columnize($query->selects);
65+
}
66+
67+
/**
68+
* Generate the ANSI standard SQL for an offset clause.
69+
*
70+
* @param Query $query
71+
* @param array $components
72+
* @return array
73+
*/
74+
protected function ansi_offset(Query $query, $components)
75+
{
76+
// An ORDER BY clause is required to make this offset query work, so if
77+
// one doesn't exist, we'll just create a dummy clause to trick the
78+
// database and pacify it so it doesn't complain about the query.
79+
if ( ! isset($components['orderings']))
80+
{
81+
$components['orderings'] = 'ORDER BY 1';
82+
}
83+
84+
// We need to add the row number to the query so we can compare it to
85+
// the offset and limit values given for the statement. So we'll add
86+
// an expression to the select for the row number.
87+
$orderings = $components['orderings'];
88+
89+
$components['selects'] .= ", ROW_NUMBER() OVER ({$orderings}) AS RowNum";
90+
91+
unset($components['orderings']);
92+
93+
$start = $query->offset + 1;
94+
95+
// Next we need to calculate the constraint that should be placed on
96+
// the row number to get the correct offset and limit on the query.
97+
// If there is not a limit, we'll just handle the offset.
98+
if ($query->limit > 0)
99+
{
100+
$finish = $query->offset + $query->limit;
101+
102+
$constraint = "BETWEEN {$start} AND {$finish}";
103+
}
104+
else
105+
{
106+
$constraint = ">= {$start}";
107+
}
108+
109+
// We're finally ready to build the final SQL query so we'll create
110+
// a common table expression with the query and select all of the
111+
// results with row numbers between the limit and offset.
112+
$sql = $this->concatenate($components);
113+
114+
return "SELECT * FROM ($sql) TempTable WHERE RowNum {$constraint}";
115+
}
116+
117+
/**
118+
* Compile the LIMIT clause for a query.
119+
*
120+
* @param Query $query
121+
* @return string
122+
*/
123+
protected function limit(Query $query)
124+
{
125+
return '';
126+
}
127+
128+
/**
129+
* Compile the OFFSET clause for a query.
130+
*
131+
* @param Query $query
132+
* @return string
133+
*/
134+
protected function offset(Query $query)
135+
{
136+
return '';
137+
}
138+
139+
}

laravel/database/schema.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ public static function grammar(Connection $connection)
186186

187187
case 'sqlite':
188188
return new Schema\Grammars\SQLite($connection);
189+
190+
case 'oracle':
191+
return new Schema\Grammars\Oracle($connection);
189192
}
190193

191194
throw new \Exception("Schema operations not supported for [$driver].");
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php namespace Laravel\Database\Schema\Grammars;
2+
3+
use Laravel\Fluent;
4+
use Laravel\Database\Schema\Table;
5+
6+
class Oracle extends Grammar {
7+
8+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)