Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Send email attachments from a DB with Indy

Posted on 2004-04-19
13
Medium Priority
?
777 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
13 Comments
 
LVL 12

Accepted Solution

by:
Ivanov_G earned 172 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 164 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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
 
LVL 12

Assisted Solution

by:Lee_Nover
Lee_Nover earned 164 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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

610 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