1--TEST-- 2PDO ODBC "long" columns 3--SKIPIF-- 4<?php # vim:ft=php 5if (!extension_loaded('pdo_odbc')) print 'skip not loaded'; 6// make sure there is an ODBC driver and a DSN, or the test will fail 7include 'ext/pdo/tests/pdo_test.inc'; 8$config = PDOTest::get_config('ext/pdo_odbc/tests/common.phpt'); 9if (!isset($config['ENV']['PDOTEST_DSN']) || $config['ENV']['PDOTEST_DSN']===false) print 'skip'; 10?> 11--FILE-- 12<?php 13// setup: set PDOTEST_DSN environment variable 14// for MyODBC (MySQL) and MS SQL Server, you need to also set PDOTEST_USER and PDOTEST_PASS 15// 16// can use MS SQL Server on Linux - using unixODBC 17// -RHEL6.2 18// -download & instructions: http://www.microsoft.com/en-us/download/details.aspx?id=28160 19// -Linux6\sqlncli-11.0.1790.0.tar.gz (it calls RHEL6.x 'Linux6' for some reason) 20// -follow instructions on web page and install script 21// -may have to specify connection info in connection string without using a DSN (DSN-less connection) 22// -for example: 23// set PDOTEST_DSN='odbc:Driver=SQL Server Native Client 11.0;Server=10.200.51.179;Database=testdb' 24// set PDOTEST_USER=sa 25// set PDOTEST_PASS=Password01 26// 27// on Windows, the easy way to do this: 28// 1. install MS Access (part of MS Office) and include ODBC (Development tools feature) 29// install the x86 build of the Drivers. You might not be able to load the x64 drivers. 30// 2. in Control Panel, search for ODBC and open "Setup data sources (ODBC)" 31// 3. click on System DSN tab 32// 4. click Add and choose "Microsoft Access Driver (*.mdb, *.accdb)" driver 33// 5. enter a DSN, ex: accdb12 34// 6. click 'Create' and select a file to save the database as 35// -otherwise, you'll have to open MS Access, create a database, then load that file in this Window to map it to a DSN 36// 7. set the environment variable PDOTEST_DSN="odbc:<system dsn from step 5>" ex: SET PDOTEST_DSN=odbc:accdb12 37// -note: on Windows, " is included in environment variable 38// 39// easy way to compile: 40// configure --disable-all --enable-cli --enable-zts --enable-pdo --with-pdo-odbc --enable-debug 41// configure --disable-all --eanble-cli --enable-pdo --with-pdo-odbc=unixODBC,/usr,/usr --with-unixODBC=/usr --enable-debug 42// 43 44require 'ext/pdo/tests/pdo_test.inc'; 45$db = PDOTest::test_factory('ext/pdo_odbc/tests/common.phpt'); 46$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); 47 48if (false === $db->exec('CREATE TABLE TEST (id INT NOT NULL PRIMARY KEY, data CLOB)')) { 49 if (false === $db->exec('CREATE TABLE TEST (id INT NOT NULL PRIMARY KEY, data longtext)')) { 50 if (false === $db->exec('CREATE TABLE TEST (id INT NOT NULL PRIMARY KEY, data varchar(4000))')) { 51 die("BORK: don't know how to create a long column here:\n" . implode(", ", $db->errorInfo())); 52 } 53 } 54} 55 56$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 57 58// the driver reads columns in blocks of 255 bytes and then reassembles those blocks into a single buffer. 59// test sizes around 255 to make sure that the reassembly works (and that the column is split into 255 byte blocks by the database) 60// also, test sizes below 255 to make sure that they work - and are not treated as a long column (should be read in a single read) 61$sizes = array(32, 53, 64, 79, 128, 253, 254, 255, 256, 257, 258, 1022, 1023, 1024, 1025, 1026, 510, 511, 512, 513, 514, 1278, 1279, 1280, 1281, 1282, 2046, 2047, 2048, 2049, 2050, 1534, 1535, 1536, 1537, 1538, 3070, 3071, 3072, 3073, 3074, 3998, 3999, 4000); 62 63function alpha_repeat($len) { 64 // use the alphabet instead of 'i' characters to make sure the blocks don't overlap when they are reassembled 65 $out = ""; 66 while (strlen($out) < $len) { 67 $out .= "abcdefghijklmnopqrstuvwxyz"; 68 } 69 return substr($out, 0, $len); 70} 71 72// don't use Prepared Statements. that fails on MS SQL server (works with Access, MyODBC), which is a separate failure, feature/code-path from what 73// this test does - nice to be able to test using MS SQL server 74foreach ($sizes as $num) { 75 $text = alpha_repeat($num); 76 $db->exec("INSERT INTO TEST VALUES($num, '$text')"); 77} 78 79// verify data 80foreach ($db->query('SELECT id, data from TEST ORDER BY LEN(data) ASC') as $row) { 81 $expect = alpha_repeat($row[0]); 82 if (strcmp($expect, $row[1])) { 83 echo "Failed on size $row[id]:\n"; 84 printf("Expected %d bytes, got %d\n", strlen($expect), strlen($row['data'])); 85 echo ($expect) . "\n"; 86 echo ($row['data']) . "\n"; 87 } else { 88 echo "Passed on size $row[id]\n"; 89 } 90} 91 92echo "Finished\n"; 93--EXPECT-- 94Passed on size 32 95Passed on size 53 96Passed on size 64 97Passed on size 79 98Passed on size 128 99Passed on size 253 100Passed on size 254 101Passed on size 255 102Passed on size 256 103Passed on size 257 104Passed on size 258 105Passed on size 510 106Passed on size 511 107Passed on size 512 108Passed on size 513 109Passed on size 514 110Passed on size 1022 111Passed on size 1023 112Passed on size 1024 113Passed on size 1025 114Passed on size 1026 115Passed on size 1278 116Passed on size 1279 117Passed on size 1280 118Passed on size 1281 119Passed on size 1282 120Passed on size 1534 121Passed on size 1535 122Passed on size 1536 123Passed on size 1537 124Passed on size 1538 125Passed on size 2046 126Passed on size 2047 127Passed on size 2048 128Passed on size 2049 129Passed on size 2050 130Passed on size 3070 131Passed on size 3071 132Passed on size 3072 133Passed on size 3073 134Passed on size 3074 135Passed on size 3998 136Passed on size 3999 137Passed on size 4000 138Finished 139