Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given ShortString is deprecated, what is the best method for limiting string length

It's not uncommon to have a record like this:

TAddress = record
  Address: string[50];
  City   : string[20];
  State  : string[2];
  ZIP    : string[5];
end;

Where it was nice to have hard-coded string sizes to ensure that the size of the string wouldn't exceed the database field size allotted for the data.

Given, however, that the ShortString type has been deprecated, what are Delphi developers doing to "solve" this problem? Declaring the record fields as string gets the job done, but doesn't protect the data from exceeding the proper length.

What is the best solution here?

like image 648
Nick Hodges Avatar asked Dec 17 '12 16:12

Nick Hodges


3 Answers

If I had to keep data from exceeding the right length, I'd let the database code handle it as much as possible. Put size limits on the fields, and display data to the user in data-bound controls. A TDBEdit bound to a string field will enforce the length limit correctly. Set it up so the record gets populated directly from the dataset, and it will always have the right length.

Then all you need to worry about is data coming into the record from some outside source that is not part of your UI. For that, use the same process. Have the import code insert the data into the dataset, and let its length constraints do the validation for you. If it raises an exception, reject the import. If not, then you've got a valid dataset row that you can use to populate a record from.

like image 117
Mason Wheeler Avatar answered Nov 15 '22 07:11

Mason Wheeler


The short string types in your question don't really protect the strings from exceeding the proper length. When you assign a longer value to these short strings, the value is silently truncated.

I'm not sure what database access method you are using but I rather imagine that it will do the same thing. Namely truncate any over-length strings to the maximum length. In which case there is nothing to do.

If your database access method throws an error when you give it an over long string then you would need to truncate before passing the value to the database.

If you have to truncate explicitly, then there are lots of places where you might choose to do so. My philosophy would be to truncate at the last possible moment. That's the point at which you are subject to the limit. Truncating anywhere else seems wrong. It means that a database limitation is spreading to parts of the code that are not obviously related to the database.

Of course, all this is based on the assumption that you want to carry on silently truncating. If you want to do provide user feedback in the event of truncation, then you will need to decide just where are the right points to action that feedback.

like image 43
David Heffernan Avatar answered Nov 15 '22 07:11

David Heffernan


From my understanding, my answer should be "do not mix layers".

I suspect that the string length is specified at the database layer level (a column width), or at the business application layer (e.g. to validate a card number).

From the "pure Delphi code" point of view, you should not know that your string variable has a maximum length, unless you reach the persistence layer or even the business layer.

Using attributes could be an idea. But it may "pollute" the source code for the very same reason that it is mixing layers.

So what I recommend is to use a dedicated Data Modeling, in which you specify your data expectations. Then, at the Delphi var level, you just define a plain string. This is exactly how our mORMot framework implements data filtering and validation: at Model level, with some dedicated classes - convenient, extendable and clean.

like image 24
Arnaud Bouchez Avatar answered Nov 15 '22 05:11

Arnaud Bouchez