1--TEST--
2DB_driver::quote
3--SKIPIF--
4<?php require_once dirname(__FILE__) . '/skipif.inc'; ?>
5--FILE--
6<?php
7require_once dirname(__FILE__) . '/connect.inc';
8require_once dirname(__FILE__) . '/droptable.inc';
9
10
11/**
12 * Local error callback handler.
13 *
14 * Drops the phptest table, prints out an error message and kills the
15 * process.
16 *
17 * @param object  $o  PEAR error object automatically passed to this method
18 * @return void
19 * @see PEAR::setErrorHandling()
20 */
21function pe($o) {
22    global $dbh;
23
24    $dbh->setErrorHandling(PEAR_ERROR_RETURN);
25    drop_table($dbh, 'pearquote');
26
27    die($o->toString());
28}
29
30// DBMS boolean column type simulation...
31$boolean_col_type = array(
32    'dbase'  => 'Logical',
33    'fbsql'  => 'BOOLEAN',
34    'ibase'  => 'SMALLINT',
35    'ifx'    => 'SMALLINT',
36    'msql'   => 'INTEGER',
37    'mssql'  => 'BIT',
38    'mysql'  => 'TINYINT(1)',
39    'mysqli' => 'TINYINT(1)',
40    'oci8'   => 'NUMBER(1)',
41    'odbc'   => 'SMALLINT',
42    'pgsql'  => 'BOOLEAN',
43    'sqlite' => 'INTEGER',
44    'sybase' => 'TINYINT',
45);
46
47// adjust things for specific DBMS's
48
49if ($dbh->phptype == 'odbc') {
50    if ($dbh->dbsyntax == 'odbc') {
51        $type = $dbh->phptype;
52    } else {
53        $type = $dbh->dbsyntax;
54    }
55} else {
56    $type = $dbh->phptype;
57}
58
59switch ($type) {
60    case 'access':
61        $decimal = 'SINGLE';
62        $null = '';
63        $chr  = 'VARCHAR(8)';
64        $identifier = 'q\ut "dnt';
65        break;
66    case 'db2':
67    case 'ibase':
68        $decimal = 'DECIMAL(3,1)';
69        $null = '';
70        $chr  = 'VARCHAR(8)';
71        $identifier = 'q\ut] "dn[t';
72        break;
73    case 'ifx':
74        // doing this for ifx to keep certain versions happy
75        $decimal = 'DECIMAL(3,1)';
76        $null = '';
77        $chr  = 'CHAR(8)';
78        $identifier = '';
79        break;
80    case 'msql':
81        $decimal = 'REAL';
82        $null = '';
83        $chr  = 'CHAR(8)';
84        $identifier = '';
85        break;
86    case 'fbsql':
87    case 'oci8':
88        $decimal = 'DECIMAL(3,1)';
89        $null = '';
90        $chr  = 'VARCHAR(8)';
91        $identifier = 'q\ut] dn[t';
92        break;
93    default:
94        $decimal = 'DECIMAL(3,1)';
95        $null = 'NULL';
96        $chr  = 'VARCHAR(8)';
97        $identifier = 'q\ut] "dn[t';
98}
99
100$dbh->setErrorHandling(PEAR_ERROR_RETURN);
101drop_table($dbh, 'pearquote');
102
103
104if ($identifier) {
105    switch ($dbh->phptype) {
106        case 'sybase':
107            $res = $dbh->query('set quoted_identifier on');
108            if (DB::isError($res) ) {
109                pe($res);
110            }
111            break;
112        default:
113    }
114    $create = $dbh->query("
115        CREATE TABLE pearquote (
116          n $decimal $null,
117          s $chr $null,
118          " . $dbh->quoteIdentifier($identifier) . " $decimal $null,
119          b {$boolean_col_type[$dbh->phptype]} $null
120        )
121    ");
122
123    if (DB::isError($create) ) {
124        pe($create);
125    }
126
127    $info = $dbh->tableInfo('pearquote');
128    if (DB::isError($info) ) {
129        if ($info->code == DB_ERROR_NOT_CAPABLE) {
130            print "Got outcome expected from delimited identifier.\n";
131        } else {
132            print "tableInfo() failed.\n";
133        }
134    } else {
135        if ($identifier == $info[2]['name']) {
136            print "Got outcome expected from delimited identifier.\n";
137            // print "COLUMN NAME IS: {$info[2]['name']}\n";
138        } else {
139            print "Expected column name: '$identifier' ... ";
140            print "Actual column name: '{$info[2]['name']}'\n";
141        }
142    }
143
144} else {
145    $dbh->query("
146        CREATE TABLE pearquote (
147          n $decimal $null,
148          s $chr $null,
149          plainidentifier $decimal $null,
150          b {$boolean_col_type[$dbh->phptype]} $null
151        )
152    ");
153    print "Got outcome expected from delimited identifier.\n";
154}
155
156
157$dbh->setErrorHandling(PEAR_ERROR_CALLBACK, 'pe');
158
159
160$strings = array(
161    "'",
162    "\"",
163    "\\",
164    "%",
165    "_",
166    "''",
167    "\"\"",
168    "\\\\",
169    "\\'\\'",
170    "\\\"\\\""
171);
172
173$nums = array(
174    12.3,
175    15,
176);
177
178$bools = array(
179    TRUE,
180    FALSE,
181);
182
183
184echo "String escape test: ";
185foreach ($strings as $s) {
186    $quoted = $dbh->quoteSmart($s);
187    $dbh->query("INSERT INTO pearquote (s) VALUES ($quoted)");
188}
189$diff = array_diff($strings, $res = $dbh->getCol("SELECT s FROM pearquote"));
190if (count($diff) > 0) {
191    echo "FAIL";
192    print_r($strings);
193    print_r($res);
194} else {
195    echo "OK";
196}
197
198$dbh->query("DELETE FROM pearquote");
199
200
201echo "\nNumber escape test: ";
202foreach ($nums as $n) {
203    $quoted = $dbh->quoteSmart($n);
204    $dbh->query("INSERT INTO pearquote (n) VALUES ($quoted)");
205}
206
207$diff = array();
208$res =& $dbh->getCol('SELECT n FROM pearquote ORDER BY n');
209foreach ($nums as $key => $val) {
210    if ($val != $res[$key]) {
211        $diff[] = "$val != {$res[$key]}";
212    }
213}
214
215if (count($diff) > 0) {
216    echo "FAIL\n";
217    print_r($diff);
218} else {
219    echo 'OK';
220}
221
222$dbh->query('DELETE FROM pearquote');
223
224
225echo "\nBoolean escape test: ";
226$i = 1;
227foreach ($bools as $b) {
228    $quoted = $dbh->quoteSmart($b);
229    $dbh->query("INSERT INTO pearquote (n, b) VALUES ($i, $quoted)");
230    $i++;
231}
232
233$diff = array();
234$res =& $dbh->getCol('SELECT b, n FROM pearquote ORDER BY n');
235foreach ($bools as $key => $val) {
236    if ($val === true) {
237        if ($res[$key] == 1 || $res[$key] == true ||
238            substr(strtolower($res[$key]), 0, 1) == 't')
239        {
240            // good
241        } else {
242            $diff[] = "in:true != out:{$res[$key]}";
243        }
244    } else {
245        if ($res[$key] == 0 || $res[$key] == false ||
246            substr(strtolower($res[$key]), 0, 1) == 'f')
247        {
248            // good
249        } else {
250            $diff[] = "in:false != out:{$res[$key]}";
251        }
252    }
253}
254
255if (count($diff) > 0) {
256    echo "FAIL\n";
257    print_r($diff);
258} else {
259    echo "OK\n";
260}
261
262
263$dbh->setErrorHandling(PEAR_ERROR_RETURN);
264drop_table($dbh, 'pearquote');
265
266?>
267--EXPECT--
268Got outcome expected from delimited identifier.
269String escape test: OK
270Number escape test: OK
271Boolean escape test: OK
272