Subversion Repositories oidplus

Rev

Rev 1086 | Rev 1130 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1086 Rev 1116
Line 27... Line 27...
27
        protected /*bool*/ $connected = false;
27
        protected /*bool*/ $connected = false;
28
        protected /*?bool*/ $html = null;
28
        protected /*?bool*/ $html = null;
29
        protected /*?string*/ $last_query = null;
29
        protected /*?string*/ $last_query = null;
30
        protected /*bool*/ $slangDetectionDone = false;
30
        protected /*bool*/ $slangDetectionDone = false;
31
 
31
 
-
 
32
        /**
-
 
33
         * @param string $sql
-
 
34
         * @param array|null $prepared_args
-
 
35
         * @return OIDplusQueryResult
-
 
36
         * @throws OIDplusException
-
 
37
         */
32
        protected abstract function doQuery(string $sql, /*?array*/ $prepared_args=null): OIDplusQueryResult;
38
        protected abstract function doQuery(string $sql, array $prepared_args=null): OIDplusQueryResult;
-
 
39
 
-
 
40
        /**
-
 
41
         * @return string
-
 
42
         */
33
        public abstract function error(): string;
43
        public abstract function error(): string;
-
 
44
 
-
 
45
        /**
-
 
46
         * @return void
-
 
47
         */
34
        public abstract function transaction_begin()/*: void*/;
48
        public abstract function transaction_begin()/*: void*/;
-
 
49
 
-
 
50
        /**
-
 
51
         * @return void
-
 
52
         */
35
        public abstract function transaction_commit()/*: void*/;
53
        public abstract function transaction_commit()/*: void*/;
-
 
54
 
-
 
55
        /**
-
 
56
         * @return void
-
 
57
         */
36
        public abstract function transaction_rollback()/*: void*/;
58
        public abstract function transaction_rollback()/*: void*/;
-
 
59
 
-
 
60
        /**
-
 
61
         * @return bool
-
 
62
         */
37
        public abstract function transaction_supported(): bool;
63
        public abstract function transaction_supported(): bool;
-
 
64
 
-
 
65
        /**
-
 
66
         * @return int
-
 
67
         */
38
        public abstract function transaction_level(): int;
68
        public abstract function transaction_level(): int;
-
 
69
 
-
 
70
        /**
-
 
71
         * @return void
-
 
72
         */
39
        protected abstract function doConnect()/*: void*/;
73
        protected abstract function doConnect()/*: void*/;
-
 
74
 
-
 
75
        /**
-
 
76
         * @return void
-
 
77
         */
40
        protected abstract function doDisconnect()/*: void*/;
78
        protected abstract function doDisconnect()/*: void*/;
41
 
79
 
-
 
80
        /**
-
 
81
         * @return OIDplusDatabasePlugin|null
-
 
82
         */
42
        public function getPlugin()/*: ?OIDplusDatabasePlugin*/ {
83
        public function getPlugin()/*: ?OIDplusDatabasePlugin*/ {
43
                $res = null;
84
                $res = null;
44
                $plugins = OIDplus::getDatabasePlugins();
85
                $plugins = OIDplus::getDatabasePlugins();
45
                foreach ($plugins as $plugin) {
86
                foreach ($plugins as $plugin) {
46
                        if (get_class($this) == get_class($plugin::newConnection($this))) {
87
                        if (get_class($this) == get_class($plugin::newConnection())) {
47
                                return $plugin;
88
                                return $plugin;
48
                        }
89
                        }
49
                }
90
                }
50
                return $res;
91
                return $res;
51
        }
92
        }
52
 
93
 
-
 
94
        /**
-
 
95
         * @return int
-
 
96
         * @throws OIDplusException
-
 
97
         */
53
        public function insert_id(): int {
98
        public function insert_id(): int {
54
                // This is the "fallback" variant. If your database provider (e.g. PDO) supports
99
                // This is the "fallback" variant. If your database provider (e.g. PDO) supports
55
                // a function to detect the last inserted id, please override this
100
                // a function to detect the last inserted id, please override this
56
                // function in order to use that specialized function (since it is usually
101
                // function in order to use that specialized function (since it is usually
57
                // more reliable).
102
                // more reliable).
58
                return $this->getSlang()->insert_id($this);
103
                return $this->getSlang()->insert_id($this);
59
        }
104
        }
60
 
105
 
-
 
106
        /**
-
 
107
         * @param string $sql
-
 
108
         * @return array[]
-
 
109
         * @throws OIDplusException
-
 
110
         */
61
        public final function getTable(string $sql) {
111
        public final function getTable(string $sql): array {
62
                $out = array();
112
                $out = array();
63
                $res = $this->query($sql);
113
                $res = $this->query($sql);
64
                while ($row = $res->fetch_array()) {
114
                while ($row = $res->fetch_array()) {
65
                        $out[] = $row;
115
                        $out[] = $row;
66
                }
116
                }
67
                return $out;
117
                return $out;
68
        }
118
        }
69
 
119
 
-
 
120
        /**
-
 
121
         * @param string $sql
-
 
122
         * @return mixed|null
-
 
123
         * @throws OIDplusException
-
 
124
         */
70
        public final function getScalar(string $sql) {
125
        public final function getScalar(string $sql) {
71
                $res = $this->query($sql);
126
                $res = $this->query($sql);
72
                $row = $res->fetch_array();
127
                $row = $res->fetch_array();
73
                return $row ? reset($row) : null;
128
                return $row ? reset($row) : null;
74
        }
129
        }
75
 
130
 
-
 
131
        /**
-
 
132
         * @param string $sql
-
 
133
         * @param array|null $prepared_args
-
 
134
         * @return OIDplusQueryResult
-
 
135
         * @throws OIDplusException
-
 
136
         */
76
        public final function query(string $sql, /*?array*/ $prepared_args=null): OIDplusQueryResult {
137
        public final function query(string $sql, /*?array*/ $prepared_args=null): OIDplusQueryResult {
77
 
138
 
78
                $query_logfile = OIDplus::baseConfig()->getValue('QUERY_LOGFILE', '');
139
                $query_logfile = OIDplus::baseConfig()->getValue('QUERY_LOGFILE', '');
79
                if (!empty($query_logfile)) {
140
                if (!empty($query_logfile)) {
80
                        $ts = explode(" ",microtime());
141
                        $ts = explode(" ",microtime());
Line 98... Line 159...
98
                }
159
                }
99
 
160
 
100
                return $this->doQuery($sql, $prepared_args);
161
                return $this->doQuery($sql, $prepared_args);
101
        }
162
        }
102
 
163
 
-
 
164
        /**
-
 
165
         * @return void
-
 
166
         * @throws OIDplusException
-
 
167
         */
103
        public final function connect()/*: void*/ {
168
        public final function connect()/*: void*/ {
104
                if ($this->connected) return;
169
                if ($this->connected) return;
105
                $this->beforeConnect();
170
                $this->beforeConnect();
106
                $this->doConnect();
171
                $this->doConnect();
107
                $this->connected = true;
172
                $this->connected = true;
108
                OIDplus::register_shutdown_function(array($this, 'disconnect'));
173
                OIDplus::register_shutdown_function(array($this, 'disconnect'));
109
                $this->afterConnectMandatory();
174
                $this->afterConnectMandatory();
110
                $this->afterConnect();
175
                $this->afterConnect();
111
        }
176
        }
112
 
177
 
-
 
178
        /**
-
 
179
         * @return void
-
 
180
         */
113
        public final function disconnect()/*: void*/ {
181
        public final function disconnect()/*: void*/ {
114
                if (!$this->connected) return;
182
                if (!$this->connected) return;
115
                $this->beforeDisconnect();
183
                $this->beforeDisconnect();
116
                $this->doDisconnect();
184
                $this->doDisconnect();
117
                $this->connected = false;
185
                $this->connected = false;
118
                $this->afterDisconnect();
186
                $this->afterDisconnect();
119
        }
187
        }
120
 
188
 
-
 
189
        /**
-
 
190
         * @param string $fieldname
-
 
191
         * @param string $order
-
 
192
         * @return string
-
 
193
         * @throws OIDplusException
-
 
194
         */
121
        public function natOrder($fieldname, $order='asc'): string {
195
        public function natOrder(string $fieldname, string $order='asc'): string {
122
                $slang = $this->getSlang();
196
                $slang = $this->getSlang();
123
                if (!is_null($slang)) {
197
                if (!is_null($slang)) {
124
                        return $slang->natOrder($fieldname, $order);
198
                        return $slang->natOrder($fieldname, $order);
125
                } else {
199
                } else {
126
                        $order = strtolower($order);
200
                        $order = strtolower($order);
Line 131... Line 205...
131
                        // For (yet) unsupported DBMS, we do not offer natural sort
205
                        // For (yet) unsupported DBMS, we do not offer natural sort
132
                        return "$fieldname $order";
206
                        return "$fieldname $order";
133
                }
207
                }
134
        }
208
        }
135
 
209
 
-
 
210
        /**
-
 
211
         * @return void
-
 
212
         */
136
        protected function beforeDisconnect()/*: void*/ {}
213
        protected function beforeDisconnect()/*: void*/ {}
137
 
214
 
-
 
215
        /**
-
 
216
         * @return void
-
 
217
         */
138
        protected function afterDisconnect()/*: void*/ {}
218
        protected function afterDisconnect()/*: void*/ {}
139
 
219
 
-
 
220
        /**
-
 
221
         * @return void
-
 
222
         */
140
        protected function beforeConnect()/*: void*/ {}
223
        protected function beforeConnect()/*: void*/ {}
141
 
224
 
-
 
225
        /**
-
 
226
         * @return void
-
 
227
         */
142
        protected function afterConnect()/*: void*/ {}
228
        protected function afterConnect()/*: void*/ {}
143
 
229
 
-
 
230
        /**
-
 
231
         * @return void
-
 
232
         * @throws OIDplusConfigInitializationException
-
 
233
         * @throws OIDplusException
-
 
234
         */
144
        private function afterConnectMandatory()/*: void*/ {
235
        private function afterConnectMandatory()/*: void*/ {
145
                // Check if the config table exists. This is important because the database version is stored in it
236
                // Check if the config table exists. This is important because the database version is stored in it
146
                $this->initRequireTables(array('config'));
237
                $this->initRequireTables(array('config'));
147
 
238
 
148
                // Do the database tables need an update?
239
                // Do the database tables need an update?
Line 161... Line 252...
161
                // PDO would automatically roll-back. Therefore, we detect the slang right at the beginning,
252
                // PDO would automatically roll-back. Therefore, we detect the slang right at the beginning,
162
                // before any transaction is used.
253
                // before any transaction is used.
163
                $this->getSlang();
254
                $this->getSlang();
164
        }
255
        }
165
 
256
 
-
 
257
        /**
-
 
258
         * @param string[] $tableNames
-
 
259
         * @return void
-
 
260
         * @throws OIDplusConfigInitializationException
-
 
261
         * @throws OIDplusException
-
 
262
         */
166
        private function initRequireTables($tableNames)/*: void*/ {
263
        private function initRequireTables(array $tableNames)/*: void*/ {
167
                $msgs = array();
264
                $msgs = array();
168
                foreach ($tableNames as $tableName) {
265
                foreach ($tableNames as $tableName) {
169
                        $prefix = OIDplus::baseConfig()->getValue('TABLENAME_PREFIX', '');
266
                        $prefix = OIDplus::baseConfig()->getValue('TABLENAME_PREFIX', '');
170
                        if (!$this->tableExists($prefix.$tableName)) {
267
                        if (!$this->tableExists($prefix.$tableName)) {
171
                                $msgs[] = _L('Table %1 is missing!',$prefix.$tableName);
268
                                $msgs[] = _L('Table %1 is missing!',$prefix.$tableName);
Line 174... Line 271...
174
                if (count($msgs) > 0) {
271
                if (count($msgs) > 0) {
175
                        throw new OIDplusConfigInitializationException(implode("\n\n",$msgs));
272
                        throw new OIDplusConfigInitializationException(implode("\n\n",$msgs));
176
                }
273
                }
177
        }
274
        }
178
 
275
 
-
 
276
        /**
-
 
277
         * @param string $tableName
-
 
278
         * @return bool
-
 
279
         */
179
        public function tableExists($tableName): bool {
280
        public function tableExists(string $tableName): bool {
180
                try {
281
                try {
181
                        // Attention: This query could interrupt transactions if Rollback-On-Error is enabled
282
                        // Attention: This query could interrupt transactions if Rollback-On-Error is enabled
182
                        $this->query("select 0 from ".$tableName." where 1=0");
283
                        $this->query("select 0 from ".$tableName." where 1=0");
183
                        return true;
284
                        return true;
184
                } catch (\Exception $e) {
285
                } catch (\Exception $e) {
185
                        return false;
286
                        return false;
186
                }
287
                }
187
        }
288
        }
188
 
289
 
-
 
290
        /**
-
 
291
         * @return bool
-
 
292
         */
189
        public function isConnected(): bool {
293
        public function isConnected(): bool {
190
                return $this->connected;
294
                return $this->connected;
191
        }
295
        }
192
 
296
 
-
 
297
        /**
-
 
298
         * @param bool $html
-
 
299
         * @return void
-
 
300
         */
193
        public function init($html = true)/*: void*/ {
301
        public function init(bool $html = true)/*: void*/ {
194
                $this->html = $html;
302
                $this->html = $html;
195
        }
303
        }
196
 
304
 
-
 
305
        /**
-
 
306
         * @return string
-
 
307
         * @throws OIDplusException
-
 
308
         */
197
        public function sqlDate(): string {
309
        public function sqlDate(): string {
198
                $slang = $this->getSlang();
310
                $slang = $this->getSlang();
199
                if (!is_null($slang)) {
311
                if (!is_null($slang)) {
200
                        return $slang->sqlDate();
312
                        return $slang->sqlDate();
201
                } else {
313
                } else {
202
                        return "'" . date('Y-m-d H:i:s') . "'";
314
                        return "'" . date('Y-m-d H:i:s') . "'";
203
                }
315
                }
204
        }
316
        }
205
 
317
 
-
 
318
        /**
-
 
319
         * @param bool $mustExist
-
 
320
         * @return OIDplusSqlSlangPlugin|null
-
 
321
         * @throws OIDplusConfigInitializationException
-
 
322
         * @throws OIDplusException
-
 
323
         */
206
        protected function doGetSlang(bool $mustExist=true)/*: ?OIDplusSqlSlangPlugin*/ {
324
        protected function doGetSlang(bool $mustExist=true)/*: ?OIDplusSqlSlangPlugin*/ {
207
                $res = null;
325
                $res = null;
208
 
326
 
209
                if (OIDplus::baseConfig()->exists('FORCE_DBMS_SLANG')) {
327
                if (OIDplus::baseConfig()->exists('FORCE_DBMS_SLANG')) {
210
                        $name = OIDplus::baseConfig()->getValue('FORCE_DBMS_SLANG', '');
328
                        $name = OIDplus::baseConfig()->getValue('FORCE_DBMS_SLANG', '');
Line 232... Line 350...
232
                }
350
                }
233
 
351
 
234
                return $res;
352
                return $res;
235
        }
353
        }
236
 
354
 
-
 
355
        /**
-
 
356
         * @param bool $mustExist
-
 
357
         * @return OIDplusSqlSlangPlugin|null
-
 
358
         * @throws OIDplusConfigInitializationException
-
 
359
         * @throws OIDplusException
-
 
360
         */
237
        public final function getSlang(bool $mustExist=true)/*: ?OIDplusSqlSlangPlugin*/ {
361
        public final function getSlang(bool $mustExist=true)/*: ?OIDplusSqlSlangPlugin*/ {
238
                static /*?OIDplusSqlSlangPlugin*/ $slangCache = null;
362
                static /*?OIDplusSqlSlangPlugin*/ $slangCache = null;
239
 
363
 
240
                if ($this->slangDetectionDone) {
364
                if ($this->slangDetectionDone) {
241
                        return $slangCache;
365
                        return $slangCache;