001: /*
002: Copyright (C) 2002-2004 MySQL AB
003:
004: This program is free software; you can redistribute it and/or modify
005: it under the terms of version 2 of the GNU General Public License as
006: published by the Free Software Foundation.
007:
008: There are special exceptions to the terms and conditions of the GPL
009: as it is applied to this software. View the full text of the
010: exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
011: software distribution.
012:
013: This program is distributed in the hope that it will be useful,
014: but WITHOUT ANY WARRANTY; without even the implied warranty of
015: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: GNU General Public License for more details.
017:
018: You should have received a copy of the GNU General Public License
019: along with this program; if not, write to the Free Software
020: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021:
022:
023:
024: */
025: package testsuite.regression;
026:
027: import java.io.ByteArrayInputStream;
028: import java.io.File;
029: import java.io.FileInputStream;
030: import java.io.BufferedOutputStream;
031: import java.io.FileOutputStream;
032: import java.io.IOException;
033: import java.io.StringReader;
034: import java.sql.Blob;
035: import java.sql.Connection;
036: import java.sql.DriverManager;
037: import java.sql.PreparedStatement;
038: import java.sql.ResultSet;
039: import java.sql.Statement;
040: import java.util.Properties;
041:
042: import testsuite.BaseTestCase;
043:
044: /**
045: * Tests fixes for BLOB handling.
046: *
047: * @author Mark Matthews
048: * @version $Id: BlobRegressionTest.java,v 1.1.2.19 2005/03/09 18:16:16
049: * mmatthews Exp $
050: */
051: public class BlobRegressionTest extends BaseTestCase {
052: /**
053: * Creates a new BlobRegressionTest.
054: *
055: * @param name
056: * name of the test to run
057: */
058: public BlobRegressionTest(String name) {
059: super (name);
060: }
061:
062: /**
063: * Runs all test cases in this test suite
064: *
065: * @param args
066: */
067: public static void main(String[] args) {
068: junit.textui.TestRunner.run(BlobRegressionTest.class);
069: }
070:
071: /**
072: *
073: *
074: * @throws Exception
075: * ...
076: */
077: public void testBug2670() throws Exception {
078: if (!isRunningOnJdk131()) {
079: try {
080: byte[] blobData = new byte[32];
081:
082: for (int i = 0; i < blobData.length; i++) {
083: blobData[i] = 1;
084: }
085:
086: this .stmt
087: .executeUpdate("DROP TABLE IF EXISTS testBug2670");
088: this .stmt
089: .executeUpdate("CREATE TABLE testBug2670(blobField LONGBLOB)");
090:
091: PreparedStatement pStmt = this .conn
092: .prepareStatement("INSERT INTO testBug2670 (blobField) VALUES (?)");
093: pStmt.setBytes(1, blobData);
094: pStmt.executeUpdate();
095:
096: this .rs = this .stmt
097: .executeQuery("SELECT blobField FROM testBug2670");
098: this .rs.next();
099:
100: Blob blob = this .rs.getBlob(1);
101:
102: //
103: // Test mid-point insertion
104: //
105: blob.setBytes(4, new byte[] { 2, 2, 2, 2 });
106:
107: byte[] newBlobData = blob.getBytes(1L, (int) blob
108: .length());
109:
110: assertTrue("Blob changed length",
111: blob.length() == blobData.length);
112:
113: assertTrue(
114: "New data inserted wrongly",
115: ((newBlobData[3] == 2) && (newBlobData[4] == 2)
116: && (newBlobData[5] == 2) && (newBlobData[6] == 2)));
117:
118: //
119: // Test end-point insertion
120: //
121: blob.setBytes(32, new byte[] { 2, 2, 2, 2 });
122:
123: assertTrue("Blob length should be 3 larger", blob
124: .length() == (blobData.length + 3));
125: } finally {
126: this .stmt
127: .executeUpdate("DROP TABLE IF EXISTS testUpdateLongBlob");
128: }
129: }
130: }
131:
132: /**
133: *
134: *
135: * @throws Exception
136: * ...
137: */
138: public void testUpdateLongBlobGT16M() throws Exception {
139: if (versionMeetsMinimum(4, 0)) {
140: try {
141: byte[] blobData = new byte[18 * 1024 * 1024]; // 18M blob
142:
143: this .stmt
144: .executeUpdate("DROP TABLE IF EXISTS testUpdateLongBlob");
145: this .stmt
146: .executeUpdate("CREATE TABLE testUpdateLongBlob(blobField LONGBLOB)");
147: this .stmt
148: .executeUpdate("INSERT INTO testUpdateLongBlob (blobField) VALUES (NULL)");
149:
150: PreparedStatement pStmt = this .conn
151: .prepareStatement("UPDATE testUpdateLongBlob SET blobField=?");
152: pStmt.setBytes(1, blobData);
153: pStmt.executeUpdate();
154: } finally {
155: this .stmt
156: .executeUpdate("DROP TABLE IF EXISTS testUpdateLongBlob");
157: }
158: }
159: }
160:
161: /**
162: *
163: * @throws Exception
164: */
165: public void testUpdatableBlobsWithCharsets() throws Exception {
166: byte[] smallBlob = new byte[32];
167:
168: for (byte i = 0; i < smallBlob.length; i++) {
169: smallBlob[i] = i;
170: }
171:
172: try {
173: this .stmt
174: .executeUpdate("DROP TABLE IF EXISTS testUpdatableBlobsWithCharsets");
175: this .stmt
176: .executeUpdate("CREATE TABLE testUpdatableBlobsWithCharsets(pk INT NOT NULL PRIMARY KEY, field1 BLOB)");
177:
178: PreparedStatement pStmt = this .conn
179: .prepareStatement("INSERT INTO testUpdatableBlobsWithCharsets (pk, field1) VALUES (1, ?)");
180: pStmt.setBinaryStream(1,
181: new ByteArrayInputStream(smallBlob),
182: smallBlob.length);
183: pStmt.executeUpdate();
184:
185: Statement updStmt = this .conn.createStatement(
186: ResultSet.TYPE_SCROLL_SENSITIVE,
187: ResultSet.CONCUR_UPDATABLE);
188:
189: this .rs = updStmt
190: .executeQuery("SELECT pk, field1 FROM testUpdatableBlobsWithCharsets");
191: System.out.println(this .rs);
192: this .rs.next();
193:
194: for (byte i = 0; i < smallBlob.length; i++) {
195: smallBlob[i] = (byte) (i + 32);
196: }
197:
198: this .rs.updateBinaryStream(2, new ByteArrayInputStream(
199: smallBlob), smallBlob.length);
200: this .rs.updateRow();
201:
202: ResultSet newRs = this .stmt
203: .executeQuery("SELECT field1 FROM testUpdatableBlobsWithCharsets");
204:
205: newRs.next();
206:
207: byte[] updatedBlob = newRs.getBytes(1);
208:
209: for (byte i = 0; i < smallBlob.length; i++) {
210: byte origValue = smallBlob[i];
211: byte newValue = updatedBlob[i];
212:
213: assertTrue("Original byte at position " + i + ", "
214: + origValue + " != new value, " + newValue,
215: origValue == newValue);
216: }
217:
218: } finally {
219: this .stmt
220: .executeUpdate("DROP TABLE IF EXISTS testUpdatableBlobsWithCharsets");
221: }
222: }
223:
224: public void testBug5490() throws Exception {
225: try {
226: this .stmt.executeUpdate("DROP TABLE IF EXISTS testBug5490");
227: this .stmt.executeUpdate("CREATE TABLE testBug5490"
228: + "(pk INT NOT NULL PRIMARY KEY, blobField BLOB)");
229: String sql = "insert into testBug5490 values(?,?)";
230:
231: int blobFileSize = 871;
232: File blobFile = newTempBinaryFile("Bug5490", blobFileSize);
233:
234: PreparedStatement pStmt = this .conn.prepareStatement(sql,
235: ResultSet.TYPE_SCROLL_INSENSITIVE,
236: ResultSet.CONCUR_READ_ONLY);
237: pStmt.setInt(1, 2);
238: FileInputStream fis = new FileInputStream(blobFile);
239: pStmt.setBinaryStream(2, fis, blobFileSize);
240: pStmt.execute();
241: fis.close();
242: pStmt.close();
243:
244: this .rs = this .stmt
245: .executeQuery("SELECT blobField FROM testBug5490");
246:
247: this .rs.next();
248:
249: byte[] returned = this .rs.getBytes(1);
250:
251: assertEquals(blobFileSize, returned.length);
252: } finally {
253: this .stmt.executeUpdate("DROP TABLE IF EXISTS testBug5490");
254: }
255: }
256:
257: /**
258: * Tests BUG#8096 where emulated locators corrupt binary data when using
259: * server-side prepared statements.
260: *
261: * @throws Exception
262: * if the test fails.
263: */
264: public void testBug8096() throws Exception {
265: if (!isRunningOnJdk131()) {
266: int dataSize = 256;
267:
268: Properties props = new Properties();
269: props.setProperty("emulateLocators", "true");
270: Connection locatorConn = getConnectionWithProps(props);
271:
272: String createTable = "CREATE TABLE testBug8096 (ID VARCHAR(10) "
273: + "PRIMARY KEY, DATA LONGBLOB)";
274: String select = "SELECT ID, 'DATA' AS BLOB_DATA FROM testBug8096 "
275: + "WHERE ID = ?";
276: String insert = "INSERT INTO testBug8096 (ID, DATA) VALUES (?, '')";
277:
278: String id = "1";
279: byte[] testData = new byte[dataSize];
280:
281: for (int i = 0; i < testData.length; i++) {
282: testData[i] = (byte) i;
283: }
284:
285: try {
286: this .stmt
287: .executeUpdate("DROP TABLE IF EXISTS testBug8096");
288:
289: this .stmt.executeUpdate(createTable);
290:
291: PreparedStatement ps = locatorConn
292: .prepareStatement(insert);
293: ps.setString(1, id);
294: ps.execute();
295:
296: ps = locatorConn.prepareStatement(select);
297: ps.setString(1, id);
298:
299: this .rs = ps.executeQuery();
300:
301: if (this .rs.next()) {
302: Blob b = rs.getBlob("BLOB_DATA");
303: b.setBytes(1, testData);
304: }
305:
306: this .rs.close();
307: ps.close();
308:
309: ps = locatorConn.prepareStatement(select);
310: ps.setString(1, id);
311:
312: this .rs = ps.executeQuery();
313:
314: byte[] result = null;
315: if (this .rs.next()) {
316: Blob b = this .rs.getBlob("BLOB_DATA");
317:
318: result = b.getBytes(1, dataSize - 1);
319: }
320:
321: this .rs.close();
322: ps.close();
323:
324: assertNotNull(result);
325:
326: for (int i = 0; i < result.length
327: && i < testData.length; i++) {
328: // Will print out all of the values that don't match.
329: // All negative values will instead be replaced with 63.
330: if (result[i] != testData[i]) {
331: assertEquals("At position " + i, testData[i],
332: result[i]);
333: }
334: }
335:
336: } finally {
337: this .stmt
338: .executeUpdate("DROP TABLE IF EXISTS testBug8096");
339: }
340: }
341: }
342:
343: /**
344: * Tests fix for BUG#9040 - PreparedStatement.addBatch() doesn't work with
345: * server-side prepared statements and streaming BINARY data.
346: *
347: * @throws Exception
348: * if the test fails.
349: */
350: public void testBug9040() throws Exception {
351: try {
352: this .stmt.executeUpdate("DROP TABLE IF EXISTS testBug9040");
353:
354: this .stmt
355: .executeUpdate("create table if not exists testBug9040 "
356: + "(primary_key int not null primary key, "
357: + "data mediumblob)");
358:
359: this .pstmt = this .conn
360: .prepareStatement("replace into testBug9040 (primary_key, data) values(?,?)");
361:
362: int primaryKey = 1;
363: byte[] data = "First Row".getBytes();
364: this .pstmt.setInt(1, primaryKey);
365: this .pstmt.setBinaryStream(2,
366: new ByteArrayInputStream(data), data.length);
367: this .pstmt.addBatch();
368:
369: primaryKey = 2;
370: data = "Second Row".getBytes();
371: this .pstmt.setInt(1, primaryKey);
372: this .pstmt.setBinaryStream(2,
373: new ByteArrayInputStream(data), data.length);
374: this .pstmt.addBatch();
375:
376: this .pstmt.executeBatch();
377: } finally {
378: this .stmt.executeUpdate("DROP TABLE IF EXISTS testBug9040");
379:
380: if (this .pstmt != null) {
381: this .pstmt.close();
382: }
383: }
384: }
385:
386: public void testBug10850() throws Exception {
387: String tableName = "testBug10850";
388:
389: createTable(tableName, "(field1 TEXT)");
390:
391: PreparedStatement pStmt = null;
392:
393: try {
394: pStmt = this .conn.prepareStatement("INSERT INTO " +
395:
396: tableName + " VALUES (?)");
397: pStmt.setCharacterStream(1, new StringReader(""), 0);
398: pStmt.executeUpdate();
399:
400: assertEquals("0", getSingleIndexedValueWithQuery(1,
401: "SELECT LENGTH(field1) FROM " + tableName)
402: .toString());
403: this .stmt.executeUpdate("TRUNCATE TABLE " + tableName);
404:
405: pStmt.clearParameters();
406: pStmt.setBinaryStream(1, new ByteArrayInputStream(
407: new byte[0]), 0);
408: pStmt.executeUpdate();
409:
410: assertEquals("0", getSingleIndexedValueWithQuery(1,
411: "SELECT LENGTH(field1) FROM " + tableName)
412: .toString());
413: this .stmt.executeUpdate("TRUNCATE TABLE " + tableName);
414: } finally {
415: if (pStmt != null) {
416: pStmt.close();
417: }
418: }
419: }
420: }
|