Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/**
4
 * Tests the drivers' error mapping
5
 *
6
 * Executed by driver/10errormap.phpt
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * that is available through the world-wide-web at the following URI:
12
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * the PHP License and are unable to obtain it through the web, please
14
 * send a note to license@php.net so we can mail you a copy immediately.
15
 *
16
 * @category   Database
17
 * @package    DB
18
 * @author     Daniel Convissor <danielc@php.net>
19
 * @copyright  1997-2007 The PHP Group
20
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
21
 * @version    $Id: errors.inc 239211 2007-07-06 05:19:21Z aharvey $
22
 * @link       http://pear.php.net/package/DB
23
 */
24
 
25
/**
26
 * Determine if the error from the driver matches the error we expect
27
 *
28
 * If things are as we expect, print out "matches expected outcome"
29
 *
30
 * If things go wrong, print "UNEXPECTED OUTCOME" and display the
31
 * error's information.
32
 *
33
 * @param object  $e                 the DB_Error object from the query
34
 * @param int     $expected_db_code  the DB_ERROR* constant to expect
35
 * @param boolean $should_be_error   does the DBMS consider this an error?
36
 *
37
 * @return void
38
 */
39
function check_error($e, $expected_db_code, $should_be_error = true) {
40
    if ($should_be_error) {
41
        if (DB::isError($e)) {
42
            if ($e->getCode() == $expected_db_code) {
43
                print "matches expected outcome\n";
44
            } else {
45
                print "UNEXPECTED OUTCOME...\n";
46
                print '    PEAR::DB errorcode: ' . $e->getCode() . "\n";
47
                print '    ' . $e->getUserInfo() . "\n";
48
            }
49
        } else {
50
            print "\n    UNEXPECTED OUTCOME... expected error but it wasn't\n";
51
        }
52
    } else {
53
        if (DB::isError($e)) {
54
            print "UNEXPECTED OUTCOME... didn't expect error but it was\n";
55
            print '    PEAR::DB errorcode: ' . $e->getCode() . "\n";
56
            print '    ' . $e->getUserInfo() . "\n";
57
        } else {
58
            print "matches expected outcome\n";
59
        }
60
    }
61
}
62
 
63
/**
64
 * Local error callback handler
65
 *
66
 * @param object  $o  PEAR error object automatically passed to this method
67
 * @return void
68
 * @see PEAR::setErrorHandling()
69
 */
70
function pe($o) {
71
    print "\n---------------\n";
72
    print "Having problems creating a table for testing...\n";
73
    print $o->getDebugInfo() . "\n";
74
    print "---------------\n";
75
}
76
 
77
 
78
$dbh->setErrorHandling(PEAR_ERROR_RETURN);
79
 
80
 
81
print 'DB_ERROR_NOSUCHTABLE for select:  ';
82
$res = $dbh->query('SELECT * FROM tableThatsBogus');
83
check_error($res, DB_ERROR_NOSUCHTABLE);
84
 
85
print 'DB_ERROR_NOSUCHTABLE for drop:  ';
86
$res = drop_table($dbh, 'tableThatsBogus');
87
check_error($res, DB_ERROR_NOSUCHTABLE);
88
 
89
print 'DB_ERROR_NOT_FOUND for drop index:  ';
90
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
91
    case 'fbsql:fbsql':
92
    case 'ibase:firebird':
93
    case 'ibase:ibase':
94
    case 'ifx:ifx':
95
    case 'odbc:db2':
96
    case 'oci8:oci8':
97
    case 'pgsql:pgsql':
98
    case 'sqlite:sqlite':
99
        $res = $dbh->query('DROP INDEX fakeindex');
100
        break;
101
    case 'mssql:mssql':
102
    case 'sybase:sybase':
103
        $res = $dbh->query('DROP INDEX phptest.fakeindex');
104
        break;
105
    case 'msql:msql':
106
        $res = $dbh->query('DROP INDEX fakeindex FROM phptest');
107
        break;
108
    default:
109
        $res = $dbh->query('DROP INDEX fakeindex ON phptest');
110
}
111
check_error($res, DB_ERROR_NOT_FOUND);
112
 
113
 
114
print 'DB_ERROR_ALREADY_EXISTS for create table:  ';
115
$res = $dbh->query($test_mktable_query);
116
check_error($res, DB_ERROR_ALREADY_EXISTS);
117
 
118
print 'DB_ERROR_ALREADY_EXISTS for create index:  ';
119
$res = drop_table($dbh, 'a');
120
$dbh->pushErrorHandling(PEAR_ERROR_CALLBACK, 'pe');
121
$res = $dbh->query('CREATE TABLE a (a INTEGER)');
122
$dbh->popErrorHandling();
123
$res = $dbh->query('CREATE INDEX aa_idx ON a (a)');
124
$res = $dbh->query('CREATE INDEX aa_idx ON a (a)');
125
switch ($dbh->phptype) {
126
    case 'fbsql':
127
        // FrontBase doesn't assign a specific code for this yet.
128
        check_error($res, DB_ERROR_ALREADY_EXISTS, false);
129
        break;
130
    default:
131
        check_error($res, DB_ERROR_ALREADY_EXISTS);
132
}
133
$res = drop_table($dbh, 'a');
134
 
135
 
136
print 'DB_ERROR_CONSTRAINT for primary key insert duplicate:  ';
137
$res = drop_table($dbh, 'a');
138
$dbh->pushErrorHandling(PEAR_ERROR_CALLBACK, 'pe');
139
switch ($dbh->phptype) {
140
    case 'msql':
141
        $res = $dbh->query('CREATE TABLE a (a INTEGER NOT NULL)');
142
        $res = $dbh->query('CREATE UNIQUE INDEX apk ON a (a)');
143
        break;
144
    default:
145
        $res = $dbh->query('CREATE TABLE a (a INTEGER NOT NULL, PRIMARY KEY (a))');
146
}
147
$dbh->popErrorHandling();
148
$res = $dbh->query('INSERT INTO a VALUES (1)');
149
$res = $dbh->query('INSERT INTO a VALUES (1)');
150
check_error($res, DB_ERROR_CONSTRAINT);
151
 
152
 
153
print 'DB_ERROR_CONSTRAINT for primary key update duplicate:  ';
154
$res = $dbh->query('INSERT INTO a VALUES (2)');
155
$res = $dbh->query('UPDATE a SET a=1 WHERE a=2');
156
check_error($res, DB_ERROR_CONSTRAINT);
157
 
158
 
159
print 'DB_ERROR_CONSTRAINT for unique key insert duplicate:  ';
160
$res = drop_table($dbh, 'a');
161
$dbh->pushErrorHandling(PEAR_ERROR_CALLBACK, 'pe');
162
switch ($dbh->phptype) {
163
    case 'msql':
164
        $res = $dbh->query('CREATE TABLE a (a INTEGER NOT NULL)');
165
        $res = $dbh->query('CREATE UNIQUE INDEX auk ON a (a)');
166
        break;
167
    default:
168
        $res = $dbh->query('CREATE TABLE a (a INTEGER NOT NULL, UNIQUE (a))');
169
}
170
$dbh->popErrorHandling();
171
$res = $dbh->query('INSERT INTO a VALUES (1)');
172
$res = $dbh->query('INSERT INTO a VALUES (1)');
173
check_error($res, DB_ERROR_CONSTRAINT);
174
 
175
 
176
print 'DB_ERROR_CONSTRAINT for unique key update duplicate:  ';
177
$res = $dbh->query('INSERT INTO a VALUES (2)');
178
$res = $dbh->query('UPDATE a SET a=1 WHERE a=2');
179
check_error($res, DB_ERROR_CONSTRAINT);
180
 
181
 
182
print 'DB_ERROR_CONSTRAINT for foreign key on insert:  ';
183
$res = drop_table($dbh, 'b');
184
$res = drop_table($dbh, 'a');
185
$dbh->pushErrorHandling(PEAR_ERROR_CALLBACK, 'pe');
186
switch ($dbh->phptype) {
187
    case 'mysql':
188
    case 'mysqli':
189
        $res = $dbh->query('CREATE TABLE a (a INT NOT NULL, '
190
                    . 'PRIMARY KEY (a)) '
191
                    . 'TYPE=INNODB');
192
        $res = $dbh->query('CREATE TABLE b (b INT, '
193
                    . 'INDEX par_ind (b), '
194
                    . 'FOREIGN KEY (b) REFERENCES a (a)) '
195
                    . 'TYPE=INNODB');
196
        $dbh->popErrorHandling();
197
        break;
198
 
199
    case 'msql':
200
        // msql does not support foreign keys
201
        $res = $dbh->query('CREATE TABLE a (a INTEGER NOT NULL)');
202
        $res = $dbh->query('CREATE UNIQUE INDEX auk ON a (a)');
203
        $dbh->popErrorHandling();
204
        $res = $dbh->query('CREATE TABLE b (b INTEGER REFERENCES a (a))');
205
        if (DB::isError($res)) {
206
            print "matches expected outcome\n";
207
            print "DB_ERROR_CONSTRAINT for foreign key on delete:  matches expected outcome\n";
208
        } else {
209
            print "WOW, it seems mSQL now supports references\n";
210
            print "WOW, it seems mSQL now supports references\n";
211
        }
212
        break;
213
 
214
    default:
215
        $res = $dbh->query('CREATE TABLE a (a INTEGER NOT NULL, PRIMARY KEY (a))');
216
        $res = $dbh->query('CREATE TABLE b (b INTEGER REFERENCES a (a))');
217
        $dbh->popErrorHandling();
218
}
219
 
220
if ($dbh->phptype != 'msql') {
221
    $res = $dbh->query('INSERT INTO a (a) values (1)');
222
    $res = $dbh->query('INSERT INTO b (b) values (2)');
223
    switch ($dbh->phptype) {
224
        case 'sqlite':
225
            check_error($res, DB_ERROR_CONSTRAINT, false);
226
            break;
227
        default:
228
            check_error($res, DB_ERROR_CONSTRAINT);
229
    }
230
 
231
    print 'DB_ERROR_CONSTRAINT for foreign key on delete:  ';
232
    $res = $dbh->query('INSERT INTO b (b) values (1)');
233
    $res = $dbh->query('DELETE FROM a WHERE a = 1');
234
    switch ($dbh->phptype) {
235
        case 'sqlite':
236
            check_error($res, DB_ERROR_CONSTRAINT, false);
237
            break;
238
        default:
239
            check_error($res, DB_ERROR_CONSTRAINT);
240
    }
241
}
242
 
243
 
244
print 'DB_ERROR_CONSTRAINT_NOT_NULL on insert:  ';
245
$res = drop_table($dbh, 'peartestnull');
246
$dbh->pushErrorHandling(PEAR_ERROR_CALLBACK, 'pe');
247
$res = $dbh->query('CREATE TABLE peartestnull (a CHAR(3) NOT NULL)');
248
$dbh->popErrorHandling();
249
$res = $dbh->query('INSERT INTO peartestnull VALUES (NULL)');
250
check_error($res, DB_ERROR_CONSTRAINT_NOT_NULL);
251
 
252
 
253
print 'DB_ERROR_CONSTRAINT_NOT_NULL on update:  ';
254
$res = $dbh->query("INSERT INTO peartestnull VALUES ('one')");
255
$res = $dbh->query("UPDATE peartestnull SET a = NULL WHERE a = 'one'");
256
switch ($dbh->phptype) {
257
    case 'mysql':
258
    case 'mysqli':
259
        check_error($res, DB_ERROR_CONSTRAINT_NOT_NULL, false);
260
        break;
261
    default:
262
        check_error($res, DB_ERROR_CONSTRAINT_NOT_NULL);
263
}
264
 
265
 
266
print 'DB_ERROR_NOSUCHFIELD joining ON bogus column:  ';
267
$res = $dbh->query('SELECT * FROM phptest JOIN a ON (phptest.a = a.b)');
268
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
269
    case 'msql:msql':
270
    case 'odbc:access':
271
        check_error($res, DB_ERROR_SYNTAX);
272
        break;
273
    default:
274
        check_error($res, DB_ERROR_NOSUCHFIELD);
275
}
276
 
277
 
278
print 'DB_ERROR_NOSUCHFIELD joining USING bogus column:  ';
279
$res = $dbh->query('SELECT * FROM phptest JOIN a USING (b)');
280
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
281
    case 'ibase:firebird':
282
        /* FirebirdSQL 2 returns -902 (feature is not supported) for this test
283
         * rather than a syntax error. For now, we'll test for both. */
284
        if ($res->getCode() == DB_ERROR_SYNTAX)
285
            check_error($res, DB_ERROR_SYNTAX);
286
        else
287
            check_error($res, DB_ERROR_NOT_CAPABLE);
288
        break;
289
    case 'ibase:ibase':
290
    case 'ifx:ifx':
291
    case 'msql:msql':
292
    case 'odbc:access':
293
    case 'odbc:db2':
294
    case 'sybase:sybase':
295
        check_error($res, DB_ERROR_SYNTAX);
296
        break;
297
    default:
298
        check_error($res, DB_ERROR_NOSUCHFIELD);
299
}
300
 
301
 
302
print 'DB_ERROR_DIVZERO:  ';
303
// Interbase detects the error on fetching
304
$res = $dbh->getAll('SELECT 0/0 FROM phptest');
305
switch ($dbh->phptype) {
306
    case 'odbc':
307
        switch ($dbh->dbsyntax) {
308
            case 'access':
309
                check_error($res, DB_ERROR_DIVZERO, false);
310
                break;
311
            case 'db2':
312
                check_error($res, DB_ERROR_DIVZERO);
313
                break;
314
        }
315
        break;
316
    case 'msql':
317
        check_error($res, DB_ERROR_SYNTAX);
318
        break;
319
    case 'fbsql':
320
    case 'ibase':
321
    case 'mssql':
322
    case 'mysql':
323
    case 'mysqli':
324
    case 'sqlite':
325
        /* Not all databases detect division by zero errors. We call these
326
         * databases "broken". */
327
        check_error($res, null, false);
328
        break;
329
    default:
330
        check_error($res, DB_ERROR_DIVZERO);
331
}
332
 
333
 
334
print 'DB_ERROR_INVALID_NUMBER putting chars in INT column:  ';
335
$res = $dbh->query("UPDATE phptest SET a = 'abc' WHERE a = 42");
336
switch ($dbh->phptype) {
337
    case 'mysql':
338
    case 'mysqli':
339
    case 'sqlite':
340
        check_error($res, DB_ERROR_INVALID_NUMBER, false);
341
        break;
342
    default:
343
        check_error($res, DB_ERROR_INVALID_NUMBER);
344
}
345
 
346
 
347
print 'DB_ERROR_INVALID_NUMBER putting float in INT column:  ';
348
$res = $dbh->query("UPDATE phptest SET a = 8.9 WHERE a = 42");
349
switch ($dbh->phptype) {
350
    case 'fbsql':
351
    case 'ibase':
352
    case 'ifx':
353
    case 'mssql':
354
    case 'mysql':
355
    case 'mysqli':
356
    case 'oci8':
357
    case 'odbc':
358
    case 'pgsql':
359
    case 'sqlite':
360
        check_error($res, DB_ERROR_INVALID_NUMBER, false);
361
        break;
362
    default:
363
        check_error($res, DB_ERROR_INVALID_NUMBER);
364
}
365
 
366
 
367
print 'DB_ERROR_INVALID_NUMBER putting excessive int in INT column:  ';
368
$res = $dbh->query("UPDATE phptest SET a = 18446744073709551616 WHERE a = 42");
369
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
370
    case 'ibase:ibase':
371
    case 'ibase:firebird':
372
        check_error($res, DB_ERROR_SYNTAX);
373
        break;
374
    case 'fbsql:fbsql':
375
    case 'ifx:ifx':
376
    case 'msql:msql':
377
    case 'mssql:mssql':
378
    case 'mysql:mysql':
379
    case 'mysqli:mysqli':
380
    case 'oci8:oci8':
381
    case 'odbc:access':
382
    case 'sqlite:sqlite':
383
        check_error($res, DB_ERROR_INVALID_NUMBER, false);
384
        break;
385
    default:
386
        check_error($res, DB_ERROR_INVALID_NUMBER);
387
}
388
 
389
 
390
print 'DB_ERROR_INVALID_NUMBER putting int in CHAR column:  ';
391
$res = $dbh->query("UPDATE phptest SET b = 8 WHERE a = 42");
392
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
393
    case 'ibase:ibase':
394
    case 'ibase:firebird':
395
    case 'ifx:ifx':
396
    case 'mssql:mssql':
397
    case 'mysql:mysql':
398
    case 'mysqli:mysqli':
399
    case 'oci8:oci8':
400
    case 'odbc:access':
401
    case 'pgsql:pgsql':
402
    case 'sqlite:sqlite':
403
        check_error($res, DB_ERROR_INVALID_NUMBER, false);
404
        break;
405
    default:
406
        check_error($res, DB_ERROR_INVALID_NUMBER);
407
}
408
 
409
 
410
print 'DB_ERROR_NOSUCHFIELD:  ';
411
$res = $dbh->query('SELECT e FROM phptest');
412
check_error($res, DB_ERROR_NOSUCHFIELD);
413
 
414
 
415
print 'DB_ERROR_SYNTAX:  ';
416
$res = $dbh->query('CREATE');
417
check_error($res, DB_ERROR_SYNTAX);
418
 
419
 
420
print 'DB_ERROR_VALUE_COUNT_ON_ROW:  ';
421
$res = $dbh->query('INSERT INTO phptest (a) VALUES (678, 2)');
422
switch ($dbh->phptype) {
423
    case 'msql':
424
        check_error($res, DB_ERROR_VALUE_COUNT_ON_ROW, false);
425
        break;
426
    default:
427
        check_error($res, DB_ERROR_VALUE_COUNT_ON_ROW);
428
}
429
 
430
 
431
print 'DB_ERROR_INVALID on CHAR column data too long:  ';
432
$res = $dbh->query("INSERT INTO phptest (b) VALUES ('123456789.123456789.123456789.123456789.1')");
433
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
434
    case 'ifx:ifx':
435
    case 'msql:msql':
436
    case 'mssql:mssql':
437
    case 'mysql:mysql':
438
    case 'mysqli:mysqli':
439
    case 'odbc:access':
440
    case 'sqlite:sqlite':
441
    case 'sybase:sybase':
442
        check_error($res, DB_ERROR_INVALID, false);
443
        break;
444
    case 'fbsql:fbsql':
445
        check_error($res, DB_ERROR_TRUNCATED);
446
        break;
447
    default:
448
        check_error($res, DB_ERROR_INVALID);
449
}
450
 
451
 
452
print 'DB_ERROR_INVALID on VARCHAR column data too long:  ';
453
$res = $dbh->query("INSERT INTO phptest (d) VALUES ('123456789.123456789.1')");
454
switch ($dbh->phptype . ':' . $dbh->dbsyntax) {
455
    case 'ifx:ifx':
456
    case 'msql:msql':
457
    case 'mssql:mssql':
458
    case 'mysql:mysql':
459
    case 'mysqli:mysqli':
460
    case 'odbc:access':
461
    case 'sqlite:sqlite':
462
    case 'sybase:sybase':
463
        check_error($res, DB_ERROR_INVALID, false);
464
        break;
465
    case 'fbsql:fbsql':
466
        check_error($res, DB_ERROR_TRUNCATED);
467
        break;
468
    default:
469
        check_error($res, DB_ERROR_INVALID);
470
}
471
 
472
 
473
 
474
drop_table($dbh, 'phptest');
475
drop_table($dbh, 'b');
476
drop_table($dbh, 'a');
477
drop_table($dbh, 'peartestnull');