Completed
Push — master ( 117114...c02abd )
by smiley
04:21
created

src/Drivers/MSSqlSrvPDO.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Class MSSqlSrvPDO
4
 *
5
 * @filesource   MSSqlSrvPDO.php
6
 * @created      28.06.2017
7
 * @package      chillerlan\Database\Drivers
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Drivers;
14
15
use chillerlan\Database\Dialects\MSSQL;
16
use chillerlan\Traits\ImmutableSettingsInterface;
17
use PDO;
18
use Psr\{
19
	Log\LoggerInterface, SimpleCache\CacheInterface
20
};
21
22
/**
23
 * @property \PDO $db
24
 */
25
class MSSqlSrvPDO extends PDODriverAbstract{
26
27
	protected $drivername = 'sqlsrv';
28
	protected $dialect    = MSSQL::class;
29
30
	/**
31
	 * MSSqlSrvPDO constructor.
32
	 *
33
	 * @param \chillerlan\Traits\ImmutableSettingsInterface $options
34
	 * @param \Psr\SimpleCache\CacheInterface|null $cache
35
	 * @param \Psr\Log\LoggerInterface|null        $log
36
	 */
37
	public function __construct(ImmutableSettingsInterface $options, CacheInterface $cache = null, LoggerInterface $log = null){
38
		unset($this->pdo_options[PDO::ATTR_EMULATE_PREPARES]);
39
40
		// @todo
41
		$this->pdo_options[PDO::SQLSRV_ATTR_QUERY_TIMEOUT] = $options->mssql_timeout; // doesn't seem to have an effect
0 ignored issues
show
Accessing mssql_timeout on the interface chillerlan\Traits\ImmutableSettingsInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
42
		$this->pdo_options[PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE] = true;
43
		$this->pdo_options[PDO::SQLSRV_ATTR_ENCODING ] = PDO::SQLSRV_ENCODING_UTF8;
44
45
		parent::__construct($options, $cache);
46
	}
47
48
	/** @inheritdoc */
49
	protected function getDSN():string{
50
		$dsn = $this->drivername;
51
52
		$dsn .= ':Server='.$this->options->host;
53
54
		if(is_numeric($this->options->port)){
55
			$dsn .=  ','.$this->options->port;
56
		}
57
58
		$dsn .= ';Database='.$this->options->database;
59
60
		return $dsn;
61
	}
62
63
	/** @inheritdoc */
64
	public function getClientInfo():string{
65
		$info = $this->db->getAttribute(PDO::ATTR_CLIENT_VERSION);
66
67
		if(is_array($info) && !empty($info)){
68
			return $info['DriverVer'].' - '.$info['ExtensionVer'].' - '.$info['DriverODBCVer'];
69
		}
70
71
		return 'disconnected, no info available';
72
	}
73
74
	/** @inheritdoc */
75
	public function getServerInfo():?string{
76
		$info = $this->db->getAttribute(PDO::ATTR_SERVER_INFO);
77
78
		if(is_array($info) && !empty($info)){
79
			return PHP_OS.' - '.$info['SQLServerVersion'].' - '.$info['SQLServerName'].'/'.$info['CurrentDatabase'];
80
		}
81
82
		return 'disconnected, no info available';
83
	}
84
85
	/** @inheritdoc */
86
	public function raw(string $sql, string $index = null, bool $assoc = null){
87
88
		try{
89
			return $this->raw_query($sql, $index, $assoc);
90
		}
91
		catch(\Exception $e){
92
			return $this->silenceNonErrorException($e);
93
		}
94
95
	}
96
97
	/** @inheritdoc */
98
	public function prepared(string $sql, array $values = null, string $index = null, bool $assoc = null){
99
100
		try{
101
			return $this->prepared_query($sql, $values, $index, $assoc);
102
		}
103
		catch(\Exception $e){
104
			return $this->silenceNonErrorException($e);
105
		}
106
107
	}
108
109
	/**
110
	 * @param \Exception $e
111
	 *
112
	 * @return bool
113
	 * @throws \chillerlan\Database\Drivers\DriverException
114
	 */
115
	protected function silenceNonErrorException(\Exception $e){
116
		$message = $e->getMessage();
117
118
		// @todo silence.
119
		$x = explode(':', $message, 2);
120
121
		if(trim($x[0]) === 'SQLSTATE[IMSSP]'){
122
123
			if(strpos(strtolower($x[1]), 'no fields') > 0){
124
				return true;
125
			}
126
127
		}
128
129
		throw new DriverException('sql error: ['.get_called_class().'::raw()]'.$message);
130
	}
131
132
}
133