Package org.syncany.database.dao

Source Code of org.syncany.database.dao.FileHistorySqlDao

/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.syncany.database.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.syncany.database.DatabaseVersion.DatabaseVersionStatus;
import org.syncany.database.FileVersion.FileStatus;
import org.syncany.database.FileVersion.FileType;
import org.syncany.database.FileVersion;
import org.syncany.database.PartialFileHistory;
import org.syncany.database.PartialFileHistory.FileHistoryId;
import org.syncany.database.VectorClock;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

/**
* The file history DAO queries and modifies the <i>filehistory</i> in
* the SQL database. This table corresponds to the Java object {@link PartialFileHistory}.
*
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class FileHistorySqlDao extends AbstractSqlDao {
  protected static final Logger logger = Logger.getLogger(FileHistorySqlDao.class.getSimpleName());

  private FileVersionSqlDao fileVersionDao; 
 
  public FileHistorySqlDao(Connection connection, FileVersionSqlDao fileVersionDao) {
    super(connection);   
    this.fileVersionDao = fileVersionDao;   
  }

  /**
   * Writes a list of {@link PartialFileHistory}s to the database table <i>filehistory</i> using <tt>INSERT</tt>s
   * and the given connection. In addition, this method also writes the corresponding {@link FileVersion}s of
   * each file history to the database using
   * {@link FileVersionSqlDao#writeFileVersions(Connection, FileHistoryId, long, Collection) FileVersionSqlDao#writeFileVersions}.
   *
   * <p><b>Note:</b> This method executes, but <b>does not commit</b> the queries.
   *
   * @param connection The connection used to execute the statements
   * @param databaseVersionId References the {@link PartialFileHistory} to which the list of file versions belongs
   * @param fileHistories List of {@link PartialFileHistory}s to be written to the database
   * @throws SQLException If the SQL statement fails
   */
  public void writeFileHistories(Connection connection, long databaseVersionId, Collection<PartialFileHistory> fileHistories) throws SQLException {
    for (PartialFileHistory fileHistory : fileHistories) {
      PreparedStatement preparedStatement = getStatement(connection, "filehistory.insert.all.writeFileHistories.sql");

      preparedStatement.setString(1, fileHistory.getFileHistoryId().toString());
      preparedStatement.setLong(2, databaseVersionId);

      int affectedRows = preparedStatement.executeUpdate();
     
      if (affectedRows == 0) {
        throw new SQLException("Cannot add database version header. Affected rows is zero.");
      }

      preparedStatement.close();
     
      fileVersionDao.writeFileVersions(connection, fileHistory.getFileHistoryId(), databaseVersionId, fileHistory.getFileVersions().values());
    }
  }

  public void writePurgeFileHistories(Connection connection, long purgeDatabaseVersionId, Collection<PartialFileHistory> purgeFileHistories) throws SQLException {
    for (PartialFileHistory purgeFileHistory : purgeFileHistories) {
      fileVersionDao.writePurgeFileVersions(connection, purgeFileHistory.getFileHistoryId(), purgeDatabaseVersionId, purgeFileHistory.getFileVersions().values());
    }
  }
 
  public void removeDirtyFileHistories() throws SQLException {
    try (PreparedStatement preparedStatement = getStatement("filehistory.delete.dirty.removeDirtyFileHistories.sql")) {
      preparedStatement.executeUpdate();
    }   
  }
 
  /**
   * Removes unreferenced {@link PartialFileHistory}s from the database table
   * <i>filehistory</i>. This method <b>does not</b> remove the corresponding {@link FileVersion}s.
   *
   * <p><b>Note:</b> This method executes, but <b>does not commit</b> the query.
   *
   * @throws SQLException If the SQL statement fails
   */ 
  public void removeUnreferencedFileHistories() throws SQLException {
    try (PreparedStatement preparedStatement = getStatement("filehistory.delete.all.removeUnreferencedFileHistories.sql")) {
      preparedStatement.executeUpdate();
   
  }

  /**
   * Note: Also selects versions marked as {@link DatabaseVersionStatus#DIRTY DIRTY}
   */
  public Map<FileHistoryId, PartialFileHistory> getFileHistoriesWithFileVersions(VectorClock databaseVersionVectorClock) {
    try (PreparedStatement preparedStatement = getStatement("filehistory.select.all.getFileHistoriesWithFileVersionsByVectorClock.sql")) {
      preparedStatement.setString(1, databaseVersionVectorClock.toString());

      try (ResultSet resultSet = preparedStatement.executeQuery()) {
        return createFileHistoriesFromResult(resultSet);
      }
    }
    catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }

  public FileHistoryId expandFileHistoryId(FileHistoryId fileHistoryIdPrefix) {
    String fileHistoryIdPrefixLikeQuery = fileHistoryIdPrefix.toString() + "%";

    try (PreparedStatement preparedStatement = getStatement("filehistory.select.master.expandFileHistoryId.sql")) {
      preparedStatement.setString(1, fileHistoryIdPrefixLikeQuery);

      try (ResultSet resultSet = preparedStatement.executeQuery()) {
        if (resultSet.next()) {
          FileHistoryId fullFileHistoryId = FileHistoryId.parseFileId(resultSet.getString("filehistory_id"));
         
          boolean nonUniqueResult = resultSet.next();
         
          if (nonUniqueResult) {
            return null;
          }
          else {
            return fullFileHistoryId;
          }
        }
        else {
          return null;
        }       
      }
    }
    catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }
 
  public Map<FileHistoryId, PartialFileHistory> getFileHistories(List<FileHistoryId> fileHistoryIds) {
    String[] fileHistoryIdsStr = createFileHistoryIdsArray(fileHistoryIds);
   
    try (PreparedStatement preparedStatement = getStatement("filehistory.select.master.getFileHistoriesByIds.sql")) {
      preparedStatement.setArray(1, connection.createArrayOf("varchar", fileHistoryIdsStr));

      try (ResultSet resultSet = preparedStatement.executeQuery()) {
        return createFileHistoriesFromResult(resultSet);
      }
    }
    catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }
 
  private String[] createFileHistoryIdsArray(List<FileHistoryId> fileHistoryIds) {
    return Lists.transform(fileHistoryIds, new Function<FileHistoryId, String>() {
      public String apply(FileHistoryId fileHistoryId) {
        return fileHistoryId.toString();
      }     
    }).toArray(new String[0]);
  }

  public Map<FileHistoryId, PartialFileHistory> getFileHistoriesWithFileVersions() {
    try (PreparedStatement preparedStatement = getStatement("filehistory.select.master.getFileHistoriesWithFileVersions.sql")) {
      try (ResultSet resultSet = preparedStatement.executeQuery()) {
        return createFileHistoriesFromResult(resultSet);
      }
    }
    catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }

  protected Map<FileHistoryId, PartialFileHistory> createFileHistoriesFromResult(ResultSet resultSet) throws SQLException {
    Map<FileHistoryId, PartialFileHistory> fileHistories = new HashMap<FileHistoryId, PartialFileHistory>();;
    PartialFileHistory fileHistory = null;

    while (resultSet.next()) {
      FileVersion lastFileVersion = fileVersionDao.createFileVersionFromRow(resultSet);
      FileHistoryId fileHistoryId = FileHistoryId.parseFileId(resultSet.getString("filehistory_id"));
     
      // Old history (= same filehistory identifier)
      if (fileHistory != null && fileHistory.getFileHistoryId().equals(fileHistoryId)) { // Same history!
        fileHistory.addFileVersion(lastFileVersion);
      }
     
      // New history!     
      else {
        // Add the old history
        if (fileHistory != null) {
          fileHistories.put(fileHistory.getFileHistoryId(), fileHistory);
        }
       
        // Create a new one
        fileHistory = new PartialFileHistory(fileHistoryId);
        fileHistory.addFileVersion(lastFileVersion);
      }     
    }
   
    // Add the last history
    if (fileHistory != null) {
      fileHistories.put(fileHistory.getFileHistoryId(), fileHistory);
    }

    return fileHistories;
  }

  public List<PartialFileHistory> getFileHistoriesWithLastVersion() {
    List<PartialFileHistory> fileHistories = new ArrayList<PartialFileHistory>();

    try (PreparedStatement preparedStatement = getStatement("filehistory.select.master.getFileHistoriesWithLastVersion.sql")) {
      try (ResultSet resultSet = preparedStatement.executeQuery()) {
        while (resultSet.next()) {
          FileHistoryId fileHistoryId = FileHistoryId.parseFileId(resultSet.getString("filehistory_id"));
          FileVersion lastFileVersion = fileVersionDao.createFileVersionFromRow(resultSet);
 
          PartialFileHistory fileHistory = new PartialFileHistory(fileHistoryId);
          fileHistory.addFileVersion(lastFileVersion);
 
          fileHistories.add(fileHistory);
        }
      }

      return fileHistories;
    }
    catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }

  public List<PartialFileHistory> getPurgeFileHistoriesWithFileVersions(VectorClock purgeDatabaseVersionVectorClock) {
    List<PartialFileHistory> fileHistories = new ArrayList<PartialFileHistory>();

    try (PreparedStatement preparedStatement = getStatement("fileversion.select.all.getPurgeFileHistoriesWithFileVersionsByVectorClock.sql")) {
      preparedStatement.setString(1, purgeDatabaseVersionVectorClock.toString());

      try (ResultSet resultSet = preparedStatement.executeQuery()) {
        while (resultSet.next()) {
          FileHistoryId purgeFileHistoryId = FileHistoryId.parseFileId(resultSet.getString("filehistory_id"));
         
          // Create max purge version with dummy values (mandatory for XML serialization)
          FileVersion maxPurgeFileVersion = new FileVersion();
         
          maxPurgeFileVersion.setFileHistoryId(purgeFileHistoryId);
          maxPurgeFileVersion.setVersion(resultSet.getLong("fileversion_maxpurgeversion"));
         
          maxPurgeFileVersion.setPath("");
          maxPurgeFileVersion.setType(FileType.FILE);
          maxPurgeFileVersion.setStatus(FileStatus.DELETED);
          maxPurgeFileVersion.setSize(0L);
          maxPurgeFileVersion.setLastModified(new Date());
 
          PartialFileHistory fileHistory = new PartialFileHistory(purgeFileHistoryId);
          fileHistory.addFileVersion(maxPurgeFileVersion);
 
          fileHistories.add(fileHistory);
        }
      }
     
      return fileHistories;
    }
    catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }
}
TOP

Related Classes of org.syncany.database.dao.FileHistorySqlDao

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.