yoy.be "Why-o-Why"

Am I an "old hand"?

2017-01-18 09:23  oldhand  coding dagboek delphi  [permalink]

Am I becoming an 'old hand'? Every time I see someone that doesn't have done as many years of work in Pascal, ask something about generics, I'm troubled again by this generics thing. I don't use it (much). I don't need it. I've been perfectly fine all of this work without them. Yes there is some hype nowadays about functional programming, but there's a grand glacial movement at the base of it: stong type systems. It all started even on the big metalwhere some bright minds had the sense of taking writing logic into a domain of itself with a gentle nod to mathematics, statistics and other adjacent domains. And a lot of great work was done in this domain. A lot. Some great names that now stand on their own came forth.

A recurring theme throughout of it is type systems, or the lack thereof. Or having it bolted on at a later stage. So by the time K&R came along, they took what they needed, what they could make work for them, what they needed to summon the Unix spirit from the depths. Pascal existed at the time, but C, like JavaScript much later, was born out of necessity. Created by the people there and then that needed a new wrench to tighten the new bolts of a new machine. With personal selections here and there, and careful considerations that copy a bit of the zeitgeist of the time.

What's left for us to do is try not to repeat ourselves too much. One way is keep a look-out for patterns and in new projects, know when to apply which one. Or even better, when to switch to another one. This, I think, is where it's starting to get really tough for the younger generation. There's a lot of base-knowledge to cover, some of it is superceded or obsolete, but we can't replace it with studying patterns. I've seen newbies take it on as lawas if it's forbidden to deviate from the design even just a little. Attacking establishments on the base of their deviations from a pattern. There's something to say about attacking the establishment, but blind fury will get you nowhere.

So this generics thing...  It also is in danger of being percieved as a rule, getting over-applied. As if the one true way is using it everywhere or as often as possible. Which is strange from where I stand, since I still see it as a convenience, where you can save on writing bits of code that would otherwise be painfully similar anyway. In operation the work would get handled by this extension to the type system, checking things for you in the background, making sure everything fits. But in the end the things that need to happen, occur much in the same way as if you would have written all those specialisations out in full.

That's why, as it turns out, I don't use them all that much. Perhaps it's also because of my fading belief in the object-oriented way. That too was presented some years ago as the way to go. Everything was supposed to be objects living on the internet. But it too kind of degraded in my view to a convenience, only one of the ways to manage the things inside of your program. Luckily before any of the ORM craze could tinge me. It makes you look around the horizon, in the past where you did more with arrays and pointers, and sideways where others pass messages around all the time. For now I feel like I'm stuck here, waiting for the ground to crack open and offer a new middle ground between interfaces, pointers, traits, channels, monads, and all of the above.

But that's just my humble opinion. I can't tell for sure what the next 60 years of programming machines will bring us.

TIL: 'method modifiers' are not reserved words.

2017-01-05 21:17  TILdirrw  coding delphi  [permalink]

Thing I learned today: 'method modifiers' are not reserved words. Apparently the Object Pascal parser 'consumes' these as labels that just happen to be there or not. Which means in other contexts they're free to use as identifiers, and so they're not reserved words... Strange but OK I guess as this keeps the tokenizer that does its job right before the parser, a little smaller... (How I stumbled upon this is a different story altogether, but one I may be sharing sometime soon...) I searched the documentation a bit and there they're called directives: Fundamental Syntactic Elements: Directives which I thought were things like {$XXX+}, but those are compiler directives...

So these variable names are accepted by the parser/compiler (it doesn't mind the smell at all):

procedure test;
var
stdcall,safecall,cdecl,overload,dynamic,register,abstract,reintroduce:integer;
begin
stdcall:=1;
safecall:=11;
cdecl:=111;
//...
end;

DirFind v2.0.4.494

2016-12-16 22:30  DirFind494  delphi freeware  [permalink]

DirFind

version 2.0.4.494


E-mail: Intensive Delphi 2016 and DMongoBR

2016-12-13 10:48  20161211d  delphi  [permalink]

I recently received an e-mail from Brazil where an event is about to take place: IntenseDelphi and one of the speakers will present a suite of components for MongoDB based in part on TMongoWire. As a starter I decided to respond with a write-up of a bit of history and background story of why TMongoWire came to be. It touches on a lot of other things as well, so I've made a slightly revised version to put on my website:
 
I can give you some background on TMongoWire, and if you want to know more, please ask.
 
First a bit about me, a little CV:
I started at a young age with a little BASIC on a CP/M (on a Kaypro II!),
later GW-BASIC but soon enough Turbo Pascal versions 3, 5 and 7. Almost by chance, as my father bought Turbo Pascal and Turbo C++ on a whim without really knowing what it was. My brother who is 4 years older also did some Pascal, but picked-up on C++ and later did heavy work in assembler as well.
Later, when I studied for what is now equivalent to Bachelor Computer Science, I was introduced to Delphi 3. Again almost by chance as someone I showed old Pascal DOS programs to, told me there was something new for Windows. After that I moved to Delphi versions 5 and then 7.
By then I attained my degree and started with a web-development firm. I first did PHP and later Cold Fusion, but did a lot of work of my own on Delphi-projects as a hobby.
But as hobbies go I did not put any money in new Delphi versions. Also I did not know any other Delphi developers professionally. I later heard about the schism in Delphi-world as the first versions after Delphi 7 had put off a lot of people because the IDE and editor was less good.
So I'm afraid I'm also one of those people that sticks with Delphi 7, but in part by consequence and only in part by choice. Still, thanks to the careful design of the Object Pascal language, code written for/with Delphi 7 still works really well in modern Delphi versions (just with taking care about a few little things like using AnsiString/WideString where possible.)
 
A funny fact is that I only learned about SQL and databases later on, around when I started to work on websites. I have done a lot of work in Delphi and not used the data-aware components! Also by doing PHP, ASP and Cold Fusion and developing websites without an IDE (just a source editor), I really disliked the different options you had to develop websites in Delphi. I'm conviced the IDE/RAD component eco-sphere is toxic to the performance-centric build-up of a website and will always make important choices for you that will cause problems later on when the project gets bigger.
 
So I started xxm. The Delphi compiler is so fast, it is possible to have a DLL that runs a website, when source-files change and you hit Refresh, to unload the DLL, compile a new one, load it and have it serve the page with updated logic. This way, developing a website without IDE or components would be almost the same as PHP and Cold Fusion, except in Object Pascal, and the website would perform as fast as a native service.
 
Programming a website like this reduces the work to creating a stream of HTML, and any visual components you would use offer extra overhead which takes a bit of your performance away. So that's where my search for 'really thin wrappers' comes from. When using Microsoft Access MDB's at first, and later MS SQL Server, Microsoft already developed the ADO components to do the heavy lifting, and thanks to the integration of ActiveX interfaces (IUnknown) and the type library importer (to generate ADODB_TLB.pas and others like MSXML2_TLB.pas) it's easy to use the ADO components directly (mainly Connection, Command and RecordSet, see xxmData.pas).
 
Later I also checked out other databases, but was displeased with the performance of the ODBC connector to SQLite databases. Other existing Delphi SQLite connectors were for modern Delphi versions and had long lists of 'overload' properties, which I really dislike. Using ADO much of the data-transport is based on OleVariant and I like that. Then I discovered the C API to SQLite is relatively straight-forward, and created TSQLite. Also PostgreSQL and MySQL/MariaDB have a C API DLL ready to use to connect almost directly. Since their SQL dialect is very similar, it should be easy to switch between the two (e.g. start a project off on SQLite, and later switch to PostgreSQL to serve a growing user base) so I created DataLank to take a lot of the work of switching away.
 
After that I also wanted to check out some of the new 'NoSQL' databases. I had no experience, and thought if I can write a connector I would understand more about how these databases worked.
With Redis I learned it had a human readable protocol, but was very basic and very much removed from the SQL world.
With CouchDB I learned some 'NoSQL' databases concentrate on storing (JSON) documents and can perhaps do more server-side but can do it fully separate from the front-end.
I tried RethinkDB several times: first I learned about Protocol Buffers and made Delphi support myself because I couldn't find any. By the time I got that working (remember, I'm a hobbyist programmer that only puts a few hours a week in my own projects), RethinkDB was moving away from 'ql2.proto' but was not ready with their new binary-level protocol. And the next time I checked, they were in some kind of trouble.
With MongoDB, I think a nice balance exists between storage of documents, and other features you need to do specific manipulations or queries. I was lucky to find my way through the layers of documentation to what I needed to know about the binary protcol. First BSON and then the wire protocol, both show careful design and are not needlessly complicated.
 
There are a few more on my to-do-list, but I kind of lost interest. I'm using TSQLite the most for the moment, and will probably start on a new connector if I'm sure there's the drive for it from a new project that's bound to have to run on this or that newfangled database. One big change I consider making somewhat soon, is reworking everything BSON but based on my own JSON parser I created because I needed it for a project that otherwise didn't need the bits specific for BSON...

Another Multi-User Dungeon

2016-12-08 23:15  amud  coding delphi freeware  [permalink]

I wanted to make an extra demonstration of WebSockets from/on/with an xxm project. What I also have dreamed about is making a multi-user game where players would navigate a virtual realm and manipulate the objects in it. Problem is that I don't have too much experience with playing existing multi-player online games, and that animated graphics design is not one of my strong points. But still, I wondered if combining the two would lead to something that somehow works.

So I started a project and set out to get something working, without losing too much effort on anything non-essential. Not even on a name for it, so I called it "Another Multi-User Dungeon". I've put the source up on github and host a running version on this computer at home I use to run my xxm projects (so don't shoot me if it's not available, it's not an always-on full-fledged web-server, but it also shows xxm projects don't ask much of a machine to run stabily). Feel free to have a try:
yoy.be/home/amud

The view shows, from top to bottom:

Anything you type into the entry box, when you press enter, is passed on to your in-game persona to speak into the room it is in. Click on items or people to get a list of actions you can do with it or them. Some actions use the last statement that was spoken by your in-game persona, for example 'make a note' from the NoteBloc object (ask for a NoteBloc from the hotel's receptionist). Click on an item again to select it, and in some cases extra actions are available on other items, for example the 'give' action to pass something from your inventory to someone else in the room. Most 'door' objects have a 'go' action that will move your in-game persona to a different room, unless you don't have the key to its lock or the room is fully occupied.

For now I haven't put too much up into the virtual realm. By default you enter the world in the first free room of the Sunburst Hotel, and apart of a welcome leaflet there's not much there. I thought a decent virtual realm would have computer-operated agents you could interact with, so I remembered ELIZA. A lot has changed in the world of chat-bots since then, but I thought it would be nice to have just that in there. It turns out the syntax of the bot-script at its base serves nicely for other roles as well, so I fashioned a receptionist for the hotel that answers back to some questions (and for now can provide you with a NoteBloc if you ask politely). At the city hall, there's a registry office where you can change your display name, and perhaps leave your e-mail address into the internal database, I might make it required for some operations later or if someone wants system support. There's also money you can pick-up and drop, but nothing else you can do with it (yet!).

Under the hood, it's heavily based on a single WebSocket, your 'feed' through which you get information about the virtual realm, and through which you can send commands back. The set of commands is limited and any extra requests lauched by the client-side script use a personalized single-use key based on your personal authentication key stored in LocalStorage. (I could have gone with a cookie, but if the WebSocket were hosted over TLS, LocalStorage offers slightly better security.)

I'm not sure where to take it from here. I've been thinking about creating a shop you could use money to buy things, but then you'd need something you can earn money with... And transporters that could move you to locations further away. But I guess designing more of a city will take some effort already... Perhaps I've got what I wanted: to create a platform that has the basics to build a game on. Only the idea for a specific game isn't there yet. And thinking up a thrilling plot of an exploratory adventure isn't one of my strong points either. If you have ideas please let me know in an issue on GitHub. Perhaps I could hand out a few RoomMaker objects to people and see what they do with it...

DirDiff v2.0.0.460

2016-11-13 21:04  dirdiff2  coding delphi freeware  [permalink]

DirDiff

It feels like this was a very long time in the making, but all the little bits of time here and there probably still amount to a recent number of man-hours... It took a couple of attempts to get "An O(ND) Difference Algorithm and Its Variations" by Eugene W. Myers in an implementation of my own that performed to my liking. I've chosen to use xxHash to speed things up. Once I got that, I continued the grand re-work of DirDiff so it would accept, not 2 files, but n files (or folders); handle the work in background threads, and have both the folder-overview (and XML three) and content in the same window. In case anyone would like to have a peek inside, I've decided to open-source it as well, under the MIT license on github

I've open-sourced my productivity tools

2016-11-12 16:49  tools  coding delphi freeware  [permalink]

I've finally decided to open-source a set of my home-made tools, some of which I use almost every (working) day. Some may be very taylored to my personal taste, others may be easier to use by the broader public. Most are missing documentation, but the typical operation should be self-explanatory. (Except for handy hidden features, should make a list of those somehwere sometime soon...)

These tools have been available here for download in binary form since long, but by putting the source code in a public repository I hope I can inspire anyone that would like to know more what's going on behind the scenes to have a look, and who knows perhaps get someone to make improvements or additions.

→ github.com/stijnsanders/tools

RethinkDB: here to stay or on the way out

2016-10-07 23:23  RethinkDB-in-or-out  coding delphi freeware  [permalink]

I'm worried and confused.  The news these days is that RethinkDB is shutting down, at least the company.  The database itself may live on.  I had been attempting to write a really-thin Delphi wrapper for RethinkDB a number of times before, but got diverted into writing DelphiProtocolBuffer first, because it was used for the base of the server protocol and I couldn't find the Delphi support I was looking for (I'm sorry, but I'm a bit picky). Later it looked like they were planning on dropping this in favor of something else, but I wasn't able to investigate further at that time. In the mean time, I did a CouchDB, PostgreSQL and a MariaDB/MySQL wrapper, and a neat way to tie them together, and kept TMongoWire working, which turns out to be the one in the series of DB connectors that has the most success to date. (And which envolved learning all about PBKDF2...)

So now I'm confused about wether to keep RethinkDB on my to-do list? Or drop it? Or move it up to have a look sooner... Just like MongoDB, it may be that I won't really have a full-grown project anytime soon that is based on RethinkDB, but demand for a thin Delphi wrapper is out there and makes it worth it, I don't know. (Please let me know.)

And I'm worried about this new tale of an open-source-but-also-corporate endeavour going sour. It's only natural that when the projected sales don't appear to manifest, a project is best to get ended cleanly (as I recently witnessed over at the day-job). So I'm rooting for the open-source project to find a good new home. That the eco-system of volunteers may survive the orphanization. That the real-world users may carry enough weight to force the project into a viable after-life.

It's important to have a good climate to have entrepreneurs get enticed to take the step and start a company, but with this series of high-profile undertakings going bust, and aqui-hires where users get left in the dark, it starting to look like it's running out of control. Some people may called it a bubble, but I find the image of a pendulum swinging more appropriate. Is it swinging back already? I'm in no position to tell accurately. But I am worried.

For the record, I have had no economic gain from my open-source undertakings what-so-ever (up till now?) though OpenHub estimates about half a million went into xxm up till now. Not bad for a hobby...
But about RethinkDB, I guess I'll have to wait a little until the dust settles down...

Update 2017-02-06: RethinkDB's assets have been bought from RethinkDB Inc. By something something Linux Foundation, and a re-license to the Apache Public License. Sky is clearing up.

xxHash: an extremely fast non-cryptographic hash algorithm

2016-09-23 23:50  xxHash  delphi freeware  [permalink]

md5

I'm slowly but surely (finally!) working towards a (long overdue!) rewrite of DirDiff, but this time using threads and perhaps a different algorithm. Apparently there's still progress to make there, and I read good things about the diff git is using internally. Looking into that, some performance can be gained by doing the actual comparing on hashes of the data, instead of all of the data itself. Which lead me to xxHash,  which should hit the sweet spot between fast enough and safe enough against collisions. (Unless I misunderstood.) I'm not sure if anyone thought of combining those two. But I may be looking into that for DirDiff 2... But since I didn't find a Delphi implementation rightaway, here it is, and it fits nicely with this collection of other hashes I did before. (Though xxHash is specifically a non-cryptographic hash...)

Delphi and MySQL or MariaDB

2016-09-15 21:12  libmysql  coding delphi freeware  [permalink]

Tadaa! I added a wrapper around libmysql.dll (to connect with MySQL or MariaDB) to my collection of really (really!) thin wrappers around things like ADO, or LibPQ (to connect with PostgreSQL) or now libmysql.dll. I also had the idea to align them as much as possible into almost the same interface. It's specifically not my point to have them be exactly the same, but very much almost so, just in case when I use this for a project and need to switch database back-end later on, the work that goes into that is minimalised and can concentrate around the different in SQL dialects. (for example the postgres branch here)

https://github.com/stijnsanders/DataLank/blob/master/MyData.pas 

(previously)

AES, DES (TripleDES)

2016-09-09 23:08  aesdes  coding delphi freeware  [permalink]

→ md5

I've added AES and DES. DES may be deprecated, and Triple-DES may be soon, in any way it's cryptographically superceded by other ciphers, but still in use by some systems. I should do some work extra and change array[0..7] of byte into record l,r:cardinal; end;  or even int64 but I needed it only for something small and this works, so I'll leave it at that for now.

jsonV 1.0.3

2016-07-08 22:52  jsonv103  delphi freeware  [permalink]

jsonV

Update: v1.0.3
jsonV now shows more sensible type labels, and only the fout-digit-hex-internal-value only on the most exotic variant types.
Ctrl+Shift+C now copies the value only, not just the node caption.
I also discovered a blocking issue when jsonDoc was trying to construct an array of int64 values. (more about that here)

jsonV 1.0.2

2016-06-16 17:40  jsonv102  delphi freeware  [permalink]

jsonV

Update: v1.0.2
jsonV now accepts json-files that contain an array at the root level.
I also changed jsonDoc so all OleVariant arguments are passed const. This may break older versions, but should offer a little improvement in performance.

Just another debugging story from the trenches

2016-05-27 23:23  a-debug-story  delphi  [permalink]

It's all logic, really. Once you get to the bottom of it. But getting there... Phew!

So I was working on something that had a line like this:

function TPostgresConnection.Insert(const TableName: UTF8String;
const Values: array of OleVariant; const PKFieldName: UTF8String=''): int64;

I forgot what went wrong in the beginning (it was somewhere yesterday between midnight and bedtime...) but to check something out, to debug without a debugger so to speak, I wanted to dump a string. Deep within the data-layer you can't really access the things that handle the output to the user, so I just do this:

  raise Exception.Create('debug:'+sql1);

And then run the application again and reproduce the issue you're tending to. But it doesn't throw this exception,  it throws a quite severe access violation instead, strange. Not the error it started with, but none the less something strange going on in the exact same bit of code you're working on. But it was running late and I felt ready to go to sleep, so that is where I left it. It's always nicer to leave a project in working order at the end if the working day, but problems like this typically look different when viewed with a freshly rested set of eyes.

So the next day, let's move the debug exception somewhere higher up in the function body. Actually, all that happens before is handing the values in the Values array... So instead, I put this in near the top:

  sql1:='';
l:=Length(Values);
for i:=0 to l-1 do sql1:=sql1+','+IntToHex(VarType(Values[i]),4);
raise Exception.Create(sql1);

Which gives me:

,0000,20C8,0015,FD18,46A4,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000

Hmm, so it looks like the list of VarType's of the Values array, but these values are totally bogus! The VarType constants are (at least in older Delphi versions) right there at the top of System.pas (the unit that's always included, even if you don't list in a uses-clause), $0000 is varEmpty, but $FD18 is impossible since only varArray = $2000 and varByRef = $4000 are used of the highest 4 bits... And I'm sure I didn't pass any empties in. What is this?! Time to break out the real debugger then, I guess.

An xxm project pre-compiles files that have HTML and server-side pascal in the same source-files, into a full-fledged set of .pas files and a .dpr file, have that compiled, and then hot-swaps this new DLL in place to handle the next web-requests. So the usual development on an xxm project doesn't involve the Delphi IDE (I actually use atom.io since a while now.) but since the source is right there, you can open it in the plain old Delphi IDE and have the debugger start the DLL using something like xxmHttp.exe (the xxm handler that doesn't auto-recompile like xxmHttpDev.exe, since that would interfere with debugging.)

So, let's see what the debugger makes of this Values array the moment of this debug execption:

Values: (Unassigned, Variant array of Unknown, Unknown type: 21, Variant array of Unknown, Variant array of Unknown, Unassigned, Delphi exception EAccessViolation at $...

Yikes. But good news since with debugger it is doing the exact same thing wrong. That's something you can't take for granted, but that's another story.

So setting a breakpoint at this specific call to Insert, to see if the values get passed in:

Hey! Those are the correct values. But just one press of the F7 key later:

Bam, they're gone. Hmm, switching on the compiler "Use Debug DCUs" setting and retrying this doesn't bring me into any underlying code (sometimes some behind-the-scenes work is done on variants and strings for you), so nothing there...

And then it dawned on me! I know of one thing that can 'eat' your memory like that and it's compiler optimization.

By putting in that 'debug raise', using only an unrelated string, the optimization might conclude it can get away with releasing the memory of that Values array sooner, apparently disregarding the work that's been done on it. (Newer versions of Delphi may handle this differently, but that's another story...) So having a quick try with this:

  sql1:='';
l:=Length(Values);
for i:=0 to l-1 do sql1:=sql1+','+IntToHex(VarType(Values[i]),4);
if l<1000 then
raise Exception.Create(sql1);

And it works! So that's the weird misbehaving variant array out of the way. Now I feel extra silly not remembering what was originally the thing that I thought went wrong, was I just getting tired? This function is rather new, so I was just trying to debug for the first time, I guess. Still, makes for a nice story about debugging deeper and deeper until hitting the system, then finding out what's causing your trouble, calling on more of your knowledge of that system than usual.

(In case you want to know more about what I was working on in the first place, look here.)

Delphi and PostgreSQL

2016-05-13 00:19  LibPQData  coding delphi freeware  [permalink]

Searching for an alternative way to use PostgreSQL from Delphi? In the spirit of the other as-light-as-it-gets database connector wrappers, I've converted the header(s) to the LibPQ dll. See the LibPQ and LibPQData units in this repository:

https://github.com/stijnsanders/DataLank#datalank 

To start an attempt to move to something more like a generic database layer, I've started this DataLank idea, but it needs more work. Actually I don't intend to develop it all the way into a full-fledged data-layer. Specialities of each specific database solution are so diverse and important, that I really don't want to hide them between an opaque abstraction layer. I want a database connector wrapper to be as light as possible, but also to allow access to the underlying technology. The main point for using DataLank, is to have less work changing DB's by using TDataConnection and TQueryResult types, but not no work. Adapting the used SQL to a different dialect will probably involve updating many (or all) calls the database anyway. But I'll post about that later when I put some more time in. (And perhaps write a libmysql.dll wrapper first...)

xxm v1.2.4.430

2016-05-03 19:02  xxm430  delphi freeware  [permalink]

xxm

v1.2.4.430
- xxmISAPI: fixed issue with open connections not accepting new requests

v1.2.4.424
- revised context object lifetime management (lock-less reference counting)
- demo 7 "Resources": added "If-Modified-Since"
- demo 12 "Long Polling": added example EventSource (text/event-stream)

 

jsonV: plain and simple JSON viewer based on jsonDoc

2016-02-19 21:39  jsonV  delphi freeware  [permalink]

I decided to create a really simple JSON viewer based on a TTreeView instance and jsonDoc, which itself is heavily based on OleVariants (I really hate long lists of overloads!) so I have some VarType values handled, but show the rest '('+IntToHex(VarType(v),4)+')'. It could do so much more, but it then would be no longer a really simple JSON viewer. (I currently use Atom with beautify for JSON editing.) I've commited the source in the jsonDoc repository, see here for a ready-to-run executable (It's an exe in a zip, so some browsers and virus-scanners may cry havok about the security risk):

jsonV.zip (229KB)

just an idea: var in code for variables of limited scope

2016-02-03 16:18  var-limited-scope  coding delphi  [permalink]

I've been reading around a lot about the new programming languages (Go, Rust, D, WebJavaECMACoffee6asm.ScriptX) and there's ofcourse this thing, but I still do most work for work and distraction in Delphi. So all of a sudden, in a large code block (I know, I know, one is supposed to keep their methods many and small) I thought of something like this:

all_kinds_of_important_code();

var
s:string;
begin
s:=MyObject1.GetSomeString();
ProcessString(s);
StoreStringForFutureReference(s,Now);
end;

more_code_that_makes_the_world_tick(); //perhaps even using 's' but the one declared way above...

In light of the asynchronous programming most languages get pushed upon them, and the need to have 'scope' outliving the usual runtime of the function call, this may have been considered. But purely on the basis of syntax, this could be done. A 'var' token at that point is never valid, so could get used by a parser to initiate a declaration block, followed by a begin/end block, that the compiler would know how to convert into a separate scope (with unwinding, and auto-calling release on interfaces/reference-counted-instances)...

But it currently doesn't. The closest thing you could get is define an anonymous function and call it once there and then, but that may look ugly and is too much code for what it does, in my humble opinion.

So for now I will just be (re-)using a single s:string; on top, I'm afraid. (I feel your sqeam, but I'll be really carefull I promise.)

CouchDB connector: TCouchDBConnection

2015-12-03 07:43  TCouchDB  delphi freeware  [permalink]

After creating my own wrapper around ADO with the least possible of extra's, but with the most ease-of-use I could get; I tried the same for mongoDBthen Redis; then RethinkDB, but first had to tackle protocol buffers, but in the mean time both advanced to a new version and RethinkDB dropped protocol buffers, so I dropped my RethinkDB connector and put both on the to-do list again.

So now I thought I'd look into CouchDB, it's all HTTP so it should be easy enough. The point is you connect to your CouchDB instance on an address and port that's not publicly accessible, so a full-fledged HTTP library would be too much (though it's still highly recommended nowadays to use TLS over internal connections as well, but that's on the roadmap for xxmHttp). For handling JSON I can re-use what I created for TMongoWire: jsonDoc. So there it is. For now it offers a basic call to exchange JSON with the server, but this should be enough to unlock the main features CouchDB has to offer.

→ github.com/stijnsanders/TCouchDB

tx

2015-10-16 22:24  tx  delphi freeware  [permalink]

tx started as a tool to keep track of things. From there it evolved into a new take on data, categorisation, oversight, structure, registration, evaluation...

To complete the configuration, set up a multi-user environment or tweak the project to your needs, it's advised to install and build from the source code.
To get started quickly with default configurations, download and install this easy installer. It has tx and xxm combined into a single executable (that conveniently launches the URL in the default browser at start-up), and a minimal database to get you started. Read more about configuring tx here.

txLocalOnlySetup.exe (~1.7MB)

Learn something new every day: set tab width on a plain TMemo

2015-10-09 09:30  TMemoTabWidth  delphi  [permalink]

Strange that I haven't thought of this before, but it's surprisingly easy to do:

var
  TabWidth:cardinal;
begin
  TabWidth:=12;//override the default of 32 'units'
  Memo1.Perform(EM_SETTABSTOPS,1,integer(@TabWidth));
end;

If you want/need to you can pass an array of tab-stop positions instead if just the one (but use integer(@TabWidths[0]) then).

See also EM_SETTABSTOPS

Skipping the COM registry by calling DllGetClassObject yourself

2015-09-30 16:07  DllGetClassObject  delphi  [permalink]

Yey! For the first time ever I created a COM object from the DLL, skipping the COM registry. (Should have done this much, much sooner!) Why, you ask? Just to be sure you're using the correct DLL, and that the registry is not (ab)used to divert it to another DLL. And also this way in some cases you can avoid having to get administrative privileges at some point just to get that COM registration into the Windows registry...

type
T_DGCO=function(const CLSID, IID: TGUID; var Obj): HResult; stdcall;//DllGetClassObject
var
p:T_DGCO;
f:IClassFactory;
x:IMyObject;//replace by an interface of choice
begin
p:=GetProcAddress(LoadLibrary(FullPathToDLL),'DllGetClassObject');
if (p=nil) or (p(CLASS_MyObject,IClassFactory,f)<>S_OK) then
RaiseLastOSError;
if f.CreateInstance(nil,IMyObject,x)<>S_OK then
RaiseLastOSError;
x.Hello('World');//or whatever your object does
end;

TMongoWire can now authenticate over SCRAM-SHA-1

2015-07-09 00:51  mongoAuth3  delphi  [permalink]

TMongoWire

You can now use TMongoWire on mongoDB version 3.0 or newer and authenticate over SASL with SCRAM-SHA-1. This harder form of encryption offers a strong protection of your credentials and prevents against 'man in the middle' attacks. (But does not encrypt the data over the wire, it's advised to use TLS for that.) I did not find a ready-made SASL library for Delphi, so made the required encryption tools myself. I have added this support for HMAC and PBKDF2 to md5.zip.

To authenticate, call MongoWireAuthenticate from the new unit mongoAuth3.pas on a connected TMongoWire instance. (For backwards compatibility, mongoAuth.pas remains available.)

jsonDoc: JSON object for Delphi based on IUnknown and OleVariant

2015-06-26 21:21  jsonDoc  coding delphi freeware  [permalink]

I was using bsonDoc.pas and bsonUtils.pas from the TMongoWire project in several projects that didn't have anything to do with MongoDB, so I thought this one deserved a repository of its own:

https://github.com/stijnsanders/jsonDoc#jsondoc 

yoy/delphi on beginend.net

2015-06-25 18:07  yoybe on beginendnet  delphi weblog  [permalink]

I've proposed the Delphi RSS feed of this site to https://www.beginend.net/. Thank you Eric.

 

Archive... Search...