if (security != null)
{
security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
}
ObjectZipReaderImpl contentReader = null;
ObjectZipReaderImpl contentLenReader = null;
PreparedStatement insertNode = null;
ResultSet tableMetaData = null;
// switch table name to lower case
if (dialect.equalsIgnoreCase(DBConstants.DB_DIALECT_PGSQL)
|| dialect.equalsIgnoreCase(DBConstants.DB_DIALECT_PGSQL_SCS))
{
tableName = tableName.toLowerCase();
}
try
{
File contentFile = new File(storageDir, restoreRule.getSrcTableName() + DBBackup.CONTENT_FILE_SUFFIX);
// check old style backup format, when for every table was dedicated zip file
if (PrivilegedFileHelper.exists(contentFile))
{
contentReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentFile));
contentReader.getNextEntry();
File contentLenFile =
new File(storageDir, restoreRule.getSrcTableName() + DBBackup.CONTENT_LEN_FILE_SUFFIX);
contentLenReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentLenFile));
contentLenReader.getNextEntry();
}
else
{
contentFile = new File(storageDir, DBBackup.CONTENT_ZIP_FILE);
contentReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentFile));
while (!contentReader.getNextEntry().getName().equals(restoreRule.getSrcTableName()));
File contentLenFile = new File(storageDir, DBBackup.CONTENT_LEN_ZIP_FILE);
contentLenReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentLenFile));
while (!contentLenReader.getNextEntry().getName().equals(restoreRule.getSrcTableName()));
}
// get information about source table
int sourceColumnCount = contentReader.readInt();
List<Integer> columnType = new ArrayList<Integer>();
List<String> columnName = new ArrayList<String>();
for (int i = 0; i < sourceColumnCount; i++)
{
columnType.add(contentReader.readInt());
columnName.add(contentReader.readString());
}
int targetColumnCount = sourceColumnCount;
if (restoreRule.getNewColumnIndex() != null)
{
targetColumnCount++;
columnType.add(restoreRule.getNewColumnIndex(), restoreRule.getNewColumnType());
String newColumnName =
(dialect.equalsIgnoreCase(DBConstants.DB_DIALECT_PGSQL) || dialect
.equalsIgnoreCase(DBConstants.DB_DIALECT_PGSQL_SCS)) ? restoreRule.getNewColumnName().toLowerCase()
: restoreRule.getNewColumnName();
columnName.add(restoreRule.getNewColumnIndex(), newColumnName);
}
// construct statement
StringBuilder names = new StringBuilder();
StringBuilder parameters = new StringBuilder();
for (int i = 0; i < targetColumnCount; i++)
{
if (restoreRule.getSkipColumnIndex() != null && restoreRule.getSkipColumnIndex() == i)
{
continue;
}
names.append(columnName.get(i)).append(i == targetColumnCount - 1 ? "" : ",");
parameters.append("?").append(i == targetColumnCount - 1 ? "" : ",");
}
int batchSize = 0;
insertNode =
jdbcConn.prepareStatement("INSERT INTO " + tableName + " (" + names + ") VALUES(" + parameters + ")");
// set data
outer : while (true)
{
for (int i = 0, targetIndex = 0; i < columnType.size(); i++, targetIndex++)
{
InputStream stream;
long len;
if (restoreRule.getNewColumnIndex() != null && restoreRule.getNewColumnIndex() == i)
{
stream =
new ByteArrayInputStream(restoreRule.getDstContainerName().getBytes(Constants.DEFAULT_ENCODING));
len = ((ByteArrayInputStream)stream).available();
}
else
{
try
{
len = contentLenReader.readLong();
}
catch (EOFException e)
{
if (i == 0)
{
// content length file is empty check content file
try
{
contentReader.readByte();
}
catch (EOFException e1)
{
break outer;
}
}
throw new IOException("Content length file is empty but content still present", e);
}
stream = len == -1 ? null : spoolInputStream(contentReader, len);
}
if (restoreRule.getSkipColumnIndex() != null && restoreRule.getSkipColumnIndex() == i)
{
targetIndex--;
continue;
}
// set
if (stream != null)
{
if (restoreRule.getConvertColumnIndex() != null && restoreRule.getConvertColumnIndex().contains(i))
{
// convert column value
ByteArrayInputStream ba = (ByteArrayInputStream)stream;
byte[] readBuffer = new byte[ba.available()];
ba.read(readBuffer);
String currentValue = new String(readBuffer, Constants.DEFAULT_ENCODING);
if (currentValue.equals(Constants.ROOT_PARENT_UUID))
{
stream = new ByteArrayInputStream(Constants.ROOT_PARENT_UUID.getBytes());
}
else
{
if (restoreRule.getDstMultiDb())
{
if (!restoreRule.getSrcMultiDb())
{
stream =
new ByteArrayInputStream(new String(readBuffer, Constants.DEFAULT_ENCODING).substring(
restoreRule.getSrcContainerName().length()).getBytes());
}
}
else
{
if (restoreRule.getSrcMultiDb())
{
StringBuilder builder = new StringBuilder();
builder.append(restoreRule.getDstContainerName());
builder.append(currentValue);
stream = new ByteArrayInputStream(builder.toString().getBytes());
}
else
{
StringBuilder builder = new StringBuilder();
builder.append(restoreRule.getDstContainerName());
builder.append(new String(readBuffer, Constants.DEFAULT_ENCODING).substring(restoreRule
.getSrcContainerName().length()));
stream = new ByteArrayInputStream(builder.toString().getBytes());
}
}
}
len = ((ByteArrayInputStream)stream).available();
}
if (columnType.get(i) == Types.INTEGER || columnType.get(i) == Types.BIGINT
|| columnType.get(i) == Types.SMALLINT || columnType.get(i) == Types.TINYINT)
{
ByteArrayInputStream ba = (ByteArrayInputStream)stream;
byte[] readBuffer = new byte[ba.available()];
ba.read(readBuffer);
String value = new String(readBuffer, Constants.DEFAULT_ENCODING);
insertNode.setLong(targetIndex + 1, Integer.parseInt(value));
}
else if (columnType.get(i) == Types.BIT)
{
ByteArrayInputStream ba = (ByteArrayInputStream)stream;
byte[] readBuffer = new byte[ba.available()];
ba.read(readBuffer);
String value = new String(readBuffer);
if (dialect.equalsIgnoreCase(DBConstants.DB_DIALECT_PGSQL)
|| dialect.equalsIgnoreCase(DBConstants.DB_DIALECT_PGSQL_SCS))
{
insertNode.setBoolean(targetIndex + 1, value.equalsIgnoreCase("t"));
}
else
{
insertNode.setBoolean(targetIndex + 1, value.equals("1"));
}
}
else if (columnType.get(i) == Types.BOOLEAN)
{
ByteArrayInputStream ba = (ByteArrayInputStream)stream;
byte[] readBuffer = new byte[ba.available()];
ba.read(readBuffer);
String value = new String(readBuffer);
insertNode.setBoolean(targetIndex + 1, value.equalsIgnoreCase("true"));
}
else if (columnType.get(i) == Types.VARBINARY || columnType.get(i) == Types.LONGVARBINARY
|| columnType.get(i) == Types.BLOB || columnType.get(i) == Types.BINARY
|| columnType.get(i) == Types.OTHER)
{
insertNode.setBinaryStream(targetIndex + 1, stream, (int)len);
}
else
{
byte[] readBuffer = new byte[(int)len];
stream.read(readBuffer);
insertNode.setString(targetIndex + 1, new String(readBuffer, Constants.DEFAULT_ENCODING));
}
}
else
{
insertNode.setNull(targetIndex + 1, columnType.get(i));
}
}
// add statement to batch
insertNode.addBatch();
if (++batchSize == MAXIMUM_BATCH_SIZE)
{
insertNode.executeBatch();
commitBatch();
batchSize = 0;
}
}
if (batchSize != 0)
{
insertNode.executeBatch();
commitBatch();
}
}
finally
{
if (contentReader != null)
{
contentReader.close();
}
if (contentLenReader != null)
{
contentLenReader.close();
}
if (insertNode != null)
{
insertNode.close();