long_columns.phpt 5.3 KB

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