public static string ExtractCurrent(
            string contextKey,
            DbConnection connection,
            string schemaName,
            string extractDirectoryPath)
        {
            const string sql =
                "SELECT TOP 1 " +
                "   DeploymentId " +
                " , ContextKey " +
                " , AssemblyFileName " +
                " , Binaries " +
                " , Hashes " +
                " , DeployerVersion " +
                "FROM [{0}].[__DeploymentHistory] " +
                "WHERE ContextKey = @ContextKey " +
                "ORDER BY DeploymentId DESC ";

            var hasDeploymentHistoryTable = GetIsDeploymentHistoryTableExists(connection, schemaName);

            if (!hasDeploymentHistoryTable)
            {
                return(null);
            }

            DbCommand    command = null;
            DbDataReader reader  = null;

            try
            {
                command             = connection.CreateCommand();
                command.CommandText = string.Format(sql, schemaName);

                var contextKeyParam = command.CreateParameter();
                contextKeyParam.DbType        = DbType.String;
                contextKeyParam.Direction     = ParameterDirection.Input;
                contextKeyParam.ParameterName = "@ContextKey";
                contextKeyParam.Value         = contextKey;
                command.Parameters.Add(contextKeyParam);

                reader = command.ExecuteReader();
                if (!reader.HasRows)
                {
                    return(null);
                }

                if (!reader.Read())
                {
                    throw new Exception($"Couldn't read {schemaName} deployment history; contextKey: {contextKey}");
                }

                // extract to a working sub-directory using the deploymentId
                var deploymentId        = reader.GetString(0);
                var targetDirectoryPath = Path.Combine(extractDirectoryPath, deploymentId);

                using (var zipArchive = new ZipArchive(reader.GetStream(3), ZipArchiveMode.Read))
                {
                    ZipUtility.Unzip(targetDirectoryPath, zipArchive);
                }

                using (var hashesReader = new StreamReader(reader.GetStream(4)))
                {
                    HashUtility.Verify(targetDirectoryPath, hashesReader, m_HashName);
                }

                var assemblyFilePath = Path.Combine(targetDirectoryPath, reader.GetString(2));

                reader.Close();

                return(assemblyFilePath);
            }
            finally
            {
                reader.SafeDispose();
                command.SafeDispose();
            }
        }
        public static string Extract(
            string deploymentId,
            DbConnection connection,
            string schemaName,
            string extractDirectoryPath,
            bool disableVerification = false)
        {
            const string sql =
                "SELECT " +
                "   AssemblyFileName " +
                " , Binaries " +
                " , Hashes " +
                "FROM [{0}].[__DeploymentHistory] " +
                "WHERE DeploymentId = @DeploymentId ";

            var hasDeploymentHistoryTable = GetIsDeploymentHistoryTableExists(connection, schemaName);

            if (!hasDeploymentHistoryTable)
            {
                return(null);
            }

            DbCommand    command = null;
            DbDataReader reader  = null;

            try
            {
                command             = connection.CreateCommand();
                command.CommandText = string.Format(sql, schemaName);

                var deploymentIdParam = command.CreateParameter();
                deploymentIdParam.DbType        = DbType.String;
                deploymentIdParam.Direction     = ParameterDirection.Input;
                deploymentIdParam.ParameterName = "@DeploymentId";
                deploymentIdParam.Value         = deploymentId;
                command.Parameters.Add(deploymentIdParam);

                reader = command.ExecuteReader();
                if (!reader.HasRows)
                {
                    return(null);
                }

                if (!reader.Read())
                {
                    throw new Exception($"Couldn't read {schemaName} deployment history; deploymentId: {deploymentId}");
                }

                using (var zipArchive = new ZipArchive(reader.GetStream(1), ZipArchiveMode.Read))
                {
                    ZipUtility.Unzip(extractDirectoryPath, zipArchive);
                }

                if (!disableVerification)
                {
                    using (var hashesReader = new StreamReader(reader.GetStream(2)))
                    {
                        HashUtility.Verify(extractDirectoryPath, hashesReader, m_HashName);
                    }
                }

                var assemblyFilePath = Path.Combine(extractDirectoryPath, reader.GetString(0));

                reader.Close();

                return(assemblyFilePath);
            }
            finally
            {
                reader.SafeDispose();
                command.SafeDispose();
            }
        }