function report_customsql_generate_csv($report, $timenow)
{
    global $DB;
    $starttime = microtime(true);
    $sql = report_customsql_prepare_sql($report, $timenow);
    $queryparams = !empty($report->queryparams) ? unserialize($report->queryparams) : array();
    $querylimit = !empty($report->querylimit) ? $report->querylimit : REPORT_CUSTOMSQL_MAX_RECORDS;
    $rs = report_customsql_execute_query($sql, $queryparams, $querylimit);
    $csvfilenames = array();
    $csvtimestamp = null;
    foreach ($rs as $row) {
        if (!$csvtimestamp) {
            list($csvfilename, $csvtimestamp) = report_customsql_csv_filename($report, $timenow);
            $csvfilenames[] = $csvfilename;
            if (!file_exists($csvfilename)) {
                $handle = fopen($csvfilename, 'w');
                report_customsql_start_csv($handle, $row, $report->singlerow);
            } else {
                $handle = fopen($csvfilename, 'a');
            }
        }
        $data = get_object_vars($row);
        foreach ($data as $name => $value) {
            if (report_customsql_get_element_type($name) == 'date_time_selector' && report_customsql_is_integer($value)) {
                $data[$name] = userdate($value, '%F %T');
            }
        }
        if ($report->singlerow) {
            array_unshift($data, strftime('%Y-%m-%d', $timenow));
        }
        report_customsql_write_csv_row($handle, $data);
    }
    $rs->close();
    if (!empty($handle)) {
        fclose($handle);
    }
    // Update the execution time in the DB.
    $updaterecord = new stdClass();
    $updaterecord->id = $report->id;
    $updaterecord->lastrun = time();
    $updaterecord->lastexecutiontime = round((microtime(true) - $starttime) * 1000);
    $DB->update_record('report_customsql_queries', $updaterecord);
    // Report is runable daily, weekly or monthly.
    if ($report->runable != 'manual' && !empty($report->emailto)) {
        if ($csvfilenames) {
            foreach ($csvfilenames as $csvfilename) {
                report_customsql_email_report($report, $csvfilename);
            }
        } else {
            // If there is no data.
            report_customsql_email_report($report);
        }
    }
    return $csvtimestamp;
}
function report_customsql_generate_csv($report, $timenow, $limitnum = REPORT_CUSTOMSQL_MAX_RECORDS)
{
    global $db;
    $starttime = microtime(true);
    $sql = report_customsql_prepare_sql($report, $timenow);
    $rs = report_customsql_execute_query($sql, $limitnum);
    if (!$rs) {
        throw new Exception($db->ErrorMsg());
    }
    $cvstimestamp = null;
    while ($row = rs_fetch_next_record($rs)) {
        if (!$cvstimestamp) {
            list($csvfilename, $cvstimestamp) = report_customsql_csv_filename($report, $timenow);
            if (!file_exists($csvfilename)) {
                $handle = fopen($csvfilename, 'w');
                report_customsql_start_csv($handle, $row, $report->singlerow);
            } else {
                $handle = fopen($csvfilename, 'a');
            }
        }
        $data = get_object_vars($row);
        if ($report->singlerow) {
            array_unshift($data, strftime('%Y-%m-%d', $timenow));
        }
        report_customsql_write_csv_row($handle, $data);
    }
    rs_close($rs);
    if (!empty($handle)) {
        fclose($handle);
    }
    // Update the execution time in the DB.
    $updaterecord = new stdClass();
    $updaterecord->id = $report->id;
    $updaterecord->lastrun = time();
    $updaterecord->lastexecutiontime = round((microtime(true) - $starttime) * 1000);
    update_record('report_customsql_queries', $updaterecord);
    return $cvstimestamp;
}