Quantcast
Channel: Planet Object Pascal
Viewing all 1725 articles
Browse latest View live

It's a blong, blong, blong road...: 10 Tips For Delphi Users

$
0
0

Working on some Delphi projects with some clients over recent weeks has thrown up a number of tips that have been well-received so I thought I’d write them up for a more global audience.

1) Running apps from network shares

Sometimes people like to put executables on network drives and run them from there – it allows potentially many users to launch a single executable. However if the program is running and the network connection breaks there is a more than reasonable chance that the program will crash is a quite ghastly manner, understandably enough.

Given users are at liberty to launch there apps like this it may be an idea to make habit a simple step that alleviates the aforementioned crash scenario. You can have the Delphi linker set a special bit in a 32-bit Windows executable header to instruct Windows that in the event of being launched off a network drive the executable should first be copied to the local paging file and then be launched from there. This flag was introduced in Windows NT 4.0 and described in this old MSJ article by Matt Pietrek from 1996.

This is quite straightforward. You can do this with a compiler directive in the project file or you can change the linker setting (at least in recent versions of Delphi).

To change the project file, you must make sure that Windows (or Winapi.Windows, if you prefer) is in the uses clause and then add in this compiler directiveafter the uses clause:

{$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP}

To set the linker option directly, open the project options dialog (Ctrl+Shift+F11), go to the Linking options, ensure you are looking at options for a 32-bit build configuration and then give a value of 2048 to the Set extra PE Header flags option. This is passed along to the compiler as the --peflags:2048 command-line switch and does the same thing.

You could work out the value to pass along yourself by looking in Winapi.Windows.pas and seeing that IMAGE_FILE_NET_RUN_FROM_SWAP has a value of $800, which in decimal in 2048.

Update: Just to clarify some points that have come up in comments, this linker setting does not affect operation of the program in terms of how .ini files shipped alongside the .exe get loaded or what the value is returned by Application.ExeName.

2) Inspecting an item in a TList

The old TList class is still a useful beast, even if in many cases we should be using the newer generic TList<T>. TList is useful when the list will potentially contain objects of different types, with suitable backup code that knows to check the type and cast appropriately.

In the debugger, if you want to inspect an item in a TList things can be a bit of a challenge. When you inspect your TList variable (Alt+F5) you get a debug inspector that hints at the items contained therein in its FList field.

TList1

If you right-click on FList and choose Descend (or Ctrl+D, to make this inspector inspect that field) or Inspect (or Ctrl+I, to launch a new inspector showing that field) you’ll see the addresses of the items in the list.

TList2

These aren’t much use though; being as this is the type-unsafe general TList these values are just pointers. Indeed if you look in the definition of TList you’ll see this FList field is a TPointerList– an array of pointers.

So what do we do to inspect the item underlying a pointer variable? Well, we cast the pointer to the right type and inspect that. To work out what type that is, add a watch that casts the address shown in the inspector to a TObject and call its ClassName method – don’t forget to ensure the watch is set to allow side effects and function calls when adding it.

TList3

This tells you the type. Now you can bring up an inspector for the currently unhelpful point by selecting it in the inspector and pressing Ctrl+I, or maybe just double-clicking it.

TList4

Then you can apply the typecast by right-clicking and choosing Type Cast... or pressing Ctrl+T, and entering the target type of TFoo (in this example’s case). And then you have what you sought:

TList5

For bonus points you can identify the target type in the CPU window’s memory pane rather than the watch window. Invoke the CPU window with Ctrl+Alt+C and pay attention just to the memory pane at the bottom left. In recent IDEs you can also just invoke a solitary memory pane using View, Debug Windows, CPU Windows, Memory 1 (Ctrl+Alt+E) or Memory 2 (Ctrl+Alt+2) or Memory 3 (Ctrl+Alt+3) or Memory 4 (Ctrl+Alt+4).

In the memory pane, firstly have the memory displayed in 8 byte chunks of data by right-clicking and choosing Display As, DWords.

Now right-click again and choose Go to address… (Ctrl+G) and enter a suitable expression based on the pointer value. In the case above the first pointer in the list had the value $27E2C20. This is an object reference – the address of an object’s instance data. So if we de-reference the pointer we’ll be at the start of the instance data. But the address of the class name string is a little way into the instance data, a distance given by the constant vmtClassName, so the required expression will be:

PInteger($27E2C20)^+vmtClassName

TList6

As mentioned, we’re now looking at the address of the class name, which is stored as a short string. To follow (de-reference) this address, right-click on it and choose Follow, Offset to Data or press Ctrl+D. This takes us to the information we seek: TFoo.

TList7

If you wish you can change the display back to bytes (right click, Display As, Bytes) and then the short string is more obvious – you can see the length prefix byte for the 4 character string is indeed 4.

TList8

3) Loop failure iteration detection

You’ve doubtless encountered this scenario while debugging. There’s an issue in a loop. The loop executes *loads* of times but you need to look into the problem so you need to know how many times round the loop the problem occurs. Stepping through the loop, or using a breakpoint and pressing F9 or clicking on the last line of the loop and pressing F4, counting in your head – all such options are mind-numbing and hugely prone to losing count or messing up in some regard, so how about letting the system work it out for you?

Place a breakpoint at the end of the loop with a massive pass count – say 1000000. Now run the app and make the problem occur. Now look in the breakpoints window and check the current pass count – it will tell you how many times the breakpoint has been passed without actually breaking.

Once you know how many iterations it has been through, modify the properties of the breakpoint and set the pass count to that value. Restart the program and the when the breakpoint triggers the error will occur on the next iteration of the loop. Nice!

4) Breakpoint logging

Breakpoints had their advanced properties added many, many versions ago. You can use advanced breakpoint properties for a variety of cunning debugging scenarios, but a simple usage is to enable cheap logging without writing additional code statements.

Wherever you want to log some information, add a breakpoint and bring up the breakpoint properties. Press the Advanced button, set the breakpoint to not actually break and then specify the log message. For bonus points you can also choose to have an expression evaluated and (optionally) logged at the same time.

AdvancedBreakpoints

This log information will be added to the Event Log window during your debug session in the same way that OutputDebugString messages are, but with the benefit of not having written any code. If you have the IDE set to save your project desktop then the breakpoints will be saved when you close the project and reappear next time you open it.

5) Leaving RTL assembler code

When stepping through code with Debug DCUs enabled you often inadvertently end up in RTL assembly code. In most instances Shift+F8 (Run, Run Until Return) will run the rest of the code through and take you back to where you were so you can try F7 again.

Shift+F8 doesn’t always work. For example if you use F7 on a call to a dynamic method you end up in the System unit’s _CallDynaInst routine. This doesn’t exit in the normal manner, but by jumping off to the located method address stored in the ESI register.

CallDynaInst

The best way forward here is to click on the JMP ESI line, press F4 to run up to that point and then press F7– that will take you into the dynamic method that was called.

6) Find declaration while debugging

Seasoned Delphi developers know that you can locate the definition of a symbol by right-clicking it in the editor and choosing Find Declaration. Rather annoyingly there is no shortcut listed next to it, but it is commonly known that if you hold down Ctrl and wave your mouse around the editor, anything that the IDE thinks it can locate the definition/declaration of turns into a hyperlink – this Ctrl+click hyperlink feature is Code Browsing and links to the Code Browsing History keystrokes of Alt+← and Alt+→ that allow you to go back and forth though the links you’ve clicked.

The problem with Ctrl+click is that it doesn’t work in a debug session. Many times it would be handy to find the definition of a symbol in a debug session but Ctrl+click just doesn’t cut it. Fortunately, however, Alt+↑ *does* work in a debug session (yay!)… (or at least should do – it generally does for me). Why Alt+↑ isn’t listed in the editor context menu against Find Declaration baffles me. It’s a very little-known but useful shortcut.

7) Non-destructively locally disable a compiler option

Often-times a build configuration has range-checking enabled to ensure problems show up when they occur as tangible issues rather than vague Access Violations through memory overwrites way down the line during an execution. That said, it can still be important to selectively turn off range-checking for specific small sections of code that are valid, but will flag up range-check errors thanks to, say, the pointer types involved.

Clearly you can turn range-checking (or overflow-checking or whatever) off and on using local compiler directives, as in:

{$R-}
//code that requires range-checking off
{$R+}

but what about if you then build the code with a build configuration that has range-checking globally disabled? This use of compiler directives means the file in question will have range-checking *enabled* from that point onwards, despite the intent being to have it disabled throughout the project.

This is where this tip comes in. You can selectively change a compiler option using code like this, where this example disables range-checking if it was enabled, and then ensures it gets enabled again if appropriate:

{$IFOPT R+}
  {$DEFINE RANGE_CHECKING_WAS_ON}
  {$R-}
{$ENDIF}
//code that requires range-checking to be disabled
{$IFDEF RANGE_CHECKING_WAS_ON}
  {$R+}
{$ENDIF}

Here we define a conditional symbol if we toggle range-checking off, and we use that symbol’s existence to decide whether to enable range-checking later.

8) Building a Delphi project at the command-line

For quite a few versions now, Delphi has used the MSBuild format for its project files and project group files. This means you can use MSBuild to build your projects and project groups, using appropriate MSBuild command-lines to pass in options or specify build targets (the targets include clean, make and build). So if you have a project Foo.dproj and you want to clean up the previously produced binaries (compiled units and executable output) and then build it in Release and Debug configurations for Win32 and Win64 you could run these commands in a RAD Studio Command Prompt:

msbuild -t:clean -p:Config=Debug -p:Platform=Win32 Foo.dproj
msbuild -t:build -p:Config=Debug -p:Platform=Win32 Foo.dproj
msbuild -t:clean -p:Config=Release -p:Platform=Win32 Foo.dproj
msbuild -t:build -p:Config=Release -p:Platform=Win32 Foo.dproj
msbuild -t:clean -p:Config=Debug -p:Platform=Win64 Foo.dproj
msbuild -t:build -p:Config=Debug -p:Platform=Win64 Foo.dproj
msbuild -t:clean -p:Config=Release -p:Platform=Win64 Foo.dproj
msbuild -t:build -p:Config=Release -p:Platform=Win64 Foo.dproj

9) Formatting entire projects

Recent versions of Delphi have offered pretty printing, as it used to be called, or source formatting as the process is now described. It’s invoked by Edit, Format Source (or Ctrl+D) and can be fully customised in the Tools, Options dialog. Your custom settings can be saved into formatter profile files.

It’s less well known that the formatter is also available through a command-line tool. You can use this to run it across all files in a project directory tree.

Assuming you’ve saved your custom IDE formatter options in a formatter profile called Formatter_MyProfile.config then you start by running up a RAD Studio Command Prompt. Now issue some commands along these lines and it’s all done for you:

set CONFIG="Formatter_MyProfile.config"
set LOG=Format.log
del %LOG%
formatter -delphi -config %CONFIG% -r –d . > %LOG%

10) Case toggle

If you are not a touch typist and occasionally type a whole bunch of code in with CAPS LOCK on you should become familiar with the keystroke that toggles the case of a marked block: Ctrl+O, U.

11) Bonus tip: disable Error Insight to lower blood pressure

I’ve said this before in talks and in writing. I’m very happy to say it again. Please, *please*, don’t suffer the shame of Error Insight and its hopeless and hapless efforts in working out what might compile and what might not. Yes, it gets the simple ones right. But any vaguely interesting project that you work within is pretty much guaranteed to be besmirched with lots of red squiggles over perfectly good code and perfectly locatable units in the uses clause all within a fully compilable code base. The fact that Error Insight continues to be enabled by default, despite the growing problem of its inaccurate problem detection is really rather surprising. I urge you to disable Error Insight by going to Tools, Options… and then locating the Code Insight options within the Editor Options.

Yes, yes, there are reasons why it gets it wrong – it’s not using the exact same code as the compiler does and doesn’t know all the things that the compiler does. But this has been the case for years, and it still offends my eyes with its tenacity of squiggling over code that has just compiled cleanly.

Ease your annoyance at Error Insight by turning it off. Then pick any of the plethora of Error Insight bugs logged on QC and vote for it/them.

Seriously though, on very large projects, disabling anything that executes and isn’t useful/productive is a benefit. When working with clients’ large projects I disable Error Insight, Tooltip Help Insight and automatic Code Completion.


Andy's Blog and Tools: IDE Fix Pack 5.31 for XE3 Update

$
0
0

The new IDE Fix Pack for XE3 had a bug that caused the Delphi Win64 compiler to crash. This is fixed with version 5.31 which only exists for RAD Studio XE3 as this bug only affected XE3.

NameIDE VersionFileSizeDownloadsAdded
IDE Fix Pack 5.3 for 20092009IDEFixPack2009Reg53.zip169.52 KB110 times 2013-06-07
IDE Fix Pack 5.3 for 20102010IDEFixPack2010Reg53.zip155.56 KB193 times 2013-06-07
IDE Fix Pack 5.3 for XEXEIDEFixPackXEReg53.zip144.64 KB332 times 2013-06-07
IDE Fix Pack 5.3 for XE2+UP4+Hotfix1XE2+UP4+HF1IDEFixPackXE2Reg53.zip210.66 KB413 times 2013-06-07
IDE Fix Pack 5.3 for XE4XE4IDEFixPackXE4Reg53.zip206.12 KB533 times 2013-06-07
IDE Fix Pack 5.31 for XE3XE3IDEFixPackXE3Reg531.zip206.53 KB1 times 2013-06-11

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

I was involved in a big project migrating a complex stack from Windows XP to Windows 7 x86, and got scared this !@#$ out of me.

The stack communicated to WebSphere MQ on AS/400 from Windows, and on the Windows side of things consisted of a UI developed in in Cool:Gen, a C interface to a Delphi DLL, which takes care of the communication to WebSphere MQ.

Digression:

This all was histerically grown. In the beginning (early to mid 90s last century) it was a big Borland Pascal/Turbo Pascal application – running on DOS, Windows 3.1x, Windows 95 and OS/2 2.x/3.0– that talked over a propriatary layer over SNA to AS/400.
The vendor of that layer didn’t respond to a request for Windows NT 4.x compatibility, and meanwhile some client applications were about to be developed in Delphi.

So in 1997/1998 – together with a great AS/400 software developer – I wrote a SNA based APPC/CPI-C communication layer in Delphi 3 that could be accessed from both Turbo Pascal (using a file based interface) and Delphi (using an object interface).
The DOS interface was an executable around the Delphi interface, which was a set of classes.

The Delphi part of the DOS interface was centered around FindFirstChangeNotification/CreateProcess combined with MsgWaitForMultipleObjects/WaitForSingleObject to make the waiting as efficient as possible.
The DOS part of the Delphi interface was centered around this piece to make waiting efficient:

asm
  int $28
  mov ax, $1000
  int $15 { DESQview/TopView give up time slice }
  mov ax, $1680
  int $2F
end;

Thanks to the RBIL: Ralf Brown’s Interrupt List (there are now multiple HTML versions of it), it makes use of these tricks so DOS applications can efficiently wait :

About 5 years into this century, it was decided that the Turbo Pascal code should be rewritten, and that it should be done by an outsourcing “partner” (this was in the heydays of outsourcing).
Since that outsourcing party did a lot of HOST and AS/400 stuff, and there were already a lot of things written in Composer by IEF (which was originally chosen because of the expected stability of Texas Instruments but – via Sterling Software– now has ended as a cash cow at CA), the “natural” choice for the PC part was to use the IEF successor COOL:Gen (I think back then it was COOL:Gen version 5, but it is hard to find COOL:Gen version history on-line; CA is very protective about sharing knowledge, and also renamed COOL:Gen into CA Gen). Anyway, the final version delivered was in CA Gen 6, then the outsourcing contract was terminated and most source code was delivered).

By the time I got involved, the application was a whopping 3 executable files large, as the Windows version of CA Gen could not handle the number of CAGen models that the outsourcing people had come up with.

The outsourcing partner – having an off the scale CMM level– had some C experts that could do interfacing to “difficult” things on the PC side, and – I hadn’t been involved as the communication library had been maintenance free for years – called me in last minute to get the AS/400 communication working.

Since the Delphi SNA code was a tad complicated, and the time frame was about zero, I wanted to stick do Delphi and proposed a 3-function (InitSNA/CallSNA/ExitSNA) DLL that  the C guys would need to call.

Back then, my warning system should have gone bezerk, as I had to teach their C experts how to call a DLL, heck even make a sample Visual C 6 project that showed one call.

In fact, I made use of the – then undocumented – dcc32 JPH switch so the Delphi compiler would emit .hpp, .lib and .def files, created a Visual C 6 sample project for one specific call on the AS/400 with documentation that they should change that sample code (and the error checking) according to the documented system requirements for each available call.

This year I found out that they did not adapted error checking, so all calls have the same checks. Which explains the number of errors you get when something fails.

But wait, there is more!

The CallSNA function basically transmits a buffer (slightly over 8k) back and forth between the PC and the AS/400. The business logic on both sides knows how to pack/unpack the buffer contents, and the asian outsourcing company rewrite that part in C based on some Turbo Pascal examples they tried to read.

Since I wasn’t allowed to spend more than 60 hours on this (they almost went bezerk when it appeared to be 85 hours), I was not allowed to do any code inspection.
In retrospect (I still was a relatively young nerd), I should have stopped the project right there, questioned the use of CA Gen, and proposed a Windows RAD solution in .NET or Delphi. But that was then.

I translated the Delphi 3 code into Delphi 5 (the only Delphi version available at the client).

Actually – welcome to the corporate world – it would have taken them at least 4 weeks to give me a proper account and access to the building, so

  1. I wrote most of the code in Delphi 7 on my laptop,
  2. backported it to Delphi 5,
  3. transferred the changes a couple of times a day by my 28k8 modem, which would go 14k4 over their corporate phone system, mostly borrowing the line of a FAX machine as their phones could not dial out after-hours, but the FAX machines could,
  4. each time have one of their employees download it and put it on a corporate development machine).

About 2 years ago, I was given the task of migrating the whole layer from SNA to something modern (TCP/IP based, it turned out to be WebSphere MQ).
That started out as a tough job (when switching version control systems from CVS, via MKS Integrity to Serena Dimensions, they managed to loose 75% of the source code). But with some old partial backups I had somewhere on CD-ROM, I managed to restore the full source.
The move to MQ worked out dandy, as the CA Gen stuff didn’t need any changes (I had made the 3 function interface so generic that it could survive a major overhaul), and even more important: the end users were really happy as the MQ based communication path was at least twice as fast as the Windows->SNA-Server->Enterprise-Extender->Host->AS/400 communication path.

Last year, I was given the task of migrating it over from Windows XP to Windows 7 (which meant from Delphi 2006 to Delphi XE2).
That worked out well for the DOS part (yes, some DOS apps were still being used), but not so well for the CA Gen part: it needed to be at least CA Gen 7.6 (which is still old: 2010) to survive Windows 7.

And that’s where the C code raise its ugly head, and I return from the digression:

The C code layer had quite a few pieces of code similar to the construct below, and literally thousands of manual call-site copies that were almost-but-not-entirely the same:

char *greet()
{
  char c[] = "Hello";
  return c;
}

Anyone that even remotely knows C – even me – should know that returning a local variable is bug no-no (big/bug pun intended).

Back in 2005, that code must have raised some big warnings in Visual C 6, but somehow worked. I should have insisted into scrutinizing their code.
Now – compiled by the Visual Studio 2005 commandline compiler as required by Cool:Gen 7.6 – it caused all kinds of Heisenbugs crashing in the MSVCR70.DLL with memory overwrites and null reference errors.

Since Cool:Gen 7.6 does not generate Visual Studio 2005 projects – only a mix of build batch and NMAKE files – it was virtually impossible to debug the code.
With lots of luck, we found out that Cool:Gen had a debug flag in their build tool, which generated enough stack information for the Visual Studio 2005 JIT-debugger to roughly point at the C code near to the actual bugs.

When building the DLL in 2005, I had to make it threading aware, as it would otherwise occasionally fail (occasionally as those were the days of single core CPUs with an almost zero chance of inter-thread race conditions, nowadays thread-oblivious code would have failed at one of the first tries).

Which means that a stop-gap solution like making the char array static (moving it out of the stack into global memory) would get rid of the memory overwrite, but introduce a race condition.

In the end, we decided to do the stop-gap so initial testing could start, then add <code>char *</code> parameters to the affected functions and all (thousands!) of call-sites.

–jeroen

via: Since I can’t return a local variable, what’s the best way to return a string from a C or C++ function? – Stack Overflow.


Filed under: C, CVS, Delphi, Delphi 2006, Delphi 3, Delphi 5, Delphi XE2, Development, Dimensions CM by Serena, MKS Integrity, Software Development, Source Code Management

Lazarus Team Anouncements: Lazarus 1.0.10 release available for download

$
0
0
The Lazarus team is glad to announce the release of Lazarus 1.0.10.

This is a bug fix release, built with the fpc 2.6.2.
The previous release 1.0.8 was built with 2.6.2 too, while release 1.0.6 was built with 2.6.0.

Here is the list of changes for Laz...

Žarko Gajić: Full Text Search Functionality in Delphi Applications Implementation Idea

$
0
0

delphi-sqlite-firedac-fts
Ah … real world problems require some proof-of-concept almost-finished implementation solutions.
This time I’m into figuring out what would be the best way to introduce full text search in one of my Delphi applications.

“Setup”

There’s a Delphi application operating on files. Files are located in various sub-folders and, with 99% certainty, files will not change – i.e. a provided folder and file structure is “ready only”. Folders and files are referred to using some XML as the backbone – just imagine an XML file where tags map to folders and subfolders (in a tree like fashion), files carry some attributes (name, title, version, owner, etc.) mapped to XML file-tag attributes.

The application, beside other stuff, offers search functionality for a user to locate / filter out those files “assigned to an owner” or “having a title” and alike – therefore something you could call a “metadata search”.

We are now looking into an option to provide something like full text search to the user – to have the ability to locate a file where the file content matches some token (word or partial word).

Due to the nature of the application and the nature of the target user audience, there are some requirements for any possible implementation: light implementation – must be easy to use, no complex third party engines, should work the same way on all Windows versions, no fat (paid) databases – therefore an implementation existing users will not be aware of. Also: preferably free (so the final price of the application for the end user does not go up) :)

For the sake of simplicity let’s say we are talking about TXT files. In reality the files are not TXT files – but whatever the file type actually is –we already know how to grab the textual content from it.

For the idea, here’s a simplified XML structure – all “file” tags should have all 3 attributes (name, title, owner):

<items root="E:\ftsTXTTest\A\">
  <folder name="a1">
    <file title="t" owner="o" name="n">a1\d14.txt</file>
    <file title="t" owner="o" name="n">a1\d17.txt</file>
  </folder>
  <folder name="a2">
    <file title="t" owner="o" name="n">a2\c6.txt</file>
    <file title="t" owner="o" name="n">a2\c6per.txt</file>
    <folder name="a21">
        <file>a2\a21\announce.txt</file>
        <file>a2\a21\announce_fr.txt</file>
    </folder>
    <folder name="a22">
        <file>a2\a22\c6.txt</file>
        <file>a2\a22\d6.txt</file>
        <folder name"a221">
            <file>a2\a22\a221\d11.txt</file>
            <file>a2\a22\a221\d12.txt</file>
        </folder>
    </folder>
</items> 

“Light” Full Text Search in Delphi

My initial idea was to check out what Windows as OS has to offer through its indexed Windows Search, but since each version of Windows brings something new I’ve very quickly decided not to go along that path.

I’ve spent some time investigating available options and it seemed it all boils down to either using some fat FTS engine/framework like Rubicon, Lucene, Sphinks OR rely on some database having built-in support for full text search.

Following the requirements stated before, I would want to go for a database having support for FTS queries. The database should be free, “natively” supported by Delphi and embedded (with no restrictions).

An embedded database is a database that does not run in a separate process, but instead is directly linked (embedded or integrated) into the application requiring access to the stored data. An embedded database is hidden from the application’s end-user and requires little or no ongoing maintenance.

Out of those embedded databases that include support for FTS queries – SQLite seems like the best choice.

SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. SQLite is in the public domain and does not require a license.

Having picked SQLite the natural selection for me is FireDac (formerly AnyDac from Da-Soft).

FireDAC enables native high-speed direct access from Delphi to InterBase, SQLite, MySQL, SQL Server, Oracle, PostgreSQL, DB2, SQL Anywhere, Advantage DB, Firebird, Access, Informix, DataSnap and more.

To sum up the above:

  1. Task: provide full text search queries for a read-only folder-file structure (where file types are known and content can be programmatically extracted)
    • At one time, in most cases, only 1 user will “attack” the folder (and the FTS database)
    • Text extraction requires time – should be done out of users eyes
    • Once extraction is done and content is stored, provide FTS type queries
  2. Requisites: light implementation, free, no fat-bulky engines, easy to setup and use from inside the existing application.
  3. Possible solution: SQLite + FireDac (+Delphi)
  4. Possible “problems”: speed of initial extraction, size of the database, updates to the database (even if read-only things happen), …

Complex and Less Complex Tasks In Implementing FTS

The “complex” part is the text extraction as it can take some time to extract the content (text) from files and store it in the database for FTS retrieval.
Once a folder is processed, and since we are talking about read-only locations, the search functionality from within the application is not a complex task. Text extraction could run in threads, be implemented as a Windows service or something alike – that’s something I still have to decide (read: try out).

I’ve already done a proof of concept application using FireDac and SQLite and things seem to be nicely aligning to what the final goal is – of course on a small folder structure where text extraction takes a few seconds.

Next time I’ll share some code to how to create the FTS-enabled SQLite database supporting referential integrity and how to use FireDac.

As always is the case, I would not like to spend a few moths figuring out everything leads to a dead-end. :)

Any thoughts that you want to share, if you had some similar task to implement in your Delphi applications?

I would like be as-sure-as-possible I’ve picked the right path.

DelphiTools.info: Fixed TIOBE index

$
0
0
For some unfathomable reason, the TIOBE index distinguishes between “Pascal” and “Object Pascal”, and the “Pascal” category is seeing growth: So it can’t be the old classic procedural Pascal, can it? That leaves only Object Pascal dialects (FreePascal the largest, but also Oxygene and SmartPascal/DWScript). Pascal programming isn’t dead or dying. I’m guessing they’re getting [...]

Firebird News: Django Firebird current status

$
0
0
Maximiliano Robaina announced django firebird driver status related to django 1.6 : I’m pleased to announce that django-firebird with django 1.6 support is underway. Django 1.6 is still in alpha state, so django-firebird 1.6 too. Then, you can see the current status at the master branch . The master branch has the “in develop” version. [...]

Dr.Bob's Delphi Notes: Delphi XE4 Update #1


The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Slightly more than a month ago, Thomas Müller release the experimental GExperts + code formatter for Delphi XE4.

Since there is no official GExperts for Delphi XE4 build yet, his installation instructions include this:

Use the ExpertManager tool to register GExperts to Delphi XE4.

The thing is: ExpertManager is part of GExperts, so this introduces a “chichen-and-egg” situation.

So I wrote a small batch file and a bit of documentation to install it.

Just in case you cannot download that SVN changeset easily, here are the documentation and batch-file:

Documentation

Steps to install:
0- Quit Delphi XE4
1- Download the GExperts XE4 experimental from http://blog.dummzeuch.de/2013/04/28/experimental-gexperts-code-formatter-for-delphi-xe4/
2- Recursively unpack that download
3- Copy the batch file Install-GExperts-XE4-experimental–run-as-administrator-from-ExpertManager.exe-directory.bat into that directory
4- From that directory, run the copied Install-GExperts-XE4-experimental–run-as-administrator-from-ExpertManager.exe-directory.bat
5- Run Delphi XE4
6- Check if GExperts is installed

Batch file

:: check if user is administrator

  "C:\Windows\system32\cacls.exe" "C:\Windows\system32\config\system" 1>nul 2>&1  && (goto :isAdmin)
:isNoAdmin
  echo you need to be Administrator, and (when under Vista or higher) run this using using UAC
  goto :exit

:isAdmin

:: Gets the right link for x86 (32-bit) program files
IF /I %PROCESSOR_ARCHITECTURE% == amd64 goto :x64
IF /I %PROCESSOR_ARCHITEW6432% == amd64 goto :x64
goto :x86
:x64
   :: OS is 64bit
   set ProgramFilesX86=%ProgramFiles(x86)%
  goto :continue
:x86
   :: OS is 32bit
  set ProgramFilesX86=%ProgramFiles%
  goto :continue

:continue

:: create the right directory and copy the files

  setlocal

  set TargetDirectory=%ProgramFilesX86%\GExperts for RAD Studio XE4

  mkdir "%TargetDirectory%"
::  set FilesToCopy=DbugIntf.pas ExpertManager.exe GExperts.chm GExpertsDebugWindow.exe GExpertsGrep.exe regularexpert\GExpertsRSXE4.dll Readme.txt preview.pas
  set FilesToCopy=ExpertManager.exe GExperts.chm regularexpert\GExpertsRSXE4.dll preview.pas

  for %%f in (%FilesToCopy%) do copy /y %%f "%TargetDirectory%\"
  set RegFile="%TargetDirectory%\ExpertsXE4.reg"
::  explorer /select,"%TargetDirectory%\GExpertsRSXE4.dll"

:: expand backslash into double backslash for .REG file
  set ExpertTarget="%TargetDirectory%\GExpertsRSXE4.dll"
  set ExpertTarget=%ExpertTarget:\=\\%

::Windows Registry Editor Version 5.00
::
::[HKEY_CURRENT_USER\Software\Embarcadero\BDS\11.0\Experts]
::"GExperts"="C:\\Program Files (x86)\\GExperts for RAD Studio XE4\\GExpertsRSXE4.dll"
::
  echo Windows Registry Editor Version 5.00 >%RegFile%
  echo. >>%RegFile%
  echo [HKEY_CURRENT_USER\Software\Embarcadero\BDS\11.0\Experts] >>%RegFile%
  echo "GExperts"=%ExpertTarget% >>%RegFile%
  echo. >>%RegFile%
::  explorer /select,%RegFile%
  regedit /S %RegFile%

  endlocal

  goto :exit

:exit

–jeroen

via: experimental GExperts + code formatter for Delphi XE4 « twm’s blog.


Filed under: Batch-Files, Delphi, Delphi XE4, Development, Scripting, Software Development

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Over the last couple of days, I was asking myself

“wow, the docwiki has been updated for the Delphi XE4 update 1 version of the Mac edition of the Platform Assistant, how long until the official update is out?”

These URLs from Installing the Platform Assistant on a Mac – RAD Studio didn’t work for a couple of days:

Now they do!

The reason is that yesterday Embarcadero released 29446 Update 1 for Delphi, C++Builder and RAD Studio XE4 that fixes lots of stuff: Fix list for Update 1 for RAD Studio XE4, Delphi XE4 and C++Builder XE4.

Note it is not referring to Readme – Help Update 1 for Delphi and C++Builder XE4 – RAD Studio which got released last week as 29436 Help Update 1 for Delphi, C++Builder and RAD Studio XE4. It is the real Delphi XE4 Update 1.

The cool thing: finally it is a binary patch. Not fast about as fast as a full uninstall/reinstall), but at 336 megabytes a much smaller download than the 3.7 gigabytes of 29451 Delphi XE4 and C++Builder XE4 ISO (including Update 1).

Patched update versus full uninstall/install is a trade off:

  • Patch can take a couple of hours, and is CPU bound (too bad most of it is bound to a single CPU core)
  • Uninstall/reinstall is disk-speed and disk-size bound (make sure you have 15+ gigabytes free; an SSD improves this process a lot)

altd, ftpd, keeping off-line downloads

The altd naming scheme has been mentioned at the docwiki site for a while.

It hasn’t mentioned yet that for every http://altd link, there is also an equivalent ftp://ftpd link. Those ftpd links are very useful, as they can be resumed if an altd fails to load.

So in addition to http://altd.embarcadero.com/release/radstudio/11.0/PAServer/RADPAServerXE4_upd1.pkg
t
here is ftp://ftpd.embarcadero.com/release/radstudio/11.0/PAServer/RADPAServerXE4_upd1.pkg

I use those to keep an archive of off-line downloads.

Below are some I kept for easier off-line installation (you still need to be on-line for your registration key, unless you have a license that uses an internal registration server).

Delphi XE4 RTM:

Delphi XE4 Delphi Update 1:

Delphi XE4 Update 1:

Enjoy the new update!

Note these two do not exist (yet?):

  • ftp://ftpd.embarcadero.com/download/radstudio/xe4/radstudio_xe4_upd1_esd.exe
  • ftp://ftpd.embarcadero.com/download/radstudio/xe4/radstudio_xe4_esd_upd1.exe

–jeroen

via Installing the Platform Assistant on a Mac – RAD Studio.


Filed under: Delphi, Delphi XE4, Development, Software Development Tagged: software, technology

DelphiTools.info: TIOBE isn’t the only index that needs fixing

$
0
0
Worst thing in popularity is not being considered, or found. Looks like TIOBE is not alone in differentiating Delphi and Pascal, other popularity indexes share the same issue: http://www.langpop.com/ http://lang-index.sourceforge.net/ More indexes I looked at didn’t show the “runners up”, only the top 5 or top 10, but they may as well have differentiated. For lang-index, merging [...]

Dr.Bob's Delphi Notes: Friday, June 14th, 2013, SDN Event in Ede/Wageningen (NL)

$
0
0
Friday, June 14th, 2013, is the date for the next SDN Event in Ede/Wageningen (NL).

Firebird News: GlassFish and Firebird JDBC driver Jaybird

$
0
0
This page describes how to configure GlassFish for use with Jaybird. These instructions are based on GlassFish Server Open Source Edition 3.1.2.2 and Jaybird 2.2.3.

Lazarus Team Anouncements: Lazarus 1.0.10 release available for download

$
0
0
The Lazarus team is glad to announce the release of Lazarus 1.0.10.

This is a bug fix release, built with the fpc 2.6.2.
The previous release 1.0.8 was built with 2.6.2 too, while release 1.0.6 was built with 2.6.0.

Here is the list of changes for Laz...

Firebird News: Firebird as backend in LibreOffice status

$
0
0
Here is the wiki page with the status also the Firebird-devel thread where you can read about the plan

DelphiTools.info: String unification

$
0
0
This article deals with reference-counted String theory, it doesn’t relate to String Theory, unification of gravity with other quantum forces or canadian fashion. Instead it deals with leveraging reference-counted String data to unify them and minimize memory usage requirements. edit: as pointed in the comments, the usual terminology for that optimization is interning, which is a misnomer [...]

Behind the connection: Drag And Drop from Windows Explorer

$
0
0
This article presents the required code to handle drag& drop of images from Windows Explorer to your Delphi application. The demo code shows how to drop images on a TListView and to drag & drop from TListView to a TImage. The code is fairly basic and made so that it can be clearly understood and applied to other types of controls. Drag & Drop from windows Explorer is handled by an application

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

When at clients, I often see Delphi XE2 only updated until Delphi XE2 Update 4 (sometimes not even Update 3 is installed, which means you can run into Strange Format result in Delphi XE2 when using Currency data types).

Update 4 is the latest update offered by the ‘check for updates’. But the actual latest update is CodeCentral ID: 28881, RAD Studio XE2 Update 4 Hotfix for FireMonkey and C++.

The final ISO does include this update, so if you ever need to re-install, do it from CodeCentral ID: 28882, Delphi XE2 and C++Builder XE2 ISO (includes Update 4 Hotfix).

You can check which updates you have installed in the Help -> About box of Delphi:

  • RAD Studio XE2 Update 4:
    version 16.0.4429.46931;
    Delphi XE2 and C++ Builder XE2 Update 4
  • RAD Studio XE2 Update 4 hotfix 1:
    version 16.0.4504.48759;
    Delphi XE2 and C++ Builder XE2 Update 4 HotFix1
    Delphi XE2 and C++ Builder XE2 Update 4

So be aware: sometimes the HotFix is only recognizable as the version number, not the version text.

Though HotFix is advertised as FireMonkey and C++ update, it also includes some Delphi fixes and makes sure you don’t get the below error messages from IDE Fix Pack 5.1 for 2009-XE3.

As a matter of fact, shortly after releasing, the author Andreas Hausladen posted IDE Fix Pack 5.1 for XE2 requires XE2 Hotfix 1.

Andreas Hausladen releases new versions of the IDE Fix Pack at irregular intervals. Watch the release page. Currently it is at version 5.3: IDE Fix Pack 5.3 and for Delphi XE2 it indicates “IDE Fix Pack 5.3 for XE2+UP4+Hotfix1″.

While installing the Hotfix 1, you can get messages like these:

<br />
---------------------------<br />
Embarcadero RAD Studio XE2<br />
---------------------------<br />
Error<br />
Error applying patch to file C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\lib\win64\release\IdSSLOpenSSLHeaders.dcu.  It has probably been updated by other means, and can no longer be modified by this patch.  For more information contact your patch vendor.<br />
---------------------------<br />
Abort   Retry   Ignore<br />
---------------------------<br />

The reason is that the installer thought it had enough disk space, but the dynamic swap file growth of Windows systems decreased the disk space after the initialler estimate.

Make sure you have at lease 4 gigabytes of disk space free before installing RAD Studio XE2 Update 4 Hotfix 1.

These are the error messages you can get:

<br />
---------------------------<br />
Compiler Speed Pack x86 XE2 5.1<br />
---------------------------<br />
Not all Compiler Speed Pack x86 patches were applied. Failed patches:</p>
<p>failed : Compiler Scanner GetSourceLine [Compiler.Scanner.GetSourceLine]<br />
---------------------------<br />
OK<br />
---------------------------<br />

followed by

<br />
---------------------------<br />
Compiler Speed Pack x64 XE2 5.1<br />
---------------------------<br />
Not all Compiler Speed Pack x64 patches were applied. Failed patches:</p>
<p>failed : Compiler Scanner GetSourceLine [Compiler.Scanner.GetSourceLine]<br />
---------------------------<br />
OK<br />
---------------------------<br />

Links I kept:

–jeroen


Filed under: Delphi, Delphi XE2, Development, Software Development

Te Waka o Pascal: Delphi for iOS Kick Start – Sorry, It Isn’t Here

$
0
0
I am preparing a post inspired by my recent travels to Ukraine and the United Kingdom, but in the meantime I couldn’t help but smile (ok, “smirk”) when following a link to an Embarcadero page entitled “Delphi for iOS Kick Start”, that appeared in the DelphiFeeds, um, feed. I have now bought the RemObjects solution [...]

while true do;: Datasnap Filters Compendium updated to XE4

$
0
0
Very quick info. Not tremendous useful today as when developed (Delphi 2010 time frame) but, if someone is still using my DSFC, now can find the XE4 version on google code. Currently works all the speed test and the server/client test. Consider this as a very stable beta https://code.google.com/p/dsfc/
Viewing all 1725 articles
Browse latest View live