package db import ( "database/sql" "errors" ) func (d *DB) GetEmailLogByID(id int64) (*EmailLog, error) { row := d.QueryRow(`SELECT id, message_id, timestamp, peer_ip, mail_from, to_address, cc_addresses, bcc_addresses, subject, email_headers, message_body, status, dkim_signed, username, created_at FROM esrv_email_logs WHERE id = ?`, id) return scanEmailLog(row) } func scanEmailLog(row *sql.Row) (*EmailLog, error) { var l EmailLog var ts, createdAt string if err := row.Scan(&l.ID, &l.MessageID, &ts, &l.PeerIP, &l.MailFrom, &l.ToAddress, &l.CcAddresses, &l.BccAddresses, &l.Subject, &l.EmailHeaders, &l.MessageBody, &l.Status, &l.DKIMSigned, &l.Username, &createdAt); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, nil } return nil, err } l.Timestamp, _ = parseTime(ts) l.CreatedAt, _ = parseTime(createdAt) return &l, nil } func (d *DB) ListEmailLogsPage(offset, limit int) ([]EmailLog, error) { rows, err := d.Query(`SELECT id, message_id, timestamp, peer_ip, mail_from, to_address, cc_addresses, bcc_addresses, subject, email_headers, message_body, status, dkim_signed, username, created_at FROM esrv_email_logs ORDER BY created_at DESC LIMIT ? OFFSET ?`, limit, offset) if err != nil { return nil, err } defer rows.Close() var out []EmailLog for rows.Next() { var l EmailLog var ts, createdAt string if err := rows.Scan(&l.ID, &l.MessageID, &ts, &l.PeerIP, &l.MailFrom, &l.ToAddress, &l.CcAddresses, &l.BccAddresses, &l.Subject, &l.EmailHeaders, &l.MessageBody, &l.Status, &l.DKIMSigned, &l.Username, &createdAt); err != nil { return nil, err } l.Timestamp, _ = parseTime(ts) l.CreatedAt, _ = parseTime(createdAt) out = append(out, l) } return out, rows.Err() } func (d *DB) ListAuthLogsPage(offset, limit int) ([]AuthLog, error) { rows, err := d.Query(`SELECT id, auth_type, identifier, ip_address, success, message, created_at FROM esrv_auth_logs ORDER BY created_at DESC LIMIT ? OFFSET ?`, limit, offset) if err != nil { return nil, err } defer rows.Close() var out []AuthLog for rows.Next() { var a AuthLog var createdAt string if err := rows.Scan(&a.ID, &a.AuthType, &a.Identifier, &a.IPAddress, &a.Success, &a.Message, &createdAt); err != nil { return nil, err } a.CreatedAt, _ = parseTime(createdAt) out = append(out, a) } return out, rows.Err() } func (d *DB) ListRecentAuthLogs(limit int) ([]AuthLog, error) { return d.ListAuthLogsPage(0, limit) } func (d *DB) ListRecipientLogsForEmail(emailLogID int64) ([]EmailRecipientLog, error) { rows, err := d.Query(`SELECT id, email_log_id, recipient, recipient_type, status, error_code, error_message, server_response FROM esrv_email_recipient_logs WHERE email_log_id = ?`, emailLogID) if err != nil { return nil, err } defer rows.Close() var out []EmailRecipientLog for rows.Next() { var r EmailRecipientLog if err := rows.Scan(&r.ID, &r.EmailLogID, &r.Recipient, &r.RecipientType, &r.Status, &r.ErrorCode, &r.ErrorMessage, &r.ServerResponse); err != nil { return nil, err } out = append(out, r) } return out, rows.Err() } func (d *DB) ListAttachmentsForEmail(emailLogID int64) ([]EmailAttachment, error) { rows, err := d.Query(`SELECT id, email_log_id, filename, content_type, file_path, size, uploaded_at FROM esrv_email_attachments WHERE email_log_id = ?`, emailLogID) if err != nil { return nil, err } defer rows.Close() var out []EmailAttachment for rows.Next() { var a EmailAttachment var uploadedAt string if err := rows.Scan(&a.ID, &a.EmailLogID, &a.Filename, &a.ContentType, &a.FilePath, &a.Size, &uploadedAt); err != nil { return nil, err } a.UploadedAt, _ = parseTime(uploadedAt) out = append(out, a) } return out, rows.Err() } func (d *DB) GetAttachmentByID(id int64) (*EmailAttachment, error) { row := d.QueryRow(`SELECT id, email_log_id, filename, content_type, file_path, size, uploaded_at FROM esrv_email_attachments WHERE id = ?`, id) var a EmailAttachment var uploadedAt string if err := row.Scan(&a.ID, &a.EmailLogID, &a.Filename, &a.ContentType, &a.FilePath, &a.Size, &uploadedAt); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, nil } return nil, err } a.UploadedAt, _ = parseTime(uploadedAt) return &a, nil } func (d *DB) RemoveAttachment(id int64) error { _, err := d.Exec(`DELETE FROM esrv_email_attachments WHERE id = ?`, id) return err }