Issues (100)

src/Adodb/Db.php (16 issues)

1
<?php
2
/**
3
 * ADOdb SQL Related Functionality
4
 * @author Joe Huss <[email protected]>
5
 * @copyright 2025
6
 * @package MyAdmin
7
 * @category SQL
8
 */
9
10
namespace MyDb\Adodb;
11
12
use MyDb\Generic;
13
use MyDb\Db_Interface;
14
15
/**
16
 * Db
17
 *
18
 * @access public
19
 */
20
class Db extends Generic implements Db_Interface
21
{
22
    public $driver = 'mysql';
23
    public $Rows = [];
24
    public $type = 'adodb';
25
26
    /**
27
     * Db::connect()
28
     * @param string $database
29
     * @param string $host
30
     * @param string $user
31
     * @param string $password
32
     * @param string $driver
33
     * @return bool|\the
34
     */
35
    public function connect($database = '', $host = '', $user = '', $password = '', $driver = 'mysql')
36
    {
37
        /* Handle defaults */
38
        if ('' == $database) {
39
            $database = $this->database;
40
        }
41
        if ('' == $host) {
42
            $host = $this->host;
43
        }
44
        if ('' == $user) {
45
            $user = $this->user;
46
        }
47
        if ('' == $password) {
48
            $password = $this->password;
49
        }
50
        if ('' == $driver) {
51
            $driver = $this->driver;
52
        }
53
        /* establish connection, select database */
54
        if ($this->linkId === false) {
0 ignored issues
show
The condition $this->linkId === false is always false.
Loading history...
55
            $this->linkId = NewADOConnection($driver);
56
            $this->linkId->Connect($host, $user, $password, $database);
57
        }
58
        return $this->linkId;
59
    }
60
61
    /* This only affects systems not using persistent connections */
62
63
    /**
64
     * Db::disconnect()
65
     * @return void
66
     */
67
    public function disconnect()
68
    {
69
    }
70
71
    /**
72
     * @param $string
73
     * @return string
74
     */
75
    public function real_escape($string = '')
76
    {
77
        return escapeshellarg($string);
78
    }
79
80
    /**
81
     * discard the query result
82
     * @return void
83
     */
84
    public function free()
85
    {
86
        //			@mysql_free_result($this->queryId);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
87
        //			$this->queryId = 0;
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
88
    }
89
90
    /**
91
     * Db::queryReturn()
92
     *
93
     * Sends an SQL query to the server like the normal query() command but iterates through
94
     * any rows and returns the row or rows immediately or FALSE on error
95
     *
96
     * @param mixed $query SQL Query to be used
97
     * @param string $line optionally pass __LINE__ calling the query for logging
98
     * @param string $file optionally pass __FILE__ calling the query for logging
99
     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
100
     */
101
    public function queryReturn($query, $line = '', $file = '')
102
    {
103
        $this->query($query, $line, $file);
104
        if ($this->num_rows() == 0) {
105
            return false;
106
        } elseif ($this->num_rows() == 1) {
107
            $this->next_record(MYSQL_ASSOC);
0 ignored issues
show
The constant MYSQL_ASSOC has been deprecated: 5.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

107
            $this->next_record(/** @scrutinizer ignore-deprecated */ MYSQL_ASSOC);
Loading history...
108
            return $this->Record;
109
        } else {
110
            $out = [];
111
            while ($this->next_record(MYSQL_ASSOC)) {
0 ignored issues
show
The constant MYSQL_ASSOC has been deprecated: 5.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

111
            while ($this->next_record(/** @scrutinizer ignore-deprecated */ MYSQL_ASSOC)) {
Loading history...
112
                $out[] = $this->Record;
113
            }
114
            return $out;
115
        }
116
    }
117
118
    /**
119
     * db:qr()
120
     *
121
     *  alias of queryReturn()
122
     *
123
     * @param mixed $query SQL Query to be used
124
     * @param string $line optionally pass __LINE__ calling the query for logging
125
     * @param string $file optionally pass __FILE__ calling the query for logging
126
     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
127
     */
128
    public function qr($query, $line = '', $file = '')
129
    {
130
        return $this->queryReturn($query, $line, $file);
131
    }
132
133
    /**
134
     * Db::query()
135
     *
136
     *  Sends an SQL query to the database
137
     *
138
     * @param mixed $queryString
139
     * @param string $line
140
     * @param string $file
141
     * @return mixed 0 if no query or query id handler, safe to ignore this return
142
     */
143
    public function query($queryString, $line = '', $file = '')
144
    {
145
        /* No empty queries, please, since PHP4 chokes on them. */
146
        /* The empty query string is passed on from the constructor,
147
        * when calling the class without a query, e.g. in situations
148
        * like these: '$db = new db_Subclass;'
149
        */
150
        if ($queryString == '') {
151
            return 0;
152
        }
153
        if (!$this->connect()) {
154
            return 0;
155
            /* we already complained in connect() about that. */
156
        }
157
158
        // New query, discard previous result.
159
        if ($this->queryId !== false) {
0 ignored issues
show
The condition $this->queryId !== false is always true.
Loading history...
160
            $this->free();
161
        }
162
163
        if ($this->Debug) {
164
            printf("Debug: query = %s<br>\n", $queryString);
165
        }
166
        if (isset($GLOBALS['log_queries']) && $GLOBALS['log_queries'] !== false) {
167
            $this->log($queryString, $line, $file);
168
        }
169
170
        try {
171
            $this->queryId = $this->linkId->Execute($queryString);
172
        } catch (exception $e) {
0 ignored issues
show
The type MyDb\Adodb\exception was not found. Did you mean exception? If so, make sure to prefix the type with \.
Loading history...
173
            $this->emailError($queryString, $e, $line, $file);
174
        }
175
        $this->log("ADOdb Query $queryString (S:$success) - ".count($this->Rows).' Rows', __LINE__, __FILE__);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $success seems to be never defined.
Loading history...
176
        $this->Row = 0;
177
178
        // Will return nada if it fails. That's fine.
179
        return $this->queryId;
180
    }
181
182
    /**
183
     * Db::next_record()
184
     * @param mixed $resultType
185
     * @return bool
186
     */
187
    public function next_record($resultType = MYSQL_ASSOC)
0 ignored issues
show
The constant MYSQL_ASSOC has been deprecated: 5.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

187
    public function next_record($resultType = /** @scrutinizer ignore-deprecated */ MYSQL_ASSOC)
Loading history...
The parameter $resultType is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

187
    public function next_record(/** @scrutinizer ignore-unused */ $resultType = MYSQL_ASSOC)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
188
    {
189
        if (!$this->queryId) {
190
            $this->halt('next_record called with no query pending.');
191
            return 0;
192
        }
193
        ++$this->Row;
194
        $this->Record = $this->queryId->FetchRow();
0 ignored issues
show
The method FetchRow() does not exist on integer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

194
        /** @scrutinizer ignore-call */ 
195
        $this->Record = $this->queryId->FetchRow();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
195
        $stat = is_array($this->Record);
196
        if (!$stat && $this->autoFree) {
197
            $this->free();
198
        }
199
        return $stat;
200
    }
201
202
    /* public: position in result set */
203
204
    /**
205
     * Db::seek()
206
     * @param integer $pos
207
     * @return int
208
     */
209
    public function seek($pos = 0)
210
    {
211
        if (isset($this->Rows[$pos])) {
212
            $this->Row = $pos;
213
        } else {
214
            $this->halt("seek($pos) failed: result has ".count($this->Rows).' rows');
215
            /* half assed attempt to save the day,
216
            * but do not consider this documented or even
217
            * desirable behaviour.
218
            */
219
            return 0;
220
        }
221
        return 1;
222
    }
223
224
    /**
225
     * Db::transactionBegin()
226
     * @return bool
227
     */
228
    public function transactionBegin()
229
    {
230
        return true;
231
    }
232
233
    /**
234
     * Db::transactionCommit()
235
     * @return bool
236
     */
237
    public function transactionCommit()
238
    {
239
        return true;
240
    }
241
242
    /**
243
     * Db::transactionAbort()
244
     * @return bool
245
     */
246
    public function transactionAbort()
247
    {
248
        return true;
249
    }
250
251
    /**
252
     * Db::getLastInsertId()
253
     *
254
     * @param mixed $table
255
     * @param mixed $field
256
     * @return mixed
257
     */
258
    public function getLastInsertId($table, $field)
259
    {
260
        return $this->linkId->Insert_ID($table, $field);
261
    }
262
263
    /* public: table locking */
264
265
    /**
266
     * Db::lock()
267
     * @param mixed  $table
268
     * @param string $mode
269
     * @return void
270
     */
271
    public function lock($table, $mode = 'write')
0 ignored issues
show
The parameter $table is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

271
    public function lock(/** @scrutinizer ignore-unused */ $table, $mode = 'write')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $mode is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

271
    public function lock($table, /** @scrutinizer ignore-unused */ $mode = 'write')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
272
    {
273
        /*			$this->connect();
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
274
275
        * $query = "lock tables ";
276
        * if (is_array($table))
277
        * {
278
        * foreach ($table as $key => $value)
279
        * {
280
        * if ($key == "read" && $key!=0)
281
        * {
282
        * $query .= "$value read, ";
283
        * }
284
        * else
285
        * {
286
        * $query .= "$value $mode, ";
287
        * }
288
        * }
289
        * $query = mb_substr($query,0,-2);
290
        * }
291
        * else
292
        * {
293
        * $query .= "$table $mode";
294
        * }
295
        * $res = @mysql_query($query, $this->linkId);
296
        * if (!$res)
297
        * {
298
        * $this->halt("lock($table, $mode) failed.");
299
        * return 0;
300
        * }
301
        * return $res;
302
        */
303
    }
304
305
    /**
306
     * Db::unlock()
307
     * @return void
308
     */
309
    public function unlock()
310
    {
311
        /*			$this->connect();
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
312
313
        * $res = @mysql_query("unlock tables");
314
        * if (!$res)
315
        * {
316
        * $this->halt("unlock() failed.");
317
        * return 0;
318
        * }
319
        * return $res;
320
        */
321
    }
322
323
    /* public: evaluate the result (size, width) */
324
325
    /**
326
     * Db::affectedRows()
327
     *
328
     * @return mixed
329
     */
330
    public function affectedRows()
331
    {
332
        return @$this->linkId->Affected_Rows();
333
        //			return @$this->queryId->rowCount();
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
334
    }
335
336
    /**
337
     * Db::num_rows()
338
     *
339
     * @return mixed
340
     */
341
    public function num_rows()
342
    {
343
        return $this->queryId->NumRows();
344
    }
345
346
    /**
347
     * Db::num_fields()
348
     *
349
     * @return mixed
350
     */
351
    public function num_fields()
352
    {
353
        return $this->queryId->NumCols();
354
    }
355
356
    /**
357
     * @param mixed $msg
358
     * @param string $line
359
     * @param string $file
360
     * @return mixed|void
361
     */
362
    public function haltmsg($msg, $line = '', $file = '')
363
    {
364
        $this->log("Database error: $msg", $line, $file, 'error');
365
        if ($this->linkId->ErrorNo() != '0' && $this->linkId->ErrorMsg() != '') {
366
            $this->log('ADOdb SQL Error: '.$this->linkId->ErrorMsg(), $line, $file, 'error');
367
        }
368
        $this->logBackTrace($msg, $line, $file);
369
    }
370
371
    /**
372
     * Db::tableNames()
373
     *
374
     * @return array
375
     */
376
    public function tableNames()
377
    {
378
        $return = [];
379
        $this->query('SHOW TABLES');
380
        $i = 0;
381
        while ($info = $this->queryId->FetchRow()) {
382
            $return[$i]['table_name'] = $info[0];
383
            $return[$i]['tablespace_name'] = $this->database;
384
            $return[$i]['database'] = $this->database;
385
            ++$i;
386
        }
387
        return $return;
388
    }
389
}
390