Elevate Software

Login Login


Home  Elevate Software Blog

Icon Elevate Software Blog

Elevate Web Builder 2.01 Released
Posted by Tim Young on Wed, Aug 26 2015

Elevate Web Builder 2.01 is now available for download. If you're an existing customer, then you should be receiving an email shortly with download instructions.

2.01 Breaking Changes
The following are breaking changes in Elevate Web Builder 2.01:
  • The parameters for the TReader constructor and Initialize method have been changed.

  • The class for the TImage ContentLayout property has been changed so that it mirrors the background image layout options. You will need to reset the ContentLayout property settings for any TImage controls created using the initial Elevate Web Builder 2 release.

  • Per this incident report:

    # 4196 Line Separators Incorrectly Set to Only LF Instead of CRLF in List-Based Controls

    the TListBox, TEditComboBox, and TButtonComboBox Items properties, as well as the TMultiLineEdit Lines property must be reset if they have been assigned values at design-time using the initial Elevate Web Builder 2 release.

  • The Elevate Web Builder Web Server now automatically handles cross-resource origin headers for modules, so you do not need to manually handle such HTTP headers in your module code.

  • The Elevate Web Builder Web Server now automatically assigns URL authentication parameters (user=<UserName&password=<Password>) to the RequestUser and RequestPassword properties of the incoming TEWBServerRequest instance passed in to web server modules. This is in addition to alread automatically handling any custom Elevate Web Builder HTTP authentication headers (X-EWBUser and X-EWBPassword).
2.01 Improvements
The following are included improvements in Elevate Web Builder 2.01:
  • A new TControl Animations property that can be used to set up animations for the Left, Top, Width, Height, Opacity, and Visible properties of controls.

  • You can now use the TLayout Overflow property to implement flow and responsive design layouts.

  • There are new TCalendar and TDateEditComboBox controls for date selection.

  • There is a new TMenu control for displaying vertical menus.

  • There is a new TIconButton control for using icons like buttons.

  • The TButton control now has an Icon property that you can use to specify an icon that will appear to the left of the caption on the button.

  • There is a new TMap control for accessing Google Maps, including geocoding and marker support.

  • There are new ctIcon, ctImage, and ctDateEditComboBox TGridColumnControlType members for the TGridColumn ControlType property, allowing icons, images, and date edit combo boxes to used with grid columns.

  • There is a new TGrid AlwaysShowControls property for ensuring that grid column controls are always visible and don't need to be specifically enabled.

  • You can now control the appearance of individual cells within a grid column using the TGridColumn OnCellUpdate event.

  • There are new TGrid OnColumnChanged and OnRowChanged events for detecting when the grid's ColumnIndex and RowIndex properties change.

  • There are new TGridColumn OnEnter and OnExit events that are fired as focus shifts to or from a grid column.

  • For un-bound grids, you can now sort the rows using the TGrid SortRows method. In addition, you can use the TGridColumn OnCompare event to customize the sort.

  • For un-bound grids, you can save/load grid rows to/from JSON using the TGrid GetRows and LoadRows methods.

  • There is a new TServerRequest Timeout property (and a corresponding TDatabase Timeout property) for specifying request timeouts.

  • There is a new Refresh method for the TImage, TPlugin, and TBrowser controls for refreshing their content without having to modify their URL property. This is useful when the content changes on the server, but the URL does not.

  • There is a new TDialogCaptionBar AllowMove property that can be used to specify that a TDialog can be moved by dragging the caption bar, and a corresponding property for the TPanelCaptionBar and TPanel controls.

  • There is a new TControl DefineLayout method for "pegging" a control to its current layout bounds.

  • There is a new public (not published) TControl ClientID property that you can use to specify the unique HTML ID for the client UI element of a control. This is useful when you need to identify the element from external JavaScript.

  • The emit clause for external classes now allows for namespaces with periods (this.is.a.namespace).

  • The compiler now includes support for function/procedure references.

  • The Ord function can now be used with Boolean values (0=False, 1=True).

  • There are new DateTimeToISOStr and ISOStrToDateTime functions for converting to/from ISO 8601 date/time strings. These functions are useful when used with non-EWB REST APIs that use this date format to eliminate ambiguities with timezones/UTC.

  • The TReader and TWriter classes now include a DateTimeFormat parameter in their constructors for specifying how date/time values should be handled when being read/written as JSON: as raw integer values (the default), or as ISO 8601 strings.

  • There is a new WebDSnap unit containing a class called TDataSnapResult that can be used as a base class for creating classes for reading Delphi/C++Builder DataSnap JSON results from a server request

  • There is a new AuthenticateUser method and a new OnAuthenticateUser event for automating user authentication in web server modules.

  • There are new SendContentHeader and SendCustomContentHeader methods for handling HEAD requests in web server modules.

  • There are new SendContentStream, and SendCustomContentStreammethods for sending content in streams as responses from web server modules.

  • There are new HeaderExists, ParseHeader, and ParseHeaderAttribute methods for working with HTTP headers in web server modules.

  • The Elevate Web Builder Web Server now handles PUT and DELETE requests and will relay them on to web server modules.

  • The IDE now detects external source modifications, and will reload the modifications into the code editor.

  • There are two new code editor options in the Environment Options dialog: wrap-around and external source modification prompts.

  • New entire scope option for the find/replace bars in the code editor, and the find/replace bars now wrap their contents as the width of the IDE shrinks

  • There are new default project options for automatically saving project files before compilation, saving/restoring non-project files, default form class for new forms, and whether new forms are automatically set as auto-create in the Environment Options dialog.

  • New project, unit, form, and interface file naming is more logical now, and based upon the contents of the applicable current directory, as opposed to a base name with an ever-increasing, incremented file name suffix

  • New animation layout example project that demonstrates how to use the TControl Animations property to build animations.

  • New responsive layout example project that demonstrates how to build a responsive layout using the new TLayout Overflow property.

  • New PDF Client and PDF Module example projects that show how to dynamically return a PDF file as a content response from an Elevate Web Builder module.

  • New maps example project that shows how to use the new TMap control to display and manipulate maps using the Google Maps API.

Tags: Elevate Web Builder, New ReleasesPermanent Link 0 Comments

ElevateDB 2.19 Build 3 Released
Posted by Tim Young on Mon, Aug 10 2015

ElevateDB 2.19 Build 3 is now available for download. If you're an existing customer, then you should be receiving an email shortly with download instructions.

This build contains a bug fix for an incident report, which is detailed here.

Tags: ElevateDB, New BuildsPermanent Link 0 Comments

Why Limit Web Development to JavaScript ?
Posted by Tim Young on Fri, Aug 7 2015

I've been doing some browsing and reading recently, catching up on the current state of affairs in software development, and I came across several mentions of a quote by Anders Hejlsberg from the 2012 Lang.NEXT conference, where he was part of an expert panel on web/cloud development. You can watch the discussion yourself here:

Lang.NEXT 2012 Expert Panel: Web and Cloud Programming

I don't get as much chance as I'd like to keep up with what's going on in the industry, so at the time I missed this particular quote. In case you've been living in an even deeper cave than myself and don't know who Anders is, he created Turbo Pascal, was the chief architect of Delphi, is/was (?) the lead architect for C#, and is now working on the TypeScript language at Microsoft. As one can imagine, he definitely has some insights into the requirements of a successful development language.

During the discussion, he was asked the direct question:

"Are you saying you cannot write large programs in JavaScript?"

and he replied:

"No, you can write large programs in JavaScript. You just can't maintain them."

I won't profess to speak for Anders, but I would assume that he was talking in broad strokes with this response, and was not saying that all large JavaScript programs are un-maintainable. Rather, given a typical organization with typical resources and the typical amount of screw-ups and craziness that accompanies software development, one will typically find that large applications written in JavaScript are difficult-to-very-difficult to maintain. I'm sure that Google has no issues with throwing enough resources at flagship properties like GMail or YouTube to get them to work. But, it's probably a bad idea to predicate the success of a large segment of the software industry on always having Google-like resources at our disposal.

Of course, various blogs lit up with indignant responses, and the biggest pushback appeared to be coming from who you would expect: JavaScript developers.

Now, when I read the quote my first reaction was "duh !". This was one of the primary reasons that I started developing Elevate Web Builder in 2010-2011. Elevate Web Builder compiles Object Pascal into JavaScript, but this is not a unique idea and there are many compilers/transcoders that do the same for many different languages:

List of languages that compile to JS

Let's start out with some self-evident observations:
  • There's definitely something amiss with a language if there's a list that long of compilers/transcoders whose sole purpose is to avoid writing code in the target language.

  • JavaScript development can't be that bad, otherwise we wouldn't see the millions of web sites/web applications that are powered by JavaScript code.

  • The JavaScript engines in the various modern browsers are very good. Performance is spectacular on desktop, and normally acceptable on mobile.
So, the question is not really "Is JavaScript, the language, any good ?", but rather "Should we use only JavaScript for web development ?".

Of course, once you start getting into "should" territory, you're normally talking about very subjective arguments. But, I think it's easier than that, and I'll try to demonstrate that the arguments against using only JavaScript are not subjective at all, and are easily recognized with an objective eye. But, please don't mistake the following points for a claim that other languages are perfect, or that you cannot do stupid, awful things with them. You can, and we all do. At issue here is whether we are moving forward or backward by using only JavaScript. I also think it's important to note here that much of JavaScript's maintainability problems stem from the fact that it's a very flexible language. In fact, in many ways it's similar to much lower-level languages in the sense that it lets you do just about anything. Unfortunately, flexibility is often the converse of maintainability. It is often the case that the languages we choose to use for development are as much about preventing us from doing bad things, as they are about allowing us to do good things.

Code Size
Because JavaScript is shipped to the browser as textual source code, there has traditionally been a size limit forced upon JavaScript developers that is derived from the bandwidth of a typical user's Internet connection. In the early days of browser development, connections were so slow that even a 30-50k source file would have been considered suicide. This resulted in source code that tried to keep identifiers as short as possible, which should not be necessary and is completely contrary to good software engineering practices. JavaScript minification was developed to ease this burden, but I'm probably not the only person in the world (or maybe I am) to wonder: if one needs to post-process their source code prior to deployment, then perhaps we should use this as an opportunity to recognize that shipping readable source code to a remote execution environment is probably not a wise choice. It's simple logic. If we don't ever want to ship source code because it's too large or there are IP issues involved, and the resulting minified source code isn't readable by a human, then why are we arbitrarily restricting ourselves to one language ? Shouldn't we just compile to web assembly ?

One can also imagine that this problem will only get worse as single-page web applications that load as pure JavaScript, such as Elevate Web Builder, become more and more prevalent, and as SAAS continues to replace traditional desktop/LAN applications.

This code size issue also plays into the problems with modularization and packaging of deployed code. Minification is great for monolithic source files, but is a non-starter for any identifiers in library source files. One can work around this by providing mappings in the library source code between the "real" identifiers and the minified identifiers, but once you start going down that road you will eventually discover that it's simply easier to just keep non-minified identifiers for any "public" objects/functions. Of course, if you're doing what you're supposed to and re-using code, then probably 80-90% of your code is in, or should be in, such library source files, and there goes any benefits of minification. This is why I just said "screw it" with Elevate Web Builder and had it generate a single monolithic JavaScript source file for each application. The reduced code size from aggressive minification/compression across the entire identifier space, including the component library, far outweighs any downsides from including more code. And, I removed any dependency issues in the process. Proper signed/versioned module support in the browser, combined with web assembly (above) that supports exporting symbols, could be a solution for these issues.

JavaScript lacks any formal structure whatsoever, other than the ability to organize code into functions and "objects" via prototypes. It has no formal modules or namespaces, and there are two implicit scopes: function and global (I'm including constructors in the "function" category). Object instances are essentially hash tables, which means you can do things like this with them:

// Declare the Car prototype

function Car (type) {
    this.type = type;
    this.color = "red";
    this.drive = function() { return "Vrroommm !!!!!" };

// Create a Car instance

var car = new Car('Ferrari');
car.color = "red";
car.engine = "V8";
alert(car.engine); // where did that come from !

car.drive = function() { return "Wrrrrrrrr !!!!!" }
alert(car.drive()); // that's not a sound a Ferrari makes

You can define methods for any object, but they are simply references to functions that can be overwritten just like any other property. Namespaces and certain types of class scopes can be fudged using nested object literals, and the language is making progress towards proper classes with configurable properties and sealing/freezing objects, but these are all features that are not implicit/enforced and must be consciously used by the developer. One gets the distinct sense that the JavaScript (ECMAScript, officially) language committee is trying to "close the barn door after the horse has left".

Type System
Conversations about formal types in JavaScript tend to get very heated, and many JavaScript developers vehemently deny that the lack of a formal type system is an issue for the language. I've read comments from developers that blame other developers for their inability to always write perfect JavaScript code without runtime type errors. To me, this is just nuts. When, God forbid, an airliner crashes due to pilot error, or a surgeon amputates the wrong limb, we don't dwell on the fact that a human being made a mistake. No, in fact we immediately begin to examine the systems in place that allowed the human error to be introduced in the first place. I don't mean to diminish the gravity of such real-life horrors by comparing them to a UI bug in a browser application, but there is something to be learned here in how such errors are handled.

So, let's start out with the simplest question: why ? Why would you want to be forced to worry about creating unit tests and other automated tests to catch simple bugs that compilers with formal type systems have been catching for many years ? Isn't it the entire purpose of computers and software to process huge amounts of information in an error-free way, over and over again, so that we don't have to ?

A JavaScript developer might reply: yes, but then you have to declare types for everything and do things like casting to satisfy the compiler.

Again, a simple question: are you writing completely undocumented code ? If not, then I can pretty much guarantee that you're specifying a type for that variable or parameter, and there's a very good chance that it's located in a documentation comment block right above the actual function. Go take a look at the Google Maps API, or documentation for the built-in browser DOM objects and functions. What you'll find is that almost all of the function parameters, variables, and properties are documented as using a specific type. A formal type system would a) make in-source type documentation unnecessary, and b) make the source code self-documenting. In addition, documentation skeletons can be automatically created directly from the source code (this is what we do here at Elevate Software) and IDE productivity features like code completion and refactoring can be used.

An easy thought experiment is this: what would you rather step in to maintain ? An application built in a language that had no formal type system, or a language that does ? Anyone that indicates the former is not being 100% honest. It's just a plain fact that its easier, relatively speaking, to read source code that has formal type information. This does not account for other aspects of the code, of course.

Finally, let me put forth the most important question when deciding to use a language like JavaScript with no formal type system: what exactly are you gaining by not having types ? The ability to define a function parameter that can accept any type of value ? Many modern languages with formal type systems have variant types for things like this, so that's not a plus, and removing all types just for this one capability amounts to "throwing the baby out with the bathwater". Apart from that, I'm hard-pressed to come up with a reason why one would want to not have types, other than it saves some additional keystrokes. I think that when you start selecting a language based upon the number of keystrokes required, you're using the wrong productivity metric. Typing is easy. Typing error-free code is not.

Ugh. There's not much need to say any more, other than this: case-sensitive languages are a forest-for-the-trees nightmare that work against the way that the human mind works. Especially a tired human mind that's been writing code for hours. They're a waste of time with no tangible benefits. Combining case-sensitivity with runtime compilation of source code, as JavaScript does (it's not alone in this regard), is a recipe for creating bugs that would normally be easily caught by the developer or the compiler.

I'll wrap things up with what I think is the most compelling argument against using only JavaScript for web applications. The web browser today has grown way beyond just a documentation presentation environment. It is no longer just being used for minimally-functional web sites. As evidenced by Elevate Web Builder, and products like it, you can build entire full-featured front-end applications that rival the functionality in desktop client applications. Application execution environments like operating systems and browsers should be language-agnostic for the simple reason that many different languages already exist, and have existed for many years prior to JavaScript, and there are millions of developers in the world that have many years of experience in these other languages. It makes much more sense, in time and money, to leverage these existing skills than to force every developer on the planet to code in the JavaScript language "just because". Furthermore, by excluding these existing language skills, you're excluding a whole host of IDEs, libraries, frameworks, etc. that could be written (or modified) to target this web execution environment. Windows languished in the development arena until developers like Anders Hejlsberg and the team at Borland started creating easy-to-use Pascal compilers and IDEs in the 90's that provided a better, more productive abstraction for the Windows API. Imagine what would have happened with Windows if you were forced to use C or C++ to write applications that target it ? Forcing a single language on a powerful application execution environment like the browser is just limiting its potential and stifling innovation. There are many different types of code, and many different types of developers that write that code. Some code should be low-level, while other code should be high-level. Forcing everyone into the same language, or trying to make one language be all things to everyone, simply does not make sense.

So, there you have it. Tell me what you think in the comments.

Tags: JavaScript, Elevate Web BuilderPermanent Link 8 Comments

Mirroring DBISAM Database Server Code
Posted by Tim Young on Wed, Jul 29 2015

You can (finally) download the promised mirroring server for DBISAM 4.35 and higher here:

Mirroring DBISAM Database Server Code

It will mirror one (and only one) database to another local or remote database, and works safely with transactions. The mirroring functionality will automatically try to open, and create if necessary, two tables in the source database:


MirrorData Table

The MirrorData table holds any data that is pending for mirroring. The ActionType field in the MirrorData indicates the type of operation:


The TableName field indicates the table on which the operation occurred (if applicable). The OldValues and NewValues fields contain the record data for record operations, and the Tables field contains the list of affected tables for transaction operations.

MirrorLog Table

The MirrorLog table contains all mirroring error messages, and the date/time when they occurred.

Mirroring Parameters

The mirroring parameters are controlled via a special section in the dbsrvr.ini file. Paste the following section into your dbsrvr.ini and modify as necessary in order to properly set up and enabled the mirroring server.

[Mirror Parameters]
; Mirror update interval (default is 1000 milliseconds)
Mirror Update Interval=1000
; Max mirror failure retries (default is 4)
Mirror Max Fail Retries=4
; Mirror session type (0=Local 1=Remote)
Mirror Session Type=0
; Mirror remote session host name
Mirror Remote Host=
; Mirror remote session address
Mirror Remote Address=
; Mirror remote session port
Mirror Remote Port=12005
; Mirror remote session service name
Mirror Remote Service=
; Mirror remote session user name
Mirror Remote User=Admin
; Mirror remote session password
Mirror Remote Password=DBAdmin
; Mirror ping interval (default is 30 seconds)
Mirror Remote Ping Interval=30
; Mirror database (directory if session is local, database name if session is remote)
Mirror Database=c:\mirrortarget
; Name of database to mirror
Mirrored Database=Source
; Tables to mirror, comma-separated, or single asterisk (*) for all tables (default)
Mirrored Tables=*

The Mirror Max Fail Retries determines how many times the DBISAM Database Server will attempt to retry a mirroring operation before it suspends mirroring. If mirroring is suspended, then stopping/starting the DBISAM Database Server will allow the mirroring to resume. However, if the error being experienced is fatal, such as a key violation, you will need to manually edit the MirrorData table and edit/remove the offending mirroring operations in order to allow the mirroring to successfully resume.

If you have any questions or problems, just let me know. If everyone likes this, I can see about making it a more permanent part of DBISAM so that it shows up in the Server Administration Utility, etc.

Tags: DBISAM, Mirroring, ReplicationPermanent Link 2 Comments

DBISAM 4.41 Build 2 Released
Posted by Tim Young on Wed, Jul 8 2015

DBISAM 4.41 Build 2 is now available for download. If you're an existing customer, then you should be receiving an email shortly with download instructions.

This build contains a couple of bug fixes, which are detailed here.

In addition, the DBISAM VCL products now include proper HTML help documentation for use with Embarcadero RAD Studio XE8. However, there is still a minor issue with the keywords that needs to be resolved, and currently the DBISAM documentation is not displayed on the Third Party Help menu in the IDE. Both of these issues will be resolved in the next build.

Tags: DBISAM, New BuildsPermanent Link 0 Comments

Subscription Policy Update
Posted by Sam Young on Tue, Jul 7 2015

Effective July 7, 2015, our subscription policy will be updated to include technical support on our product support forums. Our policy regarding support sessions and direct support via email, phone, or Skype will remain the same. Previously, our product support forums were primarily a source of peer support instead of technical support from us.

This subscription policy update will result in the following changes:
  • Customers with current product subscriptions will continue to be allowed to post on our product support forums. Nothing will change for those with current product subscriptions.

  • Those without a current subscription will not be allowed to post on our product support forums. However, they will still be able to read and search the content of the support forums.
Please note that the subscription renewal policy applies to each product. If, for example, you own both a DBISAM and an ElevateDB license, but only your DBISAM subscription is current, you will not be able to post in the ElevateDB product support forums.

If your subscription(s) is/are current, you will now be able to receive technical support from us on the product support forums. This support will be considered a second tier of support, below the direct support via email, phone, or Skype. The response time will normally be no more than 24 hours, as opposed to an immediate response for direct support. Also, based upon the nature of the issue we may ask that you use a support session, rather than the support forums.

If your subscription(s) have lapsed, our subscription renewal policy remains in effect. If your subscription has been expired for two to four years, you will need to renew your license at 50% of the list price. If your subscription has been expired for more than 4 years (5 years from your last purchase or subscription renewal), you will need to purchase a new license at the full list price.

Subscription renewal pricing is as follows:

ProductsRenewal Price
DBISAM and ElevateDB Standard and Standard with Source Code$99.00
DBISAM and ElevateDB Client-Server and Client-Server with Source Code$159.00
Elevate Web Builder$99.00

As always, please contact me at sales@elevatesoft.com if you have any questions regarding this policy change.

Tags: SubscriptionsPermanent Link 0 Comments

Previous Entries: 1-6 7-12 13-18 19-24 25-30 31-36 37-42 43-48 49-54 55-60 61-66 67-72 73-78 79-84 85-90 91-96 97-102 103-108 109-114 115-120 121-126 127-132 133-138 139-144 145-150 151-156 157-162 163-168 169-174 175-180 181-186 187-192 193-198 199-204 205-210 211-216 217-222 223-228 229-234 235-240 241-246 247-252 253-258 259-264 265-270 271-276 277-282 283-288 289-294 295-300 301-306 307-312 313-318 319-324 325-325