Axamol
...is the new name for my xmldb, framework, and mb projects. It's pronouncable, and it has the letters 'xml' in it - all three of these subprojects involve XML.
My choice now is if I should release xmldb/framework together or separately. I might release them as "Axamol SQL Library" and "Axamol SAX Pipeline". Or together as "Axamol". I wrote up pros and cons. If anyone feels like reading them, I'd like opinions.
Axamol SQL Library
Recently got support for some more dynamic SQL. Jeff started using it for his SQL Logger and ran into a problem. He had some conditionally-included where clauses in his Java-generated SQL. He tried switching it to something like this:
<s:query name="foo">
<s:param name="mindate" type="date"/>
<s:param name="maxdate" type="date"/>
<s:sql databases="pgsql">
select *
from table
where (<s:param name="mindate"/> is null or date >= <s:param name="mindate"/>)
and (<s:param name="maxdate"/> is null or date <= <s:param name="maxdate"/>)
</s:sql>
</s:query>
...and found that it took 4 seconds where it used to take 15 ms. PostgreSQL was coming up with a query plan designed to work in either case, so it wasn't using his indexes. (Makes me wonder if our Oracle Reports at work should be using lexical bind variables for this same performance reason.)
So I introduced another form of dynamic query:
<s:query name="foo">
<s:param name="mindate" type="date"/>
<s:param name="maxdate" type="date"/>
<s:sql databases="pgsql">
select *
from table
where true
<s:ifNotNull param="mindate">
and date >= <s:param name="mindate"/>
</s:ifNotNull>
<s:ifNotNull param="maxdate">
and date <= <s:param name="maxdate"/>
</s:ifNotNull>
</s:sql>
</s:query>
Which just conditionally includes a SQL fragment based on whether a parameter is null. Simple but effective.
I also introduced dynamic order by clauses, also for his code. Nothing too exciting there.
He also had a list of regexps to require, but my existing <s:bindlist> dynamic SQL was general enough to handle that. I think he ended up with <s:bindlist join="" each=" and field ~* ?" param="regexps"/> or similar.
I'm not sure how much more dynamic SQL people will need. I could introduce a way to dynamically insert SQL identifiers, but hopefully that's rare to do in software. I've sometimes written queries like this:
declare
cursor grants is
select grantee, granted_role
from dba_role_privs
where granted_role in ('FOO', 'BAR');
begin
for grant in grants loop
execute immediate 'revoke ' || quote_identifier(grant.granted_role)
|| ' from ' || quote_identifier(grantee);
end loop;
end;
/
show errors
...but always as ad-hoc queries. I can't think of a reason for software to do that.
Nevertheless, I'm sure as soon as I release this code someone will ask for some form of dynamic query I haven't anticipated. People make SQL for some quite exotic stuff.
Axamol SAX Pipeline
Work on my JSP-like format for building SAX streams is going well. (Used to be .xfp. Called .axp for now, though that has an unfortunate similarity to .asp when spoken.)
I finally ditched "logicsheets", which was a stupid idea I'd gotten from Apache Cocoon. (Preprocessing .axps with XSLT to provide reusable tags.) Instead, I managed to adapt JSP's taglib idea to SAX streams. It worked out well - I even managed to derive a AxpPageContext from javax.servlet.jsp.taglib.PageContext. It has most of the same methods but makes fun of you if you try to get a JspWriter from it. It should make porting JSP taglibs easy. In particular, Struts 1.2 seems to want a PageContext to do anything, and now I have one to give it.
Multi-language support is coming. For now it supports java and java-el (Java + JSP EL expression languages). The second one only required 150 lines of code based on Apache Commons EL. (Inheritance is wonderful.) Now I'm working on PythonAxpWriter, using Jython.
I also cleaned up a lot of code and exception handling. Plus making some things just more pleasant, like the way the Ant task to compile .axps now considers them out of date if the compiler itself has changed.
AxpCompiler.Handler, the language-independent bulk of the .axp compiler, continues to defy my efforts to clean it up. It's a huge mess, and surely buggy.