Solved

Send email attachments from a DB with Indy

Posted on 2004-04-19
13
746 Views
Last Modified: 2010-04-04

Hi

I'm using indy in a Delphi 5 development to send emails, and I want to attach PDF doc's, however the PDF docs are in a blob field in a SQL server DB.

Is there a way to stream direct from the blob field to the attachment, without having to write it to a file.

I really don't want to have to create files, I know this would be simpler in many ways, but with many users using the system it becomes more complex etc...
0
Comment
Question by:dealclickcouk
  • 3
  • 2
  • 2
  • +2
13 Comments
 
LVL 12

Accepted Solution

by:
Ivanov_G earned 43 total points
ID: 10860210

I have suggestion with saving files
first you need to extract the blob in TADOBlobStream class and save it. Then use the procedure below.

function TfrmMain.SendMail(FileToSend: String): String;
var
  MailMsg        : TidMessage;
  MailFile       : TidAttachment;
begin
  // send the mail with the attachment
  MailMsg := TidMessage.Create(idSMTP);
  // from
  MailMsg.From.Address := 'someone@somewhere.com'; //GetOption('FromAddress');
  MailMsg.From.Name    := 'Your name'; //Application.Title;
  // to
  MailMsg.Recipients.Add;
  MailMsg.Recipients.Items[0].Address := 'receiver@domain.com'; //GetOption('ToAddress');
  MailMsg.Subject      := 'Subject';
  // the attachment
  MailFile             := TidAttachment.Create(MailMsg.MessageParts, FileToSend);
  MailFile.DisplayName := MailMsg.Subject;

  idSMTP.Connect();
  idSMTP.Send(MailMsg);

  // close connection and free memory
  idSMTP.Disconnect;
  MailFile.Free;
  MailMsg.Free;
end;
0
 
LVL 17

Assisted Solution

by:mokule
mokule earned 41 total points
ID: 10860380

In addition to Ivanov_G I suggest using

GetTempFileName

 which can assure that You create unque filename
0
 

Author Comment

by:dealclickcouk
ID: 10860496

Think you're missing the point, I know I can get the blob to a file and then attach it, but I don't want to do this.

I am looking for a way to do it direct from the blob field. i.e. stream from field to attachment...
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 10860548

   ne method LoadFromFile. The constructor itself requires filename... I don't have another idea...
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10860893
>I am looking for a way to do it direct from the blob field

in short, this is not possible
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 12

Assisted Solution

by:Lee_Nover
Lee_Nover earned 41 total points
ID: 10866019
a small workarround class could do it :)
try this .. not tested !


uses IdMessageCoder, IdMessage;

//MMWIN:CLASSCOPY
unit _MM_Copy_Buffer_;

interface

type
  TIdAttachmentStr = class(TIdAttachment)
  private
    FStream: TStream;
    procedure SetStream(Value: TStream);
  protected
    function MStream: TMemoryStream;
    function GetContentDisposition: string;
    procedure SetContentDisposition(const Value: string);
  public
    constructor Create(Collection: TIdMessageParts; const AStream: TStream = nil);
        reintroduce;
    destructor Destroy; override;
    procedure Encode(ADest: TStream);
    property ContentDisposition: string read GetContentDisposition write
        SetContentDisposition;
    property Stream: TStream read FStream write SetStream;
  end;


implementation

constructor TIdAttachmentStr.Create(Collection: TIdMessageParts;
  const AStream: TStream = nil);
begin
  inherited Create(Collection);
  FStream:=TMemoryStream.Create;
  Stream:=AStream;
end;

destructor TIdAttachmentStr.Destroy;
begin
  FreeAndNil(FStream);
  inherited;
end;

procedure TIdAttachmentStr.Encode(ADest: TStream);
begin
  with TIdMessageEncoderInfo(TIdMessageParts(Collection).MessageEncoderInfo).MessageEncoderClass.Create(nil) do
  try
    Encode(FStream, ADest);
  finally Free; end;
end;

function TIdAttachmentStr.GetContentDisposition: string;
begin
  Result := Headers.Values['Content-Disposition']; {do not localize}
end;

function TIdAttachmentStr.MStream: TMemoryStream;
begin
     Result:=TMemoryStream(FStream);
end;

procedure TIdAttachmentStr.SetContentDisposition(const Value: string);
begin
  Headers.Values['Content-Disposition'] := Value; {do not localize}
end;

procedure TIdAttachmentStr.SetStream(Value: TStream);
begin
     MStream.Clear;
     if Assigned(Value) then
        FStream.CopyFrom(Value, 0);
end;


end.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10866161
interesting, lee :-))
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 10866227
bleh .. it should descend from TIdMessagePart :-) .. or .. remove the ContentDisposition property (also it's Get/Set methods) .. and Encode should have Reintroduce directive .. I think :)
0
 

Author Comment

by:dealclickcouk
ID: 10866587

Sorry to be dumb here, but I'm not that experienced with Delphi, I'm more a VB developer.

Is the above code example to be used in a new unit, or in an existing one?

Also what do I call to use it?

And just to check, is this valid Delphi 5 code?

Again sorry for the dumb questions...
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 13189919
seems that one slipped by ..
it's a new unit
include it in your uses clause and call smtn like:
TIdAttachmentStr.Create(msg.MessagePart, YourMemoryStream);
where YourMemoryStream is a TMemoryStream in which you've loaded the blob data
do you still need this ?
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now