5/01/2011

Mirage 1.1.2 is now available!

Mirage is a simple SQL centric database access library. See the following URL to know about Mirage:

New features in Mirage 1.1.2:

This release does not contain so big new features. However it can be used in more large fields such as small web applications by connection-pooling in standalone usage.

I wish that Mirage helps your development. Enjoy!

13 件のコメント:

匿名 さんのコメント...

Is there any grammar file for the SQL parsers included in the sources?
Also what framework was it used for it?
I would like to extend the syntax a little for internal use.

Naoki Takezoe さんのコメント...

Mirage has a hand-written parser to parse 2waySQL.
See the jp.sf.amateras.mirage.parser package in the source tree.
http://svn.sourceforge.jp/svnroot/amateras/mirage/trunk/mirage/src/main/java/jp/sf/amateras/mirage/parser/

匿名 さんのコメント...

Thanks for your answer. The parser however it's not working properly with Oracle: it eats all optimizer hints of the form: "select /*+ first_rows(1) */a, b, c from d"

匿名 さんのコメント...

Also an example on how to use the API offline would be nice: I would like to call the SQL "generation" at build time (to have the SQLs generated), or at init time, and execute it only later - for performances (and also debug reasons).

Naoki Takezoe さんのコメント...

> The parser however it's not working properly with Oracle: it eats all optimizer hints of the form: "select /*+ first_rows(1) */a, b, c from d"

I'll fix this problem as in the next version. Thanks for your feedback.

> Also an example on how to use the API offline would be nice: I would like to call the SQL "generation" at build time (to have the SQLs generated), or at init time, and execute it only later - for performances (and also debug reasons).

Mirage requires variable information not only SQL to execute generated SQL. So it's not so easy to make build time generation. However it will be able to cache these information which were parsed once at runtime for performance.

I'll push caching of parsing result into the next release.

匿名 さんのコメント...

Thanks for your answer.

> Mirage requires variable information not only SQL to execute generated SQL. So it's not so easy to make build time generation.

Yes, that's logical for dynamic code, but for code that contains no IF/ELSE blocks, the type of the parameters seems to me it could be enough to be able to have the final PreparedStatement and it's code for setting the parameters.

While caching would be very useful, generated offline code would be even more practical with an ANT task (like the other ANT tasks in Mirage) to have a "compiled" application with final beans and SQLs.

匿名 さんのコメント...

I saw the latest changes in SVN (support for Oracle hints). Very nice, thank you :).

Further, I found that:

- As Oracle hint is also --+hint, not just /*+hint*/
- The UnitTests seem to be broken now:
"cannot find symbol method getExecutedSQLInfo(int)" in SqlManagerImplTest.testIOracleHint()

Naoki Takezoe さんのコメント...

Thanks, I'll fix soon :-)
In addition, I might add some changes for handling hint comment. It's on testing phase yet.
I'll also think about build-time processing for 2waySQL.

匿名 さんのコメント...

So far Mirage has been very useful.
One case however where I don't know how to solve with Mirage is the "IN" syntax with variable number of values. E.g. select * from x where id in (val1, val2, val3);

I can't see how to to give dynamically parameters and also how to build the comment so that Mirage does the replacement.

One possibility might be to use IF blocks but that would create totally different PreparedStatements for the driver, so there would be no caching and no performance gain (only overhead) compared to simple Statements.

Thanks.

Naoki Takezoe さんのコメント...

> One case however where I don't know how to solve with Mirage is the "IN" syntax with variable number of values.

This is an example which uses IN operator in 2waySQL:

-- SQL File --
SELECT BOOK_ID, BOOK_NAME, AUTHOR, PRICE
FROM BOOK
WHERE BOOK_NAME IN /*bookNames*/('Mirage in Action')

-- Parameter Class --
public class Param {
public List<String> bookNames = new ArrayList<String>();
}

----
Param param = new Param();
param.bookNames.add("Mirage in Action");
param.bookNames.add("Essential Mirage");

List<Book> results = sqlManager.getResultList(
Book.class,
SQL_PREFIX + "SqlManagerImplTest_selectByBookNames.sql",
param);

Naoki Takezoe さんのコメント...

> One possibility might be to use IF blocks but that would create totally different PreparedStatements for the driver, so there would be no caching and no performance gain (only overhead) compared to simple Statements.

You are right.

It's one of points in the performance improvement. I'll might improve it in the future version.

However I think it's not a problem that should be fixed prior now because Mirage has more things which have to be improved such as multiple connection support.

Anyway, we will work for performance improvement in the future. We will take this problem in that time as one of problems that should be fixed.

匿名 さんのコメント...

One more problem I found (sorry for misusing your blog - I can't find the Mirage forum):
- when using dynamic SQLs (with if blocks), and when those blocks expand on the whole line, the empty lines are there in the final string too :(.
This makes the log statements very ugly :(.

I think they should be removed (not all carriage returns, but only the empty lines where the mirage commands were).

Naoki Takezoe さんのコメント...

> sorry for misusing your blog

No problem.

I improved SQL logging to remove empty lines.
However please note, the actual SQL which is thrown to database might contain empty lines.