Skip to content

Commit afccb7f

Browse files
committed
all commit
0 parents  commit afccb7f

File tree

10 files changed

+399
-0
lines changed

10 files changed

+399
-0
lines changed

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/laravel-sqlsrv.iml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/php.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Md. Julfiker ali
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# laravel-sqlsrv
2+
Laravel integrate SQL server procedure execute
3+
4+
DB::executeFunction('function_name(:binding_1,:binding_n)', [':binding_1' => 'hi', ':binding_n' =>
5+
* 'bye'], PDO::PARAM_LOB)

composer.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "julfiker/laravel-sqlsrv",
3+
"description": "Laravel - SQL Server connectivity and procedure execute and othes",
4+
"require": {
5+
"php": ">=7.2"
6+
},
7+
"authors": [
8+
{
9+
"name": "Julfiker",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"autoload": {
14+
"psr-4": {
15+
"Julfiker\\SqlSrv\\": "src/"
16+
}
17+
},
18+
"minimum-stability": "dev",
19+
"scripts": {
20+
"post-install-cmd": [
21+
"php artisan clear-compiled",
22+
"php artisan optimize"
23+
]
24+
}
25+
}
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
<?php
2+
namespace Julfiker\SqlSrv\Connection;
3+
4+
use Illuminate\Database\Query\Processors\SqlServerProcessor;
5+
use Illuminate\Database\Schema\Grammars\SqlServerGrammar;
6+
use PDO;
7+
use PDOStatement;
8+
use Illuminate\Support\Str;
9+
use Illuminate\Database\Grammar;
10+
use Illuminate\Database\Connection;
11+
use Doctrine\DBAL\Connection as DoctrineConnection;
12+
13+
use Doctrine\DBAL\Driver\OCI8\Driver as DoctrineDriver;
14+
15+
16+
class SqlServerConnection extends Connection
17+
{
18+
const RECONNECT_ERRORS = 'reconnect_errors';
19+
20+
/**
21+
* @var string
22+
*/
23+
protected $schema;
24+
25+
26+
/**
27+
* @param PDO|\Closure $pdo
28+
* @param string $database
29+
* @param string $tablePrefix
30+
* @param array $config
31+
*/
32+
public function __construct($pdo, $database = '', $tablePrefix = '', array $config = []) {
33+
parent::__construct($pdo, $database, $tablePrefix, $config);
34+
}
35+
36+
37+
/**
38+
* Get doctrine connection.
39+
*
40+
* @return \Doctrine\DBAL\Connection
41+
*/
42+
public function getDoctrineConnection()
43+
{
44+
if (is_null($this->doctrineConnection)) {
45+
$data = ['pdo' => $this->getPdo(), 'user' => $this->getConfig('username')];
46+
$this->doctrineConnection = new DoctrineConnection(
47+
$data,
48+
$this->getDoctrineDriver()
49+
);
50+
}
51+
52+
return $this->doctrineConnection;
53+
}
54+
55+
56+
/**
57+
* @return DoctrineDriver
58+
*/
59+
protected function getDoctrineDriver()
60+
{
61+
return new DoctrineDriver();
62+
}
63+
64+
/**
65+
* Execute a Function and return its value.
66+
* Usage: DB::executeFunction('function_name(:binding_1,:binding_n)', [':binding_1' => 'hi', ':binding_n' =>
67+
* 'bye'], PDO::PARAM_LOB).
68+
*
69+
* @param string $functionName
70+
* @param array $bindings (kvp array)
71+
* @param int $returnType (PDO::PARAM_*)
72+
* @param int $length
73+
* @return mixed $returnType
74+
*/
75+
public function executeFunction($functionName, array $bindings = [], $returnType = PDO::PARAM_STR, $length = null)
76+
{
77+
$stmt = $this->createStatementFromFunction($functionName, $bindings);
78+
79+
$stmt = $this->addBindingsToStatement($stmt, $bindings);
80+
81+
$stmt->bindParam(':result', $result, $returnType, $length);
82+
$stmt->execute();
83+
84+
return $result;
85+
}
86+
87+
/**
88+
* Execute a Procedure and return its results.
89+
*
90+
* Usage: DB::executeProcedure($procedureName, $bindings).
91+
* $bindings looks like:
92+
* $bindings = [
93+
* 'p_userid' => $id
94+
* ];
95+
*
96+
* @param string $procedureName
97+
* @param array $bindings
98+
* @return bool
99+
*/
100+
public function executeProcedure($procedureName, array $bindings = [])
101+
{
102+
$stmt = $this->createStatementFromProcedure($procedureName, $bindings);
103+
$stmt = $this->addBindingsToStatement($stmt, $bindings);
104+
$stmt->execute();
105+
return $stmt;
106+
}
107+
108+
/**
109+
* Execute a Procedure and return its cursor result.
110+
* Usage: DB::executeProcedureWithCursor($procedureName, $bindings).
111+
*
112+
*
113+
* @param string $procedureName
114+
* @param array $bindings
115+
* @param string $cursorName
116+
* @return array
117+
*/
118+
public function executeProcedureWithCursor($procedureName, array $bindings = [], $cursorName = ':cursor')
119+
{
120+
$stmt = $this->createStatementFromProcedure($procedureName, $bindings, $cursorName);
121+
122+
$stmt = $this->addBindingsToStatement($stmt, $bindings);
123+
124+
$cursor = null;
125+
$stmt->bindParam($cursorName, $cursor, PDO::PARAM_STMT);
126+
$stmt->execute();
127+
128+
$statement = new Statement($cursor, $this->getPdo(), $this->getPdo()->getOptions());
129+
$statement->execute();
130+
$results = $statement->fetchAll(PDO::FETCH_OBJ);
131+
$statement->closeCursor();
132+
133+
return $results;
134+
}
135+
136+
/**
137+
* Creates sql command to run a procedure with bindings.
138+
*
139+
* @param string $procedureName
140+
* @param array $bindings
141+
* @param string|bool $cursor
142+
* @return string
143+
*/
144+
public function createSqlFromProcedure($procedureName, array $bindings, $cursor = false)
145+
{
146+
$paramsString = implode(',', array_map(function ($param) {
147+
return ':' . $param;
148+
}, array_keys($bindings)));
149+
150+
$prefix = count($bindings) ? ',' : '';
151+
$cursor = $cursor ? $prefix . $cursor : null;
152+
153+
return sprintf('exec %s %s%s;', $procedureName, $paramsString, $cursor);
154+
}
155+
156+
/**
157+
* Creates statement from procedure.
158+
*
159+
* @param string $procedureName
160+
* @param array $bindings
161+
* @param string|bool $cursorName
162+
* @return PDOStatement
163+
*/
164+
public function createStatementFromProcedure($procedureName, array $bindings, $cursorName = false)
165+
{
166+
$sql = $this->createSqlFromProcedure($procedureName, $bindings, $cursorName);
167+
return $this->getPdo()->prepare($sql);
168+
}
169+
170+
/**
171+
* Create statement from function.
172+
*
173+
* @param string $functionName
174+
* @param array $bindings
175+
* @return PDOStatement
176+
*/
177+
public function createStatementFromFunction($functionName, array $bindings)
178+
{
179+
$bindings = $bindings ? ':' . implode(', :', array_keys($bindings)) : '';
180+
181+
$sql = sprintf('begin :result := %s(%s); ', $functionName, $bindings);
182+
183+
return $this->getPdo()->prepare($sql);
184+
}
185+
186+
/**
187+
* Get the default query grammar instance.
188+
*
189+
* @return \Illuminate\Database\Grammar
190+
*/
191+
protected function getDefaultQueryGrammar()
192+
{
193+
return $this->withTablePrefix(new \Illuminate\Database\Query\Grammars\SqlServerGrammar());
194+
}
195+
196+
/**
197+
* Set the table prefix and return the grammar.
198+
*
199+
* @param \Illuminate\Database\Grammar $grammar
200+
* @return \Illuminate\Database\Grammar
201+
*/
202+
public function withTablePrefix(Grammar $grammar)
203+
{
204+
return $this->withSchemaPrefix(parent::withTablePrefix($grammar));
205+
}
206+
207+
/**
208+
* Set the schema prefix and return the grammar.
209+
*
210+
* @param \Illuminate\Database\Grammar $grammar
211+
* @return \Illuminate\Database\Grammar
212+
*/
213+
public function withSchemaPrefix(Grammar $grammar)
214+
{
215+
//$grammar->setSchemaPrefix($this->getConfigSchemaPrefix());
216+
217+
return $grammar;
218+
}
219+
220+
/**
221+
* Get config schema prefix.
222+
*
223+
* @return string
224+
*/
225+
protected function getConfigSchemaPrefix()
226+
{
227+
return isset($this->config['prefix_schema']) ? $this->config['prefix_schema'] : '';
228+
}
229+
230+
/**
231+
* Get the default schema grammar instance.
232+
*
233+
* @return \Illuminate\Database\Grammar
234+
*/
235+
protected function getDefaultSchemaGrammar()
236+
{
237+
return $this->withTablePrefix(new SqlServerGrammar());
238+
}
239+
240+
/**
241+
* Get the default post processor instance.
242+
*
243+
* @return SqlServerProcessor
244+
*/
245+
protected function getDefaultPostProcessor()
246+
{
247+
return new SqlServerProcessor();
248+
}
249+
250+
/**
251+
* Add bindings to statement.
252+
*
253+
* @param array $bindings
254+
* @param PDOStatement $stmt
255+
* @return PDOStatement
256+
*/
257+
public function addBindingsToStatement(PDOStatement $stmt, array $bindings)
258+
{
259+
foreach ($bindings as $key => &$binding) {
260+
$value = &$binding;
261+
$type = PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT;
262+
$length = 4000;
263+
$driver_options = null;
264+
265+
if (is_array($binding)) {
266+
$value = &$binding['value'];
267+
$type = array_key_exists('type', $binding) ? $binding['type'] : PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT;
268+
$length = array_key_exists('length', $binding) ? $binding['length'] : 4000;
269+
$driver_options = array_key_exists('encode', $binding) ? $binding['encode'] : null;
270+
}
271+
if ($length && $type)
272+
$stmt->bindParam(':' . $key, $value,$type,$length);
273+
else
274+
$stmt->bindParam(':' . $key, $value);
275+
}
276+
return $stmt;
277+
}
278+
}

0 commit comments

Comments
 (0)