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 excotic 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