Interesting solutions based on the TLama first answer at [WayBack] delphi – How to make a combo box with fulltext search autocomplete support? – Stack Overflow
Via: [WayBack] Nice solution by TLama – Thomas Mueller (dummzeuch) – Google+
–jeroen
Posted by jpluimers on 2018/09/12
Interesting solutions based on the TLama first answer at [WayBack] delphi – How to make a combo box with fulltext search autocomplete support? – Stack Overflow
Via: [WayBack] Nice solution by TLama – Thomas Mueller (dummzeuch) – Google+
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2018/09/11
Every now – after some period of inactivity – I get an error like this when not having changed the file at all:
--------------------------- Error --------------------------- Cannot create file "C:\Program Files (x86)\Embarcadero\Studio\18.0\Source\DUnit\src\__recovery\GUITestRunner.pas". Het systeem kan het opgegeven pad niet vinden. --------------------------- OK Details >> ---------------------------
This has been present since ever since Delphi 10 Seattle introduced the “recovery” feature on unchanged files in a read-only directory tree like for instance $(BDS).
It assumes the __recovery subdirectory has been created (which it cannot, but never raised an error about), then barfs when it cannot find the directory.
This is a classic example of “nice idea, bad execution, not caught by thinking through all the test cases”.
I think one of the roles played, is that cursor movements are part of the undo/redo stack. My suspicion is that this raises a “changed” flag, where in fact the file is unmodified.
Het systeem kan het opgegeven pad niet vinden.is the Dutch version ofERROR_PATH_NOT_FOUNDerror code0x03EnglishThe system cannot find the path specified.
Related:
–jeroen
Posted in Delphi, Development, Software Development | 2 Comments »
Posted by jpluimers on 2018/09/06
A valid SOAP message with <urn:timeStamp>9999-11-31T23:59:59.9999999</urn:timeStamp> in a xs:dateTime field return '9999-12-31 23:59:59,1000' is not a valid date and time from a Delphi application with this SOAP response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>'9999-12-31 23:59:59,1000' is not a valid date and time</faultstring>
<faultactor/>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The reason is this exception:
exception class EConvertError with message ''9999-12-31 23:59:59,1000' is not a valid date and time'.
This is from a .NET based test case passing in timeStamp = DateTime.MaxValuewhich is handled perfectly fine by other SOAP web services tested.
I know about different resolutions of time stamps, but would never expect the 999.9999 milliseconds to be rounded up to 1000 as it is always safer to truncated away from an upper limit.
A test using Soap UI [WayBack] with this parameter finally worked (max 3 digits second fraction):
<urn:timeStamp>9999-12-31T23:59:59.999</urn:timeStamp>
The true origin of problem is in this method in the Soap.XSBuiltIns unit which has been unchanged since at least Delphi 7:
function TXSBaseTime.GetMilliSecond: Word; begin Result := Round(FractionalSeconds*1000); end;
The problem exposed itself because as of Delphi XE6 the core of function TXSBaseCustomDateTime.GetAsDateTime piece was changed from
Result := EncodeDateTime(Year, Month, Day, Hour, Minute, Second, 0);
to
Result := EncodeDateTime(Year, Month, Day, Hour, Minute, Second, Millisecond);
A combination of lack of test cases and understanding XML specifications failed to reveal this bug.
The standards specify (among others):
'.' s+ (if present) represents the fractional seconds;All ·minimally conforming· processors ·must· support year values with a minimum of 4 digits (i.e., YYYY) and a minimum fractional second precision of milliseconds or three decimal digits (i.e. s.sss). However, ·minimally conforming· processors ·may· set an application-defined limit on the maximum number of digits they are prepared to support in these two cases, in which case that application-defined maximum number ·must· be clearly documented.s -- represents a digit used in the time element "second". The two digits in a ss format can have values from 0 to 60. In the formats described in this specification the whole number of seconds ·may· be followed by decimal seconds to an arbitrary level of precision. This is represented in the picture by "ss.sss". A value of 60 or more is allowed only in the case of leap seconds.Strictly speaking, a value of 60 or more is not sensible unless the month and day could represent March 31, June 30, September 30, or December 31 in UTC. Because the leap second is added or subtracted as the last second of the day in UTC time, the long (or short) minute could occur at other times in local time. In cases where the leap second is used with an inappropriate month and day it, and any fractional seconds, should considered as added or subtracted from the following minute.The reproduction is quite simple:
Posted in .NET, C#, Conference Topics, Conferences, Delphi, Development, Event, SOAP/WebServices, Software Development, XML, XML/XSD | Leave a Comment »
Posted by jpluimers on 2018/09/06
Last year, I stumbled upon [WayBack] Defer defines the “postpone procedure” pattern, this postpone should schedule a “procedure: TProc” to run it after the end of the caller method… – Cesar Romero – Google+ that points to this repository:
Some people like this usage of the RAII pattern, but I do like it even though I do not use it very often. The implementation better than my TAnonymousMethodMemento in Delphi: a memento that executes any code at end of method for various reasons:
Now the documentation could use more English (some of it is in Portuguese).
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2018/09/05
Sometimes, the Delphi WSDL importer imports fine, but the generated code does not accept test cases sent by other tools.
Below are some links for messages and comment fragments that I want to investigate further.
// Cannot unwrap:
// - Input element wrapper name does not match operation's name
// - The output part is not a complex type// CODEGEN: Generating message contract since the operation prematchChanged is neither RPC nor document wrapped.I have included the .NET message, because my experience is that searching on those gives more accurate results for something that could be broken in more than one environment.
Based on those:
ReplyAction="*" seems to be causing a lot of questions:
Some on-line tools prefer the WSDL to be in one document, but a lot of WSDL documents use import and or include features, so here are some links on that too:
wsdl:import, but now also supports wsdl:include)Bruneau Babet correctly informed me that – though Delphi SOAP clients support both document literal and RPC encoded – Delphi SOAP servers cannot support document literal, as they can only support RPC encoded. Through that I found
The Win32/native SOAP server is currently on the Deprecated list and is classified as “Other Consideration: Need alternative.” If you want a document/literal server, you should build your SOAP server using Delphi for .NET (RAD Studio), which supports the SOAP specifications that are supported by the .NET framework.
The Win32 SOAP server support generates the older RPC|Encoded style WebServices. If you want a document/literal service or a service of any other WS-I compliant style, you should build your SOAP server using Delphi Prism, which supports the SOAP specifications that are supported by the .NET framework, including WS-I compliant styles.
Unable to create a SOAP Server Application (WebService) with [WayBack] WS-I Basic Profile 1.1 compliance.
As far as I know, with delphi we can developed RPC/Encoded web services but there is no way to create Document/Literal service.
There are some companies that continue to use SOAP for information transfer, SAP one of them and we had to use C # to develop the application server.
With C# only [WayBack]
[SoapDocumentMethod]or [WayBack][SoapRpcMethod]is assigned to the Web Method.
Back on those days, the big plan was to move everything Delphi to the .NET platform which supports both document literal and RPC encoded.
All in all, document literal has been on the radar with the Delphi R&D team since at least 2009, and nothing has been done.
References:
import, but not include)WS-I Basic Profile v1.1 provides guidance for using SOAP 1.1, WSDL 1.1, and UDDI 2.0.
WS-I Basic Profile v2.0 provides guidance for using SOAP 1.2, WSDL 1.1, UDDI 2.0, WS-Addressing, and MTOM.
wsdl:import is for a WSDL importing another WSDL
wsdl:definitions element and it has namespace and location attributesxsd:import is for a schema in a WSDL importing an XSD having a different namespace (many sites incorrectly refer to this as “WSDL import element”)
xsd:schemaelement and it has id, namespace and schemaLocation attributesxsd:include is for a schema in a WSDL including an XSD having the same namespace
xsd:schema element and it has id and schemaLocation attributesR1126 An INSTANCE MUST use a “500 Internal Server Error” HTTP status code if the response message is a SOAP Fault.env:Server, a statuscode 400 is to be used, but WS-I mandates 500.I looks like a wsdl message request part entries need to be named parameters for some tooling to correctly infer document/literal in a wrapped way. Some links for further research on this:
Note how the word “wrapped” does not appear. What IBM in their document is calling “document/literal/wrapped” is simply “document/literal”, that happens to use a single message part, that happens to have a name derived from the name of the service, and that happens to refer to an element, and which happens to contain both the parameters to the operation.
When you are surely running SOAP over HTTP, you can use this small class to raise exceptions which automatically get translated into SOAP Faults having the right return code using a trick I bumped into a few years ago from [WayBack] web services – Accessing the original TWebRequest object in a Delphi SOAP Server – Stack Overflow:
unit SoapFaultWithHttpCodeExceptionUnit;
interface
uses
System.SysUtils;
type
ESoapFaultWithHttpCodeException = class(Exception)
strict private
FHttpStatusCode: Integer;
public
constructor Create(const AHttpStatusCode: Integer);
property HttpStatusCode: Integer read FHttpStatusCode;
end;
implementation
uses
Winapi.WinHTTP,
Soap.WebBrokerSOAP,
Web.HTTPApp,
IdCustomHTTPServer;
constructor ESoapFaultWithHttpCodeException.Create(const AHttpStatusCode: Integer);
var
IdHTTPResponseInfo: TIdHTTPResponseInfo;
ReasonString: string;
WebDispatcher: IWebDispatcherAccess;
begin
IdHTTPResponseInfo := TIdHTTPResponseInfo.Create(nil, nil, nil);
try
FHttpStatusCode := AHttpStatusCode;
IdHTTPResponseInfo.ResponseNo := AHttpStatusCode;
ReasonString := Format('%d: %s', [AHttpStatusCode, IdHTTPResponseInfo.ResponseText]);
inherited Create(ReasonString);
// https://stackoverflow.com/questions/10405227/accessing-the-original-twebrequest-object-in-a-delphi-soap-server
if Supports(GetSOAPWebModule, IWebDispatcherAccess, WebDispatcher) then
begin
WebDispatcher.Response.StatusCode := HTTP_STATUS_SERVER_ERROR;
WebDispatcher.Response.ReasonString := ReasonString;
end
finally
IdHTTPResponseInfo.Free;
end;
end;
end.
—jeroen
Posted in .NET, C#, Conference Topics, Conferences, Delphi, Development, Event, SOAP/WebServices, Software Development, XML/XSD | Leave a Comment »
Posted by jpluimers on 2018/09/04
Just found some notes from 2013 for my research list that are still relevant:
Note that if you are using Smart Pointers, use the ones that Spring4D implemented in 2015 named Shared/IShared<T>/TShared<T>, see [WayBack] Spring4D – Pascal Today and [WayBack2] Smart Pointers will be in Spring4D 1.2.
–jeroen
Posted in Delphi, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2018/09/03
Interesting approach, which makes one more “cross platform VCL” from outside the Embarcadero pipeline [WayBack] The Delphi VCL comes to Oxygene:
Developers switching from Delphi to Oxygene are loving our “Delphi RTL” compatibility library, as it helps them move their code over to new platforms without having to embrace all the new APIs at once. With the new Elements 10 builds we shipped in the past couple of weeks,
CrossVCL (by KSDev, the former FMX architects) already brings VCL to Linux through the Embarcadero compilers; VCL for Oxygene brings it – through the Oxygene compilers – to WebAssembly first and later to Cocoa and WPF.
I wonder how Windows VCL compatible both approaches are.
Via [WayBack] https://blogs.remobjects.com/2018/08/30/the-delphi-vcl-comes-to-oxygene/ – Ondrej Kelle – Google+
–jeroen
Posted in Delphi, Development, Oxygene, Pascal, Software Development | 2 Comments »
Posted by jpluimers on 2018/08/30
A while ago, Marjan Venema was in need for [Archive.is] Delphi SOAP: delete temporary file after response dispatched – Stack Overflow.
The solution there is a truly temporary file: a file stream that when the handle closes will have Windows delete the file by setting the correct flags.
The construct is functionally identical to the JclFileUtils.TJclTempFileStream [Archive.is].
It passes these [Archive.is] file attribute constant flags to the [Archive.is] CreateFileW Windows API function:
FILE_ATTRIBUTE_TEMPORARYFILE_FLAG_DELETE_ON_CLOSEI was glad she asked, though I wanted a temporary file to last after debugging, so I wrote code like this because internally the same FileGetTempName method is used by the JCL:
var
// ...
TempPath: string;
TempStream: TFileStream;
TempStreamWriter: TStreamWriter;
begin
// ...
TempPath := FileGetTempName('Prefix');
TempStream := TFile.Open(TempPath, TFileMode.fmOpenOrCreate, TFileAccess.faReadWrite, TFileShare.fsRead);
try
TempStreamWriter := TStreamWriter.Create(TempStream);
try
TempStreamWriter.WriteLine('Debug starts:');
MyStringList.SaveToStream(TempStream);
TempStreamWriter.WriteLine();
// ...
TempStreamWriter.WriteLine('Debug finishes.');
finally
TempStreamWriter.Free();
end;
finally
TempStream.Free();
end;
–jeroen
Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »
Posted by jpluimers on 2018/08/30
Interesting question that raise some good tips: [WayBack] How to read data from old delphi application Paradox databases without BDE? I search for freeware or open source solution. – Jacek Laskowski – Google+
–jeroen
Posted in Database Development, Delphi, Development, Paradox, Software Development | Leave a Comment »
Posted by jpluimers on 2018/08/29
I stumbled over this commit message in [WayBack] “extended the TestAttribute with “Expected” property (#181)” which isn’t phrased correctly, but adds a very nice feature.
The feature is about WillRaiseAttribute:
constructor WillRaiseAttribute.Create(AExpectedException: ExceptClass; const AInheritance: TExceptionInheritance);
This allows tests like these:
[WillRaise(EOutOfMemory)]
procedure FailMe;
[WillRaise(EHeapException, exDescendant)]
procedure FailMeToo;
[WillRaise(Exception, exDescendant)]
procedure FailAny;
[WillRaise(EOutOfMemory)]
[Ignore('I am not behaving as I should')]
procedure IgnoreMeCauseImWrong;
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »