1<?php
2require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc');
3require_once(dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc');
4
5class MySQLPDOTest extends PDOTest {
6
7    static function factory($classname = 'PDO', $drop_test_tables = false, $myattr = null, $mydsn = null) {
8
9        $dsn 	= self::getDSN($mydsn);
10        $user	= PDO_MYSQL_TEST_USER;
11        $pass	= PDO_MYSQL_TEST_PASS;
12        $attr	= getenv('PDOTEST_ATTR');
13
14        if (is_string($attr) && strlen($attr)) {
15            $attr = unserialize($attr);
16        } else {
17            $attr = null;
18        }
19        if ($user === false)
20            $user = NULL;
21        if ($pass === false)
22            $pass = NULL;
23
24        $db = new $classname($dsn, $user, $pass, $attr);
25        if (!$db) {
26            die("Could not create PDO object (DSN=$dsn, user=$user)\n");
27        }
28
29        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
30        $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
31
32        return $db;
33    }
34
35    static function createTestTable($db, $engine = null) {
36        if (!$engine)
37            $engine = PDO_MYSQL_TEST_ENGINE;
38
39        $db->exec('DROP TABLE IF EXISTS test');
40        $db->exec('CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine);
41        $db->exec("INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')");
42    }
43
44    static function getTableEngine() {
45        return PDO_MYSQL_TEST_ENGINE;
46    }
47
48
49    static function getDSN($new_options = null, $addition = '') {
50        if (!$new_options)
51            return PDO_MYSQL_TEST_DSN . $addition;
52
53        $old_options = array();
54        $dsn = substr(PDO_MYSQL_TEST_DSN,
55            strpos(PDO_MYSQL_TEST_DSN, ':') + 1,
56            strlen(PDO_MYSQL_TEST_DSN));
57
58        // no real parser - any exotic setting can fool us
59        $parts = explode(';', $dsn);
60        foreach ($parts as $k => $v) {
61            $tmp = explode('=', $v);
62            if (count($tmp) == 2)
63                $old_options[$tmp[0]] = $tmp[1];
64        }
65
66        $options = $old_options;
67        foreach ($new_options as $k => $v)
68            $options[$k] = $v;
69
70        $dsn = 'mysql:';
71        foreach ($options as $k => $v)
72            $dsn .= sprintf('%s=%s;', $k, $v);
73
74        if ($addition)
75            $dsn .= $addition;
76        else
77            $dsn = substr($dsn, 0, strlen($dsn) -1);
78
79        return $dsn;
80    }
81
82    static function getClientVersion($db) {
83        return self::extractVersion($db->getAttribute(PDO::ATTR_CLIENT_VERSION));
84    }
85
86    static function getServerVersion($db) {
87        return self::extractVersion($db->getAttribute(PDO::ATTR_SERVER_VERSION));
88    }
89
90    static function extractVersion($version_string) {
91        /*
92        TODO:
93        We're a bit in trouble: PDO_MYSQL returns version strings.
94        That's wrong according to the manual. According to the manual
95        integers should be returned. However, this code needs to work
96        with stinky PDO_MYSQL and hopefully better PDO_MYSQLND.
97        */
98
99        // already an int value?
100        if (is_int($version_string))
101            return $version_string;
102
103        // string but int value?
104        $tmp = (int)$version_string;
105        if (((string)$tmp) === $version_string)
106            return $tmp;
107
108        // stinky string which we need to parse
109        $parts = explode('.', $version_string);
110        if (count($parts) < 3)
111            return -1;
112
113        $version = (int)$parts[0] * 10000;
114        $version+= (int)$parts[1] * 100;
115        $version+= (int)$parts[2];
116
117        return $version;
118    }
119
120    static function getTempDir() {
121
122        if (!function_exists('sys_get_temp_dir')) {
123
124            if (!empty($_ENV['TMP']))
125                return realpath( $_ENV['TMP'] );
126            if (!empty($_ENV['TMPDIR']))
127                return realpath( $_ENV['TMPDIR'] );
128            if (!empty($_ENV['TEMP']))
129                return realpath( $_ENV['TEMP'] );
130
131            $temp_file = tempnam(md5(uniqid(rand(), TRUE)), '');
132            if ($temp_file) {
133                $temp_dir = realpath(dirname($temp_file));
134                unlink($temp_file);
135                return $temp_dir;
136            }
137            return FALSE;
138        } else {
139            return sys_get_temp_dir();
140        }
141
142    }
143
144    static function detect_transactional_mysql_engine($db) {
145        foreach ($db->query("show variables like 'have%'") as $row) {
146            if (!empty($row) && $row[1] == 'YES' && ($row[0] == 'have_innodb' || $row[0] == 'have_bdb')) {
147                return str_replace("have_", "", $row[0]);
148            }
149        }
150        /* MySQL 5.6.1+ */
151        foreach ($db->query("SHOW ENGINES") as $row) {
152            if (isset($row['engine']) && isset($row['support'])) {
153                 if ('InnoDB' == $row['engine'] && ('YES' == $row['support'] || 'DEFAULT' == $row['support']))
154                    return 'innodb';
155            }
156        }
157        return false;
158    }
159
160    static function isPDOMySQLnd() {
161            ob_start();
162            phpinfo();
163            $tmp = ob_get_contents();
164            ob_end_clean();
165            return (preg_match('/PDO Driver for MySQL.*enabled/', $tmp) &&
166                preg_match('/Client API version.*mysqlnd/', $tmp));
167    }
168
169    static function dropTestTable($db = NULL) {
170        if (is_null($db))
171            $db = self::factory();
172
173        $db->exec('DROP TABLE IF EXISTS test');
174    }
175
176}
177?>
178