package org.mariadb.jdbc;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.*;
import java.sql.*;
import java.util.Arrays;
import static org.junit.Assert.*;
public class BigQueryTest extends BaseTest {
/**
* Initialize test data.
* @throws SQLException id connection error occur
*/
@BeforeClass()
public static void initClass() throws SQLException {
createTable("bigblob", "id int not null primary key auto_increment, test longblob");
createTable("bigblob2", "id int not null primary key auto_increment, test longblob, test2 longblob");
createTable("bigblob3", "id int not null primary key auto_increment, test longblob, test2 longblob, test3 varchar(20)");
createTable("bigblob4", "test longblob");
createTable("bigblob5", "id int not null primary key auto_increment, test longblob, test2 text");
}
@Test
public void sendBigQuery2() throws SQLException {
Assume.assumeTrue(checkMaxAllowedPacketMore40m("sendBigQuery2"));
char[] arr = new char[20000000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (char) ('a' + (i % 10));
}
Statement stmt = sharedConnection.createStatement();
StringBuilder query = new StringBuilder("INSERT INTO bigblob VALUES (null, '")
.append(arr).append("')");
stmt.executeUpdate(query.toString());
ResultSet rs = stmt.executeQuery("select * from bigblob");
rs.next();
byte[] newBytes = rs.getBytes(2);
assertEquals(arr.length, newBytes.length);
for (int i = 0; i < arr.length; i++) {
assertEquals(arr[i], newBytes[i]);
}
}
@Test
public void sendBigPreparedQuery() throws SQLException {
Assume.assumeTrue(checkMaxAllowedPacketMore40m("sendBigPreparedQuery"));
byte[] arr = new byte[20000000];
Arrays.fill(arr, (byte) 'a');
byte[] arr2 = new byte[20000000];
Arrays.fill(arr2, (byte) 'b');
PreparedStatement ps = sharedConnection.prepareStatement("insert into bigblob2 values(null, ?,?)");
ps.setBytes(1, arr);
ps.setBytes(2, arr2);
ps.executeUpdate();
Statement stmt = sharedConnection.createStatement();
ResultSet rs = stmt.executeQuery("select * from bigblob2");
rs.next();
byte[] newBytes = rs.getBytes(2);
byte[] newBytes2 = rs.getBytes(3);
assertEquals(arr.length, newBytes.length);
assertEquals(arr2.length, newBytes2.length);
for (int i = 0; i < arr.length; i++) {
assertEquals(arr[i], newBytes[i]);
}
for (int i = 0; i < arr2.length; i++) {
assertEquals(arr2[i], newBytes2[i]);
}
}
@Test
public void sendBigBlobPreparedQuery() throws SQLException {
Assume.assumeTrue(checkMaxAllowedPacketMore40m("sendBigPreparedQuery") && sharedUsePrepare());
long maxAllowedPacket = 0;
Statement st = sharedConnection.createStatement();
ResultSet rs1 = st.executeQuery("select @@max_allowed_packet");
if (rs1.next()) {
maxAllowedPacket = rs1.getInt(1);
Assume.assumeTrue(maxAllowedPacket < 512 * 1024 * 1024L);
} else {
fail();
}
byte[] arr = new byte[(int) maxAllowedPacket - 1000];
int pos = 0;
while (pos < maxAllowedPacket - 1000) {
arr[pos] = (byte) ((pos % 132) + 40);
pos++;
}
byte[] arr2 = new byte[(int) maxAllowedPacket - 1000];
pos = 0;
while (pos < maxAllowedPacket - 1000) {
arr2[pos] = (byte) (((pos + 5 ) % 127) + 40);
pos++;
}
PreparedStatement ps = sharedConnection.prepareStatement("insert into bigblob3 values(null, ?,?,?)");
ps.setBlob(1, new MariaDbBlob(arr));
ps.setBlob(2, new MariaDbBlob(arr2));
ps.setString(3, "bob");
ps.executeUpdate();
Statement stmt = sharedConnection.createStatement();
ResultSet rs = stmt.executeQuery("select * from bigblob3");
rs.next();
byte[] newBytes = rs.getBytes(2);
byte[] newBytes2 = rs.getBytes(3);
assertEquals(arr.length, newBytes.length);
assertEquals(arr2.length, newBytes2.length);
for (int i = 0; i < arr.length; i++) {
assertEquals(arr[i], newBytes[i]);
}
for (int i = 0; i < arr2.length; i++) {
assertEquals(arr2[i], newBytes2[i]);
}
assertEquals("bob", rs.getString(4));
}
@Test
public void testError() throws SQLException {
// check that maxAllowedPacket is big enough for the test
Assume.assumeTrue(checkMaxAllowedPacketMore20m("testError"));
try (Connection connection = setConnection()) {
int selectSize = 9;
char[] arr = new char[16 * 1024 * 1024 - selectSize];
Arrays.fill(arr, 'a');
String request = "select '" + new String(arr) + "'";
ResultSet rs = connection.createStatement().executeQuery(request);
rs.next();
assertEquals(arr.length, rs.getString(1).length());
}
}
@Test
public void sendStreamComData() throws Exception {
Assume.assumeTrue(checkMaxAllowedPacketMore40m("sendBigPreparedQuery") && sharedUsePrepare());
File tmpFile = File.createTempFile("temp-file-name", ".tmp");
byte[] bb = new byte[11000];
for (int i = 0; i < 11_000; i++) {
bb[i] = (byte) (i % 110 + 40);
}
try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
for (int i = 0; i < 2_000; i++) {
fos.write(bb);
}
}
try (FileInputStream fis = new FileInputStream(tmpFile)) {
try (FileInputStream fis2 = new FileInputStream(tmpFile)) {
try (FileInputStream fis3 = new FileInputStream(tmpFile)) {
try (PreparedStatement ps = sharedConnection.prepareStatement("insert into bigblob4 values(?)")) {
//testing char stream
ps.setCharacterStream(1, new InputStreamReader(fis, "UTF-8"));
ps.executeUpdate();
//testing byte stream
ps.setBlob(1, fis2);
ps.executeUpdate();
//testing char stream with length
ps.setCharacterStream(1, new InputStreamReader(fis3, "UTF-8"), 10_000_000);
ps.executeUpdate();
}
}
}
}
//test using binary resultSet
PreparedStatement ps = sharedConnection.prepareStatement("select * from bigblob4");
checkResult(tmpFile, ps.executeQuery(), 10_000_000);
//test using text resultSet
Statement stmt = sharedConnection.createStatement();
checkResult(tmpFile, stmt.executeQuery("select * from bigblob4"), 10_000_000);
}
private void checkResult(File tmpFile, ResultSet rs, int length) throws Exception {
assertTrue(rs.next());
String res = rs.getString(1);
try (Reader initialReader = new InputStreamReader(new FileInputStream(tmpFile), "UTF-8")) {
char[] bb = new char[64 * 1024];
int len;
int pos = 0;
while ((len = initialReader.read(bb)) > 0) {
for (int i = 0; i < len; i++) {
assertEquals(bb[i], res.charAt(pos++));
}
}
}
assertTrue(rs.next());
byte[] results = rs.getBytes(1);
try (FileInputStream fis2 = new FileInputStream(tmpFile)) {
byte[] byteBuffer = new byte[64 * 1024];
int len;
int pos = 0;
while ((len = fis2.read(byteBuffer)) > 0) {
for (int i = 0; i < len; i++) {
assertEquals(byteBuffer[i], results[pos++]);
}
}
}
assertTrue(rs.next());
res = rs.getString(1);
assertEquals(length, res.length());
try (Reader initialReader = new InputStreamReader(new FileInputStream(tmpFile), "UTF-8")) {
char[] bb = new char[64 * 1024];
int len;
int pos = 0;
while ((len = initialReader.read(bb)) > 0) {
for (int i = 0; i < len; i++) {
if (pos < length) assertEquals(bb[i], res.charAt(pos++));
}
}
assertEquals(length, pos);
}
assertFalse(rs.next());
}
@Test
public void maxFieldSizeTest() throws SQLException {
byte abyte = (byte) 'a';
byte bbyte = (byte) 'b';
byte[] arr = new byte[200];
Arrays.fill(arr, abyte);
byte[] arr2 = new byte[200];
Arrays.fill(arr2, bbyte);
PreparedStatement ps = sharedConnection.prepareStatement("insert into bigblob5 values(null, ?,?)");
ps.setBytes(1, arr);
ps.setBytes(2, arr2);
ps.executeUpdate();
Statement stmt = sharedConnection.createStatement();
stmt.setMaxFieldSize(2);
ResultSet rs = stmt.executeQuery("select * from bigblob5");
rs.next();
assertEquals(2, rs.getBytes(2).length);
assertEquals(2, rs.getString(3).length());
assertArrayEquals(new byte[] {abyte, abyte}, rs.getBytes(2));
assertEquals("bb", rs.getString(3));
}
}