07 April 2004. zeroCode now includes the charSet attribute in the message data type of the mail data port.
The mime message data port has now been modified to take an optional parameter, headerName, that can be used to retrieve the value of a specific header of the message. Obviously this is only for non-list UDM nodes or actions.
The envelope data type of the mime message data port now includes a field attachmentCount with the obvious meaning.
29 March 2004. zeroCode now offers a licensing mechanism for zeroCode built applications. 
With a securely-deployed jar file, the Java command java-jar app.jar shows the application's signature. This can be used, for example, to create custom license key files after shipping the application jar files. Double-clicking the jar file on a Windows system produces a similar effect. This is achieved via the ShowAppSignature class, so that the alternative command java - classpath app.jar zerocode.udm.ShowAppSignature has the same effect. Note also that the ShowAppSignature program normally waits for user input before terminating, but invoking it via the command java-classpath app.jar zerocode.udm.ShowAppSignature-q causes it to simply output the application signature and terminate immediately. The latter mode can be used to programmatically (e.g., in a script) query an application jar file for its signature.
20 March 2004. One more data attribute, sqlSize, is available to the meta-template. It indicates the declared SQL size of the data element, if any. 
17 March 2004. zeroCode now includes a script (makeSecureDeployablePackage) for securely packaging a zeroCode application.
16 March 2004. Refactored the repository access code and added the SecureRepository object for managing web content in a secured part of the deployed jar file, making it harder to reverse-engineer the application.
04 March 2004. We now show the "ignore and show no data" option for action sequence items that use the database data port. 
Action units that manipulate lists now are automatically endowed with an attribute zc__rank__ that always contains the index of the aggregate in the list. This index is reckoned from 0.
27 February 2004. There are now two additional FreeMarker variables available in the error page (errorPage.html): exceptionMessage provides the short message associated with the exception, and exceptionClass provides the Java class name of the exception.
27 February 2004. The mail data port now automatically generates a message id for incoming messages that do not have the message-id header, and provides this generated message id in the messageId attribute of the message. This modification now ensures that every message returned by the data port includes a unique message id, so that storing and retrieving messages in a database is made easier. The message id is generated by taking the MD5 hash of the message's headers, so that (a) repeated computation of this message id gives us the same value, and (b) it is highly unlikely that two different messages have the same generated message id.
18 February 2004. When accessing large tables with lots of columns, using 'select distinct' in the default mode causes performance problems. To avert this situation, zeroCode now issues a subquery that retrieves the distinct primary keys first, and then uses a full query to retrieve the actual data. This implementation is only available with non-optimized SQL, and then only if the table has a single primary key and that primary key is being retrieved by the query.
15 February 2004. zeroCode now uses jregex instead of gnu.regexp for SQL parsing using regexes in the DbObjectStore. This gives us a significant performance improvement. But there are still many places where the old gnu.regexp package is used. 
11 February 2004. Several zeroCode-related tools are now grouped together and available in the zerocode.tools package. DbCopy Copies the content of one database to another via JDBC, respecting foreign-key dependency order among tables. 
DbDump Extracts the contents of a given database and produces SQL insert statements that can be used to populate another database. The insert statements are produced in the order respecting foreign-key dependencies between tables. 
DbQuery Executes one or more SQL queries against a database, and displays the results. 
DbSnapshot Produces an XML file containing the entire content of an input database. This tool can also be used to repopulate a database using the snapshot it produces. 
RenditionGenerator Can be used to produce "renditions" by expanding a meta-template against a set of UDMs. 
SchemaComparator Compares two database schemas (specified via files containing SQL DDL statements) and shows the differences between them. This tool is unidirectional: It shows what is lacking in the first schema with respect to the second one. To get a full picture of all the differences, it must be run twice, using the two schemas in different orders. 
SchemaExtractor Extracts the schema of a given database and produces the result as a sequence of SQL DDL statements. 
UdmSync Performs "bulk synchronization" of UDMs. For use when a large database schema change has been performed. 
Each tool produces its own "usage" message when invoked without parameters. For example, the command java zerocode.tools.DbDump invokes the DbDump tool without parameters. 
03 February 2004. The UDM expression function string.join now accepts a variable number of parameters (at least 1). If the parameters are all strings, the last one is treated as the 'joiner' for joining the remaining ones.
29 January 2004. For a database-based UDM node, it is now possible to attach a 'filter string binding', which is simply another string-valued node, occurring earlier in the tree, whose value will be used as an additional contribution to the where clause of the current node. This makes it possible to determine filter clauses dynamically, based entirely on server-side criteria, with no reliance on the condition__nn feature. The filter string binding is editable via a dropdown that is displayed in the zDE data port tab of the node.
28 January 2004. In the filter editing page, the "data filtered by" choice no longer produces a subquery that contains the 'distinct' qualifier. This speeds up the query in databases like Mckoi.
The mime message data port now takes an optional parameter, headerName, that can be used to retrieve the value of a specific header of the message. Obviously this is only for non-list UDM nodes or actions.
24 January 2004. Action units can now carry two new properties. One, for action units that retrieve lists of data, allows the designer to specify that each retrieval obtains at most a given number of records. (The number is specifiable in the zDE.) When this number is specified, the action sequence retrieves only that many records, thus saving memory during run time. However, limiting the number of records also means that only those records that have been retrieved are available in the sub-actions contained within the list action. 
A second feature allows the designer to specify, for a given node that retrieves or stores data, how to handle exceptions occurring at that action: either terminate the action sequence, log the exception and continue, or simply ignore and continue.
19 January 2004. String concatenation in expressions is now a little more forgiving: If one of the operands is null and the other is a string, the null operand is now treated as the empty string, instead of simply returning a null result.
09 January 2004. The mail data port, when reading a message from a POP3 or IMAP server, now returns three new fields: sizeInBytes (the size of the message in bytes), messageBlock (the raw message) and messageId (the string specifying the globally-unique message id -- see section 4.6.1 of RFC 822).
The app stats page now shows the min and max times in addition to the average time for each operation.
01 January 2004. The page delivery code (in SimpleRequestHandler) now removes blank lines and indentation before delivering HTML pages. (This happens only for HTML pages.) This cuts down on page size and speeds up the page loading. Note also that this renders the use of the blankLineRemover transform unnecessary in many situations, and in fact the use of that transform will incur a performance penalty.