Rev 231 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 231 | Rev 236 | ||
---|---|---|---|
Line 22... | Line 22... | ||
22 | class OIDplusDataBasePluginPDO extends OIDplusDataBasePlugin { |
22 | class OIDplusDataBasePluginPDO extends OIDplusDataBasePlugin { |
23 | private $pdo; |
23 | private $pdo; |
24 | private $last_query; |
24 | private $last_query; |
25 | private $prepare_cache = array(); |
25 | private $prepare_cache = array(); |
26 | 26 | ||
27 | public static function getPluginInformation() { |
27 | public static function getPluginInformation(): array { |
28 | $out = array(); |
28 | $out = array(); |
29 | $out['name'] = 'PDO'; |
29 | $out['name'] = 'PDO'; |
30 | $out['author'] = 'ViaThinkSoft'; |
30 | $out['author'] = 'ViaThinkSoft'; |
31 | $out['version'] = null; |
31 | $out['version'] = null; |
32 | $out['descriptionHTML'] = null; |
32 | $out['descriptionHTML'] = null; |
33 | return $out; |
33 | return $out; |
34 | } |
34 | } |
35 | 35 | ||
36 | public static function name() { |
36 | public static function name(): string { |
37 | return "PDO"; |
37 | return "PDO"; |
38 | } |
38 | } |
39 | 39 | ||
40 | public function query($sql, $prepared_args=null) { |
40 | public function query($sql, $prepared_args=null): OIDplusQueryResult { |
41 | $this->last_query = $sql; |
41 | $this->last_query = $sql; |
42 | if (is_null($prepared_args)) { |
42 | if (is_null($prepared_args)) { |
43 | return $this->pdo->query($sql); |
43 | $res = $this->pdo->query($sql); |
44 | } else { |
- | |
45 | - | ||
46 | 44 | ||
- | 45 | if ($res === false) { |
|
- | 46 | throw new OIDplusSQLException($sql, $this->error()); |
|
- | 47 | } else { |
|
- | 48 | return new OIDplusQueryResultPDO($res); |
|
- | 49 | } |
|
- | 50 | } else { |
|
47 | // TEST: Emulate the prepared statement |
51 | // TEST: Emulate the prepared statement |
48 | /* |
52 | /* |
49 | foreach ($prepared_args as $arg) { |
53 | foreach ($prepared_args as $arg) { |
50 | $needle = '?'; |
54 | $needle = '?'; |
51 | $replace = "'$arg'"; // TODO: types |
55 | $replace = "'$arg'"; // TODO: types |
52 | $pos = strpos($sql, $needle); |
56 | $pos = strpos($sql, $needle); |
53 | if ($pos !== false) { |
57 | if ($pos !== false) { |
54 | $sql = substr_replace($sql, $replace, $pos, strlen($needle)); |
58 | $sql = substr_replace($sql, $replace, $pos, strlen($needle)); |
55 | } |
59 | } |
56 | } |
60 | } |
57 | return $this->pdo->query($sql); |
61 | return OIDplusQueryResultPDO($this->pdo->query($sql)); |
58 | */ |
62 | */ |
59 | 63 | ||
60 | - | ||
61 | if (!is_array($prepared_args)) { |
64 | if (!is_array($prepared_args)) { |
62 | throw new Exception("'prepared_args' must be either NULL or an ARRAY."); |
65 | throw new Exception("'prepared_args' must be either NULL or an ARRAY."); |
63 | } |
66 | } |
64 | if (isset($this->prepare_cache[$sql])) { |
67 | if (isset($this->prepare_cache[$sql])) { |
65 | $ps = $this->prepare_cache[$sql]; |
68 | $ps = $this->prepare_cache[$sql]; |
66 | } else { |
69 | } else { |
67 | $ps = $this->pdo->prepare($sql); |
70 | $ps = $this->pdo->prepare($sql); |
68 | if (!$ps) { |
71 | if (!$ps) { |
69 | throw new Exception("Cannot prepare statement '$sql'"); |
72 | throw new OIDplusSQLException($sql, 'Cannot prepare statement'); |
70 | } |
73 | } |
71 | $this->prepare_cache[$sql] = $ps; |
74 | $this->prepare_cache[$sql] = $ps; |
72 | } |
75 | } |
73 | if (!$ps->execute($prepared_args)) { |
76 | if (!$ps->execute($prepared_args)) { |
74 | // Note: Our plugins prepare the configs by trying to insert stuff, which raises a Primary Key exception. So we cannot throw an Exception. |
- | |
75 | return false; |
77 | throw new OIDplusSQLException($sql, $this->error()); |
76 | } |
- | |
77 | return $ps; |
- | |
78 | } |
- | |
79 | } |
78 | } |
80 | public function num_rows($res) { |
- | |
81 | if (!is_object($res)) { |
- | |
82 | throw new Exception("num_rows called on non object. Last query: ".$this->last_query); |
- | |
83 | } else { |
- | |
84 | return $res->rowCount(); |
79 | return new OIDplusQueryResultPDO($ps); |
85 | } |
- | |
86 | } |
- | |
87 | public function fetch_array($res) { |
- | |
88 | if (!is_object($res)) { |
- | |
89 | throw new Exception("fetch_array called on non object. Last query: ".$this->last_query); |
- | |
90 | } else { |
- | |
91 | return $res->fetch(PDO::FETCH_ASSOC); |
- | |
92 | } |
80 | } |
93 | } |
81 | } |
94 | public function fetch_object($res) { |
- | |
95 | if (!is_object($res)) { |
- | |
96 | throw new Exception("fetch_object called on non object. Last query: ".$this->last_query); |
- | |
97 | } else { |
- | |
98 | return $res->fetch(PDO::FETCH_OBJ); |
- | |
99 | } |
- | |
100 | } |
82 | |
101 | public function insert_id() { |
83 | public function insert_id(): int { |
102 | return $this->pdo->lastInsertId(); |
84 | return $this->pdo->lastInsertId(); |
103 | } |
85 | } |
- | 86 | ||
104 | public function error() { |
87 | public function error(): string { |
105 | return $this->pdo->errorInfo()[2]; |
88 | return $this->pdo->errorInfo()[2]; |
106 | } |
89 | } |
- | 90 | ||
107 | private $html = null; |
91 | private $html = null; |
108 | public function init($html = true) { |
92 | public function init($html = true): void { |
109 | $this->html = $html; |
93 | $this->html = $html; |
110 | } |
94 | } |
- | 95 | ||
111 | public function connect() { |
96 | public function connect(): void { |
112 | try { |
97 | try { |
113 | $options = [ |
98 | $options = [ |
114 | # PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
99 | # PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
115 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, |
100 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, |
116 | PDO::ATTR_EMULATE_PREPARES => true, |
101 | PDO::ATTR_EMULATE_PREPARES => true, |
Line 138... | Line 123... | ||
138 | $this->connected = true; |
123 | $this->connected = true; |
139 | } |
124 | } |
140 | 125 | ||
141 | private $intransaction = false; |
126 | private $intransaction = false; |
142 | 127 | ||
143 | public function transaction_begin() { |
128 | public function transaction_begin(): void { |
144 | if ($this->intransaction) throw new Exception("Nested transactions are not supported by this database plugin."); |
129 | if ($this->intransaction) throw new Exception("Nested transactions are not supported by this database plugin."); |
145 | $this->pdo->beginTransaction(); |
130 | $this->pdo->beginTransaction(); |
146 | $this->intransaction = true; |
131 | $this->intransaction = true; |
147 | } |
132 | } |
148 | 133 | ||
149 | public function transaction_commit() { |
134 | public function transaction_commit(): void { |
150 | $this->pdo->commit(); |
135 | $this->pdo->commit(); |
151 | $this->intransaction = false; |
136 | $this->intransaction = false; |
152 | } |
137 | } |
153 | 138 | ||
154 | public function transaction_rollback() { |
139 | public function transaction_rollback(): void { |
155 | $this->pdo->rollBack(); |
140 | $this->pdo->rollBack(); |
156 | $this->intransaction = false; |
141 | $this->intransaction = false; |
157 | } |
142 | } |
158 | } |
143 | } |
- | 144 | ||
- | 145 | class OIDplusQueryResultPDO extends OIDplusQueryResult { |
|
- | 146 | protected $no_resultset; |
|
- | 147 | protected $res; |
|
- | 148 | ||
- | 149 | public function __construct($res) { |
|
- | 150 | $this->no_resultset = $res === false; |
|
- | 151 | $this->res = $res; |
|
- | 152 | } |
|
- | 153 | ||
- | 154 | public function containsResultSet(): bool { |
|
- | 155 | return !$this->no_resultset; |
|
- | 156 | } |
|
- | 157 | ||
- | 158 | public function num_rows(): int { |
|
- | 159 | if ($this->no_resultset) throw new Exception("The query has returned no result set (i.e. it was not a SELECT query)"); |
|
- | 160 | return $this->res->rowCount(); |
|
- | 161 | } |
|
- | 162 | ||
- | 163 | public function fetch_array()/*: ?array*/ { |
|
- | 164 | if ($this->no_resultset) throw new Exception("The query has returned no result set (i.e. it was not a SELECT query)"); |
|
- | 165 | $ret = $this->res->fetch(PDO::FETCH_ASSOC); |
|
- | 166 | if ($ret === false) $ret = null; |
|
- | 167 | return $ret; |
|
- | 168 | } |
|
- | 169 | ||
- | 170 | public function fetch_object()/*: ?object*/ { |
|
- | 171 | if ($this->no_resultset) throw new Exception("The query has returned no result set (i.e. it was not a SELECT query)"); |
|
- | 172 | $ret = $this->res->fetch(PDO::FETCH_OBJ); |
|
- | 173 | if ($ret === false) $ret = null; |
|
- | 174 | return $ret; |
|
- | 175 | } |
|
- | 176 | } |