package org.ovirt.engine.core.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;

import javax.inject.Named;
import javax.inject.Singleton;

import org.ovirt.engine.core.common.businessentities.storage.DiskImageDynamic;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.dbbroker.MapSqlParameterMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;

/**
 * JDBC template based implementation of DiskImageDynamicDAO
 *
 */
@Named
@Singleton
public class DiskImageDynamicDAODbFacadeImpl extends MassOperationsGenericDaoDbFacade<DiskImageDynamic, Guid>
        implements DiskImageDynamicDAO {

    private static final class DiskImageDynamicRowMapper implements RowMapper<DiskImageDynamic> {
        public static final DiskImageDynamicRowMapper instance = new DiskImageDynamicRowMapper();

        @Override
        public DiskImageDynamic mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            DiskImageDynamic entity = new DiskImageDynamic();
            entity.setId(getGuidDefaultEmpty(rs, "image_id"));
            entity.setread_rate((Integer) rs.getObject("read_rate"));
            entity.setwrite_rate((Integer) rs.getObject("write_rate"));
            entity.setactual_size(rs.getLong("actual_size"));
            entity.setReadLatency(rs.getObject("read_latency_seconds") != null ? rs.getDouble("read_latency_seconds")
                    : null);
            entity.setWriteLatency(rs.getObject("write_latency_seconds") != null ? rs.getDouble("write_latency_seconds")
                    : null);
            entity.setFlushLatency(rs.getObject("flush_latency_seconds") != null ? rs.getDouble("flush_latency_seconds")
                    : null);
            return entity;
        }
    }

    public DiskImageDynamicDAODbFacadeImpl() {
        super("disk_image_dynamic");
        setProcedureNameForGet("Getdisk_image_dynamicByimage_id");
        setProcedureNameForGetAll("GetAllFromdisk_image_dynamic");
    }

    @Override
    protected MapSqlParameterSource createIdParameterMapper(Guid id) {
        return getCustomMapSqlParameterSource()
                .addValue("image_id", id);
    }

    @Override
    protected MapSqlParameterSource createFullParametersMapper(DiskImageDynamic entity) {
        return createIdParameterMapper(entity.getId())
                .addValue("read_rate", entity.getread_rate())
                .addValue("write_rate", entity.getwrite_rate())
                .addValue("actual_size", entity.getactual_size())
                .addValue("read_latency_seconds", entity.getReadLatency())
                .addValue("write_latency_seconds", entity.getWriteLatency())
                .addValue("flush_latency_seconds", entity.getFlushLatency());
    }

    @Override
    protected RowMapper<DiskImageDynamic> createEntityRowMapper() {
        return DiskImageDynamicRowMapper.instance;
    }

    public MapSqlParameterMapper<Pair<Guid, DiskImageDynamic>> getBatchImageGroupMapper() {
        return new MapSqlParameterMapper<Pair<Guid, DiskImageDynamic>>() {

            @Override
            public MapSqlParameterSource map(Pair<Guid, DiskImageDynamic> entity) {
                Guid vmId = entity.getFirst();
                DiskImageDynamic diskImageDynamic = entity.getSecond();
                MapSqlParameterSource paramValue = new MapSqlParameterSource()
                        .addValue("vm_id", vmId)
                        .addValue("image_group_id", diskImageDynamic.getId())
                        .addValue("read_rate", diskImageDynamic.getread_rate())
                        .addValue("write_rate", diskImageDynamic.getwrite_rate())
                        .addValue("actual_size", diskImageDynamic.getactual_size())
                        .addValue("read_latency_seconds", diskImageDynamic.getReadLatency())
                        .addValue("write_latency_seconds", diskImageDynamic.getWriteLatency())
                        .addValue("flush_latency_seconds", diskImageDynamic.getFlushLatency());

                return paramValue;
            }
        };
    }

    @Override
    public void updateAllDiskImageDynamicWithDiskIdByVmId(Collection<Pair<Guid, DiskImageDynamic>> diskImageDynamicForVm) {
        getCallsHandler().executeStoredProcAsBatch("Updatedisk_image_dynamic_by_disk_id_and_vm_id",
                diskImageDynamicForVm, getBatchImageGroupMapper());
    }
}

@@ -103,26 +103,136 @@
 va.util.
-Collection
+ArrayList;%0Aimport java.util.Collection;%0Aimport java.util.Collections;%0Aimport java.util.Comparator;%0Aimport java.util.List
 ;%0A%0Aimpor
@@ -4486,24 +4486,449 @@
 micForVm) %7B%0A
+        List%3CPair%3CGuid, DiskImageDynamic%3E%3E sortedDisks = new ArrayList%3C%3E();%0A        sortedDisks.addAll(diskImageDynamicForVm);%0A        Collections.sort(sortedDisks, new Comparator%3CPair%3CGuid, DiskImageDynamic%3E%3E() %7B%0A%0A            @Override%0A            public int compare(Pair%3CGuid, DiskImageDynamic%3E o1, Pair%3CGuid, DiskImageDynamic%3E o2) %7B%0A                return o1.getFirst().compareTo(o2.getFirst());%0A            %7D%0A        %7D);%0A
         getC
@@ -5031,37 +5031,27 @@
         
-diskImageDynamicForVm
+sortedDisks
 , getBat

Fix Dead Locks in Updatedisk_image_dynamic_by_disk_id_and_vm_id